123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- #!/bin/bash
- # $Id: git-pbuilder,v 1.43 2016/12/10 18:54:05 eagle Exp $
- #
- # Wrapper around pbuilder for gbp buildpackage
- #
- # Note that this script requires bash, not a POSIX shell, because it uses bash
- # arrays to handle GIT_PBUILDER_OPTIONS and GIT_PBUILDER_PDEBUILDOPTIONS.
- # It's otherwise quite difficult to get the contents of that environment
- # variable to undergo the correct amount of shell expansion.
- #
- # Written by Russ Allbery <eagle@eyrie.org>
- # Based on the example in the git-buildpackage documentation
- # Copyright 2014, 2015, 2016 Russ Allbery <eagle@eyrie.org>
- # Copyright 2008, 2009, 2010, 2011, 2012, 2013
- # The Board of Trustees of the Leland Stanford Junior University
- #
- # Permission to use, copy, modify, and distribute this software and its
- # documentation for any purpose and without fee is hereby granted, provided
- # that the above copyright notice appear in all copies and that both that
- # copyright notice and this permission notice appear in supporting
- # documentation, and that the name of Stanford University not be used in
- # advertising or publicity pertaining to distribution of the software without
- # specific, written prior permission. Stanford University makes no
- # representations about the suitability of this software for any purpose. It
- # is provided "as is" without express or implied warranty.
- #
- # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
- # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- set -e
- # Helper function to quote an argument so that it's protected from the shell.
- # This is used when passing arguments through in --debbuildopts, since they'll
- # undergo another round of shell expansion.
- shell_quote () {
- echo "$1" | sed -e "s/'/'\"'\"'/g" -e "1 s/^/'/" -e "\$ s/\$/'/"
- }
- # Set default BUILDER, DIST, and ARCH based on the name we were invoked as.
- # This allows people to create symlinks like git-pbuilder-squeeze and
- # git-qemubuilder-squeeze-amd64 pointing to git-pbuilder and auto-detecting
- # the builder, distribution, and architecture from that.
- default_BUILDER=${0#*git-}
- default_DIST=${default_BUILDER#*-}
- default_BUILDER=${default_BUILDER%%-*}
- case $default_BUILDER in
- pbuilder|cowbuilder) default_BUILDER=cowbuilder ;;
- /*) default_BUILDER=cowbuilder ;;
- esac
- case $default_BUILDER in
- *builder) ;;
- *) default_BUILDER=cowbuilder ;;
- esac
- case $default_DIST in
- *builder)
- default_DIST=
- ;;
- *-*)
- default_ARCH=${default_DIST#*-}
- default_DIST=${default_DIST%%-*}
- ;;
- esac
- : ${default_BUILDER:=cowbuilder}
- # Set BUILDER, DIST, and ARCH, allowing existing settings to override.
- : ${BUILDER:=$default_BUILDER}
- : ${DIST:=$default_DIST}
- : ${ARCH:=$default_ARCH}
- # If DIST ends in -backports, strip that out of DIST and add it to EXT.
- if expr "$DIST" : '.*-backports$' >/dev/null; then
- DIST=${DIST%-backports}
- EXT="-backports"
- # The URL to the Debian backports repository to add to the chroot
- # configuration when created via this script for a distribution ending in
- # -backports. Backports was incorporated into the main mirrors as of
- # wheezy.
- case $DIST in
- squeeze)
- BACKPORTS='http://backports.debian.org/debian-backports'
- ;;
- *)
- BACKPORTS='http://ftp.debian.org/debian'
- ;;
- esac
- elif expr "$DIST" : '.*-lts$' >/dev/null; then
- DIST=${DIST%-lts}
- EXT="-lts"
- # The URL to the Debian LTS repository to add to the chroot
- # configuration when created via this script for a distribution ending in
- # -lts.
- LTS='http://ftp.debian.org/debian'
- else
- EXT=
- fi
- # Make sure we have the necessary tools.
- if [ ! -x /usr/sbin/"$BUILDER" ]; then
- echo "$BUILDER not found; you need to install the $BUILDER package" >&2
- exit 1
- fi
- # Default options come from the environment. Use eval to parse
- # GIT_PBUILDER_OPTIONS and GIT_PBUILDER_PDEBUILDOPTIONS into arrays, since
- # some arguments may have quoting.
- eval "OPTIONS=( $GIT_PBUILDER_OPTIONS )"
- eval "PDEBUILDOPTS=( $GIT_PBUILDER_PDEBUILDOPTIONS )"
- OUTPUT_DIR="${GIT_PBUILDER_OUTPUT_DIR:-../}"
- # How we handle options depends on what type of builder we're using. Ignore
- # options if $GIT_PBUILDER_AUTOCONF is set to no.
- if [ no != "$GIT_PBUILDER_AUTOCONF" ]; then
- case $BUILDER in
- pbuilder)
- # The root directory where different pbuilder --basetgz files are
- # found. git-pbuilder expects them to be named base-<dist>.tgz.
- : ${PBUILDER_BASE:=/var/cache/pbuilder}
- # If DIST is set, use base-$DIST.tgz. If DIST is not set, the sid
- # chroot may be either base.tgz or base-sid.tgz. Try both. If
- # ARCH is set, use base-$DIST-$ARCH.tgz.
- : ${DIST:=sid}
- if [ -n "$ARCH" ] ; then
- BASE="$PBUILDER_BASE/base-$DIST$EXT-$ARCH.tgz"
- OPTIONS+=( --architecture "$ARCH" )
- elif [ "$DIST" = 'sid' ] ; then
- if [ -f "$PBUILDER_BASE/base-sid.tgz" ]; then
- BASE="$PBUILDER_BASE/base-sid.tgz"
- else
- BASE="$PBUILDER_BASE/base.tgz"
- fi
- else
- BASE="$PBUILDER_BASE/base-$DIST$EXT.tgz"
- fi
- OPTIONS+=( --basetgz "$BASE" )
- # Make sure the base tarball exists.
- if [ ! -f "$BASE" ] && [ "$1" != "create" ]; then
- echo "Base tarball $BASE does not exist" >&2
- exit 1
- fi
- # Set --debian-etch-workaround if DIST is etch. Assume that
- # everything else is new enough that it will be fine.
- if [ "$DIST" = 'etch' ] || [ "$DIST" = 'ebo' ]; then
- OPTIONS+=( --debian-etch-workaround )
- fi
- ;;
-
- cowbuilder)
- # The root directory where different cowbuilder --basepath
- # directories are found. git-pbuilder expects them to be named
- # base-<dist>.cow.
- : ${COWBUILDER_BASE:=/var/cache/pbuilder}
- # If --basepath is specified on the command line we need to use
- # that and that alone, since if it's specified more than once,
- # cowbuilder will fail.
- bp_found=""
- for opt in $@; do
- case $opt in
- --basepath|--basepath=*) bp_found="yes" ;;
- esac
- done
- # If --basepath wasn't already provided, we need to set it. If
- # DIST is set, use base-$DIST.cow. If DIST is not set, the sid
- # chroot may be either base.cow or base-sid.cow. Try both. If
- # ARCH is set, use base-$DIST-$ARCH.cow.
- if [ -z "$bp_found" ]; then
- : ${DIST:=sid}
- if [ -n "$ARCH" ]; then
- BASE="$COWBUILDER_BASE/base-$DIST$EXT-$ARCH.cow"
- OPTIONS+=( --architecture "$ARCH" )
- elif [ "$DIST" = 'sid' ]; then
- if [ -d "$COWBUILDER_BASE/base-sid.cow" ] ; then
- BASE="$COWBUILDER_BASE/base-sid.cow"
- else
- BASE="$COWBUILDER_BASE/base.cow"
- fi
- else
- BASE="$COWBUILDER_BASE/base-$DIST$EXT.cow"
- fi
- OPTIONS+=( --basepath "$BASE" )
-
- # Make sure the base directory exists.
- if [ ! -d "$BASE" ] && [ "$1" != "create" ]; then
- echo "Base directory $BASE does not exist" >&2
- exit 1
- fi
- fi
-
- # Set --debian-etch-workaround if DIST is etch. Assume that
- # everything else is new enough that it will be fine.
- if [ "$DIST" = 'etch' ] || [ "$DIST" = 'ebo' ]; then
- OPTIONS+=( --debian-etch-workaround )
- fi
- ;;
-
- qemubuilder)
- # There always has to be an architecture for qemubuilder, and it
- # doesn't make much sense to default to the current architecture.
- # There's probably no good default, but this one at least makes
- # some sense.
- : ${DIST:=sid}
- : ${ARCH:=armel}
-
- # There has to be a configuration file matching our distribution
- # and architecture.
- QEMUCONFIG="/var/cache/pbuilder/$BUILDER-$ARCH-$DIST$EXT.conf"
- if [ ! -r "$QEMUCONFIG" ]; then
- echo "Cannot read configuration file $QEMUCONFIG" >&2
- exit 1
- fi
- OPTIONS+=( --config "$QEMUCONFIG" )
- ;;
-
- *)
- echo "Unknown builder $BUILDER" >&2
- exit 1
- ;;
- esac
- fi
- # If the first argument to the script is update, create, or login (or
- # --update, --create, or --login), set the $action.
- case $1 in
- update|create|login)
- action="--$1"
- shift
- ;;
- --update|--create|--login)
- action="$1"
- shift
- ;;
- *)
- action=""
- ;;
- esac
- # If $action is set, run the builder for $action under sudo rather than
- # proceeding.
- if [ -n "$action" ]; then
- # Since we're running the builder under sudo, $HOME will change to root's
- # home directory and the user's .pbuilderrc won't be run. sudo -E would
- # fix this, but that requires special configuration in sudoers to allow
- # it. Instead, check if the user has a .pbuilderrc and, if so, explicitly
- # add it as a configuration file.
- if [ -f "$HOME/.pbuilderrc" ] ; then
- OPTIONS+=( --configfile "$HOME/.pbuilderrc" )
- fi
- # Check that sudo is installed and try to provide a useful error if it
- # is not.
- if ! which sudo >/dev/null 2>&1; then
- cat >&2 <<EOE
- git-pbuilder: sudo not found in $PATH
- sudo was not found in your path. You need to install the sudo package and
- allow the current user to invoke the builder via sudo.
- EOE
- exit 1
- fi
- # Run the builder.
- if [ no = "$GIT_PBUILDER_AUTOCONF" ] ; then
- set -x
- sudo "$BUILDER" "$action" "${OPTIONS[@]}" "$@"
- else
- if [ "$EXT" = '-backports' ] ; then
- OTHERMIRROR="deb $BACKPORTS $DIST$EXT main"
- set -x
- sudo "$BUILDER" "$action" --distribution "$DIST" \
- --othermirror "$OTHERMIRROR" "${OPTIONS[@]}" "$@"
- elif [ "$EXT" = '-lts' ] ; then
- OTHERMIRROR="deb $LTS $DIST$EXT main"
- set -x
- sudo "$BUILDER" "$action" --distribution "$DIST" \
- --othermirror "$OTHERMIRROR" "${OPTIONS[@]}" "$@"
- else
- set -x
- sudo "$BUILDER" "$action" --distribution "$DIST" \
- "${OPTIONS[@]}" "$@"
- fi
- fi
- { set +x; } 2>/dev/null
- exit 0
- fi
- # Build package: not (update | create | login)
- if [ -z "$GBP_BUILD_DIR" ]; then
- echo "Warning: git-pbuilder should be run via 'gbp buildpackage'" >&2
- fi
- # Print out some information about what we're doing.
- building="Building with $BUILDER"
- if [ no = "$GIT_PBUILDER_AUTOCONF" ] ; then
- echo "$building"
- elif [ -n "$ARCH" ] ; then
- echo "$building for distribution $DIST$EXT, architecture $ARCH"
- else
- echo "$building for distribution $DIST$EXT"
- fi
- # Source package format 1.0 doesn't automatically exclude Git files, so we
- # want to add the appropriate flags to do that. But source package format 3.0
- # does exclude by default and has many other ways of controlling those
- # exclusions that we don't want to tromp on. So we don't want to give any -i
- # or -I flags unless we're using source format 1.0.
- if [ ! -f debian/source/format ] || grep -qs '^1.0' debian/source/format ; then
- echo 'Source format 1.0 detected, adding exclude flags'
- DEBBUILDOPTS="-i'(?:^|/)\\.git(attributes)?(?:\$|/.*\$)' -I.git"
- else
- DEBBUILDOPTS=''
- fi
- # Add all of the additional arguments we got on the command line, but quote
- # them from the shell since they'll undergo another round of shell expansion
- # when the pbuilder runs debbuild.
- for arg in "$@" ; do
- DEBBUILDOPTS+=" $(shell_quote "$arg")"
- done
- # Now we can finally run pdebuild. The quoting here is tricky, but this
- # seems to pass everything through properly.
- if [ no = "$GIT_PBUILDER_AUTOCONF" ] ; then
- pdebuild --pbuilder "$BUILDER" --debbuildopts "$DEBBUILDOPTS" \
- "${PDEBUILDOPTS[@]}" -- "${OPTIONS[@]}"
- else
- pdebuild --buildresult "$OUTPUT_DIR" --pbuilder "$BUILDER" \
- --debbuildopts "$DEBBUILDOPTS" "${PDEBUILDOPTS[@]}" -- "${OPTIONS[@]}"
- fi
- exit "$?"
- # Documentation. Use a hack to hide this from the shell. Because of the
- # above exit line, this should never be executed.
- DOCS=<<__END_OF_DOCS__
- =head1 NAME
- git-pbuilder - Wrapper around cowbuilder/qemubuilder for gbp buildpackage
- =head1 SYNOPSIS
- DIST=I<distribution> ARCH=I<architecture> [BUILDER=(pbuilder|qemubuilder)] \
- B<git-pbuilder> I<debbuild-options>
- DIST=I<distribution> ARCH=I<architecture> [BUILDER=(pbuilder|qemubuilder)] \
- B<git-pbuilder> (update | create | login) I<cowbuilder-options>
- =head1 DESCRIPTION
- B<git-pbuilder> is a wrapper around B<pdebuild> intended for use by
- B<gbp buildpackage>. It configures B<pdebuild> to use B<cowbuilder> by
- default, passes appropriate options to B<debbuild>, and sets the base path
- for B<cowbuilder> based on the environment variable DIST and, if set, the
- environment variable ARCH. B<qemubuilder> can be selected instead by
- setting the environment variable BUILDER to C<qemubuilder>, and
- B<pbuilder> can be selected by setting BUILDER to C<pbuilder>.
- By default, B<git-pbuilder> assumes the target distribution is C<sid>, the
- same architecture as the B<cowbuilder> default, and uses
- F</var/cache/pbuilder/base-sid.cow> if it exists. If it doesn't,
- F</var/cache/pbuilder/base.cow> is tried. If DIST is set, its value is
- the target distribution and F</var/cache/pbuilder/base-I<dist>.cow> is
- used instead. If DIST is C<etch> or C<ebo>, B<--debian-etch-workaround>
- is also passed to B<cowbuilder>. If ARCH is set, its value is the target
- architecture and F</var/cache/pbuilder/base-I<dist>-I<arch>.cow> is used,
- with I<dist> being set to C<sid> if DIST was not set.
- If B<qemubuilder> is used as the builder, no base directory is used.
- Instead, B<qemubuilder> is invoked with the B<--config> option pointing to
- the file F</var/cache/pbuilder/qemubuilder-I<arch>-I<dist>.conf>
- If B<pbuilder> is used as the builder, B<git-pbuilder> instead looks for
- F</var/cache/pbuilder/base-sid.tgz> by default and
- F</var/cache/pbuilder/base.tgz> if it doesn't exist. If DIST or ARCH are
- set, they are used to form the expected name of the tgz file in the same
- way as they're used to form the expected base directory for B<cowbuilder>.
- Similar to B<cowbuilder>, B<--debian-etch-workaround> is passed to
- B<pbuilder> if from the DIST setting it looks like the target distribution
- is etch.
- If B<git-pbuilder> is invoked via a name that starts with C<git-*->, the
- part between the hyphens is taken to be the default name of the builder to
- use. However, C<pbuilder> is mapped to B<cowbuilder> for backward
- compatibility; if you want to use B<pbuilder>, you have to explicitly set
- BUILDER. The part after the last hyphen is taken to be the default
- distribution (if it contains no additional hyphen) or the default
- distribution followed by the default architecture (if it contains a
- hyphen). One can therefore create symlinks like C<git-pbuilder-squeeze>
- pointing to B<git-pbuilder> and use that name when wanting to use a
- distribution of C<squeeze>, or C<git-qemubuilder-sid-armel> to use
- B<qemubuilder> to build for the C<armel> architecture and the C<sid>
- distribution. Explicit settings of BUILDER, DIST, or ARCH always override
- any guesses from the command name. (But note that B<gbp buildpackage>
- does not pass on environment variables when run with B<--git-pbuilder>;
- see below.)
- Any arguments are passed as-is to B<dpkg-buildpackage> via the
- B<--debbuildopts> option to B<pdebuild>. To pass arguments to the builder
- instead, put them in the environment variable GIT_PBUILDER_OPTIONS.
- To disable all attempts to discover the base path, tarball, or
- configuration file and set up the pbuilder options and instead rely on the
- settings in .pbuilderrc, set GIT_PBUILDER_AUTOCONF to C<no>.
- Normally, one does not run this script directly. Instead, it's used as
- the builder script for B<gbp buildpackage> via the B<--git-pbuilder>
- command-line option. When run this way, you should use the B<--git-dist>,
- B<--git-arch>, B<--git-qemubuilder>, B<--git-pbuilder-autoconf>, and
- B<--git-pbuilder-options> flags instead of setting the DIST, ARCH, BUILDER,
- GIT_PBUILDER_AUTOCONF, and GIT_PBUILDER_OPTIONS environment variables. See
- L<gbp-buildpackage(1)> for more information.
- Alternately, B<git-pbuilder> may be called with an argument of C<update>,
- C<create>, or C<login>. In this case, it calls B<cowbuilder> (or the
- configured builder as described above) using B<sudo> and passes the
- corresponding command to the builder, using the same logic as above to
- determine the base directory and distribution. If the distribution (set
- in DIST) ends in C<-backports>, one of the following will be added as an
- B<--othermirror> parameter to the builder:
- deb http://ftp.debian.org/debian $DIST main
- deb http://backports.debian.org/debian-backports $DIST main
- The first will be used for most distributions, and the second for
- C<squeeze-backports>. If the distribution ends in C<-lts>, the following will
- be added as an B<--othermirror> parameter to the builder:
- deb http://ftp.debian.org/debian $DIST main
- to support building for Long Term Support releases.
- Any additional arguments to B<git-pbuilder> are passed along to the
- builder. Due to how B<sudo> works, invoking the builder with an action
- will not read the user's F<.pbuilderrc> by default, so in this case
- B<git-pbuilder> will add an explicit B<--configfile> option pointing to
- the user's F<.pbuilderrc> if it exists.
- If you use B<git-pbuilder> with one of these arguments, you must have
- the C<sudo> package installed, and you must configure B<sudo> to let the
- current user run the appropriate builder command.
- =head1 ENVIRONMENT
- =over 4
- =item ARCH
- Sets the target architecture. For a B<cowbuilder> builder, this sets both
- the base path and is passed as the B<--architecture> option. With
- B<qemubuilder>, this controls the path to the configuration file. With
- B<pbuilder>, this sets the tgz path and is passed as B<--architecture>.
- =item BUILDER
- Sets the builder to use. The only supported settings are C<cowbuilder>
- (the default), C<qemubuilder>, and C<pbuilder>.
- =item COWBUILDER_BASE
- Set this environment variable to change the default location for the
- cowbuilder base directories (F</var/cache/pbuilder>).
- =item DIST
- Sets the target distribution. This is used primarily to determine the
- base path for B<cowbuilder> or B<pbuilder> or the configuration file path
- for B<qemubuilder>, but it's also used to determine whether to pass
- B<--debian-etch-workaround> to B<cowbuilder> or B<pbuilder>.
- =item GIT_PBUILDER_AUTOCONF
- If set to C<no>, disable the logic that constructs the base path, tarball,
- or configuration file and all other logic to determine the options to pass
- to the builder. Instead, just run the configured builder and assume its
- configuration is handled elsewhere (such as in F<.pbuilderrc>). This also
- suppresses setting B<--buildresult>, so the user will need to ensure that
- the configuration still puts packages where B<gbp buildpackage> expects
- them.
- =item GIT_PBUILDER_OPTIONS
- Add additional options for the builder. These options are passed as-is to
- B<cowbuilder>, B<qemubuilder>, or B<pbuilder> via B<pdebuild>. The
- contents of this variable will undergo shell expansion, so any arguments
- containing shell metacharacters or whitespace need to be quoted in the
- value of the environment variable.
- =item GIT_PBUILDER_OUTPUT_DIR
- Where to put the result of the build. The default is C<..> (the parent
- directory). This setting is ignored if GIT_PBUILDER_AUTOCONF is set to
- C<no>.
- =item GIT_PBUILDER_PDEBUILDOPTIONS
- Add additional options for B<pdebuild> itself (such as
- B<--use-pdebuild-internal>). The contents of this variable will undergo
- shell expansion, so any arguments containing shell metacharacters or
- whitespace need to be quoted in the value of the environment variable.
- =item PBUILDER_BASE
- Set this environment variable to change the default location for the
- pbuilder tgz files (F</var/cache/pbuilder>) when BUILDER is set to
- C<pbuilder>.
- =back
- =head1 FILES
- =over 4
- =item /var/cache/pbuilder/base-sid.cow
- =item /var/cache/pbuilder/base.cow
- The default C<cowbuilder --basepath> directories, searched for in that
- order, if neither DIST nor ARCH is set.
- =item /var/cache/pbuilder/base-sid-$ARCH.cow
- The C<cowbuilder --basepath> directory used if ARCH is set and DIST is not
- set.
- =item /var/cache/pbuilder/base-$DIST.cow
- The C<cowbuilder --basepath> directory used if DIST is set and ARCH is
- not.
- =item /var/cache/pbuilder/base-$DIST-$ARCH.cow
- The C<cowbuilder --basepath> directory used if DIST and ARCH are both set.
- =item /var/cache/pbuilder/base-sid.tgz
- =item /var/cache/pbuilder/base.tgz
- =item /var/cache/pbuilder/base-sid-$ARCH.tgz
- =item /var/cache/pbuilder/base-$DIST.tgz
- =item /var/cache/pbuilder/base-$DIST-$ARCH.tgz
- Similar to the above, the C<pbuilder --basetgz> path used for various
- settings of DIST and ARCH if BUILDER is set to C<pbuilder>.
- =item /var/cache/pbuilder/qemubuilder-$ARCH-$DIST.conf
- The C<qemubuilder --config> file used. $ARCH defaults to C<armel> and
- $DIST defaults to C<sid> if not set.
- =back
- =head1 SEE ALSO
- cowbuilder(8), dpkg-buildpackage(1), gbp-buildpackage(1), pbuilder(8),
- pdebuild(1), qemubuilder(8), sudo(8)
- The latest version of this script is available from
- L<http://www.eyrie.org/~eagle/software/scripts/>.
- =head1 AUTHOR
- Russ Allbery <eagle@eyrie.org>
- =cut
- __END_OF_DOCS__
|