]> git.ipfire.org Git - pakfire.git/commitdiff
General cleanup work.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Oct 2012 17:47:21 +0000 (19:47 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Oct 2012 17:47:21 +0000 (19:47 +0200)
12 files changed:
python/pakfire/api.py
python/pakfire/base.py
python/pakfire/builder.py
python/pakfire/cli.py
python/pakfire/config.py
python/pakfire/distro.py
python/pakfire/repository/__init__.py
python/pakfire/repository/base.py
python/pakfire/repository/database.py
python/pakfire/repository/local.py
python/pakfire/repository/remote.py
python/pakfire/repository/system.py

index c44c9abec2b1cd4b786770f53928b58b93a0a5ae..db02fb2ba5e533509dc6d38c8e0a3f183e5945f7 100644 (file)
@@ -35,7 +35,7 @@ def install(requires, ignore_recommended=False, **pakfire_args):
 def resolvdep(pkgs, **pakfire_args):
        pakfire = Pakfire(**pakfire_args)
 
-       return pakfire.resolvdep(pkgs)
+       return pakfire.pool.resolvdep(pkgs)
 
 def reinstall(pkgs, **pakfire_args):
        pakfire = Pakfire(**pakfire_args)
index c6419f14327113d8ce7182d6461fadaccbc6ebcc..52223d17dab6030dcf0fde3aaa711712ef6ac481 100644 (file)
@@ -25,6 +25,7 @@ import string
 
 import actions
 import builder
+import config
 import distro
 import filelist
 import keyring
@@ -45,30 +46,25 @@ from i18n import _
 class Pakfire(object):
        mode = None
 
-       def __init__(self, path="/", config=None, configs=None, arch=None,
-                       enable_repos=None, disable_repos=None, **kwargs):
+       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 self.mode == "builder":
-                       self.path = os.path.join(BUILD_ROOT, util.random_string())
-
-               elif not self.mode:
-                       # check if we are actually running on an ipfire system.
-                       if self.path == "/":
-                               self.check_is_ipfire()
+               # check if we are actually running on an ipfire system.
+               if not self.mode and self.path == "/":
+                       self.check_is_ipfire()
 
                # Get the configuration.
                if config:
-                       assert configs is None, "You cannot pass configs and config."
                        self.config = config
                else:
-                       # Read configuration file(s).
-                       self.config = Config(files=configs)
+                       self.config = self._load_config(configs)
 
                # Update configuration with additional arguments.
                for section, settings in kwargs.items():
@@ -82,21 +78,39 @@ class Pakfire(object):
 
                # Get more information about the distribution we are running
                # or building
-               self.distro = distro.Distribution(self)
+               self.distro = distro.Distribution(self.config.get_distro_conf())
                if arch:
                        self.distro.arch = arch
 
-               self.pool   = satsolver.Pool(self.distro.arch)
-               self.repos  = repository.Repositories(self,
-                       enable_repos=enable_repos, disable_repos=disable_repos)
+               self.pool = satsolver.Pool(self.distro.arch)
+               self.repos = repository.Repositories(self)
+
+       def initialize(self):
+               """
+                       Initialize pakfire instance.
+               """
+               if self.initialized:
+                       return
+
+               # Initialize repositories.
+               self.repos.initialize()
+
+               self.initialized = True
+
+       def _load_config(self, files=None):
+               """
+                       This method loads all needed configuration files.
+               """
+               return config.Config(files=files)
 
        def __del__(self):
                # Reset logging.
                logger.setup_logging()
 
        def destroy(self):
-               if not self.path == "/":
-                       util.rm(self.path)
+               self.repos.shutdown()
+
+               self.initialized = False
 
        @property
        def environ(self):
@@ -148,6 +162,9 @@ class Pakfire(object):
                return self.mode == "builder"
 
        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")
 
@@ -220,6 +237,9 @@ class Pakfire(object):
                        If strict is True, only a package with excatly the same UUID
                        will replace the currently installed one.
                """
+               # Initialize this pakfire instance.
+               self.initialize()
+
                if logger is None:
                        logger = logging.getLogger("pakfire")
 
@@ -328,6 +348,9 @@ class Pakfire(object):
                        check indicates, if the method should return after calculation
                        of the transaction.
                """
+               # Initialize this pakfire instance.
+               self.initialize()
+
                if logger is None:
                        logger = logging.getLogger("pakfire")
 
@@ -376,6 +399,9 @@ class Pakfire(object):
        def downgrade(self, pkgs, allow_vendorchange=False, allow_archchange=False):
                assert pkgs
 
+               # Initialize this pakfire instance.
+               self.initialize()
+
                # Create a new request.
                request = self.pool.create_request()
 
@@ -420,6 +446,9 @@ class Pakfire(object):
                t.run()
 
        def remove(self, pkgs):
+               # Initialize this pakfire instance.
+               self.initialize()
+
                # Create a new request.
                request = self.pool.create_request(remove=pkgs)
 
@@ -443,6 +472,9 @@ class Pakfire(object):
                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
@@ -466,6 +498,9 @@ class Pakfire(object):
                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):
