view treepkg/builder.py @ 122:6e34fc4ebe39

New arguments for the PBuilder.build method: - bindmounts to specify extra directories to be bind-mounted in the chroot (corresponds to pbuilder's --bindmounts option) - extra_packages to specify extra packages to be installed in the chroot (corresponds to pbuilder's --extrapackages option) Also adds corresponding test cases.
author Bernhard Herzog <bh@intevation.de>
date Thu, 22 May 2008 09:58:57 +0000
parents 890bb70920d6
children 68d829cac3ff
line wrap: on
line source
# Copyright (C) 2007, 2008 by Intevation GmbH
# Authors:
# Bernhard Herzog <bh@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 os
import shutil
import logging

import util
import run
from cmdexpand import cmdexpand


class PBuilder(object):

    """Represents a way to run and manage a specific pbuilder instance"""

    def __init__(self, pbuilderrc, root_cmd):
        """Initialize the PBuilder instance with the configuration file.
        The root_cmd parameter should be a list with a command that can
        be used to get root permissions to run pbuilder.  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.
        """
        self.pbuilderrc = pbuilderrc
        self.root_cmd = root_cmd

    def build(self, dsc_file, binary_dir, logfile, bindmounts=(),
              extra_packages=()):
        """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 pbuilder chroot
                         environment
           extra_packages -- Extra packages to install
           extra_env -- mapping with extra environment variables to set
                        when runing the pbuilder process.  If pbuilder
                        is started via sudo, make sure that sudo does
                        not remove these variables when it starts
                        pbuilder
        """
        util.ensure_directory(binary_dir)
        args = []
        for mount in bindmounts:
            args.extend(["--bindmounts", mount])
        for pkg in extra_packages:
            args.extend(["--extrapackages", pkg])
        run.call(cmdexpand("@rootcmd /usr/sbin/pbuilder build"
                           " --configfile $pbuilderrc @args"
                           " --logfile $logfile --buildresult $bindir $dsc",
                           rootcmd=self.root_cmd, pbuilderrc=self.pbuilderrc,
                           logfile=logfile, bindir=binary_dir, dsc=dsc_file,
                           args=args),
                 suppress_output=True)
        # remove the source package files put into the binary directory
        # by pbuilder
        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))

    def add_binaries_to_extra_pkg(self, filenames):
        """Adds binary packages to the extra-pkg directory.
        The filenames parameter should be sequence of absolute
        filenames.  The files named will be copied to the extra-pkg
        directory which is assumed to reside in the same directory as
        the pbuilderrc.  Afterwards, the method generates a Packages
        file in the directory and runs pbuilder update.  All of this
        assumes that pbuilder was set up the way bin/initpbuilder.py
        does.
        """
        extrapkg_dir = os.path.join(os.path.dirname(self.pbuilderrc),
                                    "extra-pkg")
        for filename in filenames:
            logging.info("Copying %s into %s", filename, extrapkg_dir)
            shutil.copy(filename, extrapkg_dir)
        logging.info("Running apt-ftparchive in %s", extrapkg_dir)
        run.call(cmdexpand("apt-ftparchive packages ."),
                 stdout=open(os.path.join(extrapkg_dir, "Packages"), "w"),
                 cwd=extrapkg_dir)
        logging.info("Running pbuilder update for %s", self.pbuilderrc)
        run.call(cmdexpand("@rootcmd /usr/sbin/pbuilder update"
                           " --configfile $pbuilderrc",
                           rootcmd=self.root_cmd, pbuilderrc=self.pbuilderrc),
                 suppress_output=True)

    def run_script(self, script, logfile, bindmounts=()):
        """Execute a script in pbuilder's chroot environment
        Parameters:
           script -- The filename of the script
           logfile -- name of the logfile of the build
           bindmounts -- Sequence of directory names that should be
                         bind-mounted in the pbuilder chroot
                         environment (optional)
        """
        logging.info("Running pbuilder execute on %s", script)
        args = []
        if logfile:
            args.extend(["--logfile", logfile])
        for mount in bindmounts:
            args.extend(["--bindmounts", mount])

        run.call(cmdexpand("@rootcmd /usr/sbin/pbuilder execute"
                           " --configfile $pbuilderrc @args $script",
                           rootcmd=self.root_cmd, pbuilderrc=self.pbuilderrc,
                           args=args, script=script),
                 suppress_output=False)
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)