summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbill-auger <mr.j.spam.me@gmail.com>2023-12-24 02:32:07 -0500
committerbill-auger <mr.j.spam.me@gmail.com>2024-03-28 23:13:17 -0400
commit2478cf7b101ec6769b45b8372c2e7aba8dd8b1d8 (patch)
tree6d3475d7547d355e20534df920a4a848d8e16dcb
parentfdd119785384d8c0438b6a1bfd822d6933882972 (diff)
replace REPODEST config with REPO{USER,HOST,PORT,PATH}
-rwxr-xr-xsrc/abslibre-tools/librerelease112
-rw-r--r--src/lib/notifications.sh6
-rw-r--r--src/libretools.conf34
-rw-r--r--test/cases/librerelease.bats83
4 files changed, 170 insertions, 65 deletions
diff --git a/src/abslibre-tools/librerelease b/src/abslibre-tools/librerelease
index 560e8d1..70a20b0 100755
--- a/src/abslibre-tools/librerelease
+++ b/src/abslibre-tools/librerelease
@@ -57,6 +57,16 @@ readonly rsync_flags=(
--progress
)
+DRY_RUN='' # main()
+UPLOAD_ONLY='' # main()
+TIER0_HOST='' # main()
+TIER0_STAGING='' # main()
+TIER0_LOGIN='' # main()
+TIER0_PORT='' # main()
+SSH_CMD='' # main()
+RSYNC_DEST='' # main()
+
+
# Functions ####################################################################
list0_files() {
@@ -127,7 +137,21 @@ clean_files() (
usage() {
print "Usage: %s [OPTIONS]" "${0##*/}"
- print 'Upload packages in $WORKDIR/staging to the Parabola server'
+ prose 'Upload packages staged in %s (per `librestage`) to the configured server,
+ and publish them to their respective repositories.' \$WORKDIR/staging
+ echo
+ prose 'This requires the `gpg` program, configured with your GPG key,
+ and a staging directory (%s), writable by %s.' \$WORKDIR/staging '$LIBREUSER'
+ prose '%s is determined at runtime, by %s.
+ %s is normally the local login of the invoking user,
+ but may be over-ridden by setting %s in the environment.' \
+ '$LIBREUSER' /usr/lib/libretools/conf.sh '$LIBREUSER' '$SUDO_USER'
+ prose 'By default, %s is assumed to match the hackers.git login
+ for which %s has login credentials for the repo server.
+ If %s does not match the hackers.git login,
+ you must specify %s as the remote login, (eg: in %s)' \
+ '$LIBREUSER' '$LIBREUSER' '$LIBREUSER' '$TIER0_LOGIN' \
+ \$XDG_CONFIG_HOME/libretools/libretools.conf
echo
print "Options:"
flag '-c' 'Clean; delete packages in $WORKDIR/staging'
@@ -167,54 +191,38 @@ main() {
return $EXIT_SUCCESS
fi
- declare -i ret=0
- load_conf makepkg.conf GPGKEY || ret=$?
- load_conf libretools.conf WORKDIR REPODEST DBSCRIPTS_CONFIG || ret=$? # and HOOK{PRE,POST}RELEASE, which are optional
- [[ $ret = 0 ]] || exit $ret
-
- local re_url='^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$'
- local re_authority='^(([^@]*)@)?([^][@:]*|\[[^]]*\])(:([0-9]*))?$'
- local REPODEST_ok=false
- if [[ "$REPODEST" =~ $re_url ]]; then
- REPODEST_ok=true
-
- REPODEST_scheme=${BASH_REMATCH[2]}
- REPODEST_authority=${BASH_REMATCH[4]}
- REPODEST_path=${BASH_REMATCH[5]}
- REPODEST_query=${BASH_REMATCH[7]}
- REPODEST_fragment=${BASH_REMATCH[9]}
-
- if [[ "$REPODEST_authority" =~ $re_authority ]]; then
- REPODEST_userinfo=${BASH_REMATCH[2]}
- REPODEST_host=${BASH_REMATCH[3]}
- REPODEST_port=${BASH_REMATCH[5]}
-
- if [[ "$REPODEST_host" = '['*']' ]]; then
- REPODEST_host=${REPODEST_HOST#'['}
- REPODEST_host=${REPODEST_HOST#']'}
- fi
- else
- REPODEST_ok=false
- fi
-
- [[ $REPODEST_scheme == ssh ]] || REPODEST_ok=false
- [[ -n $REPODEST_host ]] || REPODEST_ok=false
- [[ -n $REPODEST_path ]] || REPODEST_ok=false
- fi
- if ! $REPODEST_ok; then
- error 'The format of libretools.conf:REPODEST has changed.'
- plain 'Merge the /etc/libretools.conf.pacnew file!'
+ # source makepkg and libretools configuration files
+ # the specified config vars will be used in this script, and so are mandatory
+ # optional config vars used in this script, if specified in libretools.conf:
+ # TIER0_LOGIN, TIER0_PORT, TIER0_STAGING, HOOKPRERELEASE, HOOKPOSTRELEASE
+ if ! load_conf makepkg.conf GPGKEY; then
+ error '$GPGKEY is not configured.'
+ return $EXIT_NOTCONFIGURED
+ elif ! load_conf libretools.conf WORKDIR TIER0_HOST DBSCRIPTS_CONFIG; then
+ config_error_msg WORKDIR TIER0_HOST DBSCRIPTS_CONFIG
return $EXIT_NOTCONFIGURED
fi
- if [[ "$REPODEST_path" = '/~'* ]]; then
- if [[ "$REPODEST_path" = '/~/'* ]]; then
- REPODEST_path=${REPODEST_path#'/~/'}
- else
- error 'Unfortunately, `~user` home-directory expansion is not (yet?) supported in libretools.conf:REPODEST'
+
+ # validate/sanitize tier-0 repo URL components
+ if [[ -n ${TIER0_HOST:-} ]]; then
+ # normalize or reject tilde operator in staging path
+ if [[ "$TIER0_STAGING" == '/~/'* ]]; then
+ TIER0_STAGING=${TIER0_STAGING#'/~/'}
+ elif [[ "$TIER0_STAGING" == '/~'* ]]; then
+ error "Unfortunately, tilde expansion ('~' home directory) is not supported in libretools.conf::TIER0_STAGING"
return $EXIT_NOTCONFIGURED
fi
+ else
+ config_error_msg TIER0_HOST ; return $EXIT_NOTCONFIGURED ;
fi
- REPODEST_userhost="${REPODEST_userinfo:+${REPODEST_userinfo%%:*}@}${REPODEST_host}"
+
+ # construct the SSH and rsync destination parameters
+ readonly TIER0_HOST
+ readonly TIER0_STAGING=${TIER0_STAGING:-/home/${TIER0_LOGIN:-$LIBREUSER}/staging}
+ readonly TIER0_LOGIN=${TIER0_LOGIN:+${TIER0_LOGIN}@}
+ readonly TIER0_PORT=${TIER0_PORT:+-p $TIER0_PORT}
+ readonly SSH_CMD=( ssh ${TIER0_PORT} ${TIER0_LOGIN}${TIER0_HOST} )
+ readonly RSYNC_DEST=${TIER0_LOGIN}${TIER0_HOST}:${TIER0_STAGING%/}/
"$mode"
}
@@ -245,12 +253,17 @@ clean() {
}
release_packages() {
- local login_err_msg="connection or login failed"
local tier0_port="${REPODEST_port:+-p "$REPODEST_port"}"
local tier0_host="${REPODEST_userhost}"
- local ssh_cmd="ssh ${tier0_port} ${tier0_host}" # eg: ssh -p 1863 autobuilder@repo.parabola.nu STAGING='staging/' DBSCRIPTS_CONFIG='/etc/dbscripts/config.local.parabola' db-update
+ local ssh_cmd=( ssh ${tier0_port} ${tier0_host} ) # eg: ssh -p 1863 autobuilder@repo.parabola.nu STAGING='staging/' DBSCRIPTS_CONFIG='/etc/dbscripts/config.local.parabola' db-update
local dbupdate_cmd="STAGING=${REPODEST_path@Q} DBSCRIPTS_CONFIG=${DBSCRIPTS_CONFIG@Q} db-update"
+ # verify connection and login
+ if ! ${ssh_cmd[0]} -fN ${ssh_cmd[*]:1}; then
+ error "Connection or login failed."
+ return $EXIT_FAILURE
+ fi
+
## prepare ##
@@ -301,8 +314,8 @@ release_packages() {
## publish ##
- msg "Running db-update on repos"
- ${ssh_cmd} "${dbupdate_cmd}"
+ msg "Running db-update on repos"
+ ${ssh_cmd[*]} "${dbupdate_cmd}"
if [[ -n $HOOKPOSTRELEASE ]]; then
msg "Running HOOKPOSTRELEASE..."
@@ -315,10 +328,11 @@ release_packages() {
## notify pbot of the excellent work we have done ##
- notify_pbot "${ssh_cmd}" < $file_list
+ notify_pbot ${ssh_cmd[*]} < $file_list
return $EXIT_SUCCESS
}
+
main "$@"
diff --git a/src/lib/notifications.sh b/src/lib/notifications.sh
index e29d929..2aa0b0e 100644
--- a/src/lib/notifications.sh
+++ b/src/lib/notifications.sh
@@ -1,7 +1,7 @@
# process librerelease::$file_list via STDIN
-notify_pbot() # ( "ssh_cmd" ) file_list->STDIN
+notify_pbot() # ( ssh_cmd*** ) file_list->STDIN
{
- local ssh_cmd="$1"
+ local ssh_cmd=( $* )
local repo_user=${REPOUSER:-${LIBREUSER:-somebody}}
local select_rx='\.pkg\.tar\.[^\.]+$'
local reject_rx='-debug-'
@@ -24,6 +24,6 @@ notify_pbot() # ( "ssh_cmd" ) file_list->STDIN
if [[ ${ssh_cmd[0]} =~ ^ssh\ ]] && (( ${#releases[@]} )); then
msg2 "$(_ "Notifying pbot:")" ; print " ${pbotsay_msg}" ;
- ${ssh_cmd} "${pbotsay_cmd}" &> /dev/null || :
+ ${ssh_cmd[*]} "${pbotsay_cmd}" &> /dev/null || :
fi
}
diff --git a/src/libretools.conf b/src/libretools.conf
index 3ff162c..b99a347 100644
--- a/src/libretools.conf
+++ b/src/libretools.conf
@@ -1,6 +1,7 @@
#!/hint/bash
# shellcheck disable=2034
+
################################################################################
# misc #
################################################################################
@@ -21,25 +22,35 @@ DIFFPROG=$(which $([ -z "${DISPLAY:-}" ]||echo kdiff3 meld gvimdiff) vimdiff col
ABSLIBRERECV=git://git.parabola.nu/abslibre/abslibre.git
ABSLIBRESEND=ssh://git@git.parabola.nu:1863/~git/abslibre/abslibre.git
+
################################################################################
# librerelease #
################################################################################
-## Login on the $REPODEST server (normally, your hackers.git login)
-# Uncomment this and set it to your $REPODEST login, if your $LIBREUSER differs.
-# $REPOUSER may also be set in the environment.
-# Alternatively, leave it unset and configure your default login in ~/.ssh/config.
-# REPOUSER=
-
-## Where to upload packages to
-REPODEST=ssh://$REPOUSER@repo.parabola.nu:1863/~/staging/
-## Which config file to use with db-update (on the $REPODEST server)
+## Login on the $TIER0_HOST server (normally, your hackers.git login)
+# Un-comment this and set it to your $TIER0_HOST login, if your $LIBREUSER differs.
+# $TIER0_LOGIN may also be set in the environment.
+# TIER0_LOGIN=
+
+## The host, port, and remote staging directory for uploading packages via SSH
+# `librerelease` will fail if $TIER0_HOST is unset or if any of these are invalid.
+# $TIER0_PORT and $TIER0_STAGING are optional. If not configured,
+# the SSH port ($TIER0_PORT) will be the SSH system default;
+# and the remote staging location ($TIER0_STAGING) will be ~$TIER0_LOGIN/staging/.
+# Mind $TIER0_STAGING especially. `librerelease -C` deletes this entire directory.
+# Do not use tilde ('~') in $TIER0_STAGING. Specify an absolute path instead.
+TIER0_HOST=repo.parabola.nu
+TIER0_PORT=1863
+TIER0_STAGING=
+
+## Config file on the $REPOHOST server for `db-update`
DBSCRIPTS_CONFIG=/etc/dbscripts/config.local.parabola
-## These are run before and after uploading packages
-HOOKPRERELEASE='ssh -fN ${REPODEST_port:+-p "$REPODEST_port"} "${REPODEST_userhost}"'
+## Pre- and Post- hooks (BASH commands to run before or after uploading packages)
+HOOKPRERELEASE=
HOOKPOSTRELEASE="sudo librechroot clean-repo"
+
################################################################################
# dagpkg #
################################################################################
@@ -61,6 +72,7 @@ FULLBUILDCMD="sudo libremakepkg"
# successfully. When run, it is given a repository name as a single argument.
HOOKLOCALRELEASE="librestage"
+
################################################################################
# toru #
################################################################################
diff --git a/test/cases/librerelease.bats b/test/cases/librerelease.bats
index a984d73..245a6dc 100644
--- a/test/cases/librerelease.bats
+++ b/test/cases/librerelease.bats
@@ -30,7 +30,9 @@ setup() {
# Configure libretools
cat >> "$XDG_CONFIG_HOME/libretools/libretools.conf" <<-eot
- REPODEST=ssh://${USER@Q}@127.0.0.1:${ssh_port@Q}/${tmpdir@Q}/srv-staging/
+ TIER0_HOST=127.0.0.1
+ TIER0_PORT=$ssh_port
+ TIER0_STAGING=${tmpdir@Q}/srv-staging/
DBSCRIPTS_CONFIG=/etc/dbscripts/config.local.phony
HOOKPRERELEASE=:
HOOKPOSTRELEASE=:
@@ -74,7 +76,7 @@ teardown() {
diff "$tmpdir/list-correct" "$tmpdir/list"
}
-@test "librerelease fails if gpgkey not set" {
+@test "librerelease fails if GPGKEY not set" {
unset GPGKEY
local workdir="$tmpdir/workdir"
@@ -92,6 +94,24 @@ teardown() {
grep GPGKEY "$tmpdir/stderr"
}
+@test "librerelease fails if TIER0_HOST not set" {
+ unset TIER0_HOST
+
+ local workdir="$tmpdir/workdir"
+ mkdir -p "$workdir/staging/repo1" "$workdir/staging/repo2/sub"
+ touch \
+ "$workdir/staging/repo1/file1" \
+ "$workdir/staging/repo1/file2" \
+ "$workdir/staging/repo2/file with spaces" \
+ "$workdir/staging/repo2/sub/subfolder"
+
+ LC_ALL=C librerelease -l >"$tmpdir/stdout" 2>"$tmpdir/stderr" || status=$?
+
+ [[ $status != 0 ]]
+ empty "$tmpdir/stdout"
+ grep TIER0_HOST "$tmpdir/stderr"
+}
+
@test "librerelease fails if DBSCRIPTS_CONFIG is not set" {
cat >> "$XDG_CONFIG_HOME/libretools/libretools.conf" <<-eot
DBSCRIPTS_CONFIG=''
@@ -224,3 +244,62 @@ teardown() {
diff -u "$tmpdir/pwd.txt" "$tmpdir/postrelease.txt"
grep 'just published' "$tmpdir/pbot.txt"
}
+
+@test "librerelease logs in as TIER0_LOGIN" {
+ # Add a stub db-update pbot-say so that when we ssh to localhost it has
+ # something to run.
+ install -Dm755 /dev/stdin "$tmpdir/bin/db-update" <<-eot
+ #!/bin/bash
+ {
+ printf '%s\n' "\$DBSCRIPTS_CONFIG"
+ readlink -f -- "\$STAGING"
+ find "\$STAGING" -printf '%P\n' | LC_COLLATE=C sort
+ } > ${tmpdir@Q}/log.txt
+ eot
+ install -Dm755 /dev/stdin "$tmpdir/bin/pbot-say" <<-eot
+ #!/bin/bash
+ echo "\$*" >${tmpdir@Q}/pbot.txt
+ eot
+ PATH=$tmpdir/bin:$PATH
+
+ # Log which directories the hooks are run in.
+ cat >> "$XDG_CONFIG_HOME/libretools/libretools.conf" <<-eot
+ HOOKPRERELEASE='pwd > ${tmpdir@Q}/prerelease.txt'
+ HOOKPOSTRELEASE='pwd > ${tmpdir@Q}/postrelease.txt'
+ eot
+
+ # Make some files to stage
+ local workdir="$tmpdir/workdir"
+ mkdir -p "$workdir/staging/repo1" "$workdir/staging/repo2/sub"
+ touch \
+ "$workdir/staging/repo1/file1" \
+ "$workdir/staging/repo1/file2" \
+ "$workdir/staging/repo2/file with spaces" \
+ "$workdir/staging/repo2/sub/subfolder"
+
+ # Run
+ TIER0_LOGIN=tier0-user librerelease
+
+ # Make sure everything went OK
+ pwd > "$tmpdir/pwd.txt"
+ cat > "$tmpdir/log-correct.txt" <<-eot
+ /etc/dbscripts/config.local.phony
+ $(readlink -f -- "$tmpdir/srv-staging")
+
+ repo1
+ repo1/file1
+ repo1/file1.sig
+ repo1/file2
+ repo1/file2.sig
+ repo2
+ repo2/file with spaces
+ repo2/file with spaces.sig
+ repo2/sub
+ repo2/sub/subfolder
+ repo2/sub/subfolder.sig
+ eot
+ diff -u "$tmpdir/log-correct.txt" "$tmpdir/log.txt"
+ diff -u "$tmpdir/pwd.txt" "$tmpdir/prerelease.txt"
+ diff -u "$tmpdir/pwd.txt" "$tmpdir/postrelease.txt"
+ grep 'tier0-user just published' "$tmpdir/pbot.txt"
+}