@@ -486,9 +521,15 @@ class Pakfire(object):
                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.repos.whatprovides(pattern):
@@ -500,9 +541,15 @@ class Pakfire(object):
                return sorted(pkgs)
 
        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.
@@ -512,6 +559,9 @@ class Pakfire(object):
                """
                        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.
@@ -543,21 +593,46 @@ class Pakfire(object):
 class PakfireBuilder(Pakfire):
        mode = "builder"
 
+       def __init__(self, distro_name=None, *args, **kwargs):
+               self.distro_name = distro_name
+
+               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 dist(self, pkg, resultdir):
                pkg = packages.Makefile(self, pkg)
 
                return pkg.dist(resultdir=resultdir)
 
-       @staticmethod
-       def build(pkg, resultdirs=None, shell=False, install_test=True, after_shell=False, **kwargs):
-               if not resultdirs:
-                       resultdirs = []
+       def build(self, pkg, resultdirs=None, shell=False, install_test=True, after_shell=False, **kwargs):
 
-               b = builder.BuildEnviron(pkg, **kwargs)
-               p = b.pakfire
+               # 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)
 
-               # Always include local repository.
-               resultdirs.append(p.repos.local_build.path)
+               b = builder.BuildEnviron(self, pkg, **kwargs)
 
                try:
                        # Start to prepare the build environment by mounting
@@ -577,17 +652,24 @@ class PakfireBuilder(Pakfire):
                                # Run a shell to debug the issue.
                                b.shell()
 
-                       # If the user requests a shell after a successful build,
-                       # we run it here.
-                       if after_shell:
-                               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)
+
                        for resultdir in resultdirs:
                                if not resultdir:
                                        continue
 
                                b.copy_result(resultdir)
+
+                       # If the user requests a shell after a successful build,
+                       # we run it here.
+                       if after_shell:
+                               b.shell()
+
                finally:
                        b.stop()
 
@@ -607,9 +689,8 @@ class PakfireBuilder(Pakfire):
                # If the build was successful, cleanup all temporary files.
                b.cleanup()
 
-       @staticmethod
-       def shell(pkg, **kwargs):
-               b = builder.BuildEnviron(pkg, **kwargs)
+       def shell(self, pkg, **kwargs):
+               b = builder.BuildEnviron(self, pkg, **kwargs)
 
                try:
                        b.start()
index c0c0d43bccc188526292e4631bfa6d70be6e4dd8..d655fec0b161f9efc923a90f1de6940cac82f7fe 100644 (file)
@@ -69,55 +69,25 @@ class BuildEnviron(object):
        # The version of the kernel this machine is running.
        kernel_version = os.uname()[2]
 
-       def __init__(self, filename=None, distro_name=None, config=None, configs=None, arch=None,
-                       build_id=None, logfile=None, builder_mode="release", **pakfire_args):
-               # Set mode.
-               assert builder_mode in ("development", "release",)
-               self.mode = builder_mode
-
-               # Disable the build repository in release mode.
-               if self.mode == "release":
-                       if pakfire_args.has_key("disable_repos") and pakfire_args["disable_repos"]:
-                               pakfire_args["disable_repos"] += ["build",]
-                       else:
-                               pakfire_args["disable_repos"] = ["build",]
-
-               # Save the build id and generate one if no build id was provided.
-               if not build_id:
-                       build_id = "%s" % uuid.uuid4()
+       def __init__(self, pakfire, filename=None, distro_name=None, build_id=None, logfile=None, release_build=True):
+               self.pakfire = pakfire
 
-               self.build_id = build_id
+               # Check if the given pakfire instance is of the correct type.
+               assert isinstance(self.pakfire, base.PakfireBuilder)
 
-               # Setup the logging.
-               if logfile:
-                       self.log = log.getChild(self.build_id)
-                       # Propage everything to the root logger that we will see something
-                       # on the terminal.
-                       self.log.propagate = 1
-                       self.log.setLevel(logging.INFO)
-
-                       # Add the given logfile to the logger.
-                       h = logging.FileHandler(logfile)
-                       self.log.addHandler(h)
-
-                       # Format the log output for the file.
-                       f = logger.BuildFormatter()
-                       h.setFormatter(f)
-               else:
-                       # If no logile was given, we use the root logger.
-                       self.log = logging.getLogger("pakfire")
+               # Check if this host can build the requested architecture.
+               if not system.host_supports_arch(self.arch):
+                       raise BuildError, _("Cannot build for %s on this host.") % self.arch
 
-               # Initialize a cgroup (if supported).
-               self.cgroup = None
-               if cgroup.supported():
-                       self.cgroup = cgroup.CGroup("pakfire/builder/%s" % self.build_id)
+               # This build is a release build?
+               self.release_build = release_build
 
-                       # Attach the pakfire-builder process to the parent group.
-                       self.cgroup.parent.attach()
+               if self.release_build:
+                       # Disable the local build repository in release mode.
+                       self.pakfire.repos.disable_repo("build")
 
-               # Log information about pakfire and some more information, when we
-               # are running in release mode.
-               if self.mode == "release":
+                       # Log information about pakfire and some more information, when we
+                       # are running in release mode.
                        logdata = {
                                "host_arch"  : system.arch,
                                "hostname"   : system.hostname,
@@ -128,44 +98,39 @@ class BuildEnviron(object):
                        for line in BUILD_LOG_HEADER.splitlines():
                                self.log.info(line % logdata)
 
-               # Create pakfire instance.
-               if pakfire_args.has_key("mode"):
-                       del pakfire_args["mode"]
-
-               if config is None:
-                       config = ConfigBuilder(files=configs)
+               # Save the build id and generate one if no build id was provided.
+               if not build_id:
+                       build_id = "%s" % uuid.uuid4()
 
-                       if not configs:
-                               if distro_name is None:
-                                       distro_name = config.get("builder", "distro", None)
-                               config.load_distro_config(distro_name)
+               self.build_id = build_id
 
-               if not config.has_distro():
-                       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.")
+               # Setup the logging.
+               self.init_logging(logfile)
 
-               self.pakfire = base.PakfireBuilder(config=config, arch=arch, **pakfire_args)
+               # Initialize a cgroup (if supported).
+               self.init_cgroup()
 
-               self.distro = self.pakfire.distro
-               self.path = self.pakfire.path
+               # XXX need to make this configureable
+               self.settings = {
+                       "enable_loop_devices" : True,
+                       "enable_ccache"   : True,
+                       "enable_icecream" : False,
+                       "sign_packages"   : False,
+                       "buildroot_tmpfs" : False,
+               }
+               #self.settings.update(settings)
 
-               # Check if this host can build the requested architecture.
-               if not system.host_supports_arch(self.arch):
-                       raise BuildError, _("Cannot build for %s on this host.") % self.arch
+               # Try to get the configured host key. If it is available,
+               # we will automatically sign all packages with it.
+               if self.keyring.get_host_key(secret=True):
+                       self.settings["sign_packages"] = True
 
                # Where do we put the result?
-               self.resultdir = os.path.join(self.path, "result")
+               self.resultdir = os.path.join(self.pakfire.path, "result")
 
                # Open package.
                # If we have a plain makefile, we first build a source package and go with that.
                if filename:
-                       if filename.endswith(".%s" % MAKEFILE_EXTENSION):
-                               pkg = packages.Makefile(self.pakfire, filename)
-                               filename = pkg.dist(os.path.join(self.resultdir, "src"))
-
-                               assert os.path.exists(filename), filename
-
                        # Open source package.
                        self.pkg = packages.SourcePackage(self.pakfire, None, filename)
                        assert self.pkg, filename
@@ -182,35 +147,27 @@ class BuildEnviron(object):
                        # No package :(
                        self.pkg = None
 
-               # XXX need to make this configureable
-               self.settings = {
-                       "enable_loop_devices" : True,
-                       "enable_ccache"   : True,
-                       "enable_icecream" : False,
-                       "sign_packages"   : False,
-                       "buildroot_tmpfs" : False,
-               }
-               #self.settings.update(settings)
-
-               # Try to get the configured host key. If it is available,
-               # we will automatically sign all packages with it.
-               if self.keyring.get_host_key(secret=True):
-                       self.settings["sign_packages"] = True
-
                # Lock the buildroot
                self._lock = None
-               self.lock()
 
                # Save the build time.
-               self.build_time = int(time.time())
+               self.build_time = time.time()
 
        def setup_signal_handlers(self):
                pass
 
        def start(self):
+               assert not self.pakfire.initialized, "Pakfire has already been initialized"
+
                # Mount the directories.
                self._mountall()
 
+               # Lock the build environment.
+               self.lock()
+
+               # Initialize pakfire instance.
+               self.pakfire.initialize()
+
                # Populate /dev.
                self.populate_dev()
 
@@ -240,8 +197,11 @@ class BuildEnviron(object):
                else:
                        util.orphans_kill(self.path)
 
-               # Close pakfire instance.
-               del self.pakfire
+               # Shut down pakfire instance.
+               self.pakfire.destroy()
+
+               # Unlock build environment.
+               self.unlock()
 
                # Umount the build environment.
                self._umountall()
@@ -249,20 +209,33 @@ class BuildEnviron(object):
                # Remove all files.
                self.destroy()
 
+       @property
+       def distro(self):
+               """
+                       Proxy method for easy access to the distribution.
+               """
+               return self.pakfire.distro
+
+       @property
+       def path(self):
+               """
+                       Proxy method for easy access to the path.
+               """
+               return self.pakfire.path
+
        @property
        def arch(self):
                """
                        Inherit architecture from distribution configuration.
                """
-               return self.distro.arch
+               return self.pakfire.distro.arch
 
        @property
        def personality(self):
                """
                        Gets the personality from the distribution configuration.
                """
-               if self.distro:
-                       return self.distro.personality
+               return self.pakfire.distro.personality
 
        @property
        def info(self):
@@ -300,6 +273,38 @@ class BuildEnviron(object):
                        self._lock.close()
                        self._lock = None
 
+       def init_cgroup(self):
+               """
+                       Initialize cgroup (if the system supports it).
+               """
+               if not cgroup.supported():
+                       self.cgroup = None
+                       return
+
+               self.cgroup = cgroup.CGroup("pakfire/builder/%s" % self.build_id)
+
+               # Attach the pakfire-builder process to the parent group.
+               self.cgroup.parent.attach()
+
+       def init_logging(self, logfile):
+               if logfile:
+                       self.log = log.getChild(self.build_id)
+                       # Propage everything to the root logger that we will see something
+                       # on the terminal.
+                       self.log.propagate = 1
+                       self.log.setLevel(logging.INFO)
+
+                       # Add the given logfile to the logger.
+                       h = logging.FileHandler(logfile)
+                       self.log.addHandler(h)
+
+                       # Format the log output for the file.
+                       f = logger.BuildFormatter()
+                       h.setFormatter(f)
+               else:
+                       # If no logile was given, we use the root logger.
+                       self.log = logging.getLogger("pakfire")
+
        def copyin(self, file_out, file_in):
                if file_in.startswith("/"):
                        file_in = file_in[1:]
@@ -366,7 +371,7 @@ class BuildEnviron(object):
 
                return ret
 
-       def extract(self, requires=None, build_deps=True):
+       def extract(self, requires=None):
                """
                        Gets a dependency set and extracts all packages
                        to the environment.
