Add an option to specify the upload address
authorRichard Levitte <levitte@openssl.org>
Thu, 30 Mar 2023 10:11:34 +0000 (12:11 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 16 May 2023 03:54:35 +0000 (05:54 +0200)
Both local directory and several forms of SCP/SFTP addresses are supported.
For the SCP/SFTP form, it is always translated to be usable with SFTP.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/tools/pull/140)

release-tools/release-aux/upload-fn.sh [new file with mode: 0644]
release-tools/release.sh

diff --git a/release-tools/release-aux/upload-fn.sh b/release-tools/release-aux/upload-fn.sh
new file mode 100644 (file)
index 0000000..8b57138
--- /dev/null
@@ -0,0 +1,97 @@
+#! /bin/bash -e
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+# These functions all perform uploads, using sftp commands.
+# They all expect two parameters:
+#
+# $1    The destination, properly formed for the backend.
+#       In other words, it must be usable with SFTP for the sftp backend,
+#       and it must be a proper existing directory for the file backend.
+# $2    A flag, saying if the upload should (true) or shouldn't (false)
+#       be performed.  In verbose mode (governed by the variable $VERBOSE)
+#       this is useful to output what would happen if uploading was enabled.
+#
+# They also use the variable $VERBOSE as a command to perform verbose output.
+# They may also use the variable $DEBUG as a command to perform debugging
+# output.
+# These variable must be set accordingly by the loading script.  Recommended
+# values are ':' for non-verbose and 'echo' for verbose'
+
+upload_backend_sftp () {
+    local to=$1
+    local do_upload=$2
+
+    if [ -z "$to" ]; then
+        echo >&2 "No SFTP address was provided"
+        exit 1
+    fi
+    if [ -z "$do_upload" ]; then
+        echo >&2 "Upload or not?  The flag hasn't been set"
+        exit 1
+    fi
+
+    if $do_upload; then
+        sftp $to
+    else
+        $VERBOSE "Would 'sftp $to' with the following commands:"
+        while read L; do
+            $VERBOSE "  $L"
+        done
+    fi
+}
+
+upload_backend_file () {
+    local dest=$1
+    local do_upload=$2
+
+    if [ -z "$dest" ]; then
+        echo >&2 "No destination directory was provided"
+        exit 1
+    fi
+    if ! [ -d "$dest" ]; then
+        echo >&2 "Not a directory: $dest"
+        exit 1
+    fi
+    if [ -z "$do_upload" ]; then
+        echo >&2 "Upload or not?  The flag hasn't been set"
+        exit 1
+    fi
+
+    (
+        progress=
+        while read L; do
+            set -- $L
+            case $1 in
+                progress )
+                    if [ -z "$progress" ]; then
+                        progress=-v
+                    else
+                        progress=
+                    fi
+                    ;;
+                cd )
+                    if [ -d "$dest/$2" ]; then
+                        dest="$dest/$2"
+                    else
+                        echo >&2 "Warning: Not a directory: $dest/$2"
+                    fi
+                    ;;
+                put )
+                    if $do_upload; then
+                        cp $progress $2 $dest/$3
+                    else
+                        $VERBOSE "Would copy $2 -> $dest/$3"
+                    fi
+                    ;;
+                * )
+                    echo >&2 "Warning: Unknown command: $@"
+                    ;;
+            esac
+        done
+    )
+}
index e848341c79bb86be3d6885c3ff8aef209a0aaf6b..9c020905194a8b667c45d07665d2129e2f7465bd 100755 (executable)
@@ -33,7 +33,10 @@ Usage: release.sh [ options ... ]
                 For the purpose of signing tags and tar files, use this
                 key (default: use the default e-mail address’ key).
 
---no-upload     Don't upload to upload@dev.openssl.org.
+--upload-address=<address>
+                The location to upload release files to (default:
+                upload@dev.openssl.org)
+--no-upload     Don't upload the release files.
 --no-update     Don't perform 'make update' and 'make update-fips-checksums'.
 --verbose       Verbose output.
 --debug         Include debug output.  Implies --no-upload.
@@ -76,6 +79,7 @@ upload_address=upload@dev.openssl.org
 
 TEMP=$(getopt -l 'alpha,next-beta,beta,final' \
               -l 'branch' \
+              -l 'upload-address:' \
               -l 'no-upload,no-update' \
               -l 'verbose,debug' \
               -l 'local-user:' \
@@ -105,6 +109,11 @@ while true; do
         warn_branch=true
         shift
         ;;
+    --upload-address )
+        shift
+        upload_address="$1"
+        shift
+        ;;
     --no-upload )
         do_upload=false
         shift
