From 7c8f2953f3b397c9555e98eec0cf0e0a3ca9dd5a Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 9 Apr 2011 14:55:35 +0200 Subject: [PATCH] Try to design a better API. --- pakfire/__init__.py | 386 ++++++++++++++--------------------- pakfire/base.py | 107 ++++++++-- pakfire/builder.py | 32 ++- pakfire/cli.py | 131 +++++------- pakfire/distro.py | 36 +++- pakfire/errors.py | 3 + pakfire/packages/__init__.py | 3 + pakfire/server/master.py | 12 +- pakfire/server/slave.py | 20 +- pakfire/util.py | 8 + po/pakfire.pot | 199 +++++++++++------- 11 files changed, 494 insertions(+), 443 deletions(-) diff --git a/pakfire/__init__.py b/pakfire/__init__.py index 66d31b6d0..117ea065f 100644 --- a/pakfire/__init__.py +++ b/pakfire/__init__.py @@ -1,308 +1,222 @@ #!/usr/bin/python -import logging -import os -import random -import string - +import base import builder -import config import depsolve -import distro -import logger import packages -import plugins -import repository import transaction -import util - -from constants import * -from errors import BuildError, PakfireError -from i18n import _ - -__version__ = PAKFIRE_VERSION - - -class Pakfire(object): - def __init__(self, path="/", builder=False, configs=[], - disable_repos=None): - # Check if we are operating as the root user. - self.check_root_user() - - # Generate a random value. - rnd = random.sample(string.lowercase + string.digits, 12) - rnd = "".join(rnd) - - # The path where we are operating in - self.path = path - self.tempdir = os.path.join(LOCAL_TMP_PATH, rnd) - - if not os.path.exists(self.tempdir): - os.makedirs(self.tempdir) - - # Save if we are in the builder mode - self.builder = builder - if self.builder: - self.path = os.path.join(BUILD_ROOT, rnd) +from errors import * - self.debug = False +Builder = builder.Builder +Pakfire = base.Pakfire - # Read configuration file(s) - self.config = config.Config(pakfire=self) - for filename in configs: - self.config.read(filename) +def install(requires, **pakfire_args): + pakfire = Pakfire(**pakfire_args) - # Setup the logger - logger.setup_logging(self.config) - self.config.dump() + ds = depsolve.DependencySet(pakfire=pakfire) - # Load plugins - self.plugins = plugins.Plugins(pakfire=self) + for req in requires: + if isinstance(req, packages.BinaryPackage): + ds.add_package(req) + else: + ds.add_requires(req) - # Get more information about the distribution we are running - # or building - self.distro = distro.Distribution(pakfire=self) + ds.resolve() + ds.dump() - # Load all repositories - self.repos = repository.Repositories(pakfire=self) + ret = cli.ask_user(_("Is this okay?")) + if not ret: + return - # Run plugins that implement an initialization method. - self.plugins.run("init") + ts = transaction.Transaction(pakfire, ds) + ts.run() - # Disable repositories if passed on command line - if disable_repos: - for repo in disable_repos: - self.repos.disable_repo(repo) +def remove(**pakfire_args): + pass - # Check if there is at least one enabled repository. - if len(self.repos) < 2: - raise PakfireError, "No repositories were configured." +def update(pkgs, **pakfire_args): + pakfire = Pakfire(**pakfire_args) - # Update all indexes of the repositories (not force) so that we will - # always work with valid data. - self.repos.update() + ds = depsolve.DependencySet(pakfire=self) - def __del__(self): - util.rm(self.tempdir) + for pkg in ds.packages: + # Skip unwanted packages (passed on command line) + if pkgs and not pkg.name in pkgs: + continue - @property - def supported_arches(self): - return self.distro.supported_arches + updates = pakfire.repos.get_by_name(pkg.name) + updates = packages.PackageListing(updates) - 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." + latest = updates.get_most_recent() - def check_build_mode(self): - """ - Check if we are running in build mode. - Otherwise, raise an exception. - """ - if not self.builder: - raise BuildError, "Cannot build when not in build mode." + # If the current package is already the latest + # we skip it. + if latest == pkg: + continue - def check_host_arch(self, arch): - """ - Check if we can build for arch. - """ + # Otherwise we want to update the package. + ds.add_package(latest) - # If no arch was given on the command line we build for our - # own arch which should always work. - if not arch: - return True + ds.resolve() + ds.dump() - if not self.distro.host_supports_arch(arch): - raise BuildError, "Cannot build for the target architecture: %s" % arch + ret = cli.ask_user(_("Is this okay?")) + if not ret: + return - raise BuildError, arch + ts = transaction.Transaction(pakfire, ds) + ts.run() - def build(self, pkg, arch=None, resultdirs=None, **kwargs): - self.check_build_mode() - self.check_host_arch(arch) +def info(patterns, **pakfire_args): + # Create pakfire instance. + pakfire = Pakfire(**pakfire_args) - if not resultdirs: - resultdirs = [] + pkgs = [] - # Always include local repository - resultdirs.append(self.repos.local_build.path) + for pattern in patterns: + pkgs += pakfire.repos.get_by_glob(pattern) - b = builder.Builder(pakfire=self, pkg=pkg, **kwargs) + return packages.PackageListing(pkgs) - try: - b.prepare() - b.extract() - b.build() - b.install_test() +def search(pattern, **pakfire_args): + # Create pakfire instance. + pakfire = Pakfire(**pakfire_args) - # Copy-out all resultfiles - for resultdir in resultdirs: - if not resultdir: - continue + # Do the search. + pkgs = pakfire.repos.search(pattern) - b.copy_result(resultdir) + # Return the output as a package listing. + return packages.PackageListing(pkgs) - except BuildError: - b.shell() +def groupinstall(group, **pakfire_args): + pakfire = Pakfire(**pakfire_args) - finally: - b.destroy() + pkgs = grouplist(group, **pakfire_args) - def shell(self, pkg, arch=None): - self.check_build_mode() - self.check_host_arch(arch) + install(pkgs, **pakfire_args) - b = builder.Builder(pakfire=self, pkg=pkg) +def grouplist(group, **pakfire_args): + pakfire = Pakfire(**pakfire_args) - try: - b.prepare() - b.extract() - b.shell() - finally: - b.destroy() + pkgs = pakfire.repos.get_by_group(group) - def dist(self, pkgs, resultdirs=None, destroy=True): - self.check_build_mode() + pkgs = packages.PackageListing(pkgs) + pkgs.unique() - # Select first package out of pkgs. - pkg = pkgs[0] + return [p.name for p in pkgs] - b = builder.Builder(pakfire=self, pkg=pkg) - try: - b.prepare() - b.extract(build_deps=False) - except: - # If there is any exception, we destroy our stuff and raise it. - b.destroy() - raise +def build(pkg, distro_config=None, build_id=None, resultdirs=None, **pakfire_args): + if not resultdirs: + resultdirs = [] - if not resultdirs: - resultdirs = [] + b = Builder(pkg, distro_config, build_id=build_id, **pakfire_args) - # Always include local repository - resultdirs.append(self.repos.local_build.path) + # Make shortcut to pakfire instance. + p = b.pakfire - try: - for pkg in pkgs: - # Change package of the builder to current one. - b.pkg = pkg - b.extract(build_deps=False) + # Always include local repository. + resultdirs.append(p.repos.local_build.path) - # Run the actual dist. - b.dist() + try: + b.prepare() + b.extract() + b.build() + b.install_test() - # Copy-out all resultfiles - for resultdir in resultdirs: - if not resultdir: - continue - - b.copy_result(resultdir) + # Copy-out all resultfiles + for resultdir in resultdirs: + if not resultdir: + continue - # Cleanup all the stuff from pkg. - b.cleanup() - finally: - if destroy: - b.destroy() + b.copy_result(resultdir) - def install(self, requires): - ds = depsolve.DependencySet(pakfire=self) + except BuildError: + b.shell() - for req in requires: - if isinstance(req, packages.BinaryPackage): - ds.add_package(req) - else: - ds.add_requires(req) + finally: + b.destroy() - ds.resolve() - ds.dump() +def shell(pkg, distro_config=None, **pakfire_args): + b = builder.Builder(pkg, distro_config, **pakfire_args) - ret = cli.ask_user(_("Is this okay?")) - if not ret: - return + try: + b.prepare() + b.extract() + b.shell() + finally: + b.destroy() - ts = transaction.Transaction(self, ds) - ts.run() +def dist(pkg, resultdirs=None, **pakfire_args): + b = builder.Builder(pkg, **pakfire_args) + p = b.pakfire - def update(self, pkgs): - ds = depsolve.DependencySet(pakfire=self) + if not resultdirs: + resultdirs = [] - for pkg in ds.packages: - # Skip unwanted packages (passed on command line) - if pkgs and not pkg.name in pkgs: - continue + # Always include local repository + resultdirs.append(p.repos.local_build.path) - updates = self.repos.get_by_name(pkg.name) - updates = packages.PackageListing(updates) + try: + b.prepare() + b.extract(build_deps=False) - latest = updates.get_most_recent() + # Run the actual dist. + b.dist() - # If the current package is already the latest - # we skip it. - if latest == pkg: + # Copy-out all resultfiles + for resultdir in resultdirs: + if not resultdir: continue - # Otherwise we want to update the package. - ds.add_package(latest) - - ds.resolve() - ds.dump() - - ret = cli.ask_user(_("Is this okay?")) - if not ret: - return - - ts = transaction.Transaction(self, ds) - ts.run() - - def provides(self, patterns): - pkgs = [] - - for pattern in patterns: - requires = depsolve.Requires(None, pattern) - pkgs += self.repos.get_by_provides(requires) - - pkgs = packages.PackageListing(pkgs) - #pkgs.unique() + b.copy_result(resultdir) + finally: + b.destroy() - return pkgs +def provides(patterns, **pakfire_args): + # Create pakfire instance. + pakfire = Pakfire(**pakfire_args) - def requires(self, patterns): - pkgs = [] + pkgs = [] + for pattern in patterns: + requires = depsolve.Requires(None, pattern) + pkgs += pakfire.repos.get_by_provides(requires) - for pattern in patterns: - requires = depsolve.Requires(None, pattern) - pkgs += self.repos.get_by_requires(requires) + pkgs = packages.PackageListing(pkgs) + #pkgs.unique() - pkgs = packages.PackageListing(pkgs) - #pkgs.unique() + return pkgs - return pkgs +def requires(patterns, **pakfire_args): + # Create pakfire instance. + pakfire = Pakfire(**pakfire_args) - def repo_create(self, path, input_paths): - repo = repository.LocalBinaryRepository( - self, - name="new", - description="New repository.", - path=path, - ) + pkgs = [] + for pattern in patterns: + requires = depsolve.Requires(None, pattern) + pkgs += pakfire.repos.get_by_requires(requires) - for input_path in input_paths: - repo._collect_packages(input_path) + pkgs = packages.PackageListing(pkgs) + #pkgs.unique() - repo.save() + return pkgs - def groupinstall(self, group): - pkgs = self.grouplist(group) +def repo_create(path, input_paths, **pakfire_args): + pakfire = Pakfire(**pakfire_args) - self.install(pkgs) + repo = repository.LocalBinaryRepository( + pakfire, + name="new", + description="New repository.", + path=path, + ) - def grouplist(self, group): - pkgs = self.repos.get_by_group(group) + for input_path in input_paths: + repo._collect_packages(input_path) - pkgs = packages.PackageListing(pkgs) - pkgs.unique() + repo.save() - return [p.name for p in pkgs] +def repo_list(**pakfire_args): + pakfire = Pakfire(**pakfire_args) - def repolist(self): - return self.repos.all + return pakfire.repos.all diff --git a/pakfire/base.py b/pakfire/base.py index 1cd8c3fe0..965e30f7d 100644 --- a/pakfire/base.py +++ b/pakfire/base.py @@ -1,15 +1,96 @@ #!/usr/bin/python -class Singleton(type): - """ - A class for using the singleton pattern - """ - def __init__(cls, name, bases, dict): - super(Singleton, cls).__init__(name, bases, dict) - cls.instance = None - - def __call__(cls, *args, **kw): - if cls.instance is None: - cls.instance = super(Singleton, cls).__call__(*args, **kw) - - return cls.instance +import logging +import os +import random +import string + +import depsolve +import distro +import logger +import packages +import transaction +import util + +from config import Config +from constants import * +from distro import Distribution +from errors import BuildError, PakfireError +from repository import Repositories +from i18n import _ + +__version__ = PAKFIRE_VERSION + +class Pakfire(object): + def __init__(self, builder=False, configs=[], disable_repos=None, + distro_config=None): + # Check if we are operating as the root user. + self.check_root_user() + + # The path where we are operating in. + if builder: + self.builder = True + self.path = os.path.join(BUILD_ROOT, util.random_string()) + else: + self.builder = False + self.path = "/" + + # XXX check if we are actually running on an ipfire system. + + # Read configuration file(s) + self.config = Config(pakfire=self) + for filename in configs: + self.config.read(filename) + + # Setup the logger + logger.setup_logging(self.config) + self.config.dump() + + # Get more information about the distribution we are running + # or building + self.distro = Distribution(self, distro_config) + self.repos = Repositories(self) + + # XXX Disable repositories if passed on command line + #if disable_repos: + # for repo in disable_repos: + # self.repos.disable_repo(repo) + + # Update all indexes of the repositories (not force) so that we will + # always work with valid data. + self.repos.update() + + def destroy(self): + if not self.path == "/": + util.rm(self.path) + + @property + def supported_arches(self): + return self.distro.supported_arches + + 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.builder: + raise BuildError, "Cannot build when not in build mode." + + def check_host_arch(self, arch): + """ + Check if we can build for arch. + """ + + # If no arch was given on the command line we build for our + # own arch which should always work. + if not arch: + return True + + if not self.distro.host_supports_arch(arch): + raise BuildError, "Cannot build for the target architecture: %s" % arch + + raise BuildError, arch diff --git a/pakfire/builder.py b/pakfire/builder.py index e022274b6..a9fb3f1a9 100644 --- a/pakfire/builder.py +++ b/pakfire/builder.py @@ -12,6 +12,7 @@ import stat import time import uuid +import base import depsolve import packages import repository @@ -27,16 +28,26 @@ class Builder(object): # The version of the kernel this machine is running. kernel_version = os.uname()[2] - def __init__(self, pakfire, pkg, build_id=None, **settings): - self.pakfire = pakfire - self.pkg = pkg + def __init__(self, pkg, distro_config=None, build_id=None, **pakfire_args): + pakfire_args.update({ + "builder" : True, + }) + # Create pakfire instance. + self.pakfire = base.Pakfire(distro_config=distro_config, **pakfire_args) + self.distro = self.pakfire.distro + self.path = self.pakfire.path + + # Open the package. + self.pkg = packages.open(self.pakfire, None, pkg) + + # XXX need to make this configureable self.settings = { "enable_loop_devices" : True, "enable_ccache" : True, "enable_icecream" : False, } - self.settings.update(settings) + #self.settings.update(settings) self.buildroot = "/buildroot" @@ -53,6 +64,13 @@ class Builder(object): self.build_id = build_id + @property + def arch(self): + """ + Inherit architecture from distribution configuration. + """ + return self.distro.arch + @property def info(self): return { @@ -62,10 +80,6 @@ class Builder(object): "build_time" : self.build_time, } - @property - def path(self): - return self.pakfire.path - def lock(self): filename = os.path.join(self.path, ".lock") @@ -472,7 +486,7 @@ class Builder(object): # Update personality it none was set if not personality: - personality = self.pakfire.distro.personality + personality = self.distro.personality # Make every shell to a login shell because we set a lot of # environment things there. diff --git a/pakfire/cli.py b/pakfire/cli.py index aed3a13ef..c4eab2160 100644 --- a/pakfire/cli.py +++ b/pakfire/cli.py @@ -8,8 +8,7 @@ import repository import server import util -from pakfire import Pakfire - +import pakfire from constants import * from i18n import _ @@ -59,13 +58,6 @@ class Cli(object): # Finally parse all arguments from the command line and save them. self.args = self.parser.parse_args() - # Create instance of the wonderful pakfire :) - self.pakfire = Pakfire( - self.args.instroot, - configs = [self.args.config], - disable_repos = self.args.disable_repo, - ) - self.action2func = { "install" : self.handle_install, "localinstall" : self.handle_localinstall, @@ -79,6 +71,10 @@ class Cli(object): "repolist" : self.handle_repolist, } + @property + def pakfire_args(self): + return {} + def parse_common_arguments(self): self.parser.add_argument("-v", "--verbose", action="store_true", help=_("Enable verbose output.")) @@ -181,24 +177,19 @@ class Cli(object): return func() def handle_info(self, long=False): - for pattern in self.args.package: - pkgs = self.pakfire.repos.get_by_glob(pattern) + pkgs = pakfire.info(self.args.package, **self.pakfire_args) - pkgs = packages.PackageListing(pkgs) - - for pkg in pkgs: - print pkg.dump(long=long) + for pkg in pkgs: + print pkg.dump(long=long) def handle_search(self): - pkgs = self.pakfire.repos.search(self.args.pattern) - - pkgs = packages.PackageListing(pkgs) + pkgs = pakfire.search(self.args.pattern, **self.pakfire_args) for pkg in pkgs: print pkg.dump(short=True) def handle_update(self): - self.pakfire.update(self.args.package) + pakfire.update(self.args.package, **self.pakfire_args) def handle_install(self, local=False): if local: @@ -211,34 +202,34 @@ class Cli(object): pkgs.append(pkg) - self.pakfire.install(pkgs) + pakfire.install(pkgs, **self.pakfire_args) def handle_localinstall(self): - return self.handle_install(local=True) + return self.handle_install(local=True, **self.pakfire_args) def handle_provides(self): - pkgs = self.pakfire.provides(self.args.pattern) + pkgs = pakfire.provides(self.args.pattern, **self.pakfire_args) for pkg in pkgs: print pkg.dump() def handle_requires(self): - pkgs = self.pakfire.requires(self.args.pattern) + pkgs = pakfire.requires(self.args.pattern, **self.pakfire_args) for pkg in pkgs: print pkg.dump() def handle_grouplist(self): - pkgs = self.pakfire.grouplist(self.args.group[0]) + pkgs = pakfire.grouplist(self.args.group[0], **self.pakfire_args) for pkg in pkgs: print " * %s" % pkg def handle_groupinstall(self): - self.pakfire.groupinstall(self.args.group[0]) + pakfire.groupinstall(self.args.group[0], **self.pakfire_args) def handle_repolist(self): - repos = self.pakfire.repolist() + repos = pakfire.repo_list(**self.pakfire_args) repos.sort() FORMAT = " %-20s %8s %12s " @@ -280,12 +271,6 @@ class CliBuilder(Cli): # Finally parse all arguments from the command line and save them. self.args = self.parser.parse_args() - self.pakfire = Pakfire( - builder = True, - configs = [self.args.config], - disable_repos = self.args.disable_repo, - ) - self.action2func = { "build" : self.handle_build, "dist" : self.handle_dist, @@ -299,6 +284,10 @@ class CliBuilder(Cli): "repolist" : self.handle_repolist, } + @property + def pakfire_args(self): + return { "builder" : 1 } + def parse_command_update(self): # Implement the "update" command. sub_update = self.sub_commands.add_parser("update", @@ -351,18 +340,16 @@ class CliBuilder(Cli): if os.path.exists(pkg): pkg = os.path.abspath(pkg) - if pkg.endswith(MAKEFILE_EXTENSION): - pkg = packages.Makefile(self.pakfire, pkg) - - elif pkg.endswith(PACKAGE_EXTENSION): - repo = repository.FileSystemRepository(self.pakfire) - pkg = packages.SourcePackage(self.pakfire, repo, pkg) - else: - # XXX walk through the source tree and find a matching makefile - pass + raise FileNotFoundError, pkg - self.pakfire.build(pkg, arch=self.args.arch, resultdirs=[self.args.resultdir,]) + # Create distribution configuration from command line. + distro_config = { + "arch" : self.args.arch, + } + + pakfire.build(pkg, distro_config, resultdirs=[self.args.resultdir,], + **self.pakfire_args) def handle_shell(self): pkg = None @@ -371,22 +358,19 @@ class CliBuilder(Cli): if self.args.package: pkg = self.args.package - # Check, if we got a regular file - if pkg and os.path.exists(pkg): - pkg = os.path.abspath(pkg) - - if pkg.endswith(MAKEFILE_EXTENSION): - pkg = packages.Makefile(self.pakfire, pkg) + # Check, if we got a regular file + if os.path.exists(pkg): + pkg = os.path.abspath(pkg) - elif pkg.endswith(PACKAGE_EXTENSION): - repo = repository.FileSystemRepository(self.pakfire) - pkg = packages.SourcePackage(self.pakfire, repo, pkg) + else: + raise FileNotFoundError, pkg - else: - # XXX walk through the source tree and find a matching makefile - pass + # Create distribution configuration from command line. + distro_config = { + "arch" : self.args.arch, + } - self.pakfire.shell(pkg, arch=self.args.arch) + pakfire.shell(pkg, distro_config, **self.pakfire_args) def handle_dist(self): # Get the packages from the command line options @@ -396,16 +380,15 @@ class CliBuilder(Cli): # Check, if we got a regular file if os.path.exists(pkg): pkg = os.path.abspath(pkg) - - if pkg.endswith(MAKEFILE_EXTENSION): - pkg = packages.Makefile(self.pakfire, pkg) - pkgs.append(pkg) + pkgs.append(pkg) else: - # XXX walk through the source tree and find a matching makefile - pass + raise FileNotFoundError, pkg + + for pkg in pkgs: + pakfire.dist(pkg, resultdirs=[self.args.resultdir,], + **self.pakfire_args) - self.pakfire.dist(pkgs, resultdirs=[self.args.resultdir,]) class CliRepo(Cli): def __init__(self): @@ -423,12 +406,6 @@ class CliRepo(Cli): # Finally parse all arguments from the command line and save them. self.args = self.parser.parse_args() - self.pakfire = Pakfire( - builder = True, - configs = [self.args.config], - disable_repos = self.args.disable_repo, - ) - self.action2func = { "repo_create" : self.handle_repo_create, } @@ -451,7 +428,7 @@ class CliRepo(Cli): def handle_repo_create(self): path = self.args.path[0] - self.pakfire.repo_create(path, self.args.inputs) + pakfire.repo_create(path, self.args.inputs, **self.pakfire_args) class CliMaster(Cli): @@ -470,13 +447,7 @@ class CliMaster(Cli): # Finally parse all arguments from the command line and save them. self.args = self.parser.parse_args() - self.pakfire = Pakfire( - builder = True, - configs = [self.args.config], - disable_repos = self.args.disable_repo, - ) - - self.master = server.master.Master(self.pakfire) + self.master = server.master.Master() self.action2func = { "update" : self.handle_update, @@ -509,13 +480,7 @@ class CliSlave(Cli): # Finally parse all arguments from the command line and save them. self.args = self.parser.parse_args() - self.pakfire = Pakfire( - builder = True, - configs = [self.args.config], - disable_repos = self.args.disable_repo, - ) - - self.slave = server.slave.Slave(self.pakfire) + self.slave = server.slave.Slave() self.action2func = { "build" : self.handle_build, diff --git a/pakfire/distro.py b/pakfire/distro.py index 0d885afdb..8e704f62c 100644 --- a/pakfire/distro.py +++ b/pakfire/distro.py @@ -5,9 +5,10 @@ import os import re from errors import ConfigError +from repository import Repositories class Distribution(object): - def __init__(self, pakfire): + def __init__(self, pakfire, distro_config=None): self.pakfire = pakfire self._data = { @@ -18,11 +19,11 @@ class Distribution(object): "version" : "0.0", } - if not self.pakfire.config._distro: - raise ConfigError, "No distribution data was provided in the configuration" + # Inherit configuration from Pakfire configuration. + self.update(self.pakfire.config._distro) - # Import settings from Config() - self._data.update(self.pakfire.config._distro) + # Update my configuration from the constructor. + self.update(distro_config) # Dump all data self.dump() @@ -30,11 +31,23 @@ class Distribution(object): def dump(self): logging.debug("Distribution configuration:") - attrs = ("name", "version", "release", "sname", "dist", "vendor", "machine",) + attrs = ("name", "version", "release", "sname", "dist", "vendor", + "arch", "machine",) for attr in attrs: logging.debug(" %s : %s" % (attr, getattr(self, attr))) + def update(self, config): + if not config: + return + + # Exceptional handling for arch. + if config.has_key("arch"): + self.arch = config["arch"] + del config["arch"] + + self._data.update(config) + @property def name(self): return self._data.get("name") @@ -62,11 +75,14 @@ class Distribution(object): return self._data.get("vendor") def get_arch(self): - return self._data.get("arch") + return self._data.get("arch") or self.host_arch def set_arch(self, arch): # XXX check if we are allowed to set this arch - self._data.set("arch", arch) + if not arch: + return + + self._data["arch"] = arch arch = property(get_arch, set_arch) @@ -76,7 +92,9 @@ class Distribution(object): @property def machine(self): - return "%s-%s-linux-gnu" % (self.arch, self.vendor) + vendor = self.vendor.split()[0] + + return "%s-%s-linux-gnu" % (self.arch, vendor.lower()) @property def host_arch(self): diff --git a/pakfire/errors.py b/pakfire/errors.py index bad4be229..da38807f3 100644 --- a/pakfire/errors.py +++ b/pakfire/errors.py @@ -21,6 +21,9 @@ class DownloadError(Error): class FileError(Error): pass +class FileNotFoundError(Error): + pass + class PakfireError(Error): pass diff --git a/pakfire/packages/__init__.py b/pakfire/packages/__init__.py index a8717dcc3..2826bd955 100644 --- a/pakfire/packages/__init__.py +++ b/pakfire/packages/__init__.py @@ -23,4 +23,7 @@ def open(pakfire, repo, filename): if filename.endswith(".src.%s" % PACKAGE_EXTENSION): return SourcePackage(pakfire, repo, filename) + elif filename.endswith(".%s" % MAKEFILE_EXTENSION): + return Makefile(pakfire, filename) + return BinaryPackage(pakfire, repo, filename) diff --git a/pakfire/server/master.py b/pakfire/server/master.py index e0e2ad1ba..1e95956d8 100644 --- a/pakfire/server/master.py +++ b/pakfire/server/master.py @@ -7,6 +7,9 @@ import shutil import subprocess import xmlrpclib +import pakfire +import pakfire.base + import pakfire.packages as packages import pakfire.repository as repository import pakfire.util as util @@ -80,7 +83,7 @@ class Source(object): pkgs = [] for file in files: if os.path.exists(file): - pkgs.append(packages.Makefile(self.pakfire, file)) + pkgs.append(file) else: pkg_name = os.path.basename(os.path.dirname(file)) @@ -91,7 +94,8 @@ class Source(object): return # XXX This totally ignores the local configuration. - self.pakfire.dist(pkgs, destroy=False, resultdirs=[tmpdir,]) + for pkg in pkgs: + pakfire.dist(pkg, resultdirs=[tmpdir,]) # Create a kind of dummy repository to link the packages against it. repo = repository.LocalSourceRepository(self.pakfire, @@ -153,8 +157,8 @@ class Source(object): class Master(object): - def __init__(self, pakfire): - self.pakfire = pakfire + def __init__(self, **pakfire_args): + self.pakfire = pakfire.base.Pakfire(**pakfire_args) server = self.pakfire.config._master.get("server") diff --git a/pakfire/server/slave.py b/pakfire/server/slave.py index 31f760256..4a4c00090 100644 --- a/pakfire/server/slave.py +++ b/pakfire/server/slave.py @@ -5,14 +5,16 @@ import os import socket import xmlrpclib +import pakfire +import pakfire.base import pakfire.downloader import pakfire.packages from pakfire.errors import * class Slave(object): - def __init__(self, pakfire): - self.pakfire = pakfire + def __init__(self, **pakfire_args): + self.pakfire = pakfire.base.Pakfire(**pakfire_args) server = self.pakfire.config._slave.get("server") @@ -59,25 +61,23 @@ class Slave(object): grabber = pakfire.downloader.PackageDownloader() # Temporary path to store the source. - tempfile = os.path.join(self.pakfire.tempdir, os.path.basename(filename)) + tempfile = os.path.join("/var/tmp", os.path.basename(filename)) # Download the source. - grabber.urlgrab(filename, filename=tempfile) - - # Read the package file. - pkg = pakfire.packages.SourcePackage(self.pakfire, - self.pakfire.repos.dummy, tempfile) + pkg = grabber.urlgrab(filename, filename=tempfile) try: self.update_build_status(build_id, "running") - self.pakfire.build(pkg, build_id=build_id) + pakfire.build(pkg, build_id=build_id) except DependencyError, e: self.update_build_status(build_id, "dependency_error", e) except: self.update_build_status(build_id, "failed") + raise - self.update_build_status(build_id, "finished") + else: + self.update_build_status(build_id, "finished") diff --git a/pakfire/util.py b/pakfire/util.py index 220558724..5f5269782 100644 --- a/pakfire/util.py +++ b/pakfire/util.py @@ -28,6 +28,14 @@ def cli_is_interactive(): return False +def random_string(length=20): + s = "" + + for i in range(length): + s += random.choice(string.letters) + + return s + def make_progress(message, maxval): # Return nothing if stdout is not a terminal. if not sys.stdout.isatty(): diff --git a/po/pakfire.pot b/po/pakfire.pot index 0e163d2b8..dd3dbde38 100644 --- a/po/pakfire.pot +++ b/po/pakfire.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-04-04 13:33+0200\n" +"POT-Creation-Date: 2011-04-09 14:55+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,286 +17,327 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ../pakfire/cli.py:28 +#: ../pakfire/builder.py:188 +#, python-format +msgid "Extracting: %s (source)" +msgstr "" + +#: ../pakfire/cli.py:27 #, python-format msgid "%s [y/N]" msgstr "" -#: ../pakfire/cli.py:37 +#: ../pakfire/cli.py:35 msgid "Pakfire command line interface." msgstr "" -#: ../pakfire/cli.py:44 +#: ../pakfire/cli.py:42 msgid "The path where pakfire should operate in." msgstr "" -#: ../pakfire/cli.py:77 +#: ../pakfire/cli.py:80 msgid "Enable verbose output." msgstr "" -#: ../pakfire/cli.py:80 +#: ../pakfire/cli.py:83 msgid "Path to a configuration file to load." msgstr "" -#: ../pakfire/cli.py:83 +#: ../pakfire/cli.py:86 msgid "Disable a repository temporarily." msgstr "" -#: ../pakfire/cli.py:88 +#: ../pakfire/cli.py:91 msgid "Install one or more packages to the system." msgstr "" -#: ../pakfire/cli.py:90 +#: ../pakfire/cli.py:93 msgid "Give name of at least one package to install." msgstr "" -#: ../pakfire/cli.py:96 +#: ../pakfire/cli.py:99 msgid "Install one or more packages from the filesystem." msgstr "" -#: ../pakfire/cli.py:98 +#: ../pakfire/cli.py:101 msgid "Give filename of at least one package." msgstr "" -#: ../pakfire/cli.py:104 +#: ../pakfire/cli.py:107 msgid "Update the whole system or one specific package." msgstr "" -#: ../pakfire/cli.py:106 +#: ../pakfire/cli.py:109 msgid "Give a name of a package to update or leave emtpy for all." msgstr "" -#: ../pakfire/cli.py:112 +#: ../pakfire/cli.py:115 msgid "Print some information about the given package(s)." msgstr "" -#: ../pakfire/cli.py:114 +#: ../pakfire/cli.py:117 msgid "Give at least the name of one package." msgstr "" -#: ../pakfire/cli.py:120 +#: ../pakfire/cli.py:123 msgid "Search for a given pattern." msgstr "" -#: ../pakfire/cli.py:122 +#: ../pakfire/cli.py:125 msgid "A pattern to search for." msgstr "" -#: ../pakfire/cli.py:128 +#: ../pakfire/cli.py:131 msgid "Get a list of packages that provide a given file or feature." msgstr "" -#: ../pakfire/cli.py:130 +#: ../pakfire/cli.py:133 ../pakfire/cli.py:141 msgid "File or feature to search for." msgstr "" -#: ../pakfire/cli.py:192 +#: ../pakfire/cli.py:139 +msgid "Get a list of packages that require a given file or feature." +msgstr "" + +#: ../pakfire/cli.py:147 +msgid "Get list of packages that belong to the given group." +msgstr "" + +#: ../pakfire/cli.py:149 +msgid "Group name to search for." +msgstr "" + +#: ../pakfire/cli.py:155 +msgid "Install all packages that belong to the given group." +msgstr "" + +#: ../pakfire/cli.py:157 +msgid "Group name." +msgstr "" + +#: ../pakfire/cli.py:163 +msgid "List all currently enabled repositories." +msgstr "" + +#: ../pakfire/cli.py:237 ../pakfire/depsolve.py:229 +msgid "Repository" +msgstr "" + +#: ../pakfire/cli.py:237 +msgid "Enabled" +msgstr "" + +#: ../pakfire/cli.py:237 +msgid "Priority" +msgstr "" + +#: ../pakfire/cli.py:252 msgid "Pakfire builder command line interface." msgstr "" -#: ../pakfire/cli.py:230 +#: ../pakfire/cli.py:294 msgid "Update the package indexes." msgstr "" -#: ../pakfire/cli.py:236 +#: ../pakfire/cli.py:300 msgid "Build one or more packages." msgstr "" -#: ../pakfire/cli.py:238 +#: ../pakfire/cli.py:302 msgid "Give name of at least one package to build." msgstr "" -#: ../pakfire/cli.py:242 +#: ../pakfire/cli.py:306 msgid "Build the package for the given architecture." msgstr "" -#: ../pakfire/cli.py:244 ../pakfire/cli.py:266 +#: ../pakfire/cli.py:308 ../pakfire/cli.py:330 msgid "Path were the output files should be copied to." msgstr "" -#: ../pakfire/cli.py:249 +#: ../pakfire/cli.py:313 msgid "Go into a shell." msgstr "" -#: ../pakfire/cli.py:251 +#: ../pakfire/cli.py:315 msgid "Give name of a package." msgstr "" -#: ../pakfire/cli.py:255 +#: ../pakfire/cli.py:319 msgid "Emulated architecture in the shell." msgstr "" -#: ../pakfire/cli.py:260 +#: ../pakfire/cli.py:324 msgid "Generate a source package." msgstr "" -#: ../pakfire/cli.py:262 +#: ../pakfire/cli.py:326 msgid "Give name(s) of a package(s)." msgstr "" -#: ../pakfire/cli.py:338 +#: ../pakfire/cli.py:396 msgid "Pakfire repo command line interface." msgstr "" -#: ../pakfire/cli.py:363 +#: ../pakfire/cli.py:415 msgid "Repository management commands." msgstr "" -#: ../pakfire/cli.py:371 +#: ../pakfire/cli.py:423 msgid "Create a new repository index." msgstr "" -#: ../pakfire/cli.py:372 +#: ../pakfire/cli.py:424 msgid "Path to the packages." msgstr "" -#: ../pakfire/cli.py:373 +#: ../pakfire/cli.py:425 msgid "Path to input packages." msgstr "" -#: ../pakfire/cli.py:385 +#: ../pakfire/cli.py:437 msgid "Pakfire master command line interface." msgstr "" -#: ../pakfire/cli.py:413 +#: ../pakfire/cli.py:459 msgid "Update the sources." msgstr "" -#: ../pakfire/cli.py:423 +#: ../pakfire/cli.py:469 msgid "Pakfire slave command line interface." msgstr "" -#: ../pakfire/cli.py:451 +#: ../pakfire/cli.py:493 +msgid "Request a build job from the server." +msgstr "" + +#: ../pakfire/cli.py:499 msgid "Send a keepalive to the server." msgstr "" -#: ../pakfire/depsolve.py:220 +#: ../pakfire/depsolve.py:229 msgid "Package" msgstr "" -#: ../pakfire/depsolve.py:220 ../pakfire/packages/base.py:66 +#: ../pakfire/depsolve.py:229 ../pakfire/packages/base.py:72 msgid "Arch" msgstr "" -#: ../pakfire/depsolve.py:220 ../pakfire/packages/base.py:67 +#: ../pakfire/depsolve.py:229 ../pakfire/packages/base.py:73 msgid "Version" msgstr "" -#: ../pakfire/depsolve.py:220 -msgid "Repository" -msgstr "" - -#: ../pakfire/depsolve.py:220 ../pakfire/packages/base.py:69 +#: ../pakfire/depsolve.py:229 ../pakfire/packages/base.py:75 msgid "Size" msgstr "" -#: ../pakfire/depsolve.py:223 +#: ../pakfire/depsolve.py:232 msgid "Installing:" msgstr "" -#: ../pakfire/depsolve.py:224 +#: ../pakfire/depsolve.py:233 msgid "Installing for dependencies:" msgstr "" -#: ../pakfire/depsolve.py:225 +#: ../pakfire/depsolve.py:234 msgid "Updating:" msgstr "" -#: ../pakfire/depsolve.py:226 +#: ../pakfire/depsolve.py:235 msgid "Updating for dependencies:" msgstr "" -#: ../pakfire/depsolve.py:227 +#: ../pakfire/depsolve.py:236 msgid "Removing:" msgstr "" -#: ../pakfire/depsolve.py:228 +#: ../pakfire/depsolve.py:237 msgid "Removing for dependencies:" msgstr "" -#: ../pakfire/depsolve.py:230 +#: ../pakfire/depsolve.py:239 msgid "Transaction Summary" msgstr "" -#: ../pakfire/depsolve.py:236 +#: ../pakfire/depsolve.py:245 msgid "Install" msgstr "" -#: ../pakfire/depsolve.py:237 ../pakfire/depsolve.py:241 -#: ../pakfire/depsolve.py:245 +#: ../pakfire/depsolve.py:246 ../pakfire/depsolve.py:250 +#: ../pakfire/depsolve.py:254 msgid "Package(s)" msgstr "" -#: ../pakfire/depsolve.py:240 +#: ../pakfire/depsolve.py:249 msgid "Updates" msgstr "" -#: ../pakfire/depsolve.py:244 +#: ../pakfire/depsolve.py:253 msgid "Remove" msgstr "" -#: ../pakfire/depsolve.py:251 +#: ../pakfire/depsolve.py:260 #, python-format msgid "Total download size: %s" msgstr "" -#: ../pakfire/__init__.py:204 ../pakfire/__init__.py:235 +#: ../pakfire/__init__.py:28 ../pakfire/__init__.py:64 msgid "Is this okay?" msgstr "" -#: ../pakfire/packages/base.py:65 +#: ../pakfire/packages/base.py:71 msgid "Name" msgstr "" -#: ../pakfire/packages/base.py:68 +#: ../pakfire/packages/base.py:74 msgid "Release" msgstr "" -#: ../pakfire/packages/base.py:70 +#: ../pakfire/packages/base.py:76 msgid "Repo" msgstr "" -#: ../pakfire/packages/base.py:71 +#: ../pakfire/packages/base.py:77 msgid "Summary" msgstr "" -#: ../pakfire/packages/base.py:72 +#: ../pakfire/packages/base.py:78 msgid "Groups" msgstr "" -#: ../pakfire/packages/base.py:73 +#: ../pakfire/packages/base.py:79 msgid "URL" msgstr "" -#: ../pakfire/packages/base.py:74 +#: ../pakfire/packages/base.py:80 msgid "License" msgstr "" -#: ../pakfire/packages/base.py:77 +#: ../pakfire/packages/base.py:83 msgid "Description" msgstr "" -#: ../pakfire/packages/base.py:83 +#: ../pakfire/packages/base.py:89 msgid "UUID" msgstr "" -#: ../pakfire/packages/base.py:84 +#: ../pakfire/packages/base.py:90 msgid "Build ID" msgstr "" -#: ../pakfire/packages/base.py:85 +#: ../pakfire/packages/base.py:91 msgid "Build date" msgstr "" -#: ../pakfire/packages/base.py:86 +#: ../pakfire/packages/base.py:92 msgid "Build host" msgstr "" -#: ../pakfire/packages/base.py:88 +#: ../pakfire/packages/base.py:94 msgid "Provides" msgstr "" -#: ../pakfire/packages/base.py:93 +#: ../pakfire/packages/base.py:99 msgid "Requires" msgstr "" @@ -305,22 +346,22 @@ msgstr "" msgid "%s: package database" msgstr "" -#: ../pakfire/transaction.py:133 +#: ../pakfire/transaction.py:107 #, python-format msgid "Cleanup: %s" msgstr "" -#: ../pakfire/transaction.py:247 +#: ../pakfire/transaction.py:144 #, python-format msgid "Installing: %s" msgstr "" -#: ../pakfire/transaction.py:252 +#: ../pakfire/transaction.py:149 #, python-format msgid "Updating: %s" msgstr "" -#: ../pakfire/transaction.py:262 +#: ../pakfire/transaction.py:159 #, python-format msgid "Removing: %s" msgstr "" -- 2.39.5