Author: adam-guest
Date: 2008-05-04 14:57:33 +0000 (Sun, 04 May 2008)
New Revision: 1429

Added:
   trunk/cowpoke.conf
   trunk/scripts/cowpoke.1
   trunk/scripts/cowpoke.sh
Modified:
   trunk/README
   trunk/conf.default.in
   trunk/debian/changelog
   trunk/debian/control
   trunk/debian/install
   trunk/po4a/devscripts-po4a.conf
Log:
cowpoke: New script to upload a Debian source package to a cowbuilder host
and build it, optionally also signing and uploading the result to an
incoming queue 

Modified: trunk/README
===================================================================
--- trunk/README        2008-05-04 14:36:53 UTC (rev 1428)
+++ trunk/README        2008-05-04 14:57:33 UTC (rev 1429)
@@ -37,6 +37,10 @@
 - checkbashisms: checks whether a /bin/sh script uses any common
   bash-specific features
 
+- cowpoke: upload a Debian source package to a cowbuilder host and build it,
+  optionally also signing and uploading the result to an incoming queue 
+  [ssh-client]
+
 - cvs-debi, cvs-debc: wrappers around debi and debc respectively (see below)
   which allow them to be called from the CVS working directory.
   [cvs-buildpackage]

Modified: trunk/conf.default.in
===================================================================
--- trunk/conf.default.in       2008-05-04 14:36:53 UTC (rev 1428)
+++ trunk/conf.default.in       2008-05-04 14:57:33 UTC (rev 1429)
@@ -116,6 +116,10 @@
 # 
 # No variables currently
 
+##### cowpoke
+#
+# No variables currently
+
 ##### cvs-debc
 # 
 # No variables currently

Added: trunk/cowpoke.conf
===================================================================
--- trunk/cowpoke.conf                          (rev 0)
+++ trunk/cowpoke.conf  2008-05-04 14:57:33 UTC (rev 1429)
@@ -0,0 +1,43 @@
+# System configuration file for cowpoke
+# This file is sourced as a bash shell script, see cowpoke(1) for more details.
+
+# The hostname of the machine where cowbuilder is installed
+# eg. BUILDD_HOST="buildd.your.com"
+BUILDD_HOST=
+
+# The username for unprivileged operations on BUILDD_HOST
+#BUILDD_USER="$(id -un 2>/dev/null)"
+
+# The Debian architecture to build for
+#BUILDD_ARCH="$(dpkg-architecture -qDEB_BUILD_ARCH 2>/dev/null)"
+
+# The directory (under BUILDD_USER's home if relative) to upload packages
+# for building where build logs and the result of post-build checks will
+# be placed
+#INCOMING_DIR="cowbuilder-incoming"
+
+# The directory where pbuilder/cowbuilder will place the built package,
+# and where previously built packages may be found for comparison using
+# debdiff after building.
+#RESULT_DIR="/var/cache/pbuilder/result"
+
+# The gpg key id to pass to debsign's -k option.  eg. SIGN_KEYID="0x12345678"
+# Leave this unset if you do not wish to sign packages built in this way.
+#SIGN_KEYID=
+
+# The 'host' alias to pass to dput.  eg. UPLOAD_QUEUE="ftp-master"
+# Leave this unset if you do not wish to upload packages built this way.
+# This option will be ignored if SIGN_KEYID is unset.
+#UPLOAD_QUEUE=
+
+# An optional command that may be used to gain root access from the remote
+# build machine.  If unset, cowpoke will attempt to log in directly as root,
+# which is the recommended method when used in conjunction with a secure key
+# to grant root access to the machine.  If you prefer to gain root access
+# using a simple password (or worse, a normal user password), then you can
+# set this option to the security hole^W^W privilege escalation option of
+# your choice.  If set, cowpoke will log in initially as the $BUILDD_USER,
+# then use this command to gain the privileges that it required to execute
+# the cowbuilder invocation script.
+#BUILDD_ROOTCMD="sudo"
+

Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog      2008-05-04 14:36:53 UTC (rev 1428)
+++ trunk/debian/changelog      2008-05-04 14:57:33 UTC (rev 1429)
@@ -4,6 +4,9 @@
   * checkbashisms:
     + Also match use of "SHELL=/bin/bash -e" when checking whether a makefile
       explicitly uses bash