@@ -199,7 +208,8 @@ trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2
 RELEASE_AUX=$(cd $(dirname $0)/release-aux; pwd)
 found=true
 for fn in "$RELEASE_AUX/release-version-fn.sh" \
-          "$RELEASE_AUX/release-state-fn.sh"; do
+          "$RELEASE_AUX/release-state-fn.sh" \
+          "$RELEASE_AUX/upload-fn.sh"; do
     if ! [ -f "$fn" ]; then
         echo >&2 "'$fn' is missing"
         found=false
@@ -212,6 +222,8 @@ fi
 # Load version functions
 . $RELEASE_AUX/release-version-fn.sh
 . $RELEASE_AUX/release-state-fn.sh
+# Load upload backend functions
+. $RELEASE_AUX/upload-fn.sh
 
 # Make sure we're in the work directory, and remember it
 if HERE=$(git rev-parse --show-toplevel); then
@@ -267,6 +279,47 @@ if ! $found; then
     exit 1
 fi
 
+# We turn upload_address into a few variables, which can be used
+# by backends that must understand a subset of the SFTP commands
+upload_directory=
+upload_backend=
+case "$upload_address" in
+    *:* )
+        # Something with a colon is interpreted as the typical SCP
+        # location.  We reinterpret that in our terms
+        upload_directory="${upload_address#*:}"
+        upload_address="${upload_address%%:*}"
+        upload_backend=sftp
+        ;;
+    *@* )
+        upload_backend=sftp
+        ;;
+    sftp://?*/* | sftp://?* )
+        # First, remove the URI scheme
+        upload_address="${upload_address#sftp://}"
+        # Now we know that we have a host, followed by a slash, followed by
+        # a directory spec.  If there is no slash, there's no directory.
+        upload_directory="${upload_address#*/}"
+        if [ "$upload_directory" = "$upload_address" ]; then
+            # There was nothing with a slash to remove, so no directory.
+            upload_directory=
+        fi
+        upload_address="${upload_address%%/*}"
+        upload_backend=sftp
+        ;;
+    sftp:* )
+        echo >&2 "Invalid upload address $upload_address"
+        exit 1
+        ;;
+    * )
+        if $do_upload && ! [ -d "$upload_address" ]; then
+           echo >&2 "Not an existing directory: $upload_address"
+           exit 1
+        fi
+        upload_backend=file
+        ;;
+esac
+
 # Initialize #########################################################
 
 echo "== Initializing work tree"
@@ -467,19 +520,25 @@ $VERBOSE "== Push what we have to the parent repository"
 git push --follow-tags parent HEAD
 
 if $do_upload; then
-    (
-        if [ "$VERBOSE" != ':' ]; then
-            echo "progress"
-        fi
-        echo "put ../$tgzfile"
-        echo "put ../$tgzfile.sha1"
-        echo "put ../$tgzfile.sha256"
-        echo "put ../$tgzfile.asc"
-        echo "put ../$announce.asc"
-    ) \
-    | sftp "$upload_address"
+    echo "== Upload tar, hash and announcement files"
 fi
 
+(
+    # With sftp, the progress meter is enabled by default,
+    # so we turn it off unless --verbose was given
+    if [ "$VERBOSE" == ':' ]; then
+        echo "progress"
+    fi
+    if [ -n "$upload_directory" ]; then
+        echo "cd $upload_directory"
+    fi
+    echo "put ../$tgzfile"
+    echo "put ../$tgzfile.sha1"
+    echo "put ../$tgzfile.sha256"
+    echo "put ../$tgzfile.asc"
+    echo "put ../$announce.asc"
+) | upload_backend_$upload_backend "$upload_address" $do_upload
+
 # Post-release #######################################################
 
 $VERBOSE "== Reset all files to their pre-release contents"
@@ -685,6 +744,7 @@ B<--final> |
 B<--branch> |
 B<--local-user>=I<keyid> |
 B<--reviewer>=I<id> |
+B<--upload-address>=I<address> |
 B<--no-upload> |
 B<--no-update> |
 B<--verbose> |
@@ -742,9 +802,30 @@ Create a branch specific for the I<SERIES> release series, if it doesn't
 already exist, and switch to it.  The exact branch name will be
 C<< openssl-I<SERIES> >>.
 
+=item B<--upload-address>=I<address>
+
+The location that the release files are to be uploaded to.  Supported values
+are:
+
+=over 4
+
+=item -
+
+an existing local directory
+
+=item -
+
+something that can be interpreted as an SCP/SFTP address.  In this case,
+SFTP will always be used.  Typical SCP remote file specs will be translated
+into something that makes sense for SFTP.
+
+=back
+
+The default upload address is C<upload@dev.openssl.org>.
+
 =item B<--no-upload>
 
-Don't upload the produced files.
+Don't upload the release files.
 
 =item B<--no-update>