# # autodist repositories maintainance script # Copyright (c) 2007-2024 by Silvan Calarco # . /etc/autodist/config [ -r /etc/autodist/config-secret ] && . /etc/autodist/config-secret basearch=i586 me=${0##*/} function usage() { echo "autodist repositories maintainance script" echo "Copyright (c) 2007-2014 by Silvan Calarco" echo echo "Usage:" echo "$me archive REPOSITORY PKGS ..." echo "$me diff REPOSITORY [PKGS ...] [-d REPOSITORY]" echo "$me distromatic REPOSITORY" echo "$me install REPOSITORY [PKGS ...] [-f]" echo "$me import REPOSITORY [PKGS ...] [-d REPOSITORY] [-s] [-y]" echo "$me inspect REPOSITORY {PKGS ...} [-d REPOSITORY]" echo "$me list" echo "$me query REPOSITORY PKGS ..." echo "$me release REPOSITORY [PKGS ...] [-d REPOSITORY] [-s] [-y]" echo "$me restore REPOSITORY PKGS ..." echo "$me search [-i] [-r regexp] STRING" echo "$me setwarning REPOSITORY {PKG ...} -t \"TEXT\"" echo "$me verify REPOSITORY [PKGS ...]" echo echo " -d use given repository as destination (default: base)" echo " -f force operation" echo " -r match repositories with given regexp" echo " -s simulate operations to see if it would work" echo " -t warning text" echo " -y assume yes to all questions (be careful!)" } function get_packages_from_last_build() { local rep=$1 [ "$rep" ] || return [ -r $SRCPKGLIST ] || { echo "ERROR: srcpkglist file missing for $origrepository repository; aborting." >&2 exit 200 } tmpfile=`mktemp` packages=() cat $SRCPKGLIST | sort -k3 -r > $tmpfile while read line; do set -- $line [ "$4" = "$rep" ] && packages=(${packages[*]} $1) done < $tmpfile rm -f $tmpfile } # get_pkg_srcinfo - search using srcpkginfo file to find source when no builds exist # # $1: repository name # $2: pkg name get_pkg_srcinfo() { local rep pkg line [ $1 ] && rep=$1 || exit 200 [ $2 ] && pkg=$2 || exit 200 unset pkg_archs pkg_name pkg_version pkg_release line=`grep "^$pkg " $SRCPKGLIST` [ "$line" ] || return set -- $line [ "$4" = "$rep" ] || return pkg_name=$1 pkg_arch= pkg_archs= pkg_version=$2 pkg_release=$6 pkg_repository=$4 pkg_buildtime=$3 } # get_pkg_buildinfo - uses distromatic generated build file for # getting information on the repository # # $1: repository name # $2: architecture # $3: pkg name function get_pkg_buildinfo() { local pkg i a [ $1 ] && rep=$1 || exit 200 [ $2 ] && buildarch=$2 || exit 200 [ $3 ] && pkg=$3 pkg_archs=(); for a in ${AUTODIST_ARCHS[*]}; do pkg_header=(); DISTROMATIC_BUILD_FILE=${LOCAL_REPS_BASE_DIR}/distromatic/$rep/builds-$a.sh [ -e $DISTROMATIC_BUILD_FILE ] && { . $DISTROMATIC_BUILD_FILE [ "$buildarch" = "any" -a "$pkg" = "" ] && buildarch=$a [ ${pkg_header[0]} ] && { pkg_archs=(${pkg_archs[*]} $a) [ "$buildarch" = "any" ] && buildarch=$a } } done pkg_header=(); pkg_builds=(); pkg_obsoletes=(); pkg_list=(); unset pkg_name pkg_arch pkg_version pkg_release \ pkg_group pkg_license pkg_size pkg_buildtime pkg_altrep pkg_repository if [ "$buildarch" = "any" ]; then # echo "ERROR: package $pkg does not exist in $rep; aborting." >&2 return; fi DISTROMATIC_BUILD_FILE=${LOCAL_REPS_BASE_DIR}/distromatic/$rep/builds-${buildarch}.sh if [ ! -e $DISTROMATIC_BUILD_FILE ]; then return; fi . $DISTROMATIC_BUILD_FILE for i in ${pkg_list[*]}; do if [ "$i" == "${pkg_header[0]}" ]; then pkg_name=${pkg_header[0]}; # Note: pkg_arch reported in builds file is just last arch source was # built for, so we use repository arch instead pkg_arch=${pkg_header[1]}; [ "$pkg_arch" = "noarch" ] || pkg_arch=$buildarch pkg_version=${pkg_header[2]}; pkg_release=${pkg_header[3]}; pkg_group=${pkg_header[4]}; pkg_license=${pkg_header[5]}; pkg_size=${pkg_header[6]}; pkg_buildtime=${pkg_header[7]}; pkg_altrep=${pkg_header[8]}; pkg_repository=${pkg_header[9]}; return 0 fi done return 0 } # get_pkg_info - uses distromatic generated build file to get packages information from the repository # # $1: repository name # $2: architecture # $3: pkg name function get_pkg_info() { local pkg buildarch rep line [ $1 ] && rep=$1 || exit 200 [ $2 ] && buildarch=$2 || exit 200 [ $3 ] && pkg=$3 || exit 200 [ -e ${PKGLIST}.$buildarch ] || { echo "ERROR: get_pkg_info: file ${PKGLIST}.$buildarch missing; aborting." exit 1 } line=`grep "^$pkg " ${PKGLIST}.$buildarch 2>/dev/null | tail -n1` set -- $line pkg_name=$1 pkg_version=$2 pkg_size=$3 pkg_unknown=$4 pkg_repository=$5 pkg_unknown2=$6 pkg_release=$7 pkg_arch=$buildarch return 0 } function import_file() { [ $1 ] || exit 200 local f import_mode f=$1 import_mode=$2 if [ "$import_mode" = "backup" ]; then curl_delete_add="-Q '-DELE $f'" else curl_delete_add="" fi [ "$simulate" = "1" ] && return if [ "$ORIG_MODE" = "remote" ]; then if [ $ORIG_URL_LOCAL_ARCH -a ! -f $ORIG_URL_LOCAL_ARCH/$f ]; then echo "WARNING: package missing in local mirror; setting copy from remote repository." >&2 fi if [ "$DEST_MODE" = "local" ]; then # remote -> local if [ $ORIG_URL_LOCAL_ARCH -a -f $ORIG_URL_LOCAL_ARCH/$f ]; then echo -n "(L) " # if file exists in a local mirror use it by preference cp $ORIG_URL_LOCAL_ARCH/$f $DEST_URL_ARCH/ || { echo "ERROR: cannot move file $ORIG_URL_LOCAL_ARCH/$f to $DEST_URL_ARCH/$f; aborting." >&2 exit 200 } #chown ftp$DEST_REPOSITORY:users $DEST_URL_ARCH/$f eval curl -s -u${AUTODIST_REPOSITORIES_REMOTE_FTPUSER}:${AUTODIST_REPOSITORIES_REMOTE_FTPPASS} $ORIG_URL_ARCH $curl_delete_add >/dev/null && { rm -f $ORIG_URL_LOCAL_ARCH/$f touch $ORIG_URL_LOCAL_ARCH } || { echo echo "WARNING: cannot delete remote file $ORIG_URL_ARCH/$f; you'll have to delete it." >&2 } else echo -n "(R) " curl -s -u${AUTODIST_REPOSITORIES_REMOTE_FTPUSER}:${AUTODIST_REPOSITORIES_REMOTE_FTPPASS} \ --get $ORIG_URL_ARCH/$f \ -o $DEST_URL_ARCH/$f $curl_delete_add || { echo echo "ERROR: cannot get file $ORIG_URL_ARCH/$f; aborting." >&2 exit 200 } fi else # remote -> remote echo "ERROR: remote to remote file import is not implemented yet; aborting." >&2 exit 200 fi else if [ "$DEST_MODE" = "local" ]; then # local -> local cp $ORIG_URL_ARCH/$f $DEST_URL_ARCH/ || { echo "ERROR: cannot copy file $ORIG_URL_ARCH/$f to $DEST_URL_ARCH/$f; aborting." >&2 exit 200 } #chown ftp$DEST_REPOSITORY:users $DEST_URL_ARCH/$f touch $DEST_URL_ARCH if [ "$import_mode" = "backup" ]; then rm -f $ORIG_URL_ARCH/$f || { echo "ERROR: cannot remove file $ORIG_URL_ARCH/$f; aborting." >&2 exit 200 } touch $ORIG_URL_ARCH fi else # local -> remote echo -n "(R) " curl -s -u${AUTODIST_REPOSITORIES_REMOTE_FTPUSER}:${AUTODIST_REPOSITORIES_REMOTE_FTPPASS} \ -T $ORIG_URL_ARCH/$f \ $DEST_URL_ARCH/ || { echo echo "ERROR: cannot send file $ORIG_URL_ARCH/$f; aborting." >&2 exit 200 } rm -f $ORIG_URL_ARCH/$f || { echo echo "WARNING: cannot delete local file $ORIG_URL_ARCH/$f; you'll have to delete it." >&2 } touch $ORIG_URL_ARCH fi fi } function backup_local_file() { [ $1 ] || return [ -e $LOCAL_BACKUP ] || mkdir -p $LOCAL_BACKUP movefiles=$1 #`find $DEST_URL_ARCH -maxdepth 1 -regex ".*/${pkgname}-[^-]*-[^-]*"` for m in $movefiles; do echo "backing up $m" if [ "$simulate" != "1" ]; then mv $m $LOCAL_BACKUP/ || { echo "ERROR: can't move $m to $LOCAL_BACKUP; aborting." >&2 exit 200 } touch `dirname $m` fi done } function backup_package() { local rep reg i [ "$1" ] || return [ "$2" ] && rep=$2 || rep=$destrepository [ "$3" ] && reg=$3 || reg=$DESTREGFILE archive_pkg=$1 get_pkg_buildinfo $rep any $archive_pkg if [ ! "$pkg_name" ]; then get_pkg_srcinfo $rep $archive_pkg if [ "$pkg_name" ]; then echo "WARNING: only source package has been found in repository" >&2 fi fi if [ "$pkg_name" ]; then LOCAL_BACKUP=$DEST_URL_LOCAL/$rep/old/${pkg_name}_${BACKUP_DATE} PKG_FILENAME="$pkg_name-$pkg_version-$pkg_release.src.rpm" if [ -f $DEST_URL_LOCAL/$rep/SRPMS.base/$PKG_FILENAME ]; then backup_local_file $DEST_URL_LOCAL/$rep/SRPMS.base/$PKG_FILENAME else echo "WARNING: package $PKG_FILENAME does not exist in local repository">&2 fi if [ "$simulate" != "1" -a "$DEST_MODE" = "remote" ]; then curl -s -u${AUTODIST_REPOSITORIES_REMOTE_FTPUSER}:${AUTODIST_REPOSITORIES_REMOTE_FTPPASS} $DEST_URL/$rep/SRPMS.base/ -Q "-DELE $PKG_FILENAME" >/dev/null || { echo "WARNING: cannot delete remote file $DEST_URL/$rep/SRPMS.base/$PKG_FILENAME; you'll have to delete it." >&2 } fi for a in ${pkg_archs[*]}; do get_pkg_buildinfo $rep $a $archive_pkg for i in ${pkg_builds[*]}; do PKG_FILENAME="$i-$pkg_version-$pkg_release.$pkg_arch.rpm" if [ -f $DEST_URL_LOCAL/$rep/RPMS.$a/$PKG_FILENAME ]; then backup_local_file $DEST_URL_LOCAL/$rep/RPMS.$a/$PKG_FILENAME else echo "WARNING: package $PKG_FILENAME does not exist in local repository" >&2 fi if [ "$simulate" != "1" -a "$DEST_MODE" = "remote" ]; then curl -s -u${AUTODIST_REPOSITORIES_REMOTE_FTPUSER}:${AUTODIST_REPOSITORIES_REMOTE_FTPPASS} $DEST_URL/$rep/RPMS.$a/ -Q "-DELE $PKG_FILENAME" >/dev/null || { echo "WARNING: cannot delete remote file $DEST_URL/$rep/RPMS.$pkg_arch/$PKG_FILENAME; you'll have to delete it." >&2 } fi done done # write register [ "$simulate" != "1" ] && { echo "`date +%Y%m%d%H%M` Package $pkg_name ($pkg_version-$pkg_release) archived" >> $reg # | \ # tee -a $ORIGREGFILE $DESTREGFILE >/dev/null # echo "`date +%Y%m%d%H%M` \"\" \"package $pkg_name ($pkg_version-$pkg_release) archived from $rep\"" >> $reg } else echo "WARNING: package $archive_pkg does not exists in $rep; skipping." >&2 fi } function restore_local_file() { [ $1 ] || return [ $2 ] || return [ $4 ] || return local restorefiles=$1 local backupprefix=$2 local ARCH=$3 local restorerepository=$4 #`find $DEST_URL_ARCH -maxdepth 1 -regex ".*/${pkgname}-[^-]*-[^-]*"` for r in $restorefiles; do [ "$ARCH" ] && restoredest=$DEST_URL_LOCAL/$restorerepository/RPMS.$ARCH/ || restoredest=$DEST_URL_LOCAL/$restorerepository/SRPMS.base/ echo "restoring $r to $restorerepository" if [ "$simulate" != "1" ]; then cp ${backupprefix}/$r $restoredest || { echo "ERROR: can't copy $p to $restoredest; aborting." >&2 exit 200 } touch $restoredest fi done } function restore_package() { local rep reg i [ "$1" ] || return [ "$2" ] && rep=$2 || rep=$destrepository [ "$3" ] && reg=$3 || reg=$DESTREGFILE restore_pkg=$1 get_pkg_buildinfo $rep any $restore_pkg if [ ! "$pkg_name" ]; then echo "Info: package $restore_pkg does not exists in $rep" fi LOCAL_RESTORE_PREFIX=$DEST_URL_LOCAL/$rep/old/${restore_pkg}_ local cnt=0 local RESTORE_NAMES=() ls ${LOCAL_RESTORE_PREFIX}* &>/dev/null && \ for f in ${LOCAL_RESTORE_PREFIX}*; do [ "$cnt" = 0 ] && echo "Available backups: " cnt=`expr $cnt + 1` RESTORE_NAMES=(${RESTORE_NAMES[*]} `echo ${f/*_/}`) echo "($cnt) ${RESTORE_NAMES[$cnt-1]}" done [ "$cnt" == "0" ] && { echo "Sorry, no backups availables for ${restore_pkg} in $rep" return } local ans=0 while [ $ans -le 0 2>/dev/null -o $ans -gt $cnt 2>/dev/null ]; do echo echo -n "Please select the entry to restore or press ENTER to skip (1-$cnt): " read ans [ "$ans" ] || return [ $ans -eq $ans 2>/dev/null ] || ans=0 done echo "Restoring: " for f in `ls ${LOCAL_RESTORE_PREFIX}${RESTORE_NAMES[$ans-1]}`; do echo -n "${f/*\/} " done echo echo -n "Ok to restore [y/N]? " read ans1 [ "$ans1" != "y" -a "$ans1" != "Y" ] && return for a in ${AUTODIST_ARCHS[*]}; do for f in `ls ${LOCAL_RESTORE_PREFIX}${RESTORE_NAMES[$ans-1]}/*.${a}.rpm 2>/dev/null`; do restore_local_file ${f/*\/} ${LOCAL_RESTORE_PREFIX}${RESTORE_NAMES[$ans-1]}/ $a $rep done done for f in `ls ${LOCAL_RESTORE_PREFIX}${RESTORE_NAMES[$ans-1]}/*.src.rpm 2>/dev/null`; do restore_local_file ${f/*\/} ${LOCAL_RESTORE_PREFIX}${RESTORE_NAMES[$ans-1]}/ "" $rep done # write register [ "$simulate" != "1" ] && { echo "`date +%Y%m%d%H%M` Package $restore_pkg restored" >> $reg } } function import_package() { [ $1 ] || exit 200 local import_pkg import_mode import_pkg=$1 import_mode=$2 # check for all architectures for a in ${AUTODIST_ARCHS[*]}; do # check release in dest repository get_pkg_buildinfo $destrepository $a $import_pkg [ "$pkg_name" ] && { dest_ver=$pkg_version dest_rel=$pkg_release get_pkg_buildinfo $origrepository $a $import_pkg [ "$pkg_name" ] || { for b in ${AUTODIST_ARCHS[*]}; do if [ "$b" != "$a" ]; then # Get upstream version in other architecture, then if same version -> merge get_pkg_buildinfo $origrepository $b $import_pkg fi [ "$pkg_name" ] && break done if [ "$dest_ver-$dest_rel" != "$pkg_version-$pkg_release" ]; then [ "$a" == "$basearch" -a "$force" != "1" ] && { echo "ERROR: package $import_pkg for $a does not exist in $origrepository and can't merge due to different versions; skipping." >&2 return 254 } if [ "$force" = "1" ]; then echo "WARNING: package $import_pkg for $a is missing in $origrepository but present in $destrepository." >&2 echo "Import forced. You will need to port package to the missing arch." >&2 else echo "ERROR: package $import_pkg for $a is missing in $origrepository. This would break package in $destrepository($a) repository." >&2 return 255 fi fi } } done # check release in dest repository get_pkg_buildinfo $destrepository any $import_pkg [ "$pkg_version" ] && { destpkgname="$pkg_name" destpkgversion="$pkg_version-$pkg_release" # destpkgarch="$pkg_arch" } || destpkgversion="none" get_pkg_buildinfo $origrepository any $import_pkg [ "$pkg_version" ] && { origpkgname="$pkg_name" origpkgversion="$pkg_version-$pkg_release" # origpkgarch="$pkg_arch" } || origpkgversion="none" [ $origpkgname ] || { echo "ERROR: package $import_pkg does not exist in $origrepository; aborting." >&2 exit 200 } DEST_URL_ARCH=$DEST_URL/$destrepository/SRPMS.base/ ORIG_URL_ARCH=$ORIG_URL/$origrepository/SRPMS.base/ ORIG_URL_LOCAL_ARCH=$ORIG_URL_LOCAL/$origrepository/SRPMS.base/ PKG_FILENAME="$origpkgname-$origpkgversion.src.rpm" [ "$ORIG_MODE" = "remote" ] && ORIG_FILELIST=`curl -s -l -u${AUTODIST_REPOSITORIES_REMOTE_FTPUSER}:${AUTODIST_REPOSITORIES_REMOTE_FTPPASS} --url $ORIG_URL_ARCH/` || ORIG_FILELIST=`ls $ORIG_URL_ARCH` check_existence=0; for i in $ORIG_FILELIST; do [ "$i" = "$PKG_FILENAME" ] && check_existence=1; done if [ $check_existence = 1 ]; then [ "$destpkgversion" = "$origpkgversion" ] && { echo "WARNING: same version of $origpkgname exists in destination" >&2 } if [ "$assume_yes" != "1" ]; then echo -n "Import $PKG_FILENAME $origpkgversion($origrepository) -> $destpkgversion($destrepository) [y/N]?" read ans fi [ "$assume_yes" = "1" -o "$ans" = "y" -o "$ans" = "Y" ] && { echo -n "Importing $PKG_FILENAME " import_file $PKG_FILENAME $import_mode get_pkg_buildinfo $origrepository any $import_pkg for a in ${pkg_archs[*]}; do get_pkg_buildinfo $origrepository $a $import_pkg for i in ${pkg_builds[*]}; do PKG_FILENAME="$i-$origpkgversion.$pkg_arch.rpm" DEST_URL_ARCH=$DEST_URL/$destrepository/RPMS.$a/ ORIG_URL_ARCH=$ORIG_URL/$origrepository/RPMS.$a/ ORIG_URL_LOCAL_ARCH=$ORIG_URL_LOCAL/$origrepository/RPMS.$a/ echo -n "$PKG_FILENAME " import_file $PKG_FILENAME $import_mode done done echo # write register [ "$simulate" != "1" ] && { echo "`date +%Y%m%d%H%M` Package $import_pkg ($origpkgversion -> $destpkgversion) imported from $origrepository to $destrepository" | \ tee -a $ORIGREGFILE $DESTREGFILE >/dev/null } # if [ "$import_mode" = "backup" ]; then # backup old stuff in destination repository [ "$destpkgversion" != "none" -a \ "$destpkgversion" != "$origpkgversion" ] && { backup_package $import_pkg $destrepository $DESTREGFILE } # remove distromatic extra files associated with this package [ -e ${LOCAL_REPS_BASE_DIR}/distromatic/$rep/warnings/$import_pkg.in ] && { rm -f ${LOCAL_REPS_BASE_DIR}/distromatic/$rep/warnings/$import_pkg.in || echo "WARNING: cannot remove file ${LOCAL_REPS_BASE_DIR}/distromatic/$rep/warnings/$import_pkg.in" >&2 } # fi # Sync new release with autodist-git [ "$AUTODIST_GIT_SYNC" != "" ] && autodist-git syncpkg ${import_pkg} #for i in ${pkg_obsoletes}; do # PKG_FILENAME="$i-$pkg_version-$pkg_release.$namearch.rpm" # DEST_URL_ARCH=$DEST_URL/$destrepository/RPMS.$namearch/$PKG_FILENAME # [ -e $DEST_URL_ARCH ] && echo "WARNING: obsoleted package $i exists" >&2 # backup_package $i $destrepository $DESTREGFILE # #echo rm $DEST_URL_ARCH #done } # ans = y else # check_existence != 1 echo "ERROR: $import_pkg reported by distromatic does no longer exist" >&2 return 253 fi return 0 } # FIXME: only works with basearch function extract_diffinfo() { PKG=$1 REP=$2 TMP=$3 local i get_pkg_buildinfo $REP $basearch $PKG if [ "$pkg_name" ]; then PKG_FILENAME="${LOCAL_REPS_BASE_DIR}/$REP/SRPMS.base/$pkg_name-$pkg_version-$pkg_release.src.rpm" [ -e "$PKG_FILENAME" ] || { echo "ERROR: package $PKG_FILENAME missing in $origrepository; skipping" >&2 return 1 } local filesize=`stat -c %s $PKG_FILENAME` [ $filesize -gt 1073741824 ] && { echo "WARNING: $PKG_FILENAME size of $filesize is more than 1GB; skipping" >&2 return 1 } rpm -qp $PKG_FILENAME --requires > $TMP/buildrequires autospec -q -x $PKG_FILENAME -F \*.spec --destdir $TMP >/dev/null || { echo "ERROR: could not extract specfile from $PKG_FILENAME; skipping package" >&2 return 1 } [ -e "$TMP_SPEC_DIR/$pkg_name.spec" ] || { SPEC_FOUND="`ls $TMP_SPEC_DIR/*.spec`" mv $SPEC_FOUND $TMP_SPEC_DIR/$pkg_name.spec echo "WARNING: specfile name should be $pkg_name.spec instead of ${SPEC_FOUND/*\//} in $REP repository" >&2 } > $TMP/requires > $TMP/provides for i in ${pkg_builds[*]}; do PKG_FILENAME="${LOCAL_REPS_BASE_DIR}/$REP/RPMS.$basearch/$i-$pkg_version-$pkg_release.$pkg_arch.rpm" [ -e "$PKG_FILENAME" ] || { echo "ERROR: package $PKG_FILENAME missing in $origrepository; skipping" >&2 return 1 } rpm -qp $PKG_FILENAME --requires >> $TMP/requires rpm -qp $PKG_FILENAME --provides >> $TMP/provides rpm -qlp $PKG_FILENAME >> $TMP/files done else #echo "WARNING: can't find package $PKG in $REP repository" >&2 return 1 fi return 0 } [ $1 ] || { usage; exit 0; } origrepository= destrepository=base packages= command= simulate=0 while [ "$1" ]; do case $1 in -d) destrepository=$2; shift ;; -r) searchrep=$2; shift ;; -s) simulate=1 ;; -t) shift warningtext="$@" break ;; -f) force=1 ;; -i) ignorecase=1 ;; -y) assume_yes=1 ;; *) if [ "$command" ]; then case "$command" in "import"|"release"|"query"|"verify"|"archive"|"restore"|"diff"|"inspect"|"install"|"setwarning"|"distromatic") [ "$origrepository" ] && packages="$packages $1" || origrepository=$1 ;; "search") [ "$searchstring" ] && { echo "ERROR: invalid option $1; aborting." >&2 exit 1 } searchstring="$1" ;; *) usage echo "ERROR: invalid option $1; aborting." >&2 exit 1 ;; esac else case "$1" in "import"|"release"|"query"|"verify"|"archive"|"restore"|"list"|"diff"|"inspect"|"install"|"setwarning"|"distromatic"|"search") command=$1 ;; *) usage echo "Errror: $1 is not a valid command; aborting." exit 1 ;; esac fi ;; esac shift done [ "$command" = "" ] && { usage; exit 0; } #[ "$command" = "list" ] && echo "Local repositories:" for a in ${AUTODIST_REPOSITORIES_LOCAL_REPS[*]}; do [ "$a" = "$destrepository" ] && DEST_MODE=local; [ "$a" = "$origrepository" ] && ORIG_MODE=local; [ "$command" = "list" ] && echo "$a" done #[ "$command" = "list" ] && echo "Remote repositories:" for a in ${AUTODIST_REPOSITORIES_REMOTE_REPS[*]}; do [ "$a" = "$destrepository" ] && DEST_MODE=remote; [ "$a" = "$origrepository" ] && ORIG_MODE=remote; [ "$command" = "list" ] && echo "$a" done [ "$command" = "list" ] && exit 0; [ "$command" = "search" ] && { [ "$ignorecase" ] && GREP_OPTS="-i" for rep in ${AUTODIST_REPOSITORIES_LOCAL_REPS[*]} ${AUTODIST_REPOSITORIES_REMOTE_REPS[*]}; do [[ "$rep" =~ "$searchrep" ]] || continue [ -r ${LOCAL_REPS_BASE_DIR}/$rep/SRPMS.base ] || continue ls --color=none ${LOCAL_REPS_BASE_DIR}/$rep/SRPMS.base | grep $GREP_OPTS "$searchstring" 2>/dev/null | \ while read PKGLINE; do [ "$PKGLINE" ] && { echo "$rep(source): ${PKGLINE/ *}" } done for a in ${AUTODIST_ARCHS[*]}; do [ -r ${LOCAL_REPS_BASE_DIR}/$rep/RPMS.$a ] || continue ls --color=none ${LOCAL_REPS_BASE_DIR}/$rep/RPMS.$a | grep $GREP_OPTS "$searchstring" 2>/dev/null | \ while read PKGLINE; do [ "$PKGLINE" ] && { echo "$rep($a): ${PKGLINE/ *}" } done done done exit 0 } [ "$origrepository" ] || { usage; exit 200; } SRCPKGLIST="${LOCAL_REPS_BASE_DIR}/$origrepository/srcpkglist" PKGLIST="${LOCAL_REPS_BASE_DIR}/$origrepository/pkglist" [ "$DEST_MODE" ] || { echo "ERROR: $destrepository is not a valid repository; aborting." >&2; exit 200; } [ "$ORIG_MODE" ] || { echo "ERROR: $origrepository is not a valid repository; aborting." >&2; exit 200; } [ "$DEST_MODE" = "remote" ] && { echo "Waring: destination is a remote repository; this is an EXPERIMENTAL feature."; } [ "$command" = "query" ] && { [ "$packages" ] || { usage; exit 1; } for i in $packages; do get_pkg_buildinfo $origrepository any $i if [ ! "$pkg_name" ]; then echo "$i: package not found in $origrepository repository" else for a in ${pkg_archs[*]}; do get_pkg_buildinfo $origrepository $a $i if [ "$pkg_name" ]; then echo "Repository:$origrepository($a)" echo "Name: $pkg_name" echo "BuildArch: $pkg_arch" echo "Version: $pkg_version" echo "Release: $pkg_release" echo "Group: $pkg_group" echo "License: $pkg_license" echo "Size: $pkg_size" echo "Builds: ${pkg_builds[*]}" echo "Obsoletes: ${pkg_obsoletes[*]}" echo fi done fi done exit 0; } [ "$command" = "verify" ] && { [ "$packages" ] || { get_pkg_buildinfo $origrepository any packages=${pkg_list[*]} } for i in $packages; do get_pkg_buildinfo $origrepository any $i if [ ! "$pkg_name" ]; then echo "$i: package not found in $origrepository repository" else PKG_FILENAME="$i-$pkg_version-$pkg_release.src.rpm" rpm2cpio ${LOCAL_REPS_BASE_DIR}/${origrepository}/SRPMS.base/$PKG_FILENAME &>/dev/null || { echo "WARNING: source package $PKG_FILENAME is empty or corrupted." >&2 } for a in ${AUTODIST_ARCHS[*]}; do get_pkg_buildinfo $origrepository $a $i if [ "$pkg_name" ]; then for l in ${pkg_builds[*]}; do PKG_FILENAME="$l-$pkg_version-$pkg_release.$pkg_arch.rpm" rpm2cpio ${LOCAL_REPS_BASE_DIR}/${origrepository}/RPMS.$a/$PKG_FILENAME &>/dev/null || { echo "WARNING: package $PKG_FILENAME($a) is empty or corrupted." >&2 } done fi done fi done exit 0; } [ "$command" = "diff" ] && { [ "$packages" ] || { get_pkg_buildinfo $origrepository any packages=${pkg_list[*]} } TMP_SPEC_DIR=`mktemp -d --tmpdir=/dev/shm` for i in $packages; do echo echo "*******************************************************************" echo "$i package check:" echo "*******************************************************************" extract_diffinfo $i $origrepository $TMP_SPEC_DIR || continue [ -e $TMP_SPEC_DIR/$i.spec ] || { echo "ERROR: could not extract specfile for $i in $origrepository repository; skipping" >&2 continue } mv $TMP_SPEC_DIR/$i.spec $TMP_SPEC_DIR/$i.spec.origrep mv $TMP_SPEC_DIR/files $TMP_SPEC_DIR/files.origrep sort -u $TMP_SPEC_DIR/buildrequires > $TMP_SPEC_DIR/buildrequires.origrep sort -u $TMP_SPEC_DIR/requires > $TMP_SPEC_DIR/requires.origrep sort -u $TMP_SPEC_DIR/provides > $TMP_SPEC_DIR/provides.origrep extract_diffinfo $i $destrepository $TMP_SPEC_DIR || { echo "Looks like a new package; inspecting data:" echo "" echo "SPECFILE:" echo "=========" cat $TMP_SPEC_DIR/$i.spec.origrep echo "" echo "REQUIRES:" echo "=========" cat $TMP_SPEC_DIR/requires.origrep echo "" echo "PROVIDES:" echo "=========" cat $TMP_SPEC_DIR/provides.origrep echo "" echo "FILES:" echo "======" cat $TMP_SPEC_DIR/files.origrep continue } [ -e $TMP_SPEC_DIR/$i.spec ] || { echo "ERROR: could not extract specfile for $i in $destrepository repository; skipping" >&2 } mv $TMP_SPEC_DIR/$i.spec $TMP_SPEC_DIR/$i.spec.destrep mv $TMP_SPEC_DIR/files $TMP_SPEC_DIR/files.destrep sort -u $TMP_SPEC_DIR/buildrequires > $TMP_SPEC_DIR/buildrequires.destrep sort -u $TMP_SPEC_DIR/requires > $TMP_SPEC_DIR/requires.destrep sort -u $TMP_SPEC_DIR/provides > $TMP_SPEC_DIR/provides.destrep echo "Showing differences between package version in $origrepository and $destrepository:" echo "" echo "SPECFILE:" echo "=========" diff -u $TMP_SPEC_DIR/$i.spec.destrep $TMP_SPEC_DIR/$i.spec.origrep echo "" echo "BUILDREQUIRES:" echo "==============" diff -u $TMP_SPEC_DIR/buildrequires.destrep $TMP_SPEC_DIR/buildrequires.origrep echo "" echo "REQUIRES:" echo "=========" diff -u $TMP_SPEC_DIR/requires.destrep $TMP_SPEC_DIR/requires.origrep echo "" echo "PROVIDES:" echo "=========" diff -u $TMP_SPEC_DIR/provides.destrep $TMP_SPEC_DIR/provides.origrep echo "" echo "FILES:" echo "======" diff -u $TMP_SPEC_DIR/files.destrep $TMP_SPEC_DIR/files.origrep echo done rm -rf $TMP_SPEC_DIR exit 0; } [ "$command" = "setwarning" ] && { [ "$packages" ] || { usage; exit 1; } TMP_SPEC_DIR=`mktemp -d` for i in $packages; do extract_diffinfo $i $origrepository $TMP_SPEC_DIR [ -e $TMP_SPEC_DIR/$i.spec ] || { echo "ERROR: could not extract specfile for $i in $origrepository repository; aborting." >&2 exit 1 } echo "$warningtext" > ${LOCAL_REPS_BASE_DIR}/distromatic/$origrepository/warnings/$i.in done [ "$TMP_SPEC_DIR" != "/" ] && rm -rf $TMP_SPEC_DIR exit 0 } [ "$command" = "inspect" ] && { [ "$packages" ] || { usage; exit 1; } TMP_SPEC_DIR=`mktemp -d` for i in $packages; do extract_diffinfo $i $origrepository $TMP_SPEC_DIR [ -e $TMP_SPEC_DIR/$i.spec ] || { echo "ERROR: could not extract specfile for $i in $origrepository repository; aborting." >&2 exit 1 } echo "$i: details of package in $origrepository repository" echo "" echo "SPECFILE:" echo "=========" cat $TMP_SPEC_DIR/$i.spec echo "" echo "REQUIRES:" echo "=========" cat $TMP_SPEC_DIR/requires echo "" echo "PROVIDES:" echo "=========" cat $TMP_SPEC_DIR/provides done [ "$TMP_SPEC_DIR" != "/" ] && rm -rf $TMP_SPEC_DIR exit 0; } [ "$command" = "install" ] && { [ "$packages" ] || { usage; exit 1; } myarch=`uname -p` if [ "$myarch" = "*686" -o "$myarch" = "athlon" -o "$myarch" = "pentium*" ]; then myarch="i586" fi for i in $packages; do pkg=$i pkgarch= if [ "${i/.*}" != "${i}" ]; then pkg=${i/.*} pkgarch=${i/*.} fi if [ "$pkgarch" -a "$pkgarch" != "$myarch" ]; then get_pkg_info $origrepository $pkgarch $pkg [ "$pkg_name" ] || { echo "WARNING: $pkg not found in $origrepository for arch $pkgarch; skipping." continue } else get_pkg_info $origrepository $myarch $pkg [ "$pkg_name" ] || { echo "WARNING: $pkg not found in $origrepository for arch $myarch; skipping." continue } fi pkg_file=${pkg_name}-${pkg_version}-${pkg_release}.$pkg_arch.rpm pkg_path=${LOCAL_REPS_BASE_DIR}/$pkg_repository/RPMS.$pkg_arch/${pkg_file} [ -r $pkg_path ] || { echo "WARNING: file $pkg_path should exist but doesn't; skipping." continue } echo "Installing $pkg_file..." if [ "$force" = "1" ]; then rpm -i $pkg_path --force rpmret=$? [ $rpmret -gt 0 ] && echo "WARNING: rpm returned $rpmret" if [ "$pkg_arch" != "$myarch" ]; then pkg_file=${pkg_name}-${pkg_version}-${pkg_release}.$myarch.rpm pkg_path=${LOCAL_REPS_BASE_DIR}/$pkg_repository/RPMS.$myarch/${pkg_file} echo "Other arch installation forced; reinstalling native arch package after..." rpm -i $pkg_path --force rpmret=$? [ $rpmret -gt 0 ] && echo "WARNING: rpm returned $rpmret" fi else rpm -i $pkg_path rpmret=$? [ $rpmret -gt 0 ] && echo "WARNING: rpm returned $rpmret" fi done exit 0; } [ "$command" = "distromatic" ] && { [ -r $SRCPKGLIST ] || { echo "ERROR: srcpkglist file missing for $origrepository repository; aborting." >&2 exit 1 } [ -d ${LOCAL_REPS_BASE_DIR}/$origrepository/specs ] || mkdir ${LOCAL_REPS_BASE_DIR}/$origrepository/specs [ -d ${LOCAL_REPS_BASE_DIR}/$origrepository/patches ] || mkdir ${LOCAL_REPS_BASE_DIR}/$origrepository/patches while read line; do set -- $line [ -e ${LOCAL_REPS_BASE_DIR}/$origrepository/SRPMS.base/$1-$2-$6.src.rpm ] && { [ ${LOCAL_REPS_BASE_DIR}/$origrepository/SRPMS.base/$1-$2-$6.src.rpm -nt \ ${LOCAL_REPS_BASE_DIR}/$origrepository/specs/$1.spec ] && { # echo ${LOCAL_REPS_BASE_DIR}/$origrepository/SRPMS.base/$1-$2-$6.src.rpm autospec -x ${LOCAL_REPS_BASE_DIR}/$origrepository/SRPMS.base/$1-$2-$6.src.rpm -F '*.spec' \ --destdir ${LOCAL_REPS_BASE_DIR}/$origrepository/specs/ -q >/dev/null touch ${LOCAL_REPS_BASE_DIR}/$origrepository/specs/$1.spec grep -i "^Patch[0-9]*:" ${LOCAL_REPS_BASE_DIR}/$origrepository/specs/$1.spec &>/dev/null && { autospec -x ${LOCAL_REPS_BASE_DIR}/$origrepository/SRPMS.base/$1-$2-$6.src.rpm -F '*.patch' \ --destdir ${LOCAL_REPS_BASE_DIR}/$origrepository/patches/ -q >/dev/null } } } done < $SRCPKGLIST exit 0 } [ "$simulate" = "1" ] && echo "Simulation mode enabled." # # import and other active commands # if [ "$DEST_MODE" = "remote" ]; then DEST_URL=${AUTODIST_REPOSITORIES_REMOTE_FTP}/pub/openmamba else DEST_URL=${LOCAL_REPS_BASE_DIR} fi DEST_URL_LOCAL=${LOCAL_REPS_BASE_DIR} # ORIG_URL_LOCAL is set if a local copy of the repository exists # and will be preferred for file transfer optimizations if [ "$ORIG_MODE" = "remote" ]; then ORIG_URL=${AUTODIST_REPOSITORIES_REMOTE_FTP}/pub/openmamba else ORIG_URL=${LOCAL_REPS_BASE_DIR} fi ORIG_URL_LOCAL=${LOCAL_REPS_BASE_DIR} BACKUP_DATE=`date +%y%m%d.%H%M%S` LOCAL_BACKUP=$DEST_URL/$destrepository/old # operation files are always in the local copy of the repository ORIGREGFILE=${LOCAL_REPS_BASE_DIR}/$origrepository/operations.log.html DESTREGFILE=${LOCAL_REPS_BASE_DIR}/$destrepository/operations.log.html [ "$command" = "archive" ] && { DEST_URL=$ORIG_URL DEST_URL_LOCAL=$ORIG_URL_LOCAL DEST_MODE=$ORIG_MODE [ "$packages" ] || { usage; exit 1; } for i in $packages; do backup_package $i $origrepository $ORIGREGFILE done exit 0 } [ "$command" = "restore" ] && { DEST_URL=$ORIG_URL DEST_URL_LOCAL=$ORIG_URL_LOCAL DEST_MODE=$ORIG_MODE [ "$ORIG_MODE" = "remote" ] && { echo "ERROR: restore is only implemented in local repository; exiting." >&2 exit 1 } [ "$packages" ] || { usage; exit 1; } for i in $packages; do restore_package $i $origrepository $ORIGREGFILE done exit 0 } [ "$command" = "import" -o "$command" = "release" ] && { [ "$origrepository" = "$destrepository" ] && { echo "ERROR: source and destination repository cannot be the same; aborting." >&2; exit 200; } if [ "$command" = "import" ]; then echo "Importing $1: $origrepository ($ORIG_MODE) => $destrepository ($DEST_MODE)" backup_mode=backup else echo "Releasing $1: $origrepository ($ORIG_MODE) => $destrepository ($DEST_MODE)" backup_mode=release fi if [ ! "$packages" ]; then get_packages_from_last_build $origrepository fi RET=0 for i in ${packages[*]}; do import_package $i $backup_mode IMPORT_RET=$? if [ $IMPORT_RET -eq 255 -a "${AUTODIST_REPOSITORIES_TRANSITIONAL_REP}" -a \ "${AUTODIST_REPOSITORIES_TRANSITIONAL_REP}" != "$destrepository" -a \ "${AUTODIST_REPOSITORIES_TRANSITIONAL_REP}" != "$origrepository" -a \ "${AUTODIST_REPOSITORIES_TRANSITIONAL_REP/-*}" = "${destrepository/-*}" ]; then echo "Use -f to force import to $destrepository; now trying to import to ${AUTODIST_REPOSITORIES_TRANSITIONAL_REP} instead." destrepositorysave=$destrepository destrepository=${AUTODIST_REPOSITORIES_TRANSITIONAL_REP} import_package $i $backup_mode IMPORT_RET=$? destrepository=$destrepositorysave fi if [ $IMPORT_RET -ne 0 ]; then RET=`expr $RET + 1` fi done exit $RET } usage echo "ERROR: $command is not a valid command; aborting." >&2 exit 1