@@ -523,16 +528,20 @@ class BuildEnviron(object):
 
                mountpoints = []
                for src, dest, fs, options in reversed(self.mountpoints):
+                       dest = self.chrootPath(dest)
+
                        if not dest in mountpoints:
                                mountpoints.append(dest)
 
-               for dest in mountpoints:
-                       mountpoint = self.chrootPath(dest)
+               while mountpoints:
+                       for mp in mountpoints:
+                               try:
+                                       self.execute_root("umount -n %s" % mp, shell=True)
+                               except ShellEnvironmentError:
+                                       pass
 
-                       try:
-                               self.execute_root("umount -n %s" % mountpoint, shell=True)
-                       except ShellEnvironmentError:
-                               pass
+                               if not os.path.ismount(mp):
+                                       mountpoints.remove(mp)
 
        @property
        def mountpoints(self):
@@ -727,12 +736,13 @@ class BuildEnviron(object):
                        "--nodeps",
                        "--resultdir=/result",
                ]
-               build_command = " ".join(build_command)
 
                # Check if only the preparation stage should be run.
                if prepare:
                        build_command.append("--prepare")
 
+               build_command = " ".join(build_command)
+
                error = False
                try:
                        self.execute(build_command, logger=self.log)
index 0b5aa25a957369f5d6749603a440c9eb6fc5a5df..e974c0eb9f5336c1bf431110e6265d0d973d8c95 100644 (file)
@@ -26,14 +26,14 @@ import shutil
 import sys
 import tempfile
 
