]> git.ipfire.org Git - pakfire.git/blobdiff - python/pakfire/cli.py
Create an extra namespace for build environments and private network.
[pakfire.git] / python / pakfire / cli.py
index 9a72d747fea11508e414d422ea01302d5a01e229..a80b397efbd987b29bc9555195282ccaa6a90e63 100644 (file)
@@ -26,14 +26,15 @@ import shutil
 import sys
 import tempfile
 
-import pakfire.api as pakfire
-
+import base
 import client
 import config
+import daemon
 import logger
 import packages
 import repository
 import server
+import transaction
 import util
 
 from system import system
@@ -45,6 +46,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."),
@@ -74,6 +77,7 @@ class Cli(object):
                self.parse_command_clean()
                self.parse_command_check()
                self.parse_command_resolvdep()
+               self.parse_command_extract()
 
                # Finally parse all arguments from the command line and save them.
                self.args = self.parser.parse_args()
@@ -94,21 +98,16 @@ class Cli(object):
                        "clean_all"    : self.handle_clean_all,
                        "check"        : self.handle_check,
                        "resolvdep"    : self.handle_resolvdep,
+                       "extract"      : self.handle_extract,
                }
 
        @property
        def pakfire_args(self):
-               ret = { "mode" : "normal" }
+               ret = {}
 
                if hasattr(self.args, "root"):
                        ret["path"] = self.args.root
 
-               if hasattr(self.args, "disable_repo"):
-                       ret["disable_repos"] = self.args.disable_repo
-
-               if hasattr(self.args, "enable_repo"):
-                       ret["enable_repos"] = self.args.enable_repo
-
                if hasattr(self.args, "offline") and self.args.offline:
                        ret["downloader"] = {
                                "offline" : self.args.offline,
@@ -121,7 +120,26 @@ class Cli(object):
 
                return ret
 
-       def parse_common_arguments(self, repo_manage_switches=True, offline_switch=True):
+       def create_pakfire(self, cls=None, **kwargs):
+               if cls is None:
+                       cls = self.pakfire
+
+               args = self.pakfire_args
+               args.update(kwargs)
+
+               p = cls(**args)
+
+               # Disable repositories.
+               for repo in self.args.disable_repo:
+                       p.repos.disable_repo(repo)
+
+               # Enable repositories.
+               for repo in self.args.enable_repo:
+                       p.repos.enable_repo(repo)
+
+               return p
+
+       def parse_common_arguments(self, offline_switch=True):
                self.parser.add_argument("--version", action="version",
                        version="%(prog)s " + PAKFIRE_VERSION)
 
@@ -131,12 +149,11 @@ class Cli(object):
                self.parser.add_argument("-c", "--config", nargs="?",
                        help=_("Path to a configuration file to load."))
 
-               if repo_manage_switches:
-                       self.parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
-                               help=_("Disable a repository temporarily."))
+               self.parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
+                       help=_("Disable a repository temporarily."), default=[])
 
-                       self.parser.add_argument("--enabled-repo", nargs="*", metavar="REPO",
-                               help=_("Enable a repository temporarily."))
+               self.parser.add_argument("--enable-repo", nargs="*", metavar="REPO",
+                       help=_("Enable a repository temporarily."), default=[])
 
                if offline_switch:
                        self.parser.add_argument("--offline", action="store_true",
@@ -176,8 +193,8 @@ class Cli(object):
                        help=_("Exclude package from update."))
                parser.add_argument("--allow-vendorchange", action="store_true",
                        help=_("Allow changing the vendor of packages."))
-               parser.add_argument("--allow-archchange", action="store_true",
-                       help=_("Allow changing the architecture of packages."))
+               parser.add_argument("--disallow-archchange", action="store_true",
+                       help=_("Disallow changing the architecture of packages."))
 
        def parse_command_update(self):
                # Implement the "update" command.
@@ -201,8 +218,8 @@ class Cli(object):
                        help=_("Give a name of a package to downgrade."))
                sub_downgrade.add_argument("--allow-vendorchange", action="store_true",
                        help=_("Allow changing the vendor of packages."))
