#!/bin/bash # Librerelease # Uploads packages into [staging] # Copyright 2010 Nicolás Reynolds # Copyright 2013 Luke Shumaker # # 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) load_files libretools check_vars libretools WORKDIR PARABOLAHOST LIBREDESTDIR SIGID || exit 1 # The following variables are actually optional #check_vars libretools SIGEXT HOOKPRERELEASE || exit 1 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 { repos=($(find "$WORKDIR/staging/" -mindepth 1 -type d \! -empty -printf '%f ' 2>/dev/null)) for _repo in ${repos[@]}; do msg2 "$_repo" find ${WORKDIR}/staging/${_repo} -type f -printf "%f\n" done unset repos } function sign_packages { if [ -z "${SIGEXT}" ]; then SIGEXT=.sig warning "Empty SIGEXT var, using default .sig" fi if [ -z "${GPG_AGENT_INFO}" ]; then warning "It's better to use gpg-agent to sign packages in batches" fi packages=($(find "${WORKDIR}/staging/" -type f -iname '*.pkg.tar.?z')) for package in ${packages[@]}; do if [ -f "${package}${SIGEXT}" ]; then warning "Package signature found, verifying..." # Verify that the signature is correct, else remove for re-signing if ! gpg --quiet --verify "${package}${SIGEXT}" >/dev/null 2>&1; then error "Failed! Resigning..." rm -f "${package}${SIGEXT}" fi fi if ! [ -f "${package}${SIGEXT}" ]; then msg2 "Signing ${package}..." gpg --default-key "${SIGID}" --output "${package}${SIGEXT}" \ --detach-sig "${package}" || { error "Signing failed" exit 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 { [ -z ${dryrun} ] && \ rm -f $@ } function main { if [ -w / ]; then error "This program should be run as regular user" exit 1 fi while getopts 'hlcn' arg; do case $arg in h) usage; exit 0 ;; l) list_packages; exit 0 ;; c) clean; exit $? ;; n) dryrun="--dry-run" ;; esac done [[ ! -z ${HOOKPRERELEASE} ]] && bash -c "${HOOKPRERELEASE}" clean_non_packages sign_packages # 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 {} \; # Get the synced files SYNCED_FILES=($(find ${WORKDIR}/staging -type f)) msg "%s to upload" $(du -h -d 0 ${WORKDIR}/staging | tr "\t" " " | cut -d" " -f1) msg "Uploading packages..." rsync --recursive \ ${dryrun} \ --no-group \ --no-perms \ --copy-links \ --hard-links \ --partial \ --prune-empty-dirs \ --human-readable \ --progress \ -e "ssh " \ ${WORKDIR}/staging \ ${PARABOLAHOST}:${LIBREDESTDIR}/ || { error "Sync failed, try again" exit 1 } msg "Removing ${#SYNCED_FILES[@]} files from local [staging]" clean ${SYNCED_FILES[@]} msg "Running db-update on repos" ssh ${PARABOLAHOST} dbscripts/db-update exit 0 } main "$@"