Mercurial > treepkg > treepkg
view treepkg/sbuilder.py @ 546:149d18aca4f7
fix variable name
author | Bjoern Ricks <bricks@intevation.de> |
---|---|
date | Wed, 02 Feb 2011 10:00:48 +0000 |
parents | 5fa4b938a939 |
children |
line wrap: on
line source
# Copyright (C) 2010 by Intevation GmbH # Authors: # Bjoern Ricks <bjoern.ricks@intevation.de> # # This program is free software under the GPL (>=v2) # Read the file COPYING coming with the software for details. """Build binary packages from source packages""" import sys import os import shutil import logging import tempfile import util import run import builder from cmdexpand import cmdexpand class SbdmockBuilder(builder.Builder): """Represents a way to run and manage a specific sbdmock instance to build binary for Maemo within scratchbox environment""" basetgz_dir = util.filenameproperty("base") build_dir = util.filenameproperty("build") result_dir = util.filenameproperty("result") aptcache_dir = util.filenameproperty("aptcache") extra_pkg_dir = util.filenameproperty("extra-pkg") def __init__(self, builderconfig, root_cmd, release_signing_keyid=None): """Initialize the Builder instance with the configuration file. The root_cmd parameter should be a list with a command that can be used to get root permissions. It may be an empty list if no command is needed. It's a list so that commands with several shell-words can be used without having to worry about quoting. """ if not os.path.exists(builderconfig): raise RuntimeError("Config file %s for sbdmock does not exist.", builderconfig) if not os.path.isabs(builderconfig): raise RuntimeError("Config file %s must be an absolute filename.", builderconfig) self.builderconfig = builderconfig self.root_cmd = root_cmd self.release_signing_keyid = release_signing_keyid self.base_dir = os.path.dirname(self.builderconfig) self.mounted_dirs = [] def init_builder(self, distribution, mirrorsite, extramirrors): """Initializes the builder instance""" basedir = os.path.dirname(self.builderconfig) replacements = dict(basedir=basedir, distribution=distribution, mirrorsite=mirrorsite) # create the builder directories. basedir is created implicitly by # creating its subdirectories. for attr in ["build_dir", "result_dir", "aptcache_dir", "extra_pkg_dir"]: directory = getattr(self, attr) replacements[attr] = directory print "creating directory:", repr(directory) util.ensure_directory(directory) # build OTHERMIRROR value. We always include the extra-pkg dir. # othermirror = "deb file://%(extra_pkg_dir)s ./" % replacements # if extramirrors: # othermirror += " | " + extramirrors # replacements["othermirror"] = othermirror # turn the extra-pkg directory into a proper deb archive print "turning the extra-pkg dir into a debian archive" self.update_extra_pkg_dir() def update(self, suppress_output=True, log_info=True): """Runs nothing""" if log_info: logging.info("Update of apt cache is done on every start. skipping ...") def build(self, dsc_file, binary_dir=None, logfile=None, bindmounts=(), extra_packages=(), extra_env=None): """Build a binary packager from a source package Parameters: dsc_file -- name of the debian .dsc file of the source package binary_dir -- name of the directory to receive the binary packages logfile -- name of the logfile of the build bindmounts -- Sequence of directory names that should be bind-mounted in the builder chroot environment extra_packages -- Extra packages to install extra_env -- mapping with extra environment variables to set when runing the builder process. If builder is started via sudo, make sure that sudo does not remove these variables when it starts builder """ args = [] if logfile is not None: logdir = os.path.dirname(logfile) args.extend(["--rootlog=scratchlog.txt"]) args.extend(["--buildlog=%s" % logfile]) args.extend(["--logdir=%s" % logdir]) if binary_dir is not None: args.extend(["--resultdir=%s" % binary_dir]) util.ensure_directory(binary_dir) if bindmounts: self.mount(bindmounts) # for pkg in extra_packages: # args.extend(["--extrapackages", pkg]) logging.info("Mointing extra-pkg apt repository") self.mount([self.extra_pkg_dir]) logging.info("Starting build process with sbdmock ...") cmd = cmdexpand("/usr/bin/sbdmock --cleanbuilddir" " --config=$builderconfig" # " --dbo=" # aren't build options setable in treepkg.cfg? " -u -b $dsc @args", builderconfig=self.builderconfig, dsc=dsc_file, args=args) logging.debug("sbdmock cmd: %s" % cmd) try: run.call(cmd, suppress_output=True, extra_env=extra_env) # remove the source package files put into the binary directory # by pbuilder (BR: not sure if this is necessary for sbdmock) if binary_dir is not None: for filename in os.listdir(binary_dir): if os.path.splitext(filename)[1] not in (".deb", ".changes"): os.remove(os.path.join(binary_dir, filename)) finally: # remove all mounted directories self.umount_all() def run_script(self, script, logfile, bindmounts=(), save_after_exec=False): """Execute a script in builder's chroot environment Parameters: script -- A list of strings with the command line to invoke the script logfile -- name of the logfile of the build bindmounts -- Sequence of directory names that should be bind-mounted in the builder chroot environment (optional) save_after_exec -- Boolean indicating whether the chroot environment should be copied back so that modifications are available in subsequent uses of the builder instance. """ if not script[0]: raise RuntimeError("No script to execute was passed") args = [] if logfile is not None: logdir = os.path.dirname(logfile) args.extend(["--rootlog=%s" % logfile]) args.extend(["--logdir=%s" % logdir]) if bindmounts: self.mount(bindmounts) self.mount([self.extra_pkg_dir]) cmd = cmdexpand("/usr/bin/sbdmock exec $script --cleanbuilddir" " --config=$builderconfig" # " --dbo=" # aren't build options setable in treepkg.cfg? " -u @args", builderconfig=self.builderconfig, script=script[0], args=args) logging.debug("sbdmock cmd: %s" % cmd) try: run.call(cmd, suppress_output=False) finally: if logfile is not None: logdir = os.path.dirname(logfile) self.umount_all() def login(self, bindmounts=(), save_after_login=False): """Start an interactive shell in the builder environment""" args = [] for mount in bindmounts: args.extend(["--bindmounts", mount]) if save_after_login: args.extend(["--save-after-login"]) logging.info("Mointing extra-pkg apt repository") self.mount([self.extra_pkg_dir]) logging.info("Login into scratchbox...") cmd = cmdexpand("/usr/bin/sbdmock login --cleanbuilddir" " --config=$builderconfig" # " --dbo=" # aren't build options setable in treepkg.cfg? " -u @args", builderconfig=self.builderconfig, args=args) logging.debug("sbdmock cmd: %s" % cmd) run.call(cmd, suppress_output=False) def mount(self, bindmounts): for mount in bindmounts: mount_dir = "/scratchbox/users/%s/%s" % (util.getuser(), mount) util.ensure_directory(mount_dir) logging.info("Mounting %s to %s" % (mount, mount_dir)) run.call(cmdexpand("@rootcmd mount --bind $mount $mountdir", rootcmd=self.root_cmd, mount=mount, mountdir=mount_dir)) #add mountpoint to a variable to for unmounting later self.mounted_dirs.append(mount_dir) def umount(self, mounts): for mount in mounts: logging.info("Unmounting %s" % mount) run.call(cmdexpand("@rootcmd umount $dir", rootcmd=self.root_cmd, dir=mount)) self.mounted_dirs.remove(mount) def umount_all(self): mounts = self.mounted_dirs[:] self.umount(mounts)