-               sub_downgrade.add_argument("--allow-archchange", action="store_true",
-                       help=_("Allow changing the architecture of packages."))
+               sub_downgrade.add_argument("--disallow-archchange", action="store_true",
+                       help=_("Disallow changing the architecture of packages."))
                sub_downgrade.add_argument("action", action="store_const", const="downgrade")
 
        def parse_command_info(self):
@@ -277,6 +294,16 @@ class Cli(object):
                        help=_("Give name of at least one package to check."))
                sub_resolvdep.add_argument("action", action="store_const", const="resolvdep")
 
+       def parse_command_extract(self):
+               # Implement the "extract" command.
+               sub_extract = self.sub_commands.add_parser("extract",
+                       help=_("Extract a package to a directory."))
+               sub_extract.add_argument("package", nargs="+",
+                       help=_("Give name of the file to extract."))
+               sub_extract.add_argument("--target", nargs="?",
+                       help=_("Target directory where to extract to."))
+               sub_extract.add_argument("action", action="store_const", const="extract")
+
        def run(self):
                action = self.args.action
 
@@ -288,96 +315,141 @@ class Cli(object):
                return func()
 
        def handle_info(self, long=False):
-               pkgs = pakfire.info(self.args.package, **self.pakfire_args)
+               p = self.create_pakfire()
 
-               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.create_pakfire()
 
-               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.create_pakfire()
+               p.update(
+                       self.args.package,
+                       excludes=self.args.exclude,
                        allow_vendorchange=self.args.allow_vendorchange,
-                       allow_archchange=self.args.allow_archchange,
-                       **args)
+                       allow_archchange=not self.args.disallow_archchange,
+                       **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.create_pakfire()
+               p.downgrade(
+                       self.args.package,
                        allow_vendorchange=self.args.allow_vendorchange,
-                       allow_archchange=self.args.allow_archchange,
-                       **args)
+                       allow_archchange=not self.args.disallow_archchange,
+                       **args
+               )
 
        def handle_install(self):
-               pakfire.install(self.args.package,
-                       ignore_recommended=self.args.without_recommends,
-                       **self.pakfire_args)
+               p = self.create_pakfire()
+               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.create_pakfire()
+               p.reinstall(self.args.package)
 
        def handle_remove(self):
-               pakfire.remove(self.args.package, **self.pakfire_args)
+               p = self.create_pakfire()
+               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.create_pakfire()
 
-               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.create_pakfire()
 
-               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.create_pakfire()
+               p.groupinstall(self.args.group[0])
 
        def handle_repolist(self):
-               repos = pakfire.repo_list(**self.pakfire_args)
+               p = self.create_pakfire()
 
-               FORMAT = " %-20s %8s %12s %12s "
+               # Get a list of all repositories.
+               repos = p.repo_list()
 
+               FORMAT = " %-20s %8s %12s %12s "
                title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
                print title
                print "=" * len(title) # spacing line
 
                for repo in repos:
-                       # Skip the installed repository.
-                       if repo.name == "installed":
-                               continue
-
                        print FORMAT % (repo.name, repo.enabled, repo.priority, len(repo))
 
        def handle_clean_all(self):
                print _("Cleaning up everything...")
 
-               pakfire.clean_all(**self.pakfire_args)
+               p = self.create_pakfire()
+               p.clean_all()
 
        def handle_check(self):
-               pakfire.check(**self.pakfire_args)
+               p = self.create_pakfire()
+               p.check()
 
        def handle_resolvdep(self):
-               (pkg,) = self.args.package
+               p = self.create_pakfire()
 
-               solver = pakfire.resolvdep(pkg, **self.pakfire_args)
+               (pkg,) = self.args.package
 
+               solver = p.resolvdep(pkg)
                assert solver.status