-import pakfire.api as pakfire
-
+import base
 import client
 import config
 import logger
 import packages
 import repository
 import server
+import transaction
 import util
 
 from system import system
@@ -45,6 +45,8 @@ from i18n import _
 logger.setup_logging()
 
 class Cli(object):
+       pakfire = base.Pakfire
+
        def __init__(self):
                self.parser = argparse.ArgumentParser(
                        description = _("Pakfire command line interface."),
@@ -98,7 +100,7 @@ class Cli(object):
 
        @property
        def pakfire_args(self):
-               ret = { "mode" : "normal" }
+               ret = {}
 
                if hasattr(self.args, "root"):
                        ret["path"] = self.args.root
@@ -288,72 +290,76 @@ class Cli(object):
                return func()
 
        def handle_info(self, long=False):
-               pkgs = pakfire.info(self.args.package, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
 
-               for pkg in pkgs:
+               for pkg in p.info(self.args.package):
                        print pkg.dump(long=long)
 
        def handle_search(self):
-               pkgs = pakfire.search(self.args.pattern, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
 
-               for pkg in pkgs:
+               for pkg in p.search(self.args.pattern):
                        print pkg.dump(short=True)
 
        def handle_update(self, **args):
-               args.update(self.pakfire_args)
-
-               pakfire.update(self.args.package, excludes=self.args.exclude,
+               p = self.pakfire(**self.pakfire_args)
+               p.update(
+                       self.args.package,
+                       excludes=self.args.exclude,
                        allow_vendorchange=self.args.allow_vendorchange,
                        allow_archchange=self.args.allow_archchange,
-                       **args)
+                       **args
+               )
 
        def handle_check_update(self):
                self.handle_update(check=True)
 
        def handle_downgrade(self, **args):
-               args.update(self.pakfire_args)
-
-               pakfire.downgrade(self.args.package,
+               p = self.pakfire(**self.pakfire_args)
+               p.downgrade(
+                       self.args.package,
                        allow_vendorchange=self.args.allow_vendorchange,
                        allow_archchange=self.args.allow_archchange,
-                       **args)
+                       **args
+               )
 
        def handle_install(self):
-               pakfire.install(self.args.package,
-                       ignore_recommended=self.args.without_recommends,
-                       **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.install(self.args.package, ignore_recommended=self.args.without_recommends)
 
        def handle_reinstall(self):
-               pakfire.reinstall(self.args.package, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.reinstall(self.args.package)
 
        def handle_remove(self):
-               pakfire.remove(self.args.package, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.remove(self.args.package)
 
-       def handle_provides(self):
-               pkgs = pakfire.provides(self.args.pattern, **self.pakfire_args)
+       def handle_provides(self, long=False):
+               p = self.pakfire(**self.pakfire_args)
 
-               for pkg in pkgs:
-                       print pkg.dump()
+               for pkg in p.provides(self.args.pattern):
+                       print pkg.dump(long=long)
 
        def handle_grouplist(self):
-               pkgs = pakfire.grouplist(self.args.group[0], **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
 
-               for pkg in pkgs:
+               for pkg in p.grouplist(self.args.group[0]):
                        print " * %s" % pkg
 
        def handle_groupinstall(self):
-               pakfire.groupinstall(self.args.group[0], **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.groupinstall(self.args.group[0])
 
        def handle_repolist(self):
-               repos = pakfire.repo_list(**self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
 
                FORMAT = " %-20s %8s %12s %12s "
-
                title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
                print title
                print "=" * len(title) # spacing line
 
-               for repo in repos:
+               for repo in p.repo_list():
                        # Skip the installed repository.
                        if repo.name == "installed":
                                continue
@@ -363,21 +369,28 @@ class Cli(object):
        def handle_clean_all(self):
                print _("Cleaning up everything...")
 
-               pakfire.clean_all(**self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.clean_all()
 
        def handle_check(self):
-               pakfire.check(**self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.check()
 
        def handle_resolvdep(self):
-               (pkg,) = self.args.package
+               p = self.pakfire(**self.pakfire_args)
 
-               solver = pakfire.resolvdep(pkg, **self.pakfire_args)
+               (pkg,) = self.args.package
 
+               solver = p.pool.resolvdep(pkg)
                assert solver.status
-               solver.transaction.dump()
+
+               t = transaction.Transaction.from_solver(p, solver)
+               t.dump()
 
 
 class CliBuilder(Cli):
+       pakfire = base.PakfireBuilder
+
        def __init__(self):
                # Check if we are already running in a pakfire container. In that
                # case, we cannot start another pakfire-builder.
@@ -424,7 +437,7 @@ class CliBuilder(Cli):
 
        @property
        def pakfire_args(self):
-               ret = { "mode" : "builder" }
+               ret = {}
 
                if hasattr(self.args, "disable_repo"):
                        ret["disable_repos"] = self.args.disable_repo
@@ -505,9 +518,19 @@ class CliBuilder(Cli):
                # Check whether to enable the install test.
                install_test = not self.args.no_install_test
 
-               pakfire.build(pkg, builder_mode=self.args.mode, install_test=install_test,
-                       arch=self.args.arch, resultdirs=[self.args.resultdir,],
-                       shell=True, after_shell=self.args.after_shell, **self.pakfire_args)
+               if self.args.mode == "release":
+                       release_build = True
+               else:
+                       release_build = False
+
+               p = self.pakfire(arch=self.args.arch, **self.pakfire_args)
+               p.build(pkg,
+                       install_test=install_test,
+                       resultdirs=[self.args.resultdir,],
+                       shell=True,
+                       after_shell=self.args.after_shell,
+                       release_build=release_build,
+               )
 
        def handle_shell(self):
                pkg = None
@@ -523,8 +546,13 @@ class CliBuilder(Cli):
                        else:
                                raise FileNotFoundError, pkg
 
-               pakfire.shell(pkg, builder_mode=self.args.mode,
-                       arch=self.args.arch, **self.pakfire_args)
+               if self.args.mode == "release":
+                       release_build = True
+               else:
+                       release_build = False
+
+               p = self.pakfire(arch=self.args.arch, **self.pakfire_args)
+               p.shell(pkg, release_build=release_build)
 
        def handle_dist(self):
                # Get the packages from the command line options
@@ -543,22 +571,17 @@ class CliBuilder(Cli):
                # current working directory.
                resultdir = self.args.resultdir or os.getcwd()
 
-               # Change the default pakfire configuration, because
-               # packaging source packages can be done in server mode.
-               pakfire_args = self.pakfire_args
-               pakfire_args["mode"] = "server"
-
+               p = self.pakfire(**self.pakfire_args)
                for pkg in pkgs:
-                       pakfire.dist(pkg, resultdir=resultdir, **pakfire_args)
+                       p.dist(pkg, resultdir=resultdir)
 
        def handle_provides(self):
-               pkgs = pakfire.provides(self.args.pattern, **self.pakfire_args)
-
-               for pkg in pkgs:
-                       print pkg.dump(long=True)
+               Cli.handle_provides(long=True)
 
 
 class CliServer(Cli):
+       pakfire = base.PakfireServer
+
        def __init__(self):
                self.parser = argparse.ArgumentParser(
                        description = _("Pakfire server command line interface."),
@@ -590,7 +613,7 @@ class CliServer(Cli):
 
        @property
        def pakfire_args(self):
-               ret = { "mode" : "server" }
+               ret = {}
 
                if hasattr(self.args, "offline") and self.args.offline:
                        ret["downloader"] = {
@@ -683,8 +706,8 @@ class CliServer(Cli):
        def handle_repo_create(self):
                path = self.args.path[0]
 
-               pakfire.repo_create(path, self.args.inputs, key_id=self.args.key,
-                       **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.repo_create(path, self.args.inputs, key_id=self.args.key)
 
        def handle_info(self):
                info = self.server.info()
@@ -757,7 +780,7 @@ class CliBuilderIntern(Cli):
                        "resultdir"     : self.args.resultdir,
                }
 
-               pakfire._build(pkg, **kwargs)
+               self.pakfire._build(pkg, **kwargs)
 
 
 class CliClient(Cli):
@@ -882,10 +905,11 @@ class CliClient(Cli):
 
                try:
                        if package.endswith(".%s" % MAKEFILE_EXTENSION):
-                               pakfire_args = { "mode" : "server" }
+                               pakfire_args = {}
 
                                # Create a source package from the makefile.
-                               package = pakfire.dist(package, temp_dir, **pakfire_args)
+                               p = self.pakfire(**self.pakfire_args)
+                               package = p.dist(package, temp_dir)
 
                        elif package.endswith(".%s" % PACKAGE_EXTENSION):
                                pass
@@ -1141,9 +1165,6 @@ class CliKey(Cli):
                # Finally parse all arguments from the command line and save them.
                self.args = self.parser.parse_args()
 
-               # Create a pakfire instance.
-               self.pakfire = pakfire.Pakfire(**self.pakfire_args)
-
                self.action2func = {
                        "generate"    : self.handle_generate,
                        "import"      : self.handle_import,
@@ -1156,11 +1177,7 @@ class CliKey(Cli):
 
        @property
        def pakfire_args(self):
-               ret = {
-                       "mode" : "server",
-               }
-
-               return ret
+               return {}
 
        def parse_command_generate(self):
                # Parse "generate" command.
@@ -1234,30 +1251,33 @@ class CliKey(Cli):
                print
 
                # Generate the key.
-               pakfire.key_generate(realname, email, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.key_generate(realname, email)
 
        def handle_import(self):
                filename = self.args.filename[0]
 
                # Simply import the file.
-               pakfire.key_import(filename, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.key_import(filename)
 
        def handle_export(self):
                keyid    = self.args.keyid[0]
                filename = self.args.filename[0]
                secret   = self.args.secret
 
-               pakfire.key_export(keyid, filename, secret=secret, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.key_export(keyid, filename, secret=secret)
 
        def handle_delete(self):
                keyid = self.args.keyid[0]
 
-               pakfire.key_delete(keyid, **self.pakfire_args)
+               p = self.pakfire(**self.pakfire_args)
+               p.key_delete(keyid)
 
        def handle_list(self):
-               lines = pakfire.key_list(**self.pakfire_args)
-
-               for line in lines:
+               p = self.pakfire(**self.pakfire_args)
+               for line in p.key_list():
                        print line
 
        def handle_sign(self):
@@ -1275,9 +1295,12 @@ class CliKey(Cli):
 
                key = self.args.key[0]
 
+               # Create pakfire instance.
+               p = self.pakfire(**self.pakfire_args)
+
                for file in files:
                        # Open the package.
-                       pkg = packages.open(self.pakfire, None, file)
+                       pkg = packages.open(p, None, file)
 
                        print _("Signing %s...") % pkg.friendly_name
                        pkg.sign(key)
@@ -1292,9 +1315,12 @@ class CliKey(Cli):
                                file = os.path.abspath(file)
                                files.append(file)
 
+               # Create pakfire instance.
+               p = self.pakfire(**self.pakfire_args)
+
                for file in files:
                        # Open the package.
-                       pkg = packages.open(self.pakfire, None, file)
+                       pkg = packages.open(p, None, file)
 
                        print _("Verifying %s...") % pkg.friendly_name
                        sigs = pkg.verify()
index adca6549fe7759f56262a9041360a6ba6f18268c..3cc7c4224246b4b7a0459dcf1561c29fb6469bb4 100644 (file)
@@ -215,9 +215,12 @@ class _Config(object):
                for f in self._files:
                        log.debug("    %s" % f)
 
-       def has_distro(self):
+       def has_distro_conf(self):
                return self._config.has_key("distro")
 
+       def get_distro_conf(self):
+               return self.get_section("distro")
+
 
 class Config(_Config):
        files = ["general.conf", "distro.conf"]
index 832858cfe22e6418766a4aaca7f16b2f3cbc4a2c..d4cc6e7e451bd5e7ceffabad210d51feb3e34058 100644 (file)
@@ -25,29 +25,23 @@ import re
 import logging
 log = logging.getLogger("pakfire")
 
-from errors import ConfigError
-from repository import Repositories
 from system import system
 
 class Distribution(object):
-       def __init__(self, pakfire, data=None):
-               self.pakfire = pakfire
+       def __init__(self,  data=None):
                self._data = {}
 
-               if data is None:
+               if data:
+                       self.update(data)
+               else:
                        # Read /etc/os-release if it does exist.
                        self.read_osrelease()
 
-                       # Inherit configuration from Pakfire configuration.
-                       self.update(self.pakfire.config.get_section("distro"))
-               else:
-                       self._data = data
-
                # Dump all data
                self.dump()
 
        def read_osrelease(self):
-               filename = os.path.join(self.pakfire.path, "etc", "os-release")
+               filename = "/etc/os-release"
 
                if not os.path.exists(filename):
                        return
@@ -78,10 +72,6 @@ class Distribution(object):
 
                self.update(data)
 
-       @property
-       def config(self):
-               return self.pakfire.config
-
        def dump(self):
                log.debug("Distribution configuration:")
 
index 040cb5fce9cd409a0119aa278629dc8a89872f6b..5d2f4c193690af87493d9cc5c10bf839756f15a9 100644 (file)
@@ -38,12 +38,9 @@ class Repositories(object):
                This is the place where repositories can be activated or deactivated.
        """
 
-       def __init__(self, pakfire, enable_repos=None, disable_repos=None):
+       def __init__(self, pakfire):
                self.pakfire = pakfire
 
-               self.config = pakfire.config
-               self.distro = pakfire.distro
-
                # Place to store the repositories
                self.__repos = {}
 
@@ -55,7 +52,7 @@ class Repositories(object):
                self.add_repo(self.local)
 
                # If we running in build mode, we include our local build repository.
-               if self.pakfire.builder:
+               if self.pakfire.mode == "builder":
                        self.local_build = RepositoryBuild(self.pakfire)
                        self.add_repo(self.local_build)
 
@@ -63,24 +60,6 @@ class Repositories(object):
                for repo_name, repo_args in self.config.get_repos():
                        self._parse(repo_name, repo_args)
 
-               # Enable all repositories here as demanded on commandline
-               if enable_repos:
-                       for repo in enable_repos:
-                               self.enable_repo(repo)
-
-               # Disable all repositories here as demanded on commandline
-               if disable_repos:
-                       # * is magic to disable all repositories.
-                       if "*" in disable_repos:
-                               disable_repos = [r.name for r in self]
-
-                       for repo in disable_repos:
-                               self.disable_repo(repo)
-
-               # Update all indexes of the repositories (not force) so that we will
-               # always work with valid data.
-               self.update(force=False, offline=self.pakfire.offline)
-
        def __iter__(self):
                repositories = self.__repos.values()
                repositories.sort()
@@ -93,6 +72,40 @@ class Repositories(object):
                """
                return len([r for r in self if r.enabled])
 
+       @property
+       def initialized(self):
+               """
+                       Indicates if all repositories are initialized.
+               """
+               for repo in self:
+                       if not repo.opened:
+                               return False
+
+               return True
+
+       def initialize(self):
+               # Nothing to do, if everything is already up to date.
+               if self.initialized:
+                       return
+
+               for repo in self:
+                       repo.open()
+
+       def shutdown(self):
+               """
+                       Shuts down all repositores.
+               """
+               for repo in self:
+                       repo.close()
+
+       @property
+       def config(self):
+               return self.pakfire.config
+
+       @property
+       def distro(self):
+               return self.pakfire.distro
+
        @property
        def pool(self):
                return self.pakfire.pool
@@ -171,17 +184,6 @@ class Repositories(object):
                except KeyError:
                        pass
 
-       def update(self, force=False, offline=False):
-               log.debug("Updating all repository indexes (force=%s)" % force)
-
-               # update all indexes if necessary or forced
-               for repo in self:
-                       # Skip disabled repositories.
-                       if not repo.enabled:
-                               continue
-
-                       repo.update(force=force, offline=offline)
-
        def whatprovides(self, what):
                what = self.pakfire.pool.create_relation(what)
 
index d7850da0df2206f4c1cf3174574a36772b74ffe4..c16ca37c8bc0f7528ab5641d45bcf3f97fdcee01 100644 (file)
@@ -45,6 +45,9 @@ class RepositoryFactory(object):
                # Create an index (in memory).
                self.index = index.Index(self.pakfire, self)
 
+               # Marks if this repository has been opened.
+               self.opened = False
+
        def __repr__(self):
                return "<%s %s>" % (self.__class__.__name__, self.name)
 
@@ -105,12 +108,17 @@ class RepositoryFactory(object):
                """
                return False
 
-       def update(self, force=False, offline=False):
+       def open(self):
+               """
+                       Opens the repository, so we can work with the data.
+               """
+               self.opened = True
+
+       def close(self):
                """
-                       A function that is called to update the local data of
-                       the repository.
+                       Close and delete all resources that are used by this repository.
                """
-               raise NotImplementedError, self
+               self.opened = False
 
        def clean(self):
                """
index 4c5084c21a95612bfc237bdd44ae24d23e9720e9..23bb64cc60591d71331ccd6635b91835f89d6605 100644 (file)
@@ -118,6 +118,10 @@ class DatabaseLocal(Database):
 
                Database.__init__(self, pakfire, filename)
 
+       def initialize(self):
+               # Open the database.
+               self.open()
+
                # Check if we actually can open the database.
                if not self.format in DATABASE_FORMATS_SUPPORTED:
                        raise DatabaseFormatError, _("The format of the database is not supported by this version of pakfire.")
index c6f9128a428ae1762801851c255a88197c6d1da0..f38b408e31fa05dde590f7d551b6f18157c169b2 100644 (file)
@@ -255,34 +255,35 @@ class RepositoryBuild(RepositoryDir):
 
                RepositoryDir.__init__(self, pakfire, "build", "Locally built packages", path)
 
-       def update(self, force=False, offline=False):
-               # If force is not given, but there are no files in the repository,
-               # we force an update anyway.
-               if not force:
-                       force = len(self) == 0
+       def open(self):
+               # Find all files in the repository dir.
+               files = self.search_files(self.path)
 
-               if force:
-                       # Wipe the index.
-                       self.index.clear()
+               # Create progress bar.
+               pb = util.make_progress(_("%s: Reading packages...") % self.name, len(files))
+               i = 0
 
-                       # Find all files in the repository dir.
-                       files = self.search_files(self.path)
+               # Add all files to the index.
+               for file in files:
+                       if pb:
+                               i += 1
+                               pb.update(i)
 
-                       # Create progress bar.
-                       pb = util.make_progress(_("%s: Adding packages...") % self.name, len(files))
-                       i = 0
+                       pkg = packages.open(self.pakfire, self, file)
+                       self.index.add_package(pkg)
+
+               if pb:
+                       pb.finish()
 
-                       # Add all files to the index.
-                       for file in files:
-                               if pb:
-                                       i += 1
-                                       pb.update(i)
+               # Mark repo as open.
+               self.opened = True
 
-                               pkg = packages.open(self.pakfire, self, file)
-                               self.index.add_package(pkg)
+       def close(self):
+               # Wipe the index.
+               self.index.clear()
 
-                       if pb:
-                               pb.finish()
+               # Mark repository as not being open.
+               self.opened = False
 
        @property
        def local(self):
index 6d2cdc7a9ede76977d4e0078e31fb47fd16d6de3..410750acb936303572b3a21d716ce0583f9532ab 100644 (file)
@@ -117,17 +117,21 @@ class RepositoryRemote(base.RepositoryFactory):
                # Remove all files in the files cache.
                self.cache.destroy()
 
-       def update(self, force=False, offline=False):
-               if force and offline:
-                       raise OfflineModeError, _("You cannot force to update metadata in offline mode.")
-
+       def open(self):
                # First update the repository metadata.
-               self.update_metadata(force=force, offline=offline)
-               self.update_database(force=force, offline=offline)
+               self.update_metadata()
+               self.update_database()
 
                # Read the database.
                self.open_database()
 
+               # Mark the repository as open.
+               self.opened = True
+
+       def close(self):
+               # Mark the repository as not open.
+               self.opened = False
+
        def open_metadata(self, path=None):
                if not path:
                        path = self.cache_path(os.path.basename(METADATA_DOWNLOAD_FILE))
index 386f2525557a0800e6f9fe3899db1ce0be72df6f..08584cf6b85bc0d338bc731fae03b49b36d8e1e1 100644 (file)
@@ -51,35 +51,44 @@ class RepositorySystem(base.RepositoryFactory):
                """
                return 10
 
-       def update(self, force=False, offline=False):
-               # XXX using the cache is currently disabled
-               #if not force:
-               #       if os.path.exists(self.cache_file):
-               #               self.index.read(self.cache_file)
-               #
-               #       force = len(self) == 0
+       def open(self):
+               # Initialize database.
+               self.db.initialize()
 
-               force = True
+               # Create a progressbar.
+               pb = util.make_progress(_("Loading installed packages"), len(self.db))
 
-               if force:
-                       # Create a progressbar.
-                       pb = util.make_progress(_("Loading installed packages"), len(self.db))
+               # Remove all data from the current index.
+               self.index.clear()
 
-                       # Remove all data from the current index.
-                       self.index.clear()
+               i = 0
+               for pkg in self.db.packages:
+                       if pb:
+                               i += 1
+                               pb.update(i)
+
+                       self.index.add_package(pkg)
 
-                       i = 0
-                       for pkg in self.db.packages:
-                               if pb:
-                                       i += 1
-                                       pb.update(i)
+               self.index.optimize()
 
-                               self.index.add_package(pkg)
+               if pb:
+                       pb.finish()
 
-                       self.index.optimize()
+               # Mark repo as open.
+               self.opened = True
 
-                       if pb:
-                               pb.finish()
+       def close(self):
+               # Commit all data that is currently pending for writing.
+               self.db.commit()
+
+               # Close database.
+               self.db.close()
+
+               # Remove indexed data from memory.
+               self.index.clear()
+
+               # Mark repo as closed.
+               self.opened = False
 
        def commit(self):
                # Commit the database to disk.