mcermak / rpms / glibc32

Forked from rpms/glibc32 2 years ago
Clone
Blob Blame History Raw
#!/bin/bash
#
# This script is for automating the download of a built Koji package
# without having to type in each package, instead we take the build
# url, compute the package list, apply the name and arch filter, and
# download only the files you want.  We could do this with `koji
# download-build` but it refuses to download just one package and
# wants to download the entire build.
#
# Input: $1: URL of build or task in Koji.
#	 -a: List of arches.
#	 -p: List of packages.
# Output: Specific srpms and rpms built for the given task/build.
#
set -e
# Enable for debugging:
# set -x

koji_taskurl=http://koji.fedoraproject.org/koji
koji_buildurl=http://koji.fedoraproject.org/koji
koji_packages=https://kojipkgs.fedoraproject.org

buildline="buildArch"
# Remove '-q' to get more detail for debugging.
#wgetopts="--no-check-certificate -q"
wgetopts="--no-check-certificate --retry-connrefused --continue"

if [ $# -lt 1 ]; then
    echo "$0: <Build or task URL in Koji> [-p <Package list>] [-a <Arches list>]"
    exit 1
fi
url="$1"
shift
# Read options
opts=`getopt -o p:a: --long packages:arches: -n $0 -- "$@"`
eval set -- "$opts"

# Extract options and their arguments.
arg_packages=""
arg_arches=""
packages=""
arches=""
while true ; do
    case "$1" in
	-p|--packages)
	    arg_packages=$2; shift 2 ;;
	-a|--arches)
	    arg_arches=$2; shift 2 ;;
        --) shift ; break ;;
        *) echo "Internal error!" ; exit 1 ;;
    esac
done
if [ "$arg_packages" ]; then
    packages=`echo $arg_packages | sed -e 's/,/-[[:digit:]] /g' -e 's/$/-[[:digit:]]/g'`
fi
if [ "$arg_arches" ]; then
    arches=`echo $arg_arches | sed -e 's/,/\. \./g' -e 's/^/\./g' -e 's/$/\./g'`
fi

tempfiles=()
cleanup() {
    rm -f "${tempfiles[@]}"
}
trap cleanup 0

error () {
    local parent_lineno="$1"
    local message="$2"
    local code="${3:-1}"
    if [[ -n "$message" ]]; then
	echo "Error on line ${parent_lineno}: ${message} (${code})"
    else
	echo "Error on line ${parent_lineno} (${code})"
    fi
    exit "${code}"
}
trap 'error ${LINENO}' ERR

# Setup some temp files.
buildinfo=$(mktemp)
chmod u+rw $buildinfo
tempfiles+=("$buildinfo")

archinfo=$(mktemp)
chmod u+rw $archinfo
tempfiles+=("$archinfo")

pageinfo=$(mktemp)
chmod u+rw $pageinfo
tempfiles+=("$pageinfo")

rpminfo=$(mktemp)
chmod u+rw $rpminfo
tempfiles+=("$rpminfo")

# Fetch the build information.
echo "Downloading build information..."

if true;  then
  echo "Detected Koji..."
  buildurl=$koji_buildurl
  taskurl=$koji_taskurl
  packageurl=$koji_packages
fi

# All rpm downloads go through fetch_rpm and we throttle
# it slighlty to avoid getting kicked by the server.
function fetch_rpm {
    local wgetopts url ret
    wgetopts="$1"
    url="$2"
    ret=1
    while [ $ret -ne 0 ]; do
	ret=$(wget $wgetopts $url | echo $?)
	sleep 1
    done
}

# Download the globally selected arches and packages
# from RPMINFO.
function fetch_rpms {
    local rpminfo
    local line arch package
    rpminfo="$1"
    # Downloading specific packages for a given arch?
    # - The most restrictive query.
    if [ "$arches" ] && [ "$packages" ]; then
	while read line
	do
	    for arch in $arches; do
		for package in $packages; do
		    if echo $line | grep -q -F $arch && echo $line | grep -q $package; then
			echo "Downloading $line"
			fetch_rpm "$wgetopts" "$line"
		    fi
		done
	    done
	done < $rpminfo
    fi
    # Downloading a specific package only?
    # - Will download that package for all arches.
    if [ -z "$arches" ] && [ "$packages" ]; then
	while read line
	do
	    for package in $packages; do
		if echo $line | grep -q $package; then
		    echo "Downloading $line"
		    fetch_rpm "$wgetopts" "$line"
		fi
	    done
	done < $rpminfo
    fi
    # Downloading all packages for a given arch?
    if [ "$arches" ] && [ -z "$packages" ]; then
	while read line
	do
	    for arch in $arches; do
		if echo $line | grep -q -F $arch; then
		    echo "Downloading $line"
		    fetch_rpm "$wgetopts" "$line"
		fi
	    done
	done < $rpminfo
    fi
    # Downloading all rpms for all arches?
    if [ -z "$arches" ] && [ -z "$packages" ]; then
	while read line
	do
	    echo "Downloading $line"
	    fetch_rpm "$wgetopts" "$line"
	done < $rpminfo
    fi
}

# Next we need to determine if the URL is for a TASK or a BUILD.
# A TASK has sub-builds that we need to walk.
# A BUILD has an architecture list we need to walk.
wget $wgetopts --output-document=$buildinfo $url
grep "$buildline" $buildinfo | sed -e 's,^.*href=",,g' -e 's,".*$,,g' > $archinfo
count=$(cat $archinfo | wc -l)
if [ $count -lt 1 ]; then
    # It's a BUILD.
    # Get the full list of all RPMs.
    grep "$packageurl" $buildinfo | grep '\.rpm' | sed -e 's,^.*href=",,g' -e 's,".*$,,g' > $rpminfo
    rpmcount=$(wc -l $rpminfo | sed -e 's, .*$,,g')
    if [ $rpmcount -eq 0 ]; then
	echo "No RPMs detected!"
	exit 1
    fi
    fetch_rpms "$rpminfo"
else
    # It's a TASK.
    # For each sub-arch build:
    count=0
    while read line
    do
	# Download the descendent build info page...
	echo "Downloading target $count information..."
	truncate -s 0 $pageinfo
	wget $wgetopts --output-document=$pageinfo $taskurl/$line
	grep "$packageurl" $pageinfo | grep ".*rpm" | sed -e 's,^.*href=",,g' -e 's,".*$,,g' > $rpminfo
	# Then download the rpms.
	fetch_rpms "$rpminfo"
	count=$((count+1))
    done < $archinfo
fi

# Cleanup, leaving the downloaded rpms.
echo "Done."
exit 0