-               solver.transaction.dump()
+
+               t = transaction.Transaction.from_solver(p, solver)
+               t.dump()
+
+       def handle_extract(self):
+               p = self.create_pakfire()
+
+               # Open all packages.
+               pkgs = []
+               for pkg in self.args.package:
+                       pkg = packages.open(self, None, pkg)
+                       pkgs.append(pkg)
+
+               target_prefix = self.args.target
+
+               # Search for binary packages.
+               binary_packages = any([p.type == "binary" for p in pkgs])
+               source_packages = any([p.type == "source" for p in pkgs])
+
+               if binary_packages and source_packages:
+                       raise Error, _("Cannot extract mixed package types")
+
+               if binary_packages and not target_prefix:
+                       raise Error, _("You must provide an install directory with --target=...")
+
+               elif source_packages and not target_prefix:
+                       target_prefix = "/usr/src/packages/"
+
+               if target_prefix == "/":
+                       raise Error, _("Cannot extract to /.")
+
+               for pkg in pkgs:
+                       if pkg.type == "binary":
+                               target_dir = target_prefix
+                       elif pkg.type == "source":
+                               target_dir = os.path.join(target_prefix, pkg.friendly_name)
+
+                       pkg.extract(message=_("Extracting"), prefix=target_dir)
 
 
 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.
@@ -404,7 +476,7 @@ class CliBuilder(Cli):
                self.parse_command_repolist()
                self.parse_command_clean()
                self.parse_command_resolvdep()
-               self.parse_command_cache()
+               self.parse_command_extract()
 
                # Finally parse all arguments from the command line and save them.
                self.args = self.parser.parse_args()
@@ -421,27 +493,34 @@ class CliBuilder(Cli):
                        "repolist"    : self.handle_repolist,
                        "clean_all"   : self.handle_clean_all,
                        "resolvdep"   : self.handle_resolvdep,
-                       "cache_create": self.handle_cache_create,
-                       "cache_cleanup": self.handle_cache_cleanup,
+                       "extract"     : self.handle_extract,
                }
 
        @property
        def pakfire_args(self):
-               ret = { "mode" : "builder" }
-
-               if hasattr(self.args, "disable_repo"):
-                       ret["disable_repos"] = self.args.disable_repo
-
-               if hasattr(self.args, "enable_repo"):
-                       ret["enable_repos"] = self.args.enable_repo
+               ret = {
+                       "arch" : self.args.arch,
+               }
 
                if hasattr(self.args, "offline") and self.args.offline:
                        ret["downloader"] = {
                                "offline" : self.args.offline,
                        }
 
+               if hasattr(self.args, "distro"):
+                       ret["distro_name"] = self.args.distro
+
                return ret
 
+       def parse_common_arguments(self, *args, **kwargs):
+               Cli.parse_common_arguments(self, *args, **kwargs)
+
+               self.parser.add_argument("--distro", nargs="?",
+                       help=_("Choose the distribution configuration to use for build"))
+
+               self.parser.add_argument("--arch", "-a", nargs="?",
+                       help=_("Run pakfire for the given architecture."))
+
        def parse_command_update(self):
                # Implement the "update" command.
                sub_update = self.sub_commands.add_parser("update",
@@ -456,8 +535,6 @@ class CliBuilder(Cli):
                        help=_("Give name of at least one package to build."))
                sub_build.add_argument("action", action="store_const", const="build")
 
-               sub_build.add_argument("-a", "--arch",
-                       help=_("Build the package for the given architecture."))
                sub_build.add_argument("--resultdir", nargs="?",
                        help=_("Path were the output files should be copied to."))
                sub_build.add_argument("-m", "--mode", nargs="?", default="development",
@@ -466,6 +543,8 @@ class CliBuilder(Cli):
                        help=_("Run a shell after a successful build."))
                sub_build.add_argument("--no-install-test", action="store_true",
                        help=_("Do not perform the install test."))
+               sub_build.add_argument("--private-network", action="store_true",
+                       help=_("Disable network in container."))
 
        def parse_command_shell(self):
                # Implement the "shell" command.
@@ -475,10 +554,10 @@ class CliBuilder(Cli):
                        help=_("Give name of a package."))
                sub_shell.add_argument("action", action="store_const", const="shell")
 
-               sub_shell.add_argument("-a", "--arch",
-                       help=_("Emulated architecture in the shell."))
                sub_shell.add_argument("-m", "--mode", nargs="?", default="development",
                        help=_("Mode to run in. Is either 'release' or 'development' (default)."))
