# #
###############################################################################
-import logging
import os
import random
import string
+import actions
import builder
import config
import distro
import filelist
+import keyring
import logger
-import repository
import packages
+import repository
import satsolver
+import transaction
import util
+import logging
+log = logging.getLogger("pakfire")
+
+from config import Config
from constants import *
from i18n import _
class Pakfire(object):
- RELATIONS = (
- (">=", satsolver.REL_GE,),
- ("<=", satsolver.REL_LE,),
- ("=" , satsolver.REL_EQ,),
- ("<" , satsolver.REL_LT,),
- (">" , satsolver.REL_GT,),
- )
-
- def __init__(self, mode=None, path="/", configs=[],
- enable_repos=None, disable_repos=None,
- distro_config=None, **kwargs):
-
- # Set the mode.
- assert mode in ("normal", "builder", "server",)
- self.mode = mode
+ mode = None
+
+ def __init__(self, path="/", config=None, configs=None, arch=None, **kwargs):
+ # Indicates if this instance has already been initialized.
+ self.initialized = False
# Check if we are operating as the root user.
self.check_root_user()
# The path where we are operating in.
self.path = path
- # Configure the instance of Pakfire we just started.
- if mode == "builder":
- self.path = os.path.join(BUILD_ROOT, util.random_string())
-
- elif mode == "normal":
- # check if we are actually running on an ipfire system.
- if self.path == "/":
- self.check_is_ipfire()
-
- # Read configuration file(s)
- self.config = config.Config(type=mode)
- for filename in configs:
- self.config.read(filename)
- # Assume, that all other keyword arguments are configuration
- # parameters.
- self.config.update(kwargs)
-
- # Setup the logger
- logger.setup_logging(self.config)
- self.config.dump()
+ # check if we are actually running on an ipfire system.
+ if not self.mode and self.path == "/":
+ self.check_is_ipfire()
- # Get more information about the distribution we are running
- # or building
- self.distro = distro.Distribution(self, distro_config)
- self.pool = satsolver.Pool(self.distro.arch)
- self.repos = repository.Repositories(self,
- enable_repos=enable_repos, disable_repos=disable_repos)
-
- def __del__(self):
- # Reset logging.
- logger.setup_logging()
-
- def create_solver(self):
- return satsolver.Solver(self, self.pool)
+ # Get the configuration.
+ if config:
+ self.config = config
+ else:
+ self.config = self._load_config(configs)
- def create_request(self, builder=False):
- request = satsolver.Request(self.pool)
+ # Update configuration with additional arguments.
+ for section, settings in kwargs.items():
+ self.config.update(section, settings)
- # Add multiinstall information.
- for solv in PAKFIRE_MULTIINSTALL:
- request.noobsoletes(solv)
+ # Dump the configuration.
+ self.config.dump()
- return request
+ # Initialize the keyring.
+ self.keyring = keyring.Keyring(self)
- def create_relation(self, s):
- assert s
+ # Get more information about the distribution we are running
+ # or building
+ self.distro = distro.Distribution(self.config.get_distro_conf())
+ if arch:
+ self.distro.arch = arch
- if isinstance(s, filelist._File):
- return satsolver.Relation(self.pool, s.name)
+ self.pool = satsolver.Pool(self.distro.arch)
+ self.repos = repository.Repositories(self)
- elif s.startswith("/"):
- return satsolver.Relation(self.pool, s)
+ def initialize(self):
+ """
+ Initialize pakfire instance.
+ """
+ if self.initialized:
+ return
- for pattern, type in self.RELATIONS:
- if not pattern in s:
- continue
+ # Initialize repositories.
+ self.repos.initialize()
- name, version = s.split(pattern, 1)
+ self.initialized = True
- return satsolver.Relation(self.pool, name, version, type)
+ def _load_config(self, files=None):
+ """
+ This method loads all needed configuration files.
+ """
+ return config.Config(files=files)
- return satsolver.Relation(self.pool, s)
+ def __del__(self):
+ # Reset logging.
+ logger.setup_logging()
def destroy(self):
- if not self.path == "/":
- util.rm(self.path)
-
- @property
- def environ(self):
- env = {}
-
- # Get distribution information.
- env.update(self.distro.environ)
+ self.repos.shutdown()
- return env
+ self.initialized = False
@property
def supported_arches(self):
- return self.config.supported_arches
+ return system.supported_arches
@property
def offline(self):
"""
A shortcut that indicates if the system is running in offline mode.
"""
- return self.config.get("offline", False)
+ return self.config.get("downloader", "offline", False)
def check_root_user(self):
if not os.getuid() == 0 or not os.getgid() == 0:
raise Exception, "You must run pakfire as the root user."
- def check_build_mode(self):
- """
- Check if we are running in build mode.
- Otherwise, raise an exception.
- """
- if not self.mode == "builder":
- raise BuildError, "Cannot build when not in build mode."
-
def check_host_arch(self, arch):
"""
Check if we can build for arch.
if not arch:
return True
- if not self.config.host_supports_arch(arch):
+ if not system.host_supports_arch(arch):
raise BuildError, "Cannot build for the target architecture: %s" % arch
raise BuildError, arch
def check_is_ipfire(self):
- return # XXX disabled for now
-
ret = os.path.exists("/etc/ipfire-release")
if not ret:
# XXX just backwards compatibility
return self.mode == "builder"
- def resolvdep(self, requires):
- # Create a new request.
- request = self.create_request()
+ def install(self, requires, interactive=True, logger=None, signatures_mode=None, **kwargs):
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ if not logger:
+ logger = logging.getLogger("pakfire")
+
+ # Pointer to temporary repository.
+ repo = None
+
+ # Sort out what we got...
+ download_packages = []
+ local_packages = []
+ relations = []
+
for req in requires:
- req = self.create_relation(req)
- request.install(req)
+ if isinstance(req, packages.Package):
+ relations.append(req)
+ continue
- # Do the solving.
- solver = self.create_solver()
- t = solver.solve(request)
+ # This looks like a file.
+ elif req.endswith(".%s" % PACKAGE_EXTENSION) and os.path.exists(req) and os.path.isfile(req):
+ local_packages.append(req)
+ continue
- if t:
- t.dump()
- else:
- logging.info(_("Nothing to do"))
+ # Remote files.
+ elif req.startswith("http://") or req.startswith("https://") or req.startswith("ftp://"):
+ download_packages.append(req)
+ continue
- def install(self, requires, interactive=True, logger=None, **kwargs):
- if not logger:
- logger = logging.getLogger()
+ # We treat the rest as relations. The solver will return any errors.
+ relations.append(req)
- # Create a new request.
- request = self.create_request()
+ # Redefine requires, which will be the list that will be passed to the
+ # solver.
+ requires = relations
- # Expand all groups.
- for req in requires:
- if req.startswith("@"):
- reqs = self.grouplist(req[1:])
- else:
- reqs = [req,]
+ try:
+ # If we have got files to install, we need to create a temporary repository
+ # called 'localinstall'.
+ # XXX FIX TMP PATH
+ if local_packages or download_packages:
+ repo = repository.RepositoryDir(self, "localinstall", _("Local install repository"),
+ os.path.join(LOCAL_TMP_PATH, "repo_%s" % util.random_string()))
- for req in reqs:
- if not isinstance(req, packages.BinaryPackage):
- req = self.create_relation(req)
+ # Register the repository.
+ self.repos.add_repo(repo)
- request.install(req)
+ # Download packages.
+ for download_package in download_packages:
+ repo.download_package(download_package)
- # Do the solving.
- solver = self.create_solver()
- t = solver.solve(request, **kwargs)
+ # Add all packages to the repository index.
+ repo.add_packages(local_packages)
- if not t:
- if not interactive:
- raise DependencyError
+ # Add all packages to the requires.
+ requires += repo
- logging.info(_("Nothing to do"))
- return
+ # Do the solving.
+ request = self.pool.create_request(install=requires)
+ solver = self.pool.solve(request, logger=logger, interactive=interactive, **kwargs)
+
+ # Create the transaction.
+ t = transaction.Transaction.from_solver(self, solver)
+ t.dump(logger=logger)
- if interactive:
# Ask if the user acknowledges the transaction.
- if not t.cli_yesno():
+ if interactive and not t.cli_yesno():
return
- else:
- t.dump(logger=logger)
+ # Run the transaction.
+ t.run(logger=logger, signatures_mode=signatures_mode)
- # Run the transaction.
- t.run()
+ finally:
+ if repo:
+ # Remove the temporary repository we have created earlier.
+ repo.remove()
+ self.repos.rem_repo(repo)
- def localinstall(self, files, yes=None, allow_uninstall=False):
- repo_name = repo_desc = "localinstall"
+ def reinstall(self, pkgs, strict=False, logger=None):
+ """
+ Reinstall one or more packages.
- # Create a new repository that holds all packages we passed on
- # the commandline.
- repo = repository.RepositoryDir(self, repo_name, repo_desc,
- os.path.join(LOCAL_TMP_PATH, "repo_%s" % util.random_string()))
+ If strict is True, only a package with excatly the same UUID
+ will replace the currently installed one.
+ """
+ # Initialize this pakfire instance.
+ self.initialize()
- # Register the repository.
- self.repos.add_repo(repo)
+ if logger is None:
+ logger = logging.getLogger("pakfire")
- try:
- # Add all packages to the repository index.
- for file in files:
- repo.collect_packages(file)
+ # XXX it is possible to install packages without fulfulling
+ # all dependencies.
- # Break if no packages were added at all.
- if not len(repo):
- logging.critical(_("There are no packages to install."))
- return
+ reinstall_pkgs = []
+ for pattern in pkgs:
+ _pkgs = []
+ for pkg in self.repos.whatprovides(pattern):
+ # Do not reinstall non-installed packages.
+ if not pkg.is_installed():
+ continue
- # Create a new request that installs all solvables from the
- # repository.
- request = self.create_request()
- for solv in [p.solvable for p in repo]:
- request.install(solv)
+ _pkgs.append(pkg)
- solver = self.create_solver()
- t = solver.solve(request, uninstall=allow_uninstall)
+ if not _pkgs:
+ logger.warning(_("Could not find any installed package providing \"%s\".") \
+ % pattern)
+ elif len(_pkgs) == 1:
+ reinstall_pkgs.append(_pkgs[0])
+ #t.add("reinstall", _pkgs[0])
+ else:
+ logger.warning(_("Multiple reinstall candidates for \"%(pattern)s\": %(pkgs)s") \
+ % { "pattern" : pattern, "pkgs" : ", ".join(p.friendly_name for p in sorted(_pkgs)) })
- # If solving was not possible, we exit here.
- if not t:
- logging.info(_("Nothing to do"))
- return
+ if not reinstall_pkgs:
+ logger.info(_("Nothing to do"))
+ return
- if yes is None:
- # Ask the user if this is okay.
- if not t.cli_yesno():
- return
- elif yes:
- t.dump()
+ # Packages we want to replace.
+ # Contains a tuple with the old and the new package.
+ pkgs = []
+
+ # Find the package that is installed in a remote repository to
+ # download it again and re-install it. We need that.
+ for pkg in reinstall_pkgs:
+ # Collect all candidates in here.
+ _pkgs = []
+
+ provides = "%s=%s" % (pkg.name, pkg.friendly_version)
+ for _pkg in self.repos.whatprovides(provides):
+ if _pkg.is_installed():
+ continue
+
+ if strict:
+ if pkg.uuid == _pkg.uuid:
+ _pkgs.append(_pkg)
+ else:
+ _pkgs.append(_pkg)
+
+ if not _pkgs:
+ logger.warning(_("Could not find package %s in a remote repository.") % \
+ pkg.friendly_name)
else:
- return
+ # Sort packages to reflect repository priorities, etc...
+ # and take the best (first) one.
+ _pkgs.sort()
- # If okay, run the transcation.
- t.run()
+ # Re-install best package and cleanup the old one.
+ pkgs.append((pkg, _pkgs[0]))
- finally:
- # Remove the temporary copy of the repository we have created earlier.
- repo.remove()
- self.repos.rem_repo(repo)
+ # Eventually, create a request.
+ request = None
+
+ _pkgs = []
+ for old, new in pkgs:
+ if old.uuid == new.uuid:
+ _pkgs.append((old, new))
+ else:
+ if request is None:
+ # Create a new request.
+ request = self.pool.create_request()
+
+ # Install the new package, the old will
+ # be cleaned up automatically.
+ request.install(new.solvable)
+
+ if request:
+ solver = self.pool.solve(request)
+ t = transaction.Transaction.from_solver(self, solver)
+ else:
+ # Create new transaction.
+ t = transaction.Transaction(self)
+
+ for old, new in _pkgs:
+ # Install the new package and remove the old one.
+ t.add(actions.ActionReinstall.type, new)
+ t.add(actions.ActionCleanup.type, old)
+
+ t.sort()
+
+ if not t:
+ logger.info(_("Nothing to do"))
+ return
+
+ t.dump(logger=logger)
+
+ if not t.cli_yesno():
+ return
+
+ t.run(logger=logger)
- def update(self, pkgs, check=False):
+ def update(self, pkgs=None, check=False, excludes=None, interactive=True, logger=None, sync=False, **kwargs):
"""
check indicates, if the method should return after calculation
of the transaction.
"""
- request = self.create_request()
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ if logger is None:
+ logger = logging.getLogger("pakfire")
# If there are given any packets on the command line, we will
# only update them. Otherwise, we update the whole system.
+ updateall = True
if pkgs:
- update = False
- for pkg in pkgs:
- pkg = self.create_relation(pkg)
- request.update(pkg)
- else:
- update = True
+ updateall = False
- solver = self.create_solver()
- t = solver.solve(request, update=update)
+ request = self.pool.create_request(update=pkgs, updateall=updateall)
- if not t:
- logging.info(_("Nothing to do"))
+ # Exclude packages that should not be updated.
+ for exclude in excludes or []:
+ logger.info(_("Excluding %s.") % exclude)
+
+ exclude = self.pool.create_relation(exclude)
+ request.lock(exclude)
+
+ # Update or downgrade to the latest version of all packages
+ # in the enabled repositories.
+ if sync:
+ kwargs.update({
+ "allow_downgrade" : True,
+ "allow_uninstall" : True,
+ })
+
+ solver = self.pool.solve(request, logger=logger, **kwargs)
+
+ if not solver.status:
+ logger.info(_("Nothing to do"))
# If we are running in check mode, we return a non-zero value to
# indicate, that there are no updates.
else:
return
+ # Create the transaction.
+ t = transaction.Transaction.from_solver(self, solver)
+ t.dump(logger=logger)
+
# Just exit here, because we won't do the transaction in this mode.
if check:
- t.dump()
return
# Ask the user if the transaction is okay.
- if not t.cli_yesno():
+ if interactive and not t.cli_yesno():
return
# Run the transaction.
+ t.run(logger=logger)
+
+ def downgrade(self, pkgs, logger=None, **kwargs):
+ assert pkgs
+
+ if logger is None:
+ logger = logging.getLogger("pakfire")
+
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ # Create a new request.
+ request = self.pool.create_request()
+
+ # Fill request.
+ for pattern in pkgs:
+ best = None
+ for pkg in self.repos.whatprovides(pattern):
+ # Only consider installed packages.
+ if not pkg.is_installed():
+ continue
+
+ if best and pkg > best:
+ best = pkg
+ elif best is None:
+ best = pkg
+
+ if best is None:
+ logger.warning(_("\"%s\" package does not seem to be installed.") % pattern)
+ else:
+ rel = self.pool.create_relation("%s < %s" % (best.name, best.friendly_version))
+ request.install(rel)
+
+ # Solve the request.
+ solver = self.pool.solve(request, allow_downgrade=True, **kwargs)
+ assert solver.status is True
+
+ # Create the transaction.
+ t = transaction.Transaction.from_solver(self, solver)
+ t.dump(logger=logger)
+
+ if not t:
+ logger.info(_("Nothing to do"))
+ return
+
+ if not t.cli_yesno():
+ return
+
t.run()
- def remove(self, pkgs):
+ def remove(self, pkgs, logger=None):
+ if logger is None:
+ logger = logging.getLogger("pakfire")
+
+ # Initialize this pakfire instance.
+ self.initialize()
+
# Create a new request.
- request = self.create_request()
- for pkg in pkgs:
- pkg = self.create_relation(pkg)
- request.remove(pkg)
+ request = self.pool.create_request(remove=pkgs)
# Solve the request.
- solver = self.create_solver()
- t = solver.solve(request, uninstall=True)
+ solver = self.pool.solve(request, allow_uninstall=True)
+ assert solver.status is True
+
+ # Create the transaction.
+ t = transaction.Transaction.from_solver(self, solver)
+ t.dump()
if not t:
- logging.info(_("Nothing to do"))
+ log.info(_("Nothing to do"))
return
# Ask the user if okay.
t.run()
def info(self, patterns):
+ # Initialize this pakfire instance.
+ self.initialize()
+
pkgs = []
# For all patterns we run a single search which returns us a bunch
# of solvables which are transformed into Package objects.
for pattern in patterns:
- if os.path.exists(pattern):
+ if os.path.exists(pattern) and not os.path.isdir(pattern):
pkg = packages.open(self, self.repos.dummy, pattern)
if pkg:
pkgs.append(pkg)
return sorted(pkgs)
def search(self, pattern):
+ # Initialize this pakfire instance.
+ self.initialize()
+
# Do the search.
pkgs = {}
for solv in self.pool.search(pattern, satsolver.SEARCH_STRING|satsolver.SEARCH_FILES):
self.install("@%s" % group, **kwargs)
def grouplist(self, group):
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ return self.pool.grouplist(group)
+
+ def provides(self, patterns):
+ # Initialize this pakfire instance.
+ self.initialize()
+
pkgs = []
+ for pattern in patterns:
+ for pkg in self.pool.whatprovides(self, pattern):
+ if pkg in pkgs:
+ continue
- for solv in self.pool.search(group, satsolver.SEARCH_SUBSTRING, "solvable:group"):
- pkg = packages.SolvPackage(self, solv)
+ pkgs.append(pkg)
- if group in pkg.groups and not pkg.name in pkgs:
- pkgs.append(pkg.name)
+ # Sort output.
+ pkgs.sort()
+
+ return pkgs
+
+ def resolvdep(self, pkg):
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ return self.pool.resolvdep(self, pkg)
+
+ def repo_list(self):
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ return [r for r in self.repos]
+
+ def clean_all(self):
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ log.debug("Cleaning up everything...")
+
+ # Clean up repository caches.
+ self.repos.clean()
+
+ def check(self, allow_downgrade=True, allow_uninstall=True):
+ """
+ Try to fix any errors in the system.
+ """
+ # Initialize this pakfire instance.
+ self.initialize()
+
+ # Detect any errors in the dependency tree.
+ # For that we create an empty request and solver and try to solve
+ # something.
+ request = self.pool.create_request()
+ request.verify()
+
+ solver = self.pool.solve(
+ request,
+ allow_downgrade=allow_downgrade,
+ allow_uninstall=allow_uninstall,
+ )
+
+ if solver.status is False:
+ log.info(_("Everything is fine."))
+ return
+
+ # Create the transaction.
+ t = transaction.Transaction.from_solver(self, solver)
+ t.dump()
+
+ # Ask the user if okay.
+ if not t.cli_yesno():
+ return
+
+ # Process the transaction.
+ t.run()
+
+ def build(self, makefile, resultdir, stages=None, **kwargs):
+ b = builder.Builder(self, makefile, resultdir, **kwargs)
+
+ try:
+ b.build(stages=stages)
+
+ except Error:
+ raise BuildError, _("Build command has failed.")
+
+ else:
+ # If the build was successful, cleanup all temporary files.
+ b.cleanup()
+
+ def dist(self, pkg, resultdir):
+ pkg = packages.Makefile(self, pkg)
+
+ return pkg.dist(resultdir=resultdir)
- return sorted(pkgs)
- @staticmethod
- def build(pkg, resultdirs=None, shell=False, install_test=True, **kwargs):
- if not resultdirs:
- resultdirs = []
+class PakfireBuilder(Pakfire):
+ mode = "builder"
- b = builder.BuildEnviron(pkg, **kwargs)
- p = b.pakfire
+ def __init__(self, distro_name=None, *args, **kwargs):
+ self.distro_name = distro_name
- # Always include local repository.
- resultdirs.append(p.repos.local_build.path)
+ kwargs.update({
+ "path" : os.path.join(BUILD_ROOT, util.random_string()),
+ })
+
+ Pakfire.__init__(self, *args, **kwargs)
+
+ # Let's see what is our host distribution.
+ self.host_distro = distro.Distribution()
+
+ def _load_config(self, files=None):
+ c = config.ConfigBuilder(files=files)
+
+ if self.distro_name is None:
+ self.distro_name = c.get("builder", "distro", None)
+
+ if self.distro_name:
+ c.load_distro_config(self.distro_name)
+
+ if not c.has_distro_conf():
+ log.error(_("You have not set the distribution for which you want to build."))
+ log.error(_("Please do so in builder.conf or on the CLI."))
+ raise ConfigError, _("Distribution configuration is missing.")
+
+ return c
+
+ def build(self, pkg, resultdirs=None, shell=False, install_test=True, after_shell=False, **kwargs):
+ # As the BuildEnviron is only able to handle source packages, we must package makefiles.
+ if pkg.endswith(".%s" % MAKEFILE_EXTENSION):
+ pkg = self.dist(pkg, resultdir=LOCAL_TMP_PATH)
+
+ b = builder.BuildEnviron(self, pkg, **kwargs)
try:
# Start to prepare the build environment by mounting
# the filesystems and extracting files.
b.start()
- # Build the package.
- b.build(install_test=install_test)
+ try:
+ # Build the package.
+ b.build(install_test=install_test)
+
+ except BuildError:
+ # Raise the error, if the user does not want to
+ # have a shell.
+ if not shell:
+ raise
+
+ # Run a shell to debug the issue.
+ b.shell()
+
+ # Copy-out all resultfiles if the build was successful.
+ if not resultdirs:
+ resultdirs = []
+
+ # Always include local repository.
+ resultdirs.append(self.repos.local_build.path)
- # Copy-out all resultfiles
for resultdir in resultdirs:
if not resultdir:
continue
b.copy_result(resultdir)
- except BuildError:
- if shell:
+ # If the user requests a shell after a successful build,
+ # we run it here.
+ if after_shell:
b.shell()
- else:
- raise
finally:
b.stop()
- def _build(self, pkg, resultdir, nodeps=False, **kwargs):
- b = builder.Builder(self, pkg, resultdir, **kwargs)
+ def shell(self, pkg, **kwargs):
+ # As the BuildEnviron is only able to handle source packages, we must package makefiles.
+ if pkg and pkg.endswith(".%s" % MAKEFILE_EXTENSION):
+ pkg = self.dist(pkg, resultdir=LOCAL_TMP_PATH)
- try:
- b.build()
- except Error:
- raise BuildError, _("Build command has failed.")
-
- # If the build was successful, cleanup all temporary files.
- b.cleanup()
-
- @staticmethod
- def shell(pkg, **kwargs):
- b = builder.BuildEnviron(pkg, **kwargs)
+ b = builder.BuildEnviron(self, pkg, **kwargs)
try:
b.start()
+
+ try:
+ b.build(prepare=True)
+ except BuildError:
+ pass
+
b.shell()
finally:
b.stop()
- def dist(self, pkgs, resultdirs=None):
- assert resultdirs
- for pkg in pkgs:
- pkg = packages.Makefile(self, pkg)
+class PakfireClient(Pakfire):
+ mode = "client"
- pkg.dist(resultdirs)
- def provides(self, patterns):
- pkgs = []
- for pattern in patterns:
- for pkg in self.repos.whatprovides(pattern):
- if pkg in pkgs:
- continue
-
- pkgs.append(pkg)
+class PakfireServer(Pakfire):
+ mode = "server"
- return sorted(pkgs)
-
- def repo_create(self, path, input_paths, type="binary"):
+ def repo_create(self, path, input_paths, name=None, key_id=None, type="binary"):
assert type in ("binary", "source",)
- repo = repository.RepositoryDir(
- self,
- name="new",
- description="New repository.",
- path=path,
- type=type,
- )
+ if not name:
+ name = _("New repository")
+
+ # Create new repository.
+ repo = repository.RepositoryDir(self, name=name, description="New repository.",
+ path=path, key_id=key_id)
- for input_path in input_paths:
- repo.collect_packages(input_path)
+ # Add all packages.
+ repo.add_packages(input_paths)
+ # Write metadata to disk.
repo.save()
+ # Return the new repository.
return repo
- def repo_list(self):
- return [r for r in self.repos]
-
- def clean_all(self):
- logging.debug("Cleaning up everything...")
- # Clean up repository caches.
- self.repos.clean()
-
- def check(self, downgrade=True, uninstall=True):
- """
- Try to fix any errors in the system.
- """
- # Detect any errors in the dependency tree.
- # For that we create an empty request and solver and try to solve
- # something.
- request = self.create_request()
- solver = self.create_solver()
-
- # XXX the solver does crash if we call it with fix_system=1,
- # allow_downgrade=1 and uninstall=1. Need to fix this.
- allow_downgrade = False
- uninstall = False
-
- t = solver.solve(request, fix_system=True, allow_downgrade=downgrade,
- uninstall=uninstall)
-
- if not t:
- logging.info(_("Everything is fine."))
- return
-
- # Ask the user if okay.
- if not t.cli_yesno():
- return
-
- # Process the transaction.
- t.run()
+class PakfireKey(Pakfire):
+ mode = "key"