#!/bin/bash PROGNAME=$(basename $0) # $HeadURL$ $LastChangedRevision$ set -e # # Global variables # CURRENT_EXT="current" RCDIR=$HOME/.$PROGNAME main() { # # Option defaults # VERBOSELEVEL=2 # # Option processing # while [ "X$1" != X ]; do case $1 in -v|--verbose) VERBOSELEVEL=3 ;; -d) VERBOSELEVEL=$2; shift ;; --debug=*) VERBOSELEVEL=${1#*=} ;; -h|--help) usage 0 ;; # Any other option is handled within each individual function *) break ;; esac shift done # # Argument processing # debug 10 "main: argument processing" [ "X$1" != X ] || usage # better arg checking done on per-opmode basis OPMODE=$1 shift # # Sanity checks and derivations # debug 10 "main: sanity checks and derivations ..." case $OPMODE in initialise|config|upstream|create|insert|insertsrc|update|freeze|list|avail|unavail|apache|apt) : ;; *) usage ;; esac # # Guts start here # debug 10 "main: calling $OPMODE() ..." # Very important umask 022 $OPMODE "$@" } usage() { local RC RC=${1:-1} { echo "Usage: $PROGNAME [ ] initialise" echo " $PROGNAME [ ] config" echo " $PROGNAME [ ] upstream --repos=,..." echo " $PROGNAME [ ] create --repo-dirs=,..." echo " $PROGNAME [ ] insert [ --repos=,... ] ..." echo " $PROGNAME [ ] insertsrc [ --repos=,... ] ..." echo " $PROGNAME [ ] update [ --repos=,... ]" echo " $PROGNAME [ ] freeze [ --repos=,... ]" echo " $PROGNAME [ ] list [ --repos=,... ] [ --hosts=,... ]" echo " $PROGNAME [ ] avail [ --repos=,... ] --hosts=,..." echo " $PROGNAME [ ] unavail [ --repos=,... ] --hosts=,..." echo " $PROGNAME [ ] apache [ --repos=,... ] --hosts=,..." echo " $PROGNAME [ ] apt [ --repos=,... ] --hosts=,..." echo echo "Options: -v | --verbose be verbose" echo " -d | --debug= be very verbose" echo " -h | --help show this text" } | if [ $RC == 0 ]; then cat else cat >&2 fi exit $RC } initialise() { # Defaults for directive-specific options # Process directive-specific options while [ "X$1" != X ]; do case $1 in --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations # Guts [ ! -f $RCDIR/general ] || error "it looks like you've already run in initialise mode" mkdir -p $RCDIR { echo "# This file was generated automatically on $(date)" echo echo "# Setting: MIRRORS_ROOT " echo "# Scope: only needed on machines which will update the mirrors" echo "# Example: /pub/mirrors" echo "#MIRRORS_ROOT=/pub/mirrors" echo echo "# Setting: PAACRT_ROOT" echo "# Scope: needed for all operations except updating the mirrors" echo "# Example: /pub/paacrt" echo "#PAACRT_ROOT=/pub/paacrt" echo echo "# Setting: PAACRT_URL" echo "# Scope: needed on all install clients" echo "# Example: http://www.pasta.net/, file:///mnt/" echo "#PAACRT_URL=http://www.pasta.net/" echo } > $RCDIR/general warning "$RCDIR/general: MIRRORS_ROOT, PAACRT_ROOT and PAACRT_URL are undefined; no operations will not be possible until you have set it" } config() { # Defaults for directive-specific options # Process directive-specific options while [ "X$1" != X ]; do case $1 in --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations # Guts assign_var_from_rc_file $RCDIR/general MIRRORS_ROOT assign_var_from_rc_file $RCDIR/general PAACRT_ROOT assign_var_from_rc_file $RCDIR/general PAACRT_URL echo "Mirrors-Root=$MIRRORS_ROOT" echo "Paacrt-Root=$PAACRT_ROOT" echo "Paacrt-Url=$PAACRT_URL" } upstream() { local REPO CPU DIST SECTIONS # Defaults for directive-specific options OPT_REPOS= # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations for REPO in $OPT_REPOS; do [ ! -f $RCDIR/$REPO ] || error "$REPO: upstream repository already registered" done # Guts for REPO in $OPT_REPOS; do # There are a couple of code blocks like this in this file { echo "# This file was generated automatically on $(date)" echo echo "# Setting: DOWNLOAD_CMD" echo "# Scope: only needed on PAACRT server" echo "# Notes: this command will be invoked with: sh -c \"\$DOWNLOAD_CMD\" dummy " echo "# Example: debmirror --ignore-release-gpg --getcontents --nosource --method=rsync --host=ftp2.de.debian.org --root=:debian --arch=i386 --dist=squeeze \"\$1\"" echo "#DOWNLOAD_CMD='debmirror --ignore-release-gpg --getcontents --nosource --method=rsync --host=ftp2.de.debian.org --root=:debian --arch=i386 --dist=squeeze \"\$1\"'" echo echo "# Setting: SECTIONS" echo "# Scope: only needed on PAACRT server" echo "# Example: main non-free contrib" echo "#SECTIONS=\"main non-free contrib\"" echo echo "# Setting: CPU" echo "# Scope: only needed on PAACRT server" echo "# Example: i386" echo "#CPU=i386" echo echo "# Setting: DIST" echo "# Scope: only needed on PAACRT server" echo "# Example: lenny" echo "#DIST=lenny" echo echo "# The settings below should not be changed." echo "REPOSITORY_IS_LOCAL=\"false\"" } > $RCDIR/$REPO warning "$RCDIR/$REPO: DOWNLOAD_CMD, SECTIONS, CPU and dist are undefined; updates will not be possible until you have set them" done } create() { local REPO LOCAL_REPO_ROOT LOCAL_REPO_ORIGIN LOCAL_REPO_LABEL LOCAL_REPO_SIGNER_LOGNAME LOCAL_REPO_SUITE CPU DIST SECTIONS SECTION # Defaults for directive-specific options OPT_REPODIRS= # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repo-dirs=*) OPT_REPODIRS=${1#*=} OPT_REPODIRS=${OPT_REPODIRS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations SECTIONS=main LOCAL_REPO_ORIGIN="$(getent passwd $LOGNAME | cut -f5 -d: | cut -f1 -d,)" LOCAL_REPO_LABEL="$LOCAL_REPO_ORIGIN" LOCAL_REPO_SIGNER_LOGNAME=$LOGNAME LOCAL_REPO_SUITE=testing for LOCAL_REPO_ROOT in $OPT_REPODIRS; do REPO=${LOCAL_REPO_ROOT##*/} [ ! -f $RCDIR/$REPO ] || error "$REPO: repository configuration file exists already" [ "X$SECTIONS" = Xmain ] || error "$REPO: local repositories should define *only* a 'main' section" [ ! -e $LOCAL_REPO_ROOT ] || error "$REPO: directory hierarchy $LOCAL_REPO_ROOT exists already" done # Guts debug 10 "create: creating local package archive ..." for LOCAL_REPO_ROOT in $OPT_REPODIRS; do for SECTION in $SECTIONS; do mkdir -p $LOCAL_REPO_ROOT/{pool,sources} done REPO=${LOCAL_REPO_ROOT##*/} # There are a couple of code blocks like this in this file { echo "# This file was generated automatically on $(date)" echo echo "# Setting: CPU " echo "# Scope: required on the machine where DEBs will be inserted" echo "# Example: i386" echo "#CPU=\"i386\"" echo echo "# Setting: DIST " echo "# Scope: required on the machine where DEBs will be inserted" echo "# Example: lenny" echo "#DIST=\"lenny\"" echo echo "# The settings below should not be changed." echo "REPOSITORY_IS_LOCAL=\"true\"" echo "LOCAL_REPO_ROOT=\"$LOCAL_REPO_ROOT\"" echo "LOCAL_REPO_ORIGIN=\"$LOCAL_REPO_ORIGIN\"" echo "LOCAL_REPO_LABEL=\"$LOCAL_REPO_LABEL\"" echo "LOCAL_REPO_SIGNER_LOGNAME=\"$LOCAL_REPO_SIGNER_LOGNAME\"" echo "LOCAL_REPO_SUITE=\"$LOCAL_REPO_SUITE\"" echo "SECTIONS=\"$SECTIONS\"" } > $RCDIR/$REPO warning "$RCDIR/$REPO: CPU and DIST are undefined; inserts will not be possible until you have set them" done } insert() { local REPO LOCAL_REPO_ROOT LOCAL_REPO_ORIGIN LOCAL_REPO_LABEL LOCAL_REPO_SIGNER_LOGNAME LOCAL_REPO_SUITE CPU DIST SECTIONS SECTION DEBS DEB OPT_REPOS # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# -ge 1 ] || usage DEBS="$@" # Sanity checks and derivations for DEB in $DEBS; do [ -f $DEB -a -r $DEB ] || error "$DEB: not accessible" done [ "X$GPG_AGENT_INFO" != X ] || error "gpg-agent: not running (do you need to run 'eval \`gpg-agent --daemon\`'?)" for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a remote repository; skipping (are you doing updates and inserts with the same account?)"; continue; } assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ORIGIN assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_LABEL assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SIGNER_LOGNAME assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SUITE assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ROOT assign_var_from_rc_file $RCDIR/$REPO CPU assign_var_from_rc_file $RCDIR/$REPO DIST assign_var_from_rc_file $RCDIR/$REPO SECTIONS [ "X$LOGNAME" = "X$LOCAL_REPO_SIGNER_LOGNAME" ] || error "only $LOCAL_REPO_SIGNER_LOGNAME can sign the local pool after inserting debs" $REPOSITORY_IS_LOCAL || error "$LOCAL_REPO_ROOT: doesn't look like a repository" [ "X$SECTIONS" = Xmain ] || error "$REPO: local repositories should define *only* a 'main' section" [ -d "$LOCAL_REPO_ROOT" ] || error "$LOCAL_REPO_ROOT: directory not accessible" done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for inserts to remote repos is in the sanity checks above; here we skip silently. $REPOSITORY_IS_LOCAL || continue assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ORIGIN assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_LABEL assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SIGNER_LOGNAME assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SUITE assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ROOT assign_var_from_rc_file $RCDIR/$REPO CPU assign_var_from_rc_file $RCDIR/$REPO DIST assign_var_from_rc_file $RCDIR/$REPO SECTIONS for DEB in $DEBS; do cp $DEB $LOCAL_REPO_ROOT/pool/ chmod 644 $LOCAL_REPO_ROOT/pool/$(basename $DEB) done # Regenerate the control files for this repo regenerate_dist_files done } insertsrc() { local REPO LOCAL_REPO_ROOT LOCAL_REPO_ORIGIN LOCAL_REPO_LABEL LOCAL_REPO_SIGNER_LOGNAME LOCAL_REPO_SUITE CPU DIST SECTIONS SECTION CHANGES CHANGE # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# -ge 1 ] || usage CHANGES="$@" # Sanity checks and derivations for CHANGE in $CHANGES; do for FILE in $(echo ${CHANGE%_i386.changes}{.tar.gz,.dsc,\_i386.changes}); do debug 10 "insertsrc: $FILE: validating source component ..." [ -f $FILE -a -r $FILE ] || error "$FILE: not accessible" done done for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a remote repository; skipping (are you doing updates and inserts with the same account?)"; continue; } assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ORIGIN assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_LABEL assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SIGNER_LOGNAME assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SUITE assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ROOT assign_var_from_rc_file $RCDIR/$REPO CPU assign_var_from_rc_file $RCDIR/$REPO DIST assign_var_from_rc_file $RCDIR/$REPO SECTIONS $REPOSITORY_IS_LOCAL || error "$LOCAL_REPO_ROOT: doesn't look like a repository" [ "X$SECTIONS" = Xmain ] || error "$REPO: local repositories should define *only* a 'main' section" [ -d "$LOCAL_REPO_ROOT" ] || error "$LOCAL_REPO_ROOT: directory not accessible" done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for inserts to remote repos is in the sanity checks above; here we skip silently. $REPOSITORY_IS_LOCAL || continue assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ORIGIN assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_LABEL assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SIGNER_LOGNAME assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_SUITE assign_var_from_rc_file $RCDIR/$REPO LOCAL_REPO_ROOT assign_var_from_rc_file $RCDIR/$REPO CPU assign_var_from_rc_file $RCDIR/$REPO DIST assign_var_from_rc_file $RCDIR/$REPO SECTIONS for CHANGE in $CHANGES; do for FILE in $(echo ${CHANGE%_i386.changes}{.tar.gz,.dsc,\_i386.changes}); do debug 10 "insertsrc: $FILE: inserting source component ..." cp $FILE $LOCAL_REPO_ROOT/sources/ chmod 644 $LOCAL_REPO_ROOT/sources/$FILE done done done } update() { local REPO DOWNLOAD_CMD DOWNLOAD_DIR OPT_REPOS # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations assign_var_from_rc_file $RCDIR/general MIRRORS_ROOT for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL ! $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a local repository; skipping (are you doing updates and inserts with the same account?)"; continue; } done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for updates to remote repos is in the sanity checks above; here we skip silently. ! $REPOSITORY_IS_LOCAL || continue assign_var_from_rc_file $RCDIR/$REPO DOWNLOAD_CMD DOWNLOAD_DIR="$MIRRORS_ROOT/$REPO.$CURRENT_EXT" mkdir -p $DOWNLOAD_DIR info "$REPO: updating ..." sh -c "$DOWNLOAD_CMD" dummy "$DOWNLOAD_DIR" done } freeze() { local REPO SNAPSHOT_EXT # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations assign_var_from_rc_file $RCDIR/general MIRRORS_ROOT assign_var_from_rc_file $RCDIR/general PAACRT_ROOT SNAPSHOT_EXT=$(date '+%Y%m%d') for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL ! $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a local repository; skipping (are you doing updates and inserts with the same account?)"; continue; } [ -d $MIRRORS_ROOT/$REPO.$CURRENT_EXT ] || error "$MIRRORS_ROOT/$REPO.$CURRENT_EXT: no such directory" # Don't test that $PAACRT_ROOT exists; we'll create it in a minute #[ -d $PAACRT_ROOT ] || error "$PAACRT_ROOT: no such directory" done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for updates to remote repos is in the sanity checks above; here we skip silently. ! $REPOSITORY_IS_LOCAL || continue info "cloning $MIRRORS_ROOT/$REPO.$CURRENT_EXT to $PAACRT_ROOT/$REPO.$SNAPSHOT_EXT ..." mkdir -p $PAACRT_ROOT/$REPO.$SNAPSHOT_EXT rsync -a --delete $MIRRORS_ROOT/$REPO.$CURRENT_EXT/ $PAACRT_ROOT/$REPO.$SNAPSHOT_EXT/ find $PAACRT_ROOT/$REPO.$SNAPSHOT_EXT/ -type d -exec chmod 755 {} \; find $PAACRT_ROOT/$REPO.$SNAPSHOT_EXT/ -type f -exec chmod 644 {} \; done echo "Tag: $SNAPSHOT_EXT" } list() { local REPO REPOS SNAPSHOT_EXT X Y OPT_LONG OPT_REPOS OPT_HOSTS # Defaults for directive-specific options OPT_LONG=false OPT_REPOS=$(get_all_repos) OPT_HOSTS= # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --hosts=*) OPT_HOSTS=${1#*=} OPT_HOSTS=${OPT_HOSTS//,/ } ;; --long) OPT_LONG=true ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations assign_var_from_rc_file $RCDIR/general PAACRT_ROOT assign_var_from_rc_file $RCDIR/general MIRRORS_ROOT # for REPO in $OPT_REPOS; do # assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # ! $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a local repository; skipping (are you doing updates and inserts with the same account?)"; continue; } # done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for updates to remote repos is in the sanity checks above; here we skip silently. #! $REPOSITORY_IS_LOCAL || continue if ! $OPT_LONG; then echo "$REPO" else [ -d $MIRRORS_ROOT/$REPO.$CURRENT_EXT ] || error "$MIRRORS_ROOT/$REPO.$CURRENT_EXT: no such directory" REPOLINE=$(printf "%-20s " "$REPO") PRINTREPOLINE=false for X in $(ls -d $PAACRT_ROOT/$REPO.* 2>/dev/null || true); do # Repositories are non-symlinks or symlinks ending .current. Anything else # is a host symlink and not what we want to be looking for in this outer # repo-finding loop. [ ! -h $X ] || [[ $X =~ \.current$ ]] || continue # Display the name of the repo and in brackets ... FREEZEWORD="${X##$PAACRT_ROOT/$REPO.}(" PRINTFREEZEWORD=false # ... the names of any symlinks which point to the repo FIRST_LOOP=true for Y in $(ls -d $PAACRT_ROOT/$REPO.* 2>/dev/null || true); do # Only consider host symlinks pointing to freezes { [ -h $Y ] && [ $(readlink $Y) = $(basename $X) ]; } || continue # Extract hostname out of symlink HOSTWORD=${Y##$PAACRT_ROOT/$REPO.} # Only consider host symlinks matching what '--hosts' option specified. if [ "X$OPT_HOSTS" = X ]; then : else MATCH=false for HOST in $OPT_HOSTS; do [ $HOST != $HOSTWORD ] || { MATCH=true; break; } done $MATCH || continue fi $FIRST_LOOP || FREEZEWORD+=", " FREEZEWORD+=$HOSTWORD PRINTFREEZEWORD=true FIRST_LOOP=false done FREEZEWORD+=") " # This one line is to get repo freezes with no hosts printed when we didn't restrict the hosts [ "X$OPT_HOSTS" != X ] || PRINTFREEZEWORD=true ! $PRINTFREEZEWORD || { PRINTREPOLINE=true; REPOLINE+=$FREEZEWORD; } done ! $PRINTREPOLINE || echo "$REPOLINE" fi done } avail() { local REPO HOST SNAPSHOT_EXT # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) OPT_HOSTS= # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --hosts=*) OPT_HOSTS=${1#*=} OPT_HOSTS=${OPT_HOSTS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 1 ] || usage SNAPSHOT_EXT=$1 # Sanity checks and derivations assign_var_from_rc_file $RCDIR/general PAACRT_ROOT [ "X$OPT_HOSTS" != X ] || usage for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL ! $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a local repository; skipping (are you doing updates and inserts with the same account?)"; continue; } [ -d $PAACRT_ROOT/$REPO.$SNAPSHOT_EXT ] || error "$PAACRT_ROOT/$REPO.$SNAPSHOT_EXT: no such directory" for HOST in $OPT_HOSTS; do [ ! -e $PAACRT_ROOT/$REPO.$HOST -o -h $PAACRT_ROOT/$REPO.$HOST ] || error "$PAACRT_ROOT/$REPO.$HOST: won't delete what was expected to be a symlink" done done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for updates to remote repos is in the sanity checks above; here we skip silently. ! $REPOSITORY_IS_LOCAL || continue for HOST in $OPT_HOSTS; do # Above checks ensure either does not exist or is symlink so we can safely blindly remove it. rm -f $PAACRT_ROOT/$REPO.$HOST ln -s $REPO.$SNAPSHOT_EXT $PAACRT_ROOT/$REPO.$HOST done done } unavail() { local REPO HOST SNAPSHOT_EXT # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) OPT_HOSTS= # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --hosts=*) OPT_HOSTS=${1#*=} OPT_HOSTS=${OPT_HOSTS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations assign_var_from_rc_file $RCDIR/general PAACRT_ROOT [ "X$OPT_HOSTS" != X ] || usage for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL ! $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a local repository; skipping (are you doing updates and inserts with the same account?)"; continue; } for HOST in $OPT_HOSTS; do [ -h $PAACRT_ROOT/$REPO.$HOST ] || [ ! -e $PAACRT_ROOT/$REPO.$HOST ] || error "$PAACRT_ROOT/$REPO.$HOST: no such directory" done done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for updates to remote repos is in the sanity checks above; here we skip silently. ! $REPOSITORY_IS_LOCAL || continue for HOST in $OPT_HOSTS; do rm -f $PAACRT_ROOT/$REPO.$HOST done done } apache() { local REPO REPOS HOST PAACRT_URL_PATHCMPNT MISSING_REPO_IS_ERROR_FLAG # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) OPT_HOSTS= # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --hosts=*) OPT_HOSTS=${1#*=} OPT_HOSTS=${OPT_HOSTS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations assign_var_from_rc_file $RCDIR/general PAACRT_ROOT assign_var_from_rc_file $RCDIR/general PAACRT_URL [ "X$OPT_HOSTS" != X ] || usage for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL ! $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a local repository; skipping (are you doing updates and inserts with the same account?)"; continue; } for HOST in $OPT_HOSTS; do [ -d $PAACRT_ROOT/$REPO.$HOST ] || error "$PAACRT_ROOT/$REPO.$HOST: no such directory" done done # Guts for REPO in $OPT_REPOS; do assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for updates to remote repos is in the sanity checks above; here we skip silently. ! $REPOSITORY_IS_LOCAL || continue for HOST in $OPT_HOSTS; do # Extract the path component of the PAACRT URL to put at the beginning of the PAACRT_URL_PATHCMPNT=/${PAACRT_URL#http://*/} # Strip trailing slash if present 'cos we'll add again in a sec. PAACRT_URL_PATHCMPNT=${PAACRT_URL_PATHCMPNT%/} # Output the apache config stanza for this repo echo " Alias $PAACRT_URL_PATHCMPNT/$REPO.$HOST/ \"$PAACRT_ROOT/$REPO.$HOST/\"" echo " " echo " Options Indexes FollowSymLinks MultiViews" echo " AllowOverride None" echo " Order allow,deny" echo " Allow from 192.168.0.0/255.255.0.0" echo " " echo done done } apt() { local REPO HOST SECTIONS DIST SECTIONS MISSING_REPO_IS_ERROR_FLAG REPOS # Defaults for directive-specific options OPT_REPOS=$(get_all_repos) OPT_HOSTS= # Process directive-specific options while [ "X$1" != X ]; do case $1 in --repos=*) OPT_REPOS=${1#*=} OPT_REPOS=${OPT_REPOS//,/ } ;; --hosts=*) OPT_HOSTS=${1#*=} OPT_HOSTS=${OPT_HOSTS//,/ } ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process directive-specific arguments [ $# = 0 ] || usage # Sanity checks and derivations assign_var_from_rc_file $RCDIR/general PAACRT_ROOT assign_var_from_rc_file $RCDIR/general PAACRT_URL # for REPO in $OPT_REPOS; do # assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # ! $REPOSITORY_IS_LOCAL || { warning "$REPO: this is a local repository; skipping (are you doing updates and inserts with the same account?)"; continue; } # for HOST in $OPT_HOSTS; do # assign_var_from_rc_file $RCDIR/$REPO DIST # assign_var_from_rc_file $RCDIR/$REPO SECTIONS # [ -d $PAACRT_ROOT/$REPO.$HOST ] || error "$PAACRT_ROOT/$REPO.$HOST: no such directory" # done # done # Guts for REPO in $OPT_REPOS; do #assign_var_from_rc_file $RCDIR/$REPO REPOSITORY_IS_LOCAL # Raising a warning for updates to remote repos is in the sanity checks above; here we skip silently. #! $REPOSITORY_IS_LOCAL || continue for HOST in $OPT_HOSTS; do assign_var_from_rc_file $RCDIR/$REPO DIST assign_var_from_rc_file $RCDIR/$REPO SECTIONS info "for remote access" echo "deb ${PAACRT_URL%/}/$REPO.$HOST/ $DIST $SECTIONS" info "for local access" echo "deb file://${PAACRT_ROOT%/}/$REPO.$HOST/ $DIST $SECTIONS" done done } assign_var_from_rc_file() { local RCFILE VARREF VALUE RCFILE=$1 VARREF=$2 debug 10 "assign_var_from_rc_file: RCFILE=$RCFILE" [ -f $RCFILE ] || error "$RCFILE: not accessible" VALUE="$(sh -c ". $RCFILE; echo \$$VARREF")" debug 10 "assign_var_from_rc_file: VALUE=$VALUE" [ "X$VALUE" != X ] || error "$RCFILE: doesn't define $VARREF" eval "$VARREF=\"\$VALUE\"" } get_all_repos() { ls $RCDIR/ | grep -v general | paste -s -d' ' } regenerate_dist_files() { # We don't pass parameters to this function (yet), but the variable names it uses to # refer to the various things it needs are the same as the caller and as functions # are scoped *within* the parent call, this should be ok. Still, we check that the # stuff we'll use is set. for VAR in SECTIONS LOCAL_REPO_ROOT CPU DIST LOCAL_REPO_ORIGIN LOCAL_REPO_LABEL LOCAL_REPO_SUITE; do eval "[ \"X\$$VAR\" != X ]" || internal "regenerate_dist_files: $VAR: undefined" done for SECTION in $SECTIONS; do info "regenerating Packages ..." ( cd $LOCAL_REPO_ROOT mkdir -p dists/$DIST/$SECTION/binary-$CPU dpkg-scanpackages -m pool /dev/null > dists/$DIST/$SECTION/binary-$CPU/Packages chmod a+r dists/$DIST/$SECTION/binary-$CPU/Packages ) info "regenerating Packages.gz ..." ( cd $LOCAL_REPO_ROOT mkdir -p dists/$DIST/$SECTION/binary-$CPU gzip -c dists/$DIST/$SECTION/binary-$CPU/Packages > dists/$DIST/$SECTION/binary-$CPU/Packages.gz chmod a+r dists/$DIST/$SECTION/binary-$CPU/Packages.gz ) done info "regenerating Contents-$CPU.gz ..." ( cd $LOCAL_REPO_ROOT mkdir -p dists/$DIST apt-ftparchive contents pool | gzip > dists/$DIST/Contents-$CPU.gz chmod a+r dists/$DIST/Contents-$CPU.gz ) info "regenerating Release ..." ( cd $LOCAL_REPO_ROOT mkdir -p dists/$DIST apt-ftparchive release -o APT::FTPArchive::Release::Origin="$LOCAL_REPO_ORIGIN" -o APT::FTPArchive::Release::Label="$LOCAL_REPO_LABEL" -o APT::FTPArchive::Release::Components="$SECTIONS" -o APT::FTPArchive::Release::Suite=$LOCAL_REPO_SUITE -o APT::FTPArchive::Release::Codename=$DIST -o APT::FTPArchive::Release::Architectures=$CPU dists/$DIST > dists/$DIST/Release chmod a+r dists/$DIST/Release ) info "regenerating Release.gpg ..." ( cd $LOCAL_REPO_ROOT rm -f dists/$DIST/Release.gpg debug 10 "insert: generating Release.gpg ..." if [ "X$GPG_AGENT_INFO" != X ]; then GPG_AGENT_OPT="--use-agent" else GPG_AGENT_OPT="--no-use-agent" fi gpg $GPG_AGENT_OPT -abs -o dists/$DIST/Release.gpg dists/$DIST/Release debug 10 "insert: generated Release.gpg" chmod a+r dists/$DIST/Release.gpg ) } # Messaging functions debug() { [ $VERBOSELEVEL -lt $1 ] || echo "$PROGNAME: DEBUG[$1]: $2" >&2; } info() { [ $VERBOSELEVEL -lt 3 ] || echo "$PROGNAME: INFO: $1" >&2; } warning() { [ $VERBOSELEVEL -lt 2 ] || echo "$PROGNAME: WARNING: $1" >&2; } error() { [ $VERBOSELEVEL -lt 1 ] || echo "$PROGNAME: ERROR: $1" >&2; exit 1; } internal() { echo "$PROGNAME: INTERNAL ERROR: $1" >&2; exit 2; } main "$@"