+               sub_shell.add_argument("--private-network", action="store_true",
+                       help=_("Disable network in container."))
 
        def parse_command_dist(self):
                # Implement the "dist" command.
@@ -491,27 +570,6 @@ class CliBuilder(Cli):
                sub_dist.add_argument("--resultdir", nargs="?",
                        help=_("Path were the output files should be copied to."))
 
-       def parse_command_cache(self):
-               # Implement the "cache" command.
-               sub_cache = self.sub_commands.add_parser("cache",
-                       help=_("Create a build environment cache."))
-
-               # Implement subcommands.
-               sub_cache_commands = sub_cache.add_subparsers()
-
-                self.parse_command_cache_create(sub_cache_commands)
-                self.parse_command_cache_cleanup(sub_cache_commands)
-
-       def parse_command_cache_create(self, sub_commands):
-               sub_create = sub_commands.add_parser("create",
-                       help=_("Create a new build environment cache."))
-               sub_create.add_argument("action", action="store_const", const="cache_create")
-
-       def parse_command_cache_cleanup(self, sub_commands):
-               sub_cleanup = sub_commands.add_parser("cleanup",
-                       help=_("Remove all cached build environments."))
-               sub_cleanup.add_argument("action", action="store_const", const="cache_cleanup")
-
        def handle_info(self):
                Cli.handle_info(self, long=True)
 
@@ -526,12 +584,25 @@ class CliBuilder(Cli):
                else:
                        raise FileNotFoundError, pkg
 
-               # Check whether to enable the install test.
-               install_test = not self.args.no_install_test
+               # Build argument list.
+               kwargs = {
+                       "after_shell"   : self.args.after_shell,
+                       # Check whether to enable the install test.
+                       "install_test"  : not self.args.no_install_test,
+                       "result_dir"    : [self.args.resultdir,],
+                       "shell"         : True,
+               }
+
+               if self.args.mode == "release":
+                       kwargs["release_build"] = True
+               else:
+                       kwargs["release_build"] = False
+
+               if self.args.private_network:
+                       kwargs["private_network"] = True
 
-               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)
+               p = self.create_pakfire()
+               p.build(pkg, **kwargs)
 
        def handle_shell(self):
                pkg = None
@@ -547,8 +618,22 @@ 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.create_pakfire()
+
+               kwargs = {
+                       "release_build" : release_build,
+               }
+
+               # Private network
+               if self.args.private_network:
+                       kwargs["private_network"] = True
+
+               p.shell(pkg, **kwargs)
 
        def handle_dist(self):
                # Get the packages from the command line options
@@ -567,38 +652,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.create_pakfire()
                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)
-
-       def handle_cache_create(self):
-               pakfire.cache_create(**self.pakfire_args)
-
-       def handle_cache_cleanup(self):
-               for env in os.listdir(CACHE_ENVIRON_DIR):
-                       if not env.endswith(".cache"):
-                               continue
-
-                       print _("Removing environment cache file: %s..." % env)
-                       env = os.path.join(CACHE_ENVIRON_DIR, env)
-
-                       try:
-                               os.unlink(env)
-                       except OSError:
-                               print _("Could not remove file: %s") % env
+               Cli.handle_provides(self, long=True)
 
 
 class CliServer(Cli):