+  * cowpoke: New script to upload a Debian source package to a cowbuilder host
+    and build it, optionally also signing and uploading the result to an
+    incoming queue 
 
   [ James Vega ]
   * mk-build-deps:

Modified: trunk/debian/control
===================================================================
--- trunk/debian/control        2008-05-04 14:36:53 UTC (rev 1428)
+++ trunk/debian/control        2008-05-04 14:57:33 UTC (rev 1429)
@@ -38,6 +38,9 @@
   - chdist: tool to easily play with several distributions [dctrl-tools]
   - checkbashisms: check whether a /bin/sh script contains any common
     bash-specific contructs
+  - cowpoke: upload a Debian source package to a cowbuilder host and build it,
+    optionally also signing and uploading the result to an incoming queue
+    [ssh-client]
   - cvs-debi, cvs-debc: to call debi and debc from the CVS working directory
     after running cvs-debuild or cvs-buildpackage [cvs-buildpackage]
   - cvs-debrelease: to call debrelease from the CVS working directory

Modified: trunk/debian/install
===================================================================
--- trunk/debian/install        2008-05-04 14:36:53 UTC (rev 1428)
+++ trunk/debian/install        2008-05-04 14:57:33 UTC (rev 1429)
@@ -1 +1,2 @@
 debian/bug/* /usr/share/bug/devscripts
+cowpoke.conf /etc

Modified: trunk/po4a/devscripts-po4a.conf
===================================================================
--- trunk/po4a/devscripts-po4a.conf     2008-05-04 14:36:53 UTC (rev 1428)
+++ trunk/po4a/devscripts-po4a.conf     2008-05-04 14:57:33 UTC (rev 1429)
@@ -21,6 +21,8 @@
        fr:fr/chdist.fr.pl add_fr:add_fr/translator_pod.add
 [type:man] ../scripts/checkbashisms.1 \
        fr:fr/checkbashisms.fr.1 add_fr:add_fr/translator_man.add
+[type:man] ../scripts/cowpoke.1 \
+       fr:fr/cowpoke.fr.1 add_fr:add_fr/translator_man.add
 [type:man] ../scripts/cvs-debc.1 \
        fr:fr/cvs-debc.fr.1 add_fr:add_fr/translator_man.add
 [type:man] ../scripts/cvs-debi.1 \

Added: trunk/scripts/cowpoke.1
===================================================================
--- trunk/scripts/cowpoke.1                             (rev 0)
+++ trunk/scripts/cowpoke.1     2008-05-04 14:57:33 UTC (rev 1429)
@@ -0,0 +1,153 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH COWPOKE 1 "April 28, 2008"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+cowpoke \- Build a Debian source package in a remote cowbuilder instance
+.SH SYNOPSIS
+.B cowpoke
+.I packagename.dsc
+.RI [ " arch " [ " buildd-host " [ " buildd-username " ]
+] ]
+.SH DESCRIPTION
+Uploads a Debian source package to a cowbuilder host and builds it,
+optionally also signing and uploading the result to an incoming queue.
+
+
+.SH CONFIGURATION OPTIONS
+When \fBcowpoke\fP is run the following configuration options are read from
+global, per\-user, and per\-project configuration files if present:
+.TP
+.B BUILDD_HOST
+The network address or fqdn of the build machine where cowbuilder is 
configured.
+This may be overridden by an explicit hostname specified as a command line 
option.
+.TP
+.B BUILDD_USER
+The unprivileged user name for operations on the build machine.  This defaults
+to the local name of the user executing \fBcowpoke\fP, and may also be 
overridden
+by specifying the username on the command line.
+.TP
+.B BUILDD_ARCH
+The Debian architecture string to build for.  This must match the
+\fBDEB_BUILD_ARCH\fP of the build chroot being used.  It defaults to the local
+machine architecture where \fBcowpoke\fP is executed, and may be overridden on
+the command line.
+
+.TP
+.B INCOMING_DIR
+The directory path on the build machine where the source package will initially
+be placed.  An absolute path may be used, but it must be writable by the
+\fBBUILDD_USER\fP.  Relative paths are rooted at that user's home directory.
+.TP
+.B RESULT_DIR
+The directory path on the build machine where the resulting packages (source 
and
+binary) will be found, and where older versions of the package that were built
+previously may be found.  If any such older packages exist, debdiff will be 
used
+to compare the new package with the previous version after the build is 
complete,
+and the result will be included in the build log.  Files in it must be readable
+by the \fBBUILDD_USER\fP for sanity checking with \fBlintian\fP and 
\fBdebdiff\fP,
+and for upload with \fBdput\fP.  This should always be an absolute path.
+
+.TP
+.B SIGN_KEYID
+If this option is set, it is expected to contain the gpg key id to pass to
+\fBdebsign\fP if the packages are to be remotely signed.  You will be prompted
+to confirm whether you wish to sign the packages after each build is complete.
+If this option is unset or an empty string, no attempt to sign packages will be
+made.
+.TP
+.B UPLOAD_QUEUE
+If this opton is set, it is expected to contain a 'host' specification for
+\fBdput\fP which will be used to upload them after they are signed.  You will 
be
+prompted to confirm whether you wish to upload the packages after they are 
signed.
+If this option is unset or an empty string, no attempt to upload packages will
+be made.  If \fBSIGN_KEYID\fP is not set, this option will be ignored entirely.
+
+.TP
+.B BUILDD_ROOTCMD
+If this opton is unset (which is the default), cowpoke will attempt to log in
+to the build machine as the root user initially, then drop those privileges to
+assume the identity of the \fBBUILDD_USER\fP for operations which do not 
require
+them.  This is the recommended method when used in conjunction with a secure 
key
+to grant root access to the machine.  If you prefer to gain root access through
+some other method, then you should set this option to contain the privilege
+escalation command that will be used to execute the scripts which must run as
+root, and cowpoke will initially log in as the \fBBUILDD_USER\fP.
+
+
+.SH CONFIGURATION FILES
+.TP
+.I /etc/cowpoke.conf
+Global configuration options.  Will override hardcoded defaults.
+.TP
+.I ~/.cowpoke
+Per\-user configuration options.  Will override any global configuration.
+.TP
+.I .cowpoke
+Per\-project configuration options.  Will override any per-user or global
+configuration if \fBcowpoke\fP is called from the directory where they exist.
+
+If the environment variable \fBCOWPOKE_CONF\fP is set, it specifies an 
addtional
+configuration file which will override all of those above.  Options specified
+explicitly on the command line override all configuration files.
+
+
+.SH COWBUILDER CONFIGURATION
+There is nothing particularly special required to configure a cowbuilder 
instance
+for use with \fBcowpoke\fP.  Simply create them in the flavour you require with
+`cowbuilder \-\-create` according to the cowbuilder documentation, then 
configure
+\fBcowpoke\fP with the user, arch, and path information required to access it, 
on
+the machines you wish to invoke it from.  The build host running cowbuilder 
does
+not require \fBcowpoke\fP installed locally.
+
+The build machine should have the lintian and devscripts packages installed for
+post-build sanity checking.  Upon completion, the build log and the results of
+automated checks will be recorded in the \fBINCOMING_DIR\fP.  If you wish to
+upload signed packages the build machine will also need \fBdput\fP installed 
and
+configured to use the 'host' alias specified by \fBUPLOAD_QUEUE\fP.
+
+The user executing \fBcowpoke\fP must have ssh access to the build machine as
+both 'root' and the \fBBUILDD_USER\fP.  Signing keys are not required to be
+installed on the build machine (and will be ignored there if they are).  If the
+package is signed, keys will be expected on the machine that executes 
\fBcowpoke\fP.
+
+When \fBcowpoke\fP is invoked, it will first attempt to update the cowbuilder
+image if that has not already been done on the same day.  This is checked by
+the presence or absence of a \fIcowbuilder-update-log-$date\fP file in the
+\fBINCOMING_DIR\fP.  You may move, remove, or touch this file if you wish the
+image to be updated more or less often than that.  Its contents log the output
+of cowbuilder during the update.
+
+
+.SH NOTES
+Since cowbuilder creates a chroot, and to do that you need root, \fBcowpoke\fP
+also requires some degree of root access.  So all the horrible things that can
+go wrong with that may well one day rain down upon you.  cowbuilder has been
+known to accidentally wipe out bind-mounted filesystems outside the chroot, and
+worse than that can easily happen.  So be careful, keep good backups of things
+you don't want to lose on your build machine, and use \fBcowpoke\fP to keep all
+that on a machine that isn't your bleeding edge dev box with your last few 
hours
+of uncommitted work.
+
+.SH SEE ALSO
+.BR cowbuilder (1),
+.BR pbuilder (1),
+.BR ssh-agent (1).
+
+.SH AUTHOR
+.B cowpoke
+was written by Ron <[EMAIL PROTECTED]>.
+

Added: trunk/scripts/cowpoke.sh
===================================================================
--- trunk/scripts/cowpoke.sh                            (rev 0)
+++ trunk/scripts/cowpoke.sh    2008-05-04 14:57:33 UTC (rev 1429)
@@ -0,0 +1,239 @@
+#! /bin/bash
+# Simple shell script for driving a remote cowbuilder via ssh
+#
+# Copyright(C) 2007, 2008, Ron <[EMAIL PROTECTED]>
+# This script is distributed according to the terms of the GNU GPL.
+
+set -e
+
+#BUILDD_HOST=
+#BUILDD_ROOTCMD=
+BUILDD_USER="$(id -un 2>/dev/null)"
+BUILDD_ARCH="$(dpkg-architecture -qDEB_BUILD_ARCH 2>/dev/null)"
+
+INCOMING_DIR="cowbuilder-incoming"
+RESULT_DIR="/var/cache/pbuilder/result"
+
+#SIGN_KEYID=
+#UPLOAD_QUEUE="ftp-master"
+
+REMOTE_SCRIPT="cowssh_it"
+
+for f in /etc/cowpoke.conf ~/.cowpoke .cowpoke "$COWPOKE_CONF"; do [ -r "$f" ] 
&& . "$f"; done
+
+PROGNAME=`basename $0`
+
+version () {
+    echo \
+"This is $PROGNAME, from the Debian devscripts package, version ###VERSION###
+This code is copyright 2007-8 by Ron <[EMAIL PROTECTED]>, all rights reserved.
+This program comes with ABSOLUTELY NO WARRANTY.
+You are free to redistribute this code under the terms of the
+GNU General Public License."
+   exit 0
+}
+
+usage()
+{
+    cat 1>&2 <<EOF
+
+cowpoke package.dsc [ arch [ buildd-host [ buildd-username ] ] ]
+
+  Uploads a Debian source package to a cowbuilder host and builds it,
+  optionally also signing and uploading the result to an incoming queue.
+  The current default configuration is:
+
+   BUILDD_HOST = $BUILDD_HOST
+   BUILDD_USER = $BUILDD_USER
+   BUILDD_ARCH = $BUILDD_ARCH
+
+  The expected remote paths are:
+
+   INCOMING_DIR = ~$BUILDD_USER/$INCOMING_DIR
+   RESULT_DIR   = ${RESULT_DIR:-/}
+
+  The cowbuilder image must have already been created on the build host,
+  and the expected remote paths must already exist.  You must have ssh
+  access to the build host as 'root' and '$BUILDD_USER'.
+
+EOF
+
+    exit $1
+}
+
+[ "$1" = "--help" ] && usage 0;
+[ "$1" = "--version" ] && version;
+[ $# -gt 0 ] && [ $# -lt 4 ] || usage 1
+
+if [ -z "$REMOTE_SCRIPT" ]; then
+    echo "No remote script name set.  Aborted."
+    exit 1
+fi
+
+case "$1" in
+    *.dsc) ;;
+    *) echo "ERROR: '$1' is not a package .dsc file"
+       usage 1 ;;
+esac
+if ! [ -r "$1" ]; then
+    echo "ERROR: '$1' not found."
+    exit 1
+fi
+
+[ -z "$2" ] || BUILDD_ARCH="$2"
+[ -z "$3" ] || BUILDD_HOST="$3"
+[ -z "$4" ] || BUILDD_USER="$4"
+
+if [ -z "$BUILDD_ARCH" ]; then
+    echo "No BUILDD_ARCH set.  Aborted."
+    exit 1
+fi
+if [ -z "$BUILDD_HOST" ]; then
+    echo "No BUILDD_HOST set.  Aborted."
+    exit 1
+fi
+if [ -z "$BUILDD_USER" ]; then
+    echo "No BUILDD_USER set.  Aborted."
+    exit 1
+fi
+
+if [ -e "$REMOTE_SCRIPT" ]; then
+    echo "$REMOTE_SCRIPT file already exists and will be overwritten."
+    echo -n "Do you wish to continue (Y/n)? "
+    read -e yesno
+    case "$yesno" in
+       N* | n*)
+           echo "Ok, bailing out."
+           echo "You should set the REMOTE_SCRIPT variable to some other value"
+           echo "if this name conflicts with something you already expect to 
use"
+           exit 1
+           ;;
+       *) ;;
+    esac
+fi
+
+PACKAGE="$(basename $1 .dsc)"
+CHANGES="$BUILDD_ARCH.changes"
+LOGFILE="build.${PACKAGE}_$BUILDD_ARCH.log"
+DATE="$(date +%Y%m%d 2>/dev/null)"
+
+cat > "$REMOTE_SCRIPT" <<-EOF
+       #! /bin/bash
+       # cowpoke generated remote worker script.
+       # Normally this should have been deleted already, you can safely remove 
it now.
+
+
+       # Sort the list of old changes files for this package to try and
+       # determine the most recent one preceding this version.  We will
+       # debdiff to this revision in the final sanity checks if one exists.
+       # This is adapted from the insertion sort trickery in git-debimport.
+
+       OLD_CHANGES="\$(find "$RESULT_DIR/" -maxdepth 1 -type f \\
+                            -name "${PACKAGE%%_*}_*_$CHANGES" 2>/dev/null \\
+                       | sort 2>/dev/null)"
+       P=( \$OLD_CHANGES )
+       count=\${#P[*]}
+       COMPARE="dpkg --compare-versions"
+
+       for(( i=1; i < count; ++i )) do
+           j=i
+           #echo "was \$i: \${P[i]}"
+           while ((\$j)) && \$COMPARE "\${P[j-1]%_$CHANGES}" gt 
"\${P[i]%_$CHANGES}"; do ((--j)); done
+           ((i==j)) || P=( [EMAIL PROTECTED]:0:j} \${P[i]} \${P[j]} [EMAIL 
PROTECTED]:j+1:i-(j+1)} [EMAIL PROTECTED]:i+1} )
+       done
+       #for(( i=1; i < count; ++i )) do echo "now \$i: \${P[i]}"; done
+
+       OLD_CHANGES=
+       for(( i=count-1; i >= 0; --i )) do
+           if [ "\${P[i]}" != "$RESULT_DIR/${PACKAGE}_$CHANGES" ]; then 
+               OLD_CHANGES="\${P[i]}"
+               break
+           fi
+       done
+
+
+       set -eo pipefail
+
+       if ! [ -e "cowbuilder-update-log-$DATE" ]; then
+           cowbuilder --update 2>&1 | tee "cowbuilder-update-log-$DATE"
+       fi
+       cowbuilder --build "$(basename $1)" 2>&1 | tee "$LOGFILE"
+
+       set +eo pipefail
+
+
+       echo >> "$LOGFILE"
+       echo "lintian $RESULT_DIR/${PACKAGE}_$CHANGES" >> "$LOGFILE"
+       ( su "$BUILDD_USER" -c "lintian \"$RESULT_DIR/${PACKAGE}_$CHANGES\"" ) 
2>&1 \\
+       | tee -a "$LOGFILE"
+
+       if [ -n "\$OLD_CHANGES" ]; then
+           echo >> "$LOGFILE"
+           echo "debdiff \$OLD_CHANGES ${PACKAGE}_$CHANGES" >> "$LOGFILE"
+           ( su "$BUILDD_USER" -c "debdiff \"\$OLD_CHANGES\" 
\"$RESULT_DIR/${PACKAGE}_$CHANGES\"" ) 2>&1 \\
+           | tee -a "$LOGFILE"
+       else
+           echo >> "$LOGFILE"
+           echo "No previous packages for $BUILDD_ARCH to compare" >> 
"$LOGFILE"
+       fi
+
+EOF
+chmod 755 "$REMOTE_SCRIPT"
+
+dcmd scp $1 "$REMOTE_SCRIPT" "[EMAIL PROTECTED]:$INCOMING_DIR"
+
+if [ -z "$BUILDD_ROOTCMD" ]; then
+    ssh "[EMAIL PROTECTED]" "cd ~$BUILDD_USER/\"$INCOMING_DIR\" && 
\"./$REMOTE_SCRIPT\" && rm -f \"./$REMOTE_SCRIPT\""
+else
+    ssh -t "[EMAIL PROTECTED]" "cd \"$INCOMING_DIR\" && $BUILDD_ROOTCMD 
\"./$REMOTE_SCRIPT\" && rm -f \"./$REMOTE_SCRIPT\""
+fi
+
+echo
+echo "Build completed."
+
+if [ -n "$SIGN_KEYID" ]; then
+    while true; do
+       echo -n "Sign $PACKAGE with key '$SIGN_KEYID' (yes/no)? "
+       read -e yesno
+       case "$yesno" in
+           YES | yes)
+               debsign "-k$SIGN_KEYID" -r "[EMAIL PROTECTED]" 
"$RESULT_DIR/${PACKAGE}_$CHANGES"
+
+               if [ -n "$UPLOAD_QUEUE" ]; then
+                   while true; do
+                       echo -n "Upload $PACKAGE to '$UPLOAD_QUEUE' (yes/no)? "
+                       read -e upload
+                       case "$upload" in
+                           YES | yes)
+                               ssh "[EMAIL PROTECTED]" \
+                                   "cd \"$RESULT_DIR/\" && dput 
\"$UPLOAD_QUEUE\" \"${PACKAGE}_$CHANGES\""
+                               break 2
+                               ;;
+
+                           NO | no)
+                               echo "Package upload skipped."
+                               break 2
+                               ;;
+                           *)
+                               echo "Please answer 'yes' or 'no'"
+                               ;;
+                       esac
+                   done
+               fi
+               break
+               ;;
+
+           NO | no)
+               echo "Package signing skipped."
+               break
+               ;;
+           *)
+               echo "Please answer 'yes' or 'no'"
+               ;;
+       esac
+    done
+fi
+
+rm -f "$REMOTE_SCRIPT"
+
+# vi:sts=4:sw=4:noet:foldmethod=marker


Property changes on: trunk/scripts/cowpoke.sh
___________________________________________________________________
Name: svn:executable
   + *



-- 
To unsubscribe, send mail to [EMAIL PROTECTED]

Reply via email to