#!/bin/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 # Copyright (c) 2002-2006 by Judd Vinet # Copyright (c) 2005 by Aurelien Foret # Copyright (c) 2006 by Miklos Vajna # Copyright (c) 2005 by Christian Hamar # Copyright (c) 2006 by Alex Smith # Copyright (c) 2006 by Andras Voroskoi # Copyright (c) 2006-2013 Pacman Development Team # Copyright (c) 2002-2006 by Judd Vinet # Copyright (c) 2005 by Aurelien Foret # Copyright (c) 2006 by Miklos Vajna # Copyright (c) 2005 by Christian Hamar # Copyright (c) 2006 by Alex Smith # Copyright (c) 2006 by Andras Voroskoi # # 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 . . 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 "$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 "$@"