diff --git a/debian/changelog b/debian/changelog index fcf2a88..fde29b0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,8 +2,20 @@ ubuntu-dev-tools (0.52) UNRELEASED; urgency=low [ Siegfried-Angel Gevatter Pujals ] * pbuilder-dist.new: - - Add compatibility for cowbuilder. Once pbuilder-dist.new replaces - pbuilder-dist, we will also create a cowbuilder-dist symlink to it. + - Add compatibility for cowbuilder. + - Fix the mainonly support. + - Rename build.log to last_operation.log. + * pbuilder-dist, pbuilder-dist.new: + - Replace pbuilder-dist with pbuilder-dist.new. + * debian/links: + - Symlink /usr/bin/cowbuilder-dist to /usr/bin/pbuilder-dist, and the + same with the manpage. + * debian/control: + - Add cowdancer as alternative recommends to pbuilder. + * doc/pbuilder-dist.1: + - Update it to explain the usage for the new pbuilder-dist script. + * doc/mk-sbuild-lv.1: + - Fix an error (and get ride of a lintian warning). [ Nathan Handler ] * pull-debian-source: @@ -21,7 +33,7 @@ ubuntu-dev-tools (0.52) UNRELEASED; urgency=low * requestsync: If package is new, check the Ubuntu Archive team's bug list for possible duplicate requests. - -- Jonathan Davies Fri, 09 Jan 2009 14:32:37 +0000 + -- Siegfried-Angel Gevatter Pujals Sat, 10 Jan 2009 14:35:14 +0100 ubuntu-dev-tools (0.51) jaunty; urgency=low diff --git a/debian/control b/debian/control index 01cd151..28f4424 100644 --- a/debian/control +++ b/debian/control @@ -16,7 +16,7 @@ Section: devel Depends: ${python:Depends}, binutils, devscripts, sudo, python-debian, python-launchpad-bugs (>= 0.2.25), dctrl-tools, lsb-release, diffstat, dpkg-dev, ${misc:Depends} -Recommends: bzr, pbuilder | sbuild, reportbug (>= 3.39ubuntu1), +Recommends: bzr, pbuilder | cowdancer | sbuild, reportbug (>= 3.39ubuntu1), ca-certificates, genisoimage, perl-modules, libwww-perl Conflicts: devscripts (<< 2.10.7ubuntu5) Replaces: devscripts (<< 2.10.7ubuntu5) diff --git a/doc/mk-sbuild-lv.1 b/doc/mk-sbuild-lv.1 index 59ddddc..b15e5f6 100644 --- a/doc/mk-sbuild-lv.1 +++ b/doc/mk-sbuild-lv.1 @@ -73,7 +73,8 @@ To ENTER an image snapshot: \fBschroot \-c ${CHROOT_NAME}\fR To BUILD within a snapshot: \fBsbuild \-d ${SCHROOT_NAME} PACKAGE*.dsc\fR .SH SEE ALSO -.BR sbuild\-setup (7), sources.list (5), schroot.conf (5), https://help.ubuntu.com/community/SbuildLVMHowto +sbuild\-setup (7), sources.list (5), schroot.conf (5), +https://help.ubuntu.com/community/SbuildLVMHowto .SH AUTHOR \fBmk\-sbuild\-lv\fR was written by Kees Cook . diff --git a/doc/pbuilder-dist.1 b/doc/pbuilder-dist.1 index 1a3518a..231b7b4 100644 --- a/doc/pbuilder-dist.1 +++ b/doc/pbuilder-dist.1 @@ -1,11 +1,14 @@ -.TH PBUILDER\-DIST 1 "August 16, 2007" "ubuntu-dev-tools" +.TH PBUILDER\-DIST 1 "January 10, 2008" "ubuntu-dev-tools" .SH NAME -pbuilder\-dist \- multi-distribution pbuilder wrapper +pbuilder\-dist, cowbuilder\-dist \- multi-distribution pbuilder/cowbuilder wrapper .SH SYNOPSIS -\fBpbuilder\-dist\fP \fIdistribution\fR [\fBi386\fP|\fBamd64\fP] [\fBmainonly\fP|\fBallcomp\fP] -[\fBwithlog\fP|\fBnolog\fP] \fIoperation\fR [\fI...\fR] +\fBpbuilder\-dist\fP \fIdistribution\fR [\fBi386\fP|\fBamd64\fP] [\fBmainonly\fP] +\fIoperation\fR [\fI...\fR] + +\fBcowbuilder\-dist\fP \fIdistribution\fR [\fBi386\fP|\fBamd64\fP] [\fBmainonly\fP] +\fIoperation\fR [\fI...\fR] .SH DESCRIPTION \fBpbuilder\-dist\fP is a wrapper that makes it easy to use pbuilder with many different @@ -14,6 +17,11 @@ versions of Ubuntu and/or Debian. It is common to symlink this script in order to give it many names in the form of \fBpbuilder\-\fIdistribution\fP\fR (\fBpbuilder\-\fIdistribution\fR\-\fIarchitecture\fP\fR on amd64 systems), like for example \fBpbuilder\-feisty\fP, \fBpbuilder\-sid\fP, \fBpbuilder\-gutsy\-i386\fP, etc. +.PP +The same applies to \fBcowbuilder\-dist\fP, which uses cowbuilder. The main +difference between both is that pbuilder compresses the created chroot as a +a tarball, thus using less disc space but needing to uncompress (and possibly +compress) its contents again on each run, and cowbuilder doesn't do this. .SH USAGE There are many arguments listed on the synopsis; each of them, if used, has to be used exactly in @@ -30,19 +38,11 @@ Only available on amd64 systems. This is optional; default is \fBamd64\fP. If \fBi386\fP is specified, an i386 environment will be used. .TP -\fBmainonly\fP / \fBallcomp\fP -This is optional; default is \fBallcomp\fP. +\fBmainonly\fP If you specify \fBmainonly\fP, only packages from the main (in Debian) or -main and restricted (in Ubuntu) components will be used. -With the latter one, all official components will be enabled. -This only has effect when creating a new environment. -.TP -\fBwithlog\fP / \fBnolog\fP -This is optional; default is \fBnolog\fP. -When \fBwithlog\fP is used, \fBpbuilder\fP will save the output produced by -the current action in a dot-file called \fB.lastlog\fP in its base directory -(see the FILES section). -If this file already exists, it will be overwritten. +main and restricted (in Ubuntu) components will be used. By default, all +official components are enabled. This only has effect when creating a new +environment. .TP \fBoperation\fP Replace this with the action you want \fBpbuilder\fP to do (create, update, @@ -55,13 +55,9 @@ Check its manpage for more details. .br Replace this with other parameters, if needed. For example, if \fBbuild\fP is the option, you will need to also specify -a .dsc file. -.PP -The default value of all optional parameters (except the architecture) can -be changed by editing the first lines of the script. -You can also change the base directory using the global variable -$PBUILDFOLDER. -.PP +a .dsc file. As a special feature, if you specify a .dsc file you can +skip the \fBbuild\fP option and this script will automatically assume that +building is the action you want to do. .SH EXAMPLES .TP @@ -79,28 +75,35 @@ Same as above, but stores \fBpbuilder\fP's output on a file. .TP pbuilder\-etch i386 update Updates an existing i386-architecture Debian Etch environment on an amd64 system. +.TP +cowbuilder-experimental create +Creates a \fBcowbuilder\fP environment for Debian Experimental. -.SH FILES -By default, \fBpbuilder\-dist\fP will store all the files it generates in \fB~/pbuilder/\fP. -This can be changed by modifying the BASE_DIR value on the top of the script -to any other directory you want, or by using the $PBUILDFOLDER global variable. -If it doesn't exist, it will be created on the run. +.SH FILES AND ENVIRONMENT VARIABLES +By default, \fBpbuilder\-dist\fP will store all the files it generates in +\fB~/pbuilder/\fP. This can be changed by setting the $PBUILDFOLDER global +variable. If the directory doesn't exist, it will be created on the run. +.PP +A file with the log of the last operation, called last_operation.log, will be +saved in the results subdirectory of each build environment. +.PP +The default authentication method is \fBsudo\fP. You can change this by +setting the $PBUILDAUTH variable. .SH BUGS -There are no known bugs at the moment. -If you experience any problem with this script contact me on -rainct@ubuntu.com. +If you experience any problem with this script contact me on rainct@ubuntu.com +or file a bug at https://bugs.launchpad.net/ubuntu/+source/ubuntu-dev-tools. +.PP Please ensure first that the problem is really this script and not an issue -with \fBpbuilder\fP. +with \fBpbuilder\fP or \fBcowbuilder\fP themselves. .SH SEE ALSO -\fBpbuilder\fR, \fBpbuilderrc\fR +\fBpbuilder\fR, \fBpbuilderrc\fR, \fBcowbuilder\fR .SH AUTHORS -\fBpbuilder\-dist\fP was originally written by Jamin W. Collins - and Jordan Mantha . -On August 2007 it was mostly rewritten, and extended, by Siegfried-Angel -Gevatter Pujals . +\fBpbuilder\-dist\fP was written by Siegfried-A. Gevatter +and includes patches by Iain Lane . This manual page +has been written by Siegfried-A. Gevatter . \fBpbuilder\-dist\fP is released under the GNU General Public License, version 2 or later. diff --git a/pbuilder-dist b/pbuilder-dist index 2ce38fd..6556feb 100755 --- a/pbuilder-dist +++ b/pbuilder-dist @@ -1,8 +1,9 @@ -#!/bin/sh +#! /usr/bin/env python +# -*- coding: utf-8 -*- # -# Copyright (C) Jamin W. Collins -# Copyright (C) Jordan Mantha # Copyright (C) 2007-2008 Siegfried-A. Gevatter +# With some changes by Iain Lane +# Based upon pbuilder-dist-simple by Jamin Collins and Jordan Mantha. # # ################################################################## # @@ -25,300 +26,315 @@ # # You can create symlinks to a pbuilder-dist executable to get different # configurations. For example, a symlink called pbuilder-hardy will assume -# that the target distribution is always Ubuntu Hardy. +# that the target distribution is always meant to be Ubuntu Hardy. -###################################################################### +import sys +import os -# Base directory where pbuilder will put all the files it creates. -# This is overriden by the global variable $PBUILDFOLDER -BASE_DIR="$HOME/pbuilder" +debian_distros = ['etch', 'lenny', 'sid', 'stable', 'testing', 'unstable', 'experimental'] -# Change this to 0 if you don't want additional components to be used. -# That is, 'universe' and 'multiverse' for Ubuntu chroots and 'contrib' -# and 'non-free' for Debian. (This option can be overwriten at runtime). -EXTRACOMP=1 - -# Change this to 1 if you want the log for the last operation to be saved -# in the base directory by default (it will be named '.lastlog'). -SAVELOG=0 - -# Allow this script to use /var/cache/apt/archives/ when possible. -if [ -z $SYSCACHE ] -then - SYSCACHE=1 -fi - -###################################################################### - -# Detect system architecture -REALARCH=$(dpkg-architecture -qDEB_HOST_ARCH) - -# Detect Ubuntu distribution (wheter it is gutsy, hardy, etc.) -SYSDIST=$(lsb_release -cs 2>/dev/null) - -# Overwrite hardcoded base directory by that one in the global variable -if [ $PBUILDFOLDER ] && [ $PBUILDFOLDER != "" ] -then - BASE_DIR=$PBUILDFOLDER -fi - -###################################################################### - -# Abort if the name of the executable has hypens but it doesn't -# start with "pbuilder-". -if [ -n $(basename $0 | grep '-') ] && [ $(basename $0 | cut -d'-' -f1) != 'pbuilder' ] -then - echo "Error: " $(basename $0) " is not a valid name for a pbuilder-dist executable." - exit 1 -fi - -# Detect if the script has it's original name or if a symlink is being used, -# and if it's a symlink extract the information that it contains. -if [ -n $(basename $0 | grep '-') ] && [ `basename $0` != 'pbuilder-dist' ] -then - ORIGINAL_NAME=0 - DISTRIBUTION=$(basename $0 | cut -d'-' -f2) - ARCHITECTURE=$(basename $0 | cut -d'-' -f3) -else - ORIGINAL_NAME=1 - DISTRIBUTION=$1 - shift 1 -fi - -# Check if the choosen architecture is supported on the user's system. -if [ "$1" = 'i386' ] || [ "$1" = 'amd64' ] -then - if [ $REALARCH = 'amd64' ]; then - ARCHITECTURE=$1 - else - echo "Warning: Architecture switching is not supported on your system; ignoring argument '$1'." - fi - - shift 1 -fi - -# If architecture hasn't been set yet, use the system's one. -if [ -z "$ARCHITECTURE" ] -then - ARCHITECTURE=$REALARCH -fi - -# Check if there's a component modifier -if [ "$1" = 'mainonly' ]; then - EXTRACOMP=0 - shift 1 -elif [ "$1" = 'allcomp' ]; then - EXTRACOMP=1 - shift 1 -fi - -# Check if the default logging preferences should be overwriten -if [ "$1" = 'withlog' ]; then - SAVELOG=1 - shift 1 -elif [ "$1" = 'nolog' ]; then - SAVELOG=0 - shift 1 -fi - -# Check if some proxy should be used. -if [ -n "$http_proxy" ] -then - PROXY=$http_proxy -fi - -if [ -z "$PROXY" ] && [ -n "$HTTP_PROXY" ] -then - PROXY=$HTTP_PROXY -fi - -###################################################################### - -usage() -{ - echo "Usage: $0 "$( [ $ORIGINAL_NAME = 0 ] || echo " " )$( [ $ARCHITECTURE != "amd64" ] || echo "[i386|amd64] " )"[mainonly|allcomp] [withlog|nolog] " -} - -distdata() -{ - # Populate variables with Debian / Ubuntu specific data - if [ "$1" = "debian" ] - then - # Set Debian specific data +class pbuilder_dist: + + def __init__(self, builder): - ISDEBIAN=True + # Base directory where pbuilder will put all the files it creates. + self.base = None - if [ -z $ARCHIVE ] - then - ARCHIVE="http://ftp.debian.org" - fi + # Name of the operation which pbuilder should perform. + self.operation = None - COMPONENTS="main"$( [ $EXTRACOMP = 0 ] || echo " contrib non-free" ) - else - # Set Ubuntu specific data + # Wheter additional components should be used or not. That is, + # 'universe' and 'multiverse' for Ubuntu chroots and 'contrib' + # and 'non-free' for Debian. + self.extra_components = True - ISDEBIAN=False + # File where the log of the last operation will be saved. + self.logfile = None - if [ -z $ARCHIVE ] - then - ARCHIVE="http://archive.ubuntu.com/ubuntu" - fi + # System architecture + self.system_architecture = None - COMPONENTS="main restricted"$( [ $EXTRACOMP = 0 ] || echo " universe multiverse" ) - fi -} + # Build architecture + self.build_architecture = None + + # System's distribution + self.system_distro = None + + # Target distribution + self.target_distro = None + + # This is an identificative string which will either take the form + # 'distribution' or 'distribution-architecture'. + self.chroot_string = None + + # Authentication method + self.auth = 'sudo' + + # Builder + self.builder = builder + + ############################################################## + + if 'PBUILDFOLDER' in os.environ: + self.base = os.environ['PBUILDFOLDER'] + else: + self.base = os.path.expanduser('~/pbuilder/') -###################################################################### + if not os.path.exists(self.base): + os.makedirs(self.base) + + if 'PBUILDAUTH' in os.environ: + self.auth = os.environ['PBUILDAUTH'] + + self.system_architecture = host_architecture() + + if not self.system_architecture or 'not found' in self.system_architecture: + print 'Error: Not running on a Debian based system; could not detect its architecture.' + + if not os.path.isfile('/etc/lsb-release'): + print 'Error: Not running on a Debian based system; could not find /etc/lsb-release.' + exit(1) + + for line in open('/etc/lsb-release'): + line = line.strip() + if line.startswith('DISTRIB_CODENAME'): + self.system_distro = line[17:] + break + + if not self.system_distro: + print 'Error: Could not determine what distribution you are running.' + exit(1) + + self.target_distro = self.system_distro + + ############################################################## + + def __getitem__(self, name): + + return getattr(self, name) + + def set_target_distro(self, distro): + """ pbuilder_dist.set_target_distro(distro) -> None + + Check if the given target distribution name is correct, if it + isn't know to the system ask the user for confirmation before + proceeding, and finally either save the value into the appropiate + variable or finalize pbuilder-dist's execution. + + """ + + if not distro.isalpha(): + print 'Error: «%s» is an invalid distribution codename.' % distro + sys.exit(1) + + if not os.path.isfile(os.path.join('/usr/share/debootstrap/scripts/', distro)): + answer = ask('Warning: Unknown distribution «%s». Do you want to continue [y/N]? ' % distro) + if answer not in ('y', 'Y'): + sys.exit(0) + + self.target_distro = distro + + def set_operation(self, operation): + """ pbuilder_dist.set_operation -> None + + Check if the given string is a valid pbuilder operation and + depending on this either save it into the appropiate variable + or finalize pbuilder-dist's execution. + + """ + + arguments = ('create', 'update', 'build', 'clean', 'login', 'execute') + + if operation not in arguments: + if operation.endswith('.dsc'): + if os.path.isfile(operation): + self.operation = 'build' + else: + print 'Error: Could not find file «%s».' % operation + sys.exit(1) + else: + print 'Error: «%s» is not a recognized argument.' % operation + print 'Please use one of those: ' + ', '.join(arguments) + '.' + sys.exit(1) + else: + self.operation = operation + + def get_command(self, remaining_arguments = None): + """ pbuilder_dist.get_command -> string + + Generate the pbuilder command which matches the given configuration + and return it as a string. + + """ + + if not self.build_architecture: + self.chroot_string = self.target_distro + self.build_architecture = self.system_architecture + else: + self.chroot_string = '%(target_distro)s-%(build_architecture)s' % self + + prefix = os.path.join(self.base, self.chroot_string) + result = '%s_result/' % prefix + + if not self.logfile: + self.logfile = os.path.normpath('%s/last_operation.log' % result) + + if not os.path.isdir(result): + # Create the results directory, if it doesn't exist. + os.makedirs(result) + + if self.builder == 'pbuilder': + base = '--basetgz "%s-base.tgz"' % prefix + elif self.builder == 'cowbuilder': + base = '--basepath "%s-base.cow"' % prefix + + arguments = [ + '--%s' % self.operation, + base, + '--distribution "%(target_distro)s"' % self, + '--buildresult "%s"' % result, + '--logfile "%s"' % self.logfile, + '--aptcache "/var/cache/apt/archives/"', + ### --mirror "${ARCHIVE}" \ + '--override-config', + ] + + if os.path.exists('/var/cache/archive/'): + arguments.append('--bindmounts "/var/cache/archive/"') -# Check if there is at least one argument remaining. -if [ $# -lt 1 ] -then - echo "You provided an insufficent number of arguments." - usage - exit 1 -fi + localrepo = '/var/cache/archive/%(target_distro)s' % self + if os.path.exists(localrepo): + arguments.append('--othermirror ' +\ + '"deb file:///var/cache/archive/ %(target_distro)s/"' % self) + + if self.target_distro in debian_distros: + arguments.append('--mirror "ftp://ftp.debian.org/debian"') + components = 'main' + if self.extra_components: + components += ' contrib non-free' + else: + components = 'main restricted' + if self.extra_components: + components += ' universe multiverse' + arguments.append('--components %s"' % components) + + if self.build_architecture != self.system_architecture: + arguments.append('--debootstrapopts --arch') + arguments.append('--debootstrapopts "%(build_architecture)s"' % self) + + ### $( [ $ISDEBIAN != "False" ] || echo "--aptconfdir \"${BASE_DIR}/etc/${DISTRIBUTION}/apt.conf/\"" ) \ + + # Append remaining arguments + if remaining_arguments: + arguments.extend(remaining_arguments) + + return self.auth + ' /usr/sbin/' + self.builder + ' ' + ' '.join(arguments) -###################################################################### +def host_architecture(): + """ host_architecture -> string + + Detect the host's architecture and return it as a string + (i386/amd64/other values). + + """ + + return os.uname()[4].replace('x86_64', 'amd64').replace('i586', 'i386').replace('i686', 'i386') -# Check if the distribution exists, and fill the variables that change -# depending on wheter the target distribution is Ubuntu or Debian. -case $DISTRIBUTION in - dapper|edgy|feisty|gutsy|hardy|intrepid|jaunty) - distdata ubuntu - ;; - - oldstable|sarge|stable|etch|testing|lenny|unstable|sid|experimental) - distdata debian - ;; - - *) - if [ ! -f $BASE_DIR/${DISTRIBUTION}-${ARCHITECTURE}-base.tgz ] - then - echo -n "Warning: Unknown distribution «$DISTRIBUTION». Do you want to continue [y/N]? " - read continue - - if [ "$continue" != 'y' ] && [ "$continue" != 'Y' ] - then - echo "Aborting..." - exit 1 - fi - fi - - distdata ubuntu - ;; -esac +def ask(question): + """ ask(question) -> string + + Ask the given question and return the answer. Also catch + KeyboardInterrupt (Ctrl+C) and EOFError (Ctrl+D) exceptions and + immediately return None if one of those is found. + + """ + + try: + answer = raw_input(question) + except (KeyboardInterrupt, EOFError): + print + answer = None + + return answer -# Save the selected operation in a variable. -OPERATION=$1 -shift 1 +def help(exit_code = 0): + """ help() -> None + + Print a help message for pbuilder-dist, and exit with the given code. + + """ + + print 'See man pbuilder-dist for more information.' + + sys.exit(exit_code) -# Check if the selected operation is an alias for another one. -case "$OPERATION" in - upgrade) - OPERATION=update - ;; -esac +def main(): + """ main() -> None + + This is pbuilder-dist's main function. It creates a pbuilder_dist + object, modifies all necessary settings taking data from the + executable's name and command line options and finally either ends + the script and runs pbuilder itself or exists with an error message. + + """ + + script_name = os.path.basename(sys.argv[0]) + parts = script_name.split('-') + + # Copy arguments into another list for save manipulation + args = sys.argv[1:] + + if '-' in script_name and (parts[0] != 'pbuilder' and \ + parts[0] != 'cowbuilder') or len(parts) > 3: + print 'Error: «%s» is not a valid name for a «pbuilder-dist» executable.' % script_name + sys.exit(1) + + if len(args) < 1: + print 'Insufficient number of arguments.' + help(1) + + if args[0] in ('-h', '--help', 'help'): + help(0) + + app = pbuilder_dist(parts[0]) + + if len(parts) > 1 and parts[1] != 'dist' and '.' not in parts[1]: + app.set_target_distro(parts[1]) + else: + app.set_target_distro(args.pop(0)) + + if len(parts) > 2: + requested_arch = parts[2] + elif args[0] in ('i386', 'amd64'): + requested_arch = args.pop(0) + else: + requested_arch = None + + if requested_arch: + if requested_arch in ('i386', 'amd64') and app.system_architecture == 'amd64': + app.build_architecture = requested_arch + else: + print 'Error: Architecture switching is not supported on your system; wrong filename.' + sys.exit(1) + + if 'mainonly' in sys.argv: + app.extra_components = False + args.remove('mainonly') + + if len(args) < 1: + print 'Insufficient number of arguments.' + help(1) + + # Parse the operation + app.set_operation(args.pop(0)) + + # Execute the pbuilder command + sys.exit(os.system(app.get_command(args))) -# Check if the selected operation is correct, or if it is an alias for -# another one. -case "$OPERATION" in - create|update|build|clean|login|execute) - # Allright. - ;; - - upgrade) - OPERATION=update - ;; - - *) - if [ ${OPERATION##*.} = 'dsc' ] - then - OPERATION=build - else - echo "Unrecognized argument '$OPERATION'. Please use one of those:" - echo " create" - echo " update" - echo " build" - echo " clean" - echo " login" - echo " execute" - exit 1 - fi - ;; -esac - -# Determine the base name for the chroot tarball and the folder where the -# resulting files will be stored. -FOLDERBASE="${DISTRIBUTION}-$ARCHITECTURE" - -# Create the folder where the resulting files will be placed (if the -# option is build), if it doesn't exist yet. -if [ ! -d $BASE_DIR/${FOLDERBASE}_result ] -then - mkdir -p $BASE_DIR/${FOLDERBASE}_result -fi - -# Determine wheter system cache should be used or not. -if [ $SYSCACHE = 1 ] && [ "$SYSDIST" = "$DISTRIBUTION" ] && [ "$REALARCH" = "$ARCHITECTURE" ] -then - DEBCACHE='/var/cache/apt/archives/' -fi - -# If it's an Ubuntu system, create an editable configuration file, -# and if it's a stable release add the -security and -updates repositories. -if [ $ISDEBIAN = "False" ] -then - if [ ! -d $BASE_DIR/etc/$DISTRIBUTION/apt.conf/ ] - then - mkdir -p $BASE_DIR/etc/$DISTRIBUTION/apt.conf - fi - if [ ! -e $BASE_DIR/etc/$DISTRIBUTION/apt.conf/sources.list ] - then - echo "deb $ARCHIVE $DISTRIBUTION $COMPONENTS" > $BASE_DIR/etc/$DISTRIBUTION/apt.conf/sources.list - case $DISTRIBUTION in - dapper|edgy|feisty|gutsy ) - cat >> $BASE_DIR/etc/$DISTRIBUTION/apt.conf/sources.list < -# With some changes by Iain Lane -# Based upon pbuilder-dist-simple by Jamin Collins and Jordan Mantha. -# -# ################################################################## -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# See file /usr/share/common-licenses/GPL for more details. -# -# ################################################################## -# -# This script is a wrapper to be able to easily use pbuilder for -# different distributions (eg, Gutsy, Hardy, Debian unstable, etc). -# -# You can create symlinks to a pbuilder-dist executable to get different -# configurations. For example, a symlink called pbuilder-hardy will assume -# that the target distribution is always meant to be Ubuntu Hardy. - -import sys -import os - -debian_distros = ['etch', 'lenny', 'sid', 'stable', 'testing', 'unstable', 'experimental'] - -class pbuilder_dist: - - def __init__(self, builder): - - # Base directory where pbuilder will put all the files it creates. - self.base = None - - # Name of the operation which pbuilder should perform. - self.operation = None - - # Wheter additional components should be used or not. That is, - # 'universe' and 'multiverse' for Ubuntu chroots and 'contrib' - # and 'non-free' for Debian. - self.extra_components = True - - # File where the log of the last operation will be saved. - self.logfile = None - - # System architecture - self.system_architecture = None - - # Build architecture - self.build_architecture = None - - # System's distribution - self.system_distro = None - - # Target distribution - self.target_distro = None - - # This is an identificative string which will either take the form - # 'distribution' or 'distribution-architecture'. - self.chroot_string = None - - # Authentication method - self.auth = 'sudo' - - # Builder - self.builder = builder - - ############################################################## - - if 'PBUILDFOLDER' in os.environ: - self.base = os.environ['PBUILDFOLDER'] - else: - self.base = os.path.expanduser('~/pbuilder/') - - if not os.path.exists(self.base): - os.makedirs(self.base) - - if 'PBUILDAUTH' in os.environ: - self.auth = os.environ['PBUILDAUTH'] - - self.system_architecture = host_architecture() - - if not self.system_architecture or 'not found' in self.system_architecture: - print 'Error: Not running on a Debian based system; could not detect its architecture.' - - if not os.path.isfile('/etc/lsb-release'): - print 'Error: Not running on a Debian based system; could not find /etc/lsb-release.' - exit(1) - - for line in open('/etc/lsb-release'): - line = line.strip() - if line.startswith('DISTRIB_CODENAME'): - self.system_distro = line[17:] - break - - if not self.system_distro: - print 'Error: Could not determine what distribution you are running.' - exit(1) - - self.target_distro = self.system_distro - - ############################################################## - - def __getitem__(self, name): - - return getattr(self, name) - - def set_target_distro(self, distro): - """ pbuilder_dist.set_target_distro(distro) -> None - - Check if the given target distribution name is correct, if it - isn't know to the system ask the user for confirmation before - proceeding, and finally either save the value into the appropiate - variable or finalize pbuilder-dist's execution. - - """ - - if not distro.isalpha(): - print 'Error: «%s» is an invalid distribution codename.' % distro - sys.exit(1) - - if not os.path.isfile(os.path.join('/usr/share/debootstrap/scripts/', distro)): - answer = ask('Warning: Unknown distribution «%s». Do you want to continue [y/N]? ' % distro) - if answer not in ('y', 'Y'): - sys.exit(0) - - self.target_distro = distro - - def set_operation(self, operation): - """ pbuilder_dist.set_operation -> None - - Check if the given string is a valid pbuilder operation and - depending on this either save it into the appropiate variable - or finalize pbuilder-dist's execution. - - """ - - arguments = ('create', 'update', 'build', 'clean', 'login', 'execute') - - if operation not in arguments: - if operation.endswith('.dsc'): - if os.path.isfile(operation): - self.operation = 'build' - else: - print 'Error: Could not find file «%s».' % operation - sys.exit(1) - else: - print 'Error: «%s» is not a recognized argument.' % operation - print 'Please use one of those: ' + ', '.join(arguments) + '.' - sys.exit(1) - else: - self.operation = operation - - def get_command(self, remaining_arguments = None): - """ pbuilder_dist.get_command -> string - - Generate the pbuilder command which matches the given configuration - and return it as a string. - - """ - - if not self.build_architecture: - self.chroot_string = self.target_distro - self.build_architecture = self.system_architecture - else: - self.chroot_string = '%(target_distro)s-%(build_architecture)s' % self - - prefix = os.path.join(self.base, self.chroot_string) - result = '%s_result/' % prefix - - if not self.logfile: - self.logfile = os.path.normpath('%s/build.log' % result) - - if not os.path.isdir(result): - # Create the results directory, if it doesn't exist. - os.makedirs(result) - - if self.builder == 'pbuilder': - base = '--basetgz "%s-base.tgz"' % prefix - elif self.builder == 'cowbuilder': - base = '--basepath "%s-base.cow"' % prefix - - arguments = [ - '--%s' % self.operation, - base, - '--distribution "%(target_distro)s"' % self, - '--buildresult "%s"' % result, - '--logfile "%s"' % self.logfile, - '--aptcache "/var/cache/apt/archives/"', - ### --mirror "${ARCHIVE}" \ - '--override-config', - ] - - if os.path.exists('/var/cache/archive/'): - arguments.append('--bindmounts "/var/cache/archive/"') - - localrepo = '/var/cache/archive/%(target_distro)s' % self - if os.path.exists(localrepo): - arguments.append('--othermirror ' +\ - '"deb file:///var/cache/archive/ %(target_distro)s/"' % self) - - if self.target_distro in debian_distros: - arguments.append('--mirror "ftp://ftp.debian.org/debian"') - arguments.append('--components "main contrib non-free"') - else: - arguments.append('--components "main restricted universe multiverse"') - - if self.build_architecture != self.system_architecture: - arguments.append('--debootstrapopts --arch') - arguments.append('--debootstrapopts "%(build_architecture)s"' % self) - - ### $( [ $ISDEBIAN != "False" ] || echo "--aptconfdir \"${BASE_DIR}/etc/${DISTRIBUTION}/apt.conf/\"" ) \ - - # Append remaining arguments - if remaining_arguments: - arguments.extend(remaining_arguments) - - return self.auth + ' /usr/sbin/' + self.builder + ' ' + ' '.join(arguments) - -def host_architecture(): - """ host_architecture -> string - - Detect the host's architecture and return it as a string - (i386/amd64/other values). - - """ - - return os.uname()[4].replace('x86_64', 'amd64').replace('i586', 'i386').replace('i686', 'i386') - -def ask(question): - """ ask(question) -> string - - Ask the given question and return the answer. Also catch - KeyboardInterrupt (Ctrl+C) and EOFError (Ctrl+D) exceptions and - immediately return None if one of those is found. - - """ - - try: - answer = raw_input(question) - except (KeyboardInterrupt, EOFError): - print - answer = None - - return answer - -def help(exit_code = 0): - """ help() -> None - - Print a help message for pbuilder-dist, and exit with the given code. - - """ - - print 'See man pbuilder-dist for more information.' - - sys.exit(exit_code) - -def main(): - """ main() -> None - - This is pbuilder-dist's main function. It creates a pbuilder_dist - object, modifies all necessary settings taking data from the - executable's name and command line options and finally either ends - the script and runs pbuilder itself or exists with an error message. - - """ - - script_name = os.path.basename(sys.argv[0]) - parts = script_name.split('-') - - # Copy arguments into another list for save manipulation - args = sys.argv[1:] - - if '-' in script_name and (parts[0] != 'pbuilder' and \ - parts[0] != 'cowbuilder') or len(parts) > 3: - print 'Error: «%s» is not a valid name for a «pbuilder-dist» executable.' % script_name - sys.exit(1) - - if len(args) < 1: - print 'Insufficient number of arguments.' - help(1) - - if args[0] in ('-h', '--help', 'help'): - help(0) - - app = pbuilder_dist(parts[0]) - - if len(parts) > 1 and parts[1] != 'dist' and '.' not in parts[1]: - app.set_target_distro(parts[1]) - else: - app.set_target_distro(args.pop(0)) - - if len(parts) > 2: - requested_arch = parts[2] - elif args[0] in ('i386', 'amd64'): - requested_arch = args.pop(0) - else: - requested_arch = None - - if requested_arch: - if requested_arch in ('i386', 'amd64') and app.system_architecture == 'amd64': - app.build_architecture = requested_arch - else: - print 'Error: Architecture switching is not supported on your system; wrong filename.' - sys.exit(1) - - if 'mainonly' in sys.argv: - app.extra_components = False - args.remove('mainonly') - - if len(args) < 1: - print 'Insufficient number of arguments.' - help(1) - - # Parse the operation - app.set_operation(args.pop(0)) - - # Execute the pbuilder command - sys.exit(os.system(app.get_command(args))) - -if __name__ == '__main__': - - try: - main() - except KeyboardInterrupt: - print 'Manually aborted.' - sys.exit(1)