diff options
Diffstat (limited to 'src/abslibre-tools/librerelease')
-rwxr-xr-x | src/abslibre-tools/librerelease | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/abslibre-tools/librerelease b/src/abslibre-tools/librerelease new file mode 100755 index 0000000..5913670 --- /dev/null +++ b/src/abslibre-tools/librerelease @@ -0,0 +1,212 @@ +#!/usr/bin/env bash +# Librerelease +# Uploads packages into [staging] + +# Copyright 2010 Nicolás Reynolds +# Copyright 2013 Luke Shumaker +# For just the create_signature() function: +# Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> +# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> +# Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> +# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> +# +# This file is part of Parabola. +# +# Parabola is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Parabola is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Parabola. If not, see <http://www.gnu.org/licenses/>. + +. libremessages +. $(librelib conf.sh) + +function usage { + print "Usage: %s [OPTIONS]" "${0##*/}" + echo + print 'This script uploads packages on $WORKDIR/stagging' + print "to parabola server." + echo + print "Options:" + print ' -c Clean packages on $WORKDIR/staging' + print " -l Only list packages but not upload them" + print " -n Dry-run; don't actually do anything" + print " -h Show this message" +} + +function list_packages { + find "$WORKDIR/staging/" -mindepth 1 -type d -not -empty -printf '%f\n' | sort | + while read -r repo; do + msg2 "$repo" + find "${WORKDIR}/staging/${repo}" -type f -printf "%f\n" | sort + done +} + +# This function is taken almost verbatim from makepkg +create_signature() { + local ret=0 + local filename="$1" + msg "$(gettext "Signing package...")" + + local SIGNWITHKEY="" + if [[ -n $GPGKEY ]]; then + SIGNWITHKEY="-u ${GPGKEY}" + fi + # The signature will be generated directly in ascii-friendly format + gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$? + + + if (( ! ret )); then + msg2 "$(gettext "Created signature file %s.")" "$filename.sig" + else + error "$(gettext "Failed to sign package file.")" + return $ret + fi +} + +function sign_packages { + if [ -z "${GPG_AGENT_INFO}" ]; then + warning "It's better to use gpg-agent to sign packages in batches" + fi + + for package in $(find "${WORKDIR}/staging/" -type f -iname '*.pkg.tar.?z'); do + if [ -f "${package}.sig" ]; then + msg2 "Package signature found, verifying..." + + # Verify that the signature is correct, else remove for re-signing + if ! gpg --quiet --verify "${package}.sig" >/dev/null 2>&1; then + error "Failed! Re-signing..." + rm -f "${package}.sig" + fi + fi + + if ! [ -f "${package}.sig" ]; then + create_signature "$package" || return 2 + fi + done +} + +# Remove everything that's not a package or a signature +function clean_non_packages { + find $WORKDIR/staging/ -type f \ + \! -iname "*.pkg.tar.?z" -a \! -iname "*.pkg.tar.?z.sig" \ + -delete +} + +# Clean everything if not on dry-run mode +function clean { + if [[ -n "${dryrun}" ]]; then + : + else + msg "Removing files from local staging directory" + # use '-exec rm' instead of '-delete' to be verbose + find "${WORKDIR}/staging" -type f -exec rm -fv {} + + fi +} + +function main { + if [ -w / ]; then + error "This program should be run as regular user" + return 1 + fi + + # Parse options + local dryrun="" + local mode="release_packages" + while getopts 'clnh' arg; do + case $arg in + c) mode=clean ;; + l) mode=list_packages ;; + n) dryrun="--dry-run" ;; + h) mode=usage ;; + *) usage >/dev/stderr; return 1 ;; + esac + done + shift $(($OPTIND - 1)) + if [[ $# != 0 ]]; then + usage >/dev/stderr + return 1 + fi + + if [[ $mode == usage ]]; then + usage + return 0 + fi + + load_files makepkg + check_vars makepkg GPGKEY + load_files libretools + check_vars libretools WORKDIR REPODEST || return 1 + # The following variables are actually optional + #check_vars libretools HOOKPRERELEASE HOOKPOSTRELEASE || return 1 + + lock 10 "${WORKDIR}/staging.lock" 'Waiting for an exclusive lock on the staging directory' + "$mode" +} + +function release_packages { + if [[ -n $HOOKPRERELEASE ]]; then + msg "Running HOOKPRERELEASE..." + bash -c "${HOOKPRERELEASE}" + fi + + clean_non_packages + sign_packages || return 1 + + # Make the permissions of the packages 644 otherwise the user will get access + # denied error when they try to download (rsync --no-perms doesn't seem to + # work). + find ${WORKDIR}/staging -type f -exec chmod 644 {} \; + find ${WORKDIR}/staging -type d -exec chmod 755 {} \; + + msg "%s to upload" $(du -h -d 0 ${WORKDIR}/staging | tr "\t" " " | cut -d" " -f1) + msg "Uploading packages..." + if ! rsync --recursive \ + ${dryrun} \ + --no-group \ + --no-perms \ + --copy-links \ + --hard-links \ + --partial \ + --prune-empty-dirs \ + --human-readable \ + --progress \ + -e "ssh " \ + ${WORKDIR}/staging \ + ${REPODEST}/ + then + error "Sync failed, try again" + return 1 + fi + + clean + + msg "Running db-update on repos" + ssh ${REPODEST%%:*} dbscripts/db-update + + if [[ -n $HOOKPOSTRELEASE ]]; then + msg "Running HOOKPOSTRELEASE..." + bash -c "${HOOKPOSTRELEASE}" + fi + + return 0 +} + +main "$@" |