+       pakfire = base.PakfireServer
+
        def __init__(self):
                self.parser = argparse.ArgumentParser(
                        description = _("Pakfire server command line interface."),
@@ -618,7 +682,7 @@ class CliServer(Cli):
                # Finally parse all arguments from the command line and save them.
                self.args = self.parser.parse_args()
 
-               self.server = server.Server(**self.pakfire_args)
+               #self.server = server.Server(**self.pakfire_args)
 
                self.action2func = {
                        "build"      : self.handle_build,
@@ -630,7 +694,7 @@ class CliServer(Cli):
 
        @property
        def pakfire_args(self):
-               ret = { "mode" : "server" }
+               ret = {}
 
                if hasattr(self.args, "offline") and self.args.offline:
                        ret["downloader"] = {
@@ -723,8 +787,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.create_pakfire()
+               p.repo_create(path, self.args.inputs, key_id=self.args.key)
 
        def handle_info(self):
                info = self.server.info()
@@ -781,32 +845,32 @@ class CliBuilderIntern(Cli):
                else:
                        raise FileNotFoundError, pkg
 
-               conf = config.ConfigBuilder()
+               # Create pakfire instance.
+               c = config.ConfigBuilder()
+               p = base.Pakfire(arch = self.args.arch, config = c)
 
+               # Disable all repositories.
                if self.args.nodeps:
-                       disable_repos = ["*"]
-               else:
-                       disable_repos = None
+                       p.repos.disable_repo("*")
 
-               kwargs = {
-                       "arch"          : self.args.arch,
-                       "builder_mode"  : self.args.mode,
-                       "config"        : conf,
-                       "disable_repos" : disable_repos,
-                       "prepare"       : self.args.prepare,
-                       "resultdir"     : self.args.resultdir,
-               }
+               # Limit stages that are to be run.
+               if self.args.prepare:
+                       stages = ["prepare"]
+               else:
+                       stages = None
 
-               pakfire._build(pkg, **kwargs)
+               p.build(pkg, resultdir=self.args.resultdir, stages=stages)
 
 
 class CliClient(Cli):
+       pakfire = base.PakfireClient
+
        def __init__(self):
                self.parser = argparse.ArgumentParser(
                        description = _("Pakfire client command line interface."),
                )
 
-               self.parse_common_arguments(repo_manage_switches=True, offline_switch=True)
+               self.parse_common_arguments(offline_switch=True)
 
                # Add sub-commands.
                self.sub_commands = self.parser.add_subparsers()
@@ -832,15 +896,17 @@ class CliClient(Cli):
                        "test"        : self.handle_test,
                }
 
-               # Read configuration for the pakfire client.
-               self.conf = conf = config.ConfigClient()
+               # Read configuration.
+               self.config = config.ConfigClient()
 
                # Create connection to pakfire hub.
-               self.client = client.PakfireUserClient(
-                       conf.get("client", "server"),
-                       conf.get("client", "username"),
-                       conf.get("client", "password"),
-               )
+               self.client = client.PakfireClient(self.config)
+
+       @property
+       def pakfire_args(self):
+               return {
+                       "config" : self.config,
+               }
 
        def parse_command_build(self):
                # Parse "build" command.
@@ -922,10 +988,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
@@ -935,21 +1002,23 @@ class CliClient(Cli):
 
                        # Format arches.
                        if self.args.arch:
-                               arches = self.args.arch.replace(",", " ")
+                               arches = self.args.arch.split(",")
                        else:
                                arches = None
 
                        # Create a new build on the server.
-                       build = self.client.build_create(package, arches=arches)
-
-                       # XXX Print the resulting build.
-                       print build
+                       build_id = self.client.build_create(package, build_type="scratch",
+                               arches=arches)
 
                finally:
                        # Cleanup the temporary directory and all files.
                        if os.path.exists(temp_dir):
                                shutil.rmtree(temp_dir, ignore_errors=True)
 
+               # Monitor the build.
+               if build_id:
+                       self.watch_build(build_id)
+
        def handle_info(self):
                ret = []
 
@@ -957,10 +1026,10 @@ class CliClient(Cli):
                ret.append("  PAKFIRE %s" % PAKFIRE_VERSION)
                ret.append("")
                ret.append("  %-20s: %s" % (_("Hostname"), system.hostname))
-               ret.append("  %-20s: %s" % (_("Pakfire hub"), self.conf.get("client", "server")))
-               if self.conf.get("client", "username") and self.conf.get("client", "password"):
+               ret.append("  %-20s: %s" % (_("Pakfire hub"), self.config.get("client", "server")))
+               if self.config.get("client", "username") and self.config.get("client", "password"):
                        ret.append("  %-20s: %s" % \
-                               (_("Username"), self.conf.get("client", "username")))
+                               (_("Username"), self.config.get("client", "username")))
                ret.append("")
 
                # Hardware information
@@ -1129,6 +1198,11 @@ class CliClient(Cli):
                res = self.client.test_code(error_code)
                print _("Reponse from the server: %s") % res
 
+       def watch_build(self, build_id):
+               print self.client.build_get(build_id)
+               # XXX TODO
+               print build_id
+
 
 class CliDaemon(Cli):
        def __init__(self):
@@ -1136,7 +1210,7 @@ class CliDaemon(Cli):
                        description = _("Pakfire daemon command line interface."),
                )
 
