|
Packit Service |
27f74b |
# local.py
|
|
Packit Service |
27f74b |
# Automatically copy all downloaded packages to a repository on the local
|
|
Packit Service |
27f74b |
# filesystem and generating repo metadata.
|
|
Packit Service |
27f74b |
#
|
|
Packit Service |
27f74b |
# Copyright (C) 2015 Igor Gnatenko
|
|
Packit Service |
27f74b |
#
|
|
Packit Service |
27f74b |
# This copyrighted material is made available to anyone wishing to use,
|
|
Packit Service |
27f74b |
# modify, copy, or redistribute it subject to the terms and conditions of
|
|
Packit Service |
27f74b |
# the GNU General Public License v.2, or (at your option) any later version.
|
|
Packit Service |
27f74b |
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit Service |
27f74b |
# ANY WARRANTY expressed or implied, including the implied warranties of
|
|
Packit Service |
27f74b |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
Packit Service |
27f74b |
# Public License for more details. You should have received a copy of the
|
|
Packit Service |
27f74b |
# GNU General Public License along with this program; if not, write to the
|
|
Packit Service |
27f74b |
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
27f74b |
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
|
|
Packit Service |
27f74b |
# source code or documentation are not subject to the GNU General Public
|
|
Packit Service |
27f74b |
# License and may only be used or replicated with the express permission of
|
|
Packit Service |
27f74b |
# Red Hat, Inc.
|
|
Packit Service |
27f74b |
#
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
from __future__ import absolute_import
|
|
Packit Service |
27f74b |
from __future__ import unicode_literals
|
|
Packit Service |
27f74b |
from dnf.i18n import ucd
|
|
Packit Service |
27f74b |
from dnfpluginscore import _, logger
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
import dnf
|
|
Packit Service |
27f74b |
import dnf.cli
|
|
Packit Service |
27f74b |
import os
|
|
Packit Service |
27f74b |
import shutil
|
|
Packit Service |
27f74b |
import subprocess
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
class LocalConfParse(object):
|
|
Packit Service |
27f74b |
"""Parsing config
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
Args:
|
|
Packit Service |
27f74b |
conf (libdnf.conf.ConfigParser): Config to parse
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
"""
|
|
Packit Service |
27f74b |
def __init__(self, conf):
|
|
Packit Service |
27f74b |
self.conf = conf
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def get_value(self, section, key, default=None):
|
|
Packit Service |
27f74b |
if self.conf.has_section(section) and self.conf.has_option(section, key):
|
|
Packit Service |
27f74b |
return self.conf.get(section, key)
|
|
Packit Service |
27f74b |
return default
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def parse_config(self):
|
|
Packit Service |
27f74b |
conf = self.conf
|
|
Packit Service |
27f74b |
main = {}
|
|
Packit Service |
27f74b |
crepo = {}
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
if not conf.has_section("main") or not conf.has_section("createrepo") or \
|
|
Packit Service |
27f74b |
not conf.has_option("main", "enabled") or not conf.has_option("createrepo", "enabled"):
|
|
Packit Service |
27f74b |
raise KeyError("Missing key")
|
|
Packit Service |
27f74b |
main["enabled"] = conf.getboolean("main", "enabled")
|
|
Packit Service |
27f74b |
crepo["enabled"] = conf.getboolean("createrepo", "enabled")
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
if main["enabled"]:
|
|
Packit Service |
27f74b |
main["repodir"] = self.get_value("main", "repodir",
|
|
Packit Service |
27f74b |
default="/var/lib/dnf/plugins/local")
|
|
Packit Service |
27f74b |
else:
|
|
Packit Service |
27f74b |
raise KeyError("Disabled")
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
if crepo["enabled"]:
|
|
Packit Service |
27f74b |
crepo["cachedir"] = self.get_value("createrepo", "cachedir")
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
if conf.has_option("createrepo", "quiet"):
|
|
Packit Service |
27f74b |
crepo["quiet"] = conf.getboolean("createrepo", "quiet")
|
|
Packit Service |
27f74b |
else:
|
|
Packit Service |
27f74b |
crepo["quiet"] = True
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
if conf.has_option("createrepo", "verbose"):
|
|
Packit Service |
27f74b |
crepo["verbose"] = conf.getboolean("createrepo", "verbose")
|
|
Packit Service |
27f74b |
else:
|
|
Packit Service |
27f74b |
crepo["verbose"] = False
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
return main, crepo
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
class Local(dnf.Plugin):
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
name = "local"
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def __init__(self, base, cli):
|
|
Packit Service |
27f74b |
super(Local, self).__init__(base, cli)
|
|
Packit Service |
27f74b |
self.base = base
|
|
Packit Service |
27f74b |
self.main = {}
|
|
Packit Service |
27f74b |
self.crepo = {}
|
|
Packit Service |
27f74b |
self.logger = logger
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def pre_config(self):
|
|
Packit Service |
27f74b |
conf = self.read_config(self.base.conf)
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
parser = LocalConfParse(conf)
|
|
Packit Service |
27f74b |
try:
|
|
Packit Service |
27f74b |
self.main, self.crepo = parser.parse_config()
|
|
Packit Service |
27f74b |
except KeyError:
|
|
Packit Service |
27f74b |
self.main["enabled"] = False
|
|
Packit Service |
27f74b |
self.crepo["enabled"] = False
|
|
Packit Service |
27f74b |
return
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
local_repo = dnf.repo.Repo("_dnf_local", self.base.conf)
|
|
Packit Service |
27f74b |
local_repo.baseurl = "file://{}".format(self.main["repodir"])
|
|
Packit Service |
27f74b |
local_repo.cost = 500
|
|
Packit Service |
27f74b |
local_repo.skip_if_unavailable = True
|
|
Packit Service |
27f74b |
self.base.repos.add(local_repo)
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def transaction(self):
|
|
Packit Service |
27f74b |
main, crepo = self.main, self.crepo
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
if not main["enabled"] or not self.transaction:
|
|
Packit Service |
27f74b |
return
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
repodir = main["repodir"]
|
|
Packit Service |
27f74b |
if not os.path.exists(repodir):
|
|
Packit Service |
27f74b |
try:
|
|
Packit Service |
27f74b |
os.makedirs(repodir, mode=0o755)
|
|
Packit Service |
27f74b |
except OSError as e:
|
|
Packit Service |
27f74b |
self.logger.error("local: " + _(
|
|
Packit Service |
27f74b |
"Unable to create a directory '{}' due to '{}'").format(repodir, ucd(e)))
|
|
Packit Service |
27f74b |
return
|
|
Packit Service |
27f74b |
elif not os.path.isdir(repodir):
|
|
Packit Service |
27f74b |
self.logger.error(
|
|
Packit Service |
27f74b |
"local: " + _("'{}' is not a directory").format(repodir))
|
|
Packit Service |
27f74b |
return
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
needs_rebuild = False
|
|
Packit Service |
27f74b |
for pkg in self.base.transaction.install_set:
|
|
Packit Service |
27f74b |
path = pkg.localPkg()
|
|
Packit Service |
27f74b |
if os.path.dirname(path) == repodir:
|
|
Packit Service |
27f74b |
continue
|
|
Packit Service |
27f74b |
self.logger.debug(
|
|
Packit Service |
27f74b |
"local: " + _("Copying '{}' to local repo").format(path))
|
|
Packit Service |
27f74b |
try:
|
|
Packit Service |
27f74b |
shutil.copy2(path, repodir)
|
|
Packit Service |
27f74b |
needs_rebuild = True
|
|
Packit Service |
27f74b |
except IOError:
|
|
Packit Service |
27f74b |
self.logger.error(
|
|
Packit Service |
27f74b |
"local: " + _("Can't write file '{}'").format(os.path.join(
|
|
Packit Service |
27f74b |
repodir, os.path.basename(path))))
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
if not crepo["enabled"] or not needs_rebuild:
|
|
Packit Service |
27f74b |
return
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
args = ["createrepo_c", "--update", "--unique-md-filenames"]
|
|
Packit Service |
27f74b |
if crepo["verbose"]:
|
|
Packit Service |
27f74b |
args.append("--verbose")
|
|
Packit Service |
27f74b |
elif crepo["quiet"]:
|
|
Packit Service |
27f74b |
args.append("--quiet")
|
|
Packit Service |
27f74b |
if crepo["cachedir"] is not None:
|
|
Packit Service |
27f74b |
args.append("--cachedir")
|
|
Packit Service |
27f74b |
args.append(crepo["cachedir"])
|
|
Packit Service |
27f74b |
args.append(repodir)
|
|
Packit Service |
27f74b |
self.logger.debug("local: " + _("Rebuilding local repo"))
|
|
Packit Service |
27f74b |
p = subprocess.Popen(args, stdout=subprocess.PIPE,
|
|
Packit Service |
27f74b |
stderr=subprocess.STDOUT)
|
|
Packit Service |
27f74b |
for line in p.stdout:
|
|
Packit Service |
27f74b |
print(line.decode().rstrip("\n"))
|