#!/bin/bash # # The script is executed periodically by cronjob # as part of ~mirror/bin/publish_factory_leap wrapper on pontifex # # Tool publises data from stage (/src/ftp-stage) to public (/srv/ftp - download.opensuse.org) # # Configuration lives in openSUSE-release-tools.git/publish_distro_conf # Syntax: ./publish_distro config_file # # no --delete built in # number of hours to delay publishing when new isos arrive PUBLISH_DELAY=2 # force publish even if isos appear to be synced already force= # used for cleanup date='now' # set to echo for dry run dryrun= # cleanup instead of sync do_cleanup= # url with snapshot changes app diff_url_base="https://openqa.opensuse.org/snapshot-changes/opensuse" changes_dir_base="/srv/www-local/snapshot-changes" repos=("oss" "non-oss") extra_repos=("source" "debug") isodir="iso" get_version() { exit 1 } get_iso() { exit 1 } get_iso_link() { exit 1 } get_diff_url() { exit 1 } get_mark_published_url() { exit 1 } get_changes_filename() { exit 1 } # --dry and --cleanup should not be passed to rsync through $@ # config file and possibly other opts including --force need to be for arg do shift if [ "$arg" == '--force' ]; then force=1 newargs+=("$arg") shift continue elif [ "$arg" == '--dry' ]; then dryrun=echo shift continue elif [ "$arg" == '--cleanup' ]; then do_cleanup=1 date="90 days ago" continue elif [ "$arg" == '--now' ]; then PUBLISH_DELAY=0 shift continue else newargs+=("$arg") fi done # set newargs as $@ set -- "${newargs[@]}" . "$1" || { echo "need to specify config file" >&2; exit 1; } shift stage="/srv/ftp-stage/pub/opensuse/$path" dest="/srv/ftp/pub/opensuse/$path" if [ ! -e "$stage" -o ! -e "$dest" ]; then echo "stage ($stage) and/or dest ($dest) doesn't exist" >&2 exit 1 fi if [ -n "$do_cleanup" ]; then # find newest delete log of that day deletelog=$(ls -1tr ${deletelog%/*}/*-deletes.log | tail -1) test -n "$deletelog" || exit 1 ( df -h /srv for i in $(awk '/\*deleting .*/ { print $2}' $deletelog ); do if [ -e "$stage/$i" ]; then echo "WARNING: $i still exist in stage, not deleting" else $dryrun rm -rvf "$dest/$i" fi done df -h /srv ) > $deletelog-deleted exit 0 fi mkdir -p "${synclog%/*}" "${deletelog%/*}" if test -f $synclog; then old $synclog fi if test -f $deletelog; then old $deletelog fi version= do_sync_isos=1 for flavor in "${flavors[@]}"; do get_version get_iso get_diff_url get_changes_filename if [ -z "$force" -a -e "$dest/$isodir/$iso" ]; then if [ -t 1 ]; then # only log to tty echo "$iso already published, skipping isos" fi do_sync_isos=0 break fi if [ -n "$changes" ]; then if [ -d "$stage/$changes" ]; then # new way, use the obs generated changelogs $dryrun rsync -avvhiH $stage/$changes \ --link-dest=$stage \ $dest/$changes $dry_delete "$@" \ | LC_ALL=C grep -v '^\.[fdL] ' \ | LC_ALL=C grep -v '^\(sending\|delta\)' \ | tee -a $log else # old way (already broken?) if [ ! -s "$changes" ]; then echo "generating $changes" | tee -a $synclog [ -z "$dryrun" ] || changes=/dev/stdout $dryrun curl -sf "$url" > $changes fi if [ ! -e $stage/$isodir/$changes ]; then $dryrun cp -v $changes $stage/$isodir | tee -a $synclog [ -e $stage/$isodir/Changes ] || $dryrun ln -sf . $stage/$isodir/Changes 2>&1 | tee -a $synclog fi fi fi if [ ! -e "$stage/$isodir/$iso" ]; then echo "$flavor with $version doesn't exist, skipping isos" | tee -a $synclog do_sync_isos=0 break else get_iso_link if [ "`readlink $link`" != "$iso" ]; then $dryrun ln -sf "$iso" "$link" $dryrun ln -sf "$iso.sha256" "$link.sha256" fi if [ -z "$force" ]; then if test `date -d "$PUBLISH_DELAY hours ago" +%s` -lt `stat -c "%Z" "$stage/$isodir/$iso"`; then echo "$iso was created less than $PUBLISH_DELAY hours ago, delay publishing" | tee -a $synclog do_sync_isos=0 fi fi fi done # produce directories stamped with build number for r in "${repos[@]/#//repo/}"; do for i in /suse/setup /boot; do d="$stage$r$i" [ -d "$d" ] || continue if [ -e "$stage$r/media.1/build" ]; then read build < "$stage$r/media.1/build" stamp="${build#*Build}" if [ "$build" = "$stamp" ]; then echo "ERROR: build id not parsable: $build. not syncing" do_sync_isos=0 break 2 fi elif [ -e "$stage$r/media.1/media" ]; then { read dummy; read build; } < "$stage$r/media.1/media" stamp="${build#*Build}" if [ "$build" = "$stamp" ]; then echo "ERROR: build id not parsable: $build. not syncing" do_sync_isos=0 break 2 fi else echo "ERROR: repo $r is missing build id, not syncing" do_sync_isos=0 break 2 fi stamped="$stage$r${i%/*}/$stamp-${i##*/}" if [ ! -L "$d" ]; then $dryrun mv "$d" "$stamped" $dryrun ln -s "${stamped##*/}" "$d" echo "current $stamp" | $dryrun tee $stage/$r/.current.txt fi done done if [ "$do_sync_isos" = 0 ]; then if [ -t 1 ]; then echo "nothing to do" fi exit 0 fi # scan mirrors before making the files visible #mb scan -q -a -d /tumbleweed TODO=() #if [ "$do_sync_isos" = 1 ]; then TODO+=(iso) echo "current $version" | $dryrun tee $stage/$isodir/.current.txt #fi if [ -n "$repos" ]; then TODO+=(repo) TODO+=(DELETE_repo) fi # a single grep -v regexp performs awfully bad (needs at least 30x so long) # although LC_ALL=C might fix this, too for i in "${TODO[@]}"; do case $i in DELETE_*) i=${i#DELETE_} log=$deletelog dry_delete="--delete -n" ;; iso) # ISOs we sync with delete log=$synclog dry_delete="--delete-after" i="$isodir" ;; *) log=$synclog dry_delete="" ;; esac echo ========== $i $dry_delete =========== $dryrun rsync -avvhiH $stage/$i \ --link-dest=$stage \ $dest $dry_delete "$@" \ | LC_ALL=C grep -v '^\.[fdL] ' \ | LC_ALL=C grep -v '^\(sending\|delta\)' \ | tee -a $log done # also sync source and debug, not bind mounted for Leap for r in "${extra_repos[@]}"; do stage="/srv/ftp-stage/pub/opensuse/$r/$path" dest="/srv/ftp/pub/opensuse/$r/$path" $dryrun rsync -avhiH $stage/ --link-dest=$stage \ $dest --delete-after "$@" | tee -a log done # mark published get_mark_published_url if [ -n "$url" ]; then $dryrun curl -X POST -F "version=$version" "$url" fi #echo creating hashes #metalink-hasher update -t /srv/metalink-hashes/srv/ftp/pub/opensuse/tumbleweed \ # -b /srv/ftp/pub/opensuse/tumbleweed \ # /srv/ftp/pub/opensuse/tumbleweed # mb makehaskes is not needed by mirrorcache (replaced mirrorbrain) #$dryrun /usr/bin/mb makehashes -b /srv/ftp/pub/opensuse \ # -t /srv/metalink-hashes/srv/ftp/pub/opensuse \ # $dest