-               self.parse_common_arguments(repo_manage_switches=True, offline_switch=True)
+               self.parse_common_arguments(offline_switch=True)
 
                # Finally parse all arguments from the command line and save them.
                self.args = self.parser.parse_args()
@@ -1146,10 +1220,11 @@ class CliDaemon(Cli):
                        Runs the pakfire daemon with provided settings.
                """
                # Read the configuration file for the daemon.
-               conf = config.ConfigDaemon()
+               self.config = config.ConfigDaemon()
+               logger.setup_logging(self.config)
 
                # Create daemon instance.
-               d = pakfire.client.PakfireDaemon()
+               d = daemon.PakfireDaemon(self.config)
                try:
                        d.run()
 
@@ -1159,13 +1234,14 @@ class CliDaemon(Cli):
 
 
 class CliKey(Cli):
+       pakfire = base.PakfireKey
+
        def __init__(self):
                self.parser = argparse.ArgumentParser(
                        description = _("Pakfire key command line interface."),
                )
 
-               self.parse_common_arguments(repo_manage_switches=False,
-                       offline_switch=True)
+               self.parse_common_arguments(offline_switch=True)
 
                # Add sub-commands.
                self.sub_commands = self.parser.add_subparsers()
@@ -1181,9 +1257,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,
@@ -1196,11 +1269,7 @@ class CliKey(Cli):
 
        @property
        def pakfire_args(self):
-               ret = {
-                       "mode" : "server",
-               }
-
-               return ret
+               return {}
 
        def parse_command_generate(self):
                # Parse "generate" command.
@@ -1228,8 +1297,6 @@ class CliKey(Cli):
                        help=_("The ID of the key to export."))
                sub_export.add_argument("filename", nargs=1,
                        help=_("Write the key to this file."))
-               sub_export.add_argument("--secret", action="store_true",
-                       help=_("Export the secret key, too."))
                sub_export.add_argument("action", action="store_const", const="export")
 
        def parse_command_delete(self):
@@ -1274,30 +1341,32 @@ class CliKey(Cli):
                print
 
                # Generate the key.
-               pakfire.key_generate(realname, email, **self.pakfire_args)
+               p = self.create_pakfire()
+               p.keyring.gen_key(realname, email)
 
        def handle_import(self):
                filename = self.args.filename[0]
 
                # Simply import the file.
-               pakfire.key_import(filename, **self.pakfire_args)
+               p = self.create_pakfire()
+               p.keyring.import_key(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.create_pakfire()
+               p.keyring.export_key(keyid, filename)
 
        def handle_delete(self):
                keyid = self.args.keyid[0]
 
-               pakfire.key_delete(keyid, **self.pakfire_args)
+               p = self.create_pakfire()
+               p.keyring.delete_key(keyid)
 
        def handle_list(self):
-               lines = pakfire.key_list(**self.pakfire_args)
-
-               for line in lines:
+               p = self.create_pakfire()
+               for line in p.keyring.list_keys():
                        print line
 
        def handle_sign(self):
@@ -1315,9 +1384,12 @@ class CliKey(Cli):
 
                key = self.args.key[0]
 
+               # Create pakfire instance.
+               p = self.create_pakfire()
+
                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)
@@ -1332,15 +1404,18 @@ class CliKey(Cli):
                                file = os.path.abspath(file)
                                files.append(file)
 
+               # Create pakfire instance.
+               p = self.create_pakfire()
+
                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()
 
                        for sig in sigs:
-                               key = self.pakfire.keyring.get_key(sig.fpr)
+                               key = p.keyring.get_key(sig.fpr)
                                if key:
                                        subkey = key.subkeys[0]