Add sigul signing capabilities to lftools 73/11773/9
authorAndrew Grimberg <agrimberg@linuxfoundation.org>
Fri, 13 Jul 2018 01:01:45 +0000 (18:01 -0700)
committerAndrew Grimberg <agrimberg@linuxfoundation.org>
Fri, 13 Jul 2018 20:16:36 +0000 (13:16 -0700)
Add in the ability to do sigul signing using lftools. This is an
extension of the current sign subcommand

Issue: RELENG-1070
Change-Id: Ie0cc0b2de0375f3c6306858a8ecb873e44888d42
Signed-off-by: Andrew Grimberg <agrimberg@linuxfoundation.org>
docs/commands/sign.rst
lftools/cli/sign.py
shell/sign

index 5983a45..09e77ca 100644 (file)
@@ -20,6 +20,11 @@ nexus
 
 .. program-output:: lftools sign nexus --help
 
+sigul
+_____
+
+.. program-output:: lftools sign sigul --help
+
 deploy-nexus
 ------------
 
index abb5038..9f5c491 100644 (file)
@@ -7,7 +7,7 @@
 # which accompanies this distribution, and is available at
 # http://www.eclipse.org/legal/epl-v10.html
 ##############################################################################
-"""Script to GPG sign files."""
+"""Script to GPG or Sigul sign files."""
 
 __author__ = 'Thanh Ha'
 
@@ -22,7 +22,7 @@ import click
 @click.group()
 @click.pass_context
 def sign(ctx):
-    """GPG sign files."""
+    """GPG or Sigul sign files."""
     pass
 
 
@@ -37,10 +37,26 @@ def directory(ctx, directory):
 
 @click.command(name='nexus')
 @click.argument('nexus-repo-url')
+@click.option(
+    '-d', '--sign-dir', type=str,
+    default=tempfile.mkdtemp(prefix='gpg-signatures.'),
+    help='Local directory to clone repository. (default /tmp/gpg-signatures.*)')
+@click.option(
+    '-w', '--sign-with', type=str, default='gpg',
+    help='Sign artifacts with GPG or Sigul. (default gpg)')
+@click.pass_context
+def nexus(ctx, sign_dir, sign_with, nexus_repo_url):
+    """Fetch and GPG or Sigul sign a Nexus repo."""
+    status = subprocess.call(['sign', 'nexus', '-d', sign_dir, '-w', sign_with, nexus_repo_url])
+    sys.exit(status)
+
+
+@click.command(name='sigul')
+@click.argument('directory')
 @click.pass_context
-def nexus(ctx, nexus_repo_url):
-    """Fetch and GPG sign a Nexus repo."""
-    status = subprocess.call(['sign', 'nexus', nexus_repo_url])
+def sigul(ctx, directory):
+    """Sigul signs all of the files in a directory."""
+    status = subprocess.call(['sign', 'sigul', directory])
     sys.exit(status)
 
 
@@ -55,13 +71,18 @@ def nexus(ctx, nexus_repo_url):
 @click.option(
     '-r', '--root-domain', type=str, default='org',
     help='Root download path of staging repo. (default org)')
+@click.option(
+    '-w', '--sign-with', type=str, default='gpg',
+    help='Sign artifacts with GPG or Sigul. (default gpg)')
 @click.pass_context
-def deploy_nexus(ctx, nexus_url, nexus_repo, staging_profile_id, sign_dir, root_domain):
+def deploy_nexus(ctx, nexus_url, nexus_repo, staging_profile_id, sign_dir, sign_with, root_domain):
     """Sign artifacts from a Nexus repo then upload to a staging repo.
 
     This is a porcelain command that ties the lftools sign and deploy tools
     together for easier use. It calls the sign-nexus command and then the
     deploy-nexus-stage command to create a signed staging repository in Nexus.
+
+    Signing is performed either with gpg (default) or via sigul.
     """
     # wget does not appear to like to fully clone the root of a staging repo
     # as a workaround we have to at least give it 1 directory deep. Since most
@@ -70,7 +91,7 @@ def deploy_nexus(ctx, nexus_url, nexus_repo, staging_profile_id, sign_dir, root_
     nexus_url = nexus_url.rstrip('/')
     nexus_repo_url = "{}/content/repositories/{}/{}".format(nexus_url, nexus_repo, root_domain)
 
-    status = subprocess.call(['sign', 'nexus', '-d', sign_dir, nexus_repo_url])
+    status = subprocess.call(['sign', 'nexus', '-d', sign_dir, '-w', sign_with, nexus_repo_url])
     if status:
         sys.exit(status)
 
@@ -81,3 +102,4 @@ def deploy_nexus(ctx, nexus_url, nexus_repo, staging_profile_id, sign_dir, root_
 sign.add_command(directory)
 sign.add_command(nexus)
 sign.add_command(deploy_nexus)
+sign.add_command(sigul)
index 711f605..e4a7f46 100755 (executable)
@@ -9,7 +9,19 @@
 # http://www.eclipse.org/legal/epl-v10.html
 ##############################################################################
 
-# Sign artifacts with gpg
+# Sign artifacts with gpg or sigul
+
+# Sigul signing requires the following:
+#
+# * sigul is installed
+# * configuration file for sigul with the full file path to the file as an
+#   environment variable of $SIGUL_CONFIG
+# * the sigul user (key) as an environment variable of $SIGUL_KEY
+# * the sigul nss password, null terminated in a file referred to by
+#   $SIGUL_PASSWORD
+#
+# If this is being run via JJB and sigul was installed via the scaffolding
+# macros then all environment variables should already be properly set
 
 GPG_BIN="gpg"
 if hash gpg2 2>/dev/null; then
@@ -24,7 +36,7 @@ sign() {
     case "$subcommand" in
         dir )
             echo "Signing Directory..."
-            sign_dir "$@"
+            sign_dir 'gpg' "$@"
             exit 0
             ;;
         nexus )
@@ -32,6 +44,11 @@ sign() {
             sign_nexus "$@"
             exit 0
             ;;
+        sigul )
+            echo "Signing Directory with Sigul..."
+            sign_dir 'sigul' "$@"
+            exit 0
+            ;;
         * )
             echo "Invalid command: $subcommand" 1>&2
             exit 1
@@ -46,15 +63,18 @@ sign_dir() {
     # Parameters:
     #
     #     <directory>: The directory to find and sign artifacts.
-    local dir="$1"
+    local signer="$1"
+    local dir="$2"
 
-    if [ -z "$1" ]; then
+    if [ -z "$2" ]; then
         echo "Missing required arguments."
-        echo "Usage: $0 sign-dir <directory>"
+        echo "Usage: $0 sign-dir 'gpg|sigul' <directory>"
         exit 1
     fi
 
-    test_gpg_key
+    if [ "$signer" == "gpg" ]; then
+        test_gpg_key
+    fi
 
     set -e  # Fail immediately if any if signing fails
     mapfile -t files_to_sign < <(find "$dir" -type f ! -name "*.asc" \
@@ -73,19 +93,49 @@ sign_dir() {
 
     if hash parallel 2>/dev/null; then
         echo "Signing in parallel..."
-        # We need to wordsplit ${files_to_sign[*]} so disable quoting check
-        # shellcheck disable=SC2086
-        parallel --no-notice --jobs 200% --halt now,fail=1 \
-            "$GPG_BIN --batch -abq {}" ::: ${files_to_sign[*]}
+        case "$signer" in
+            gpg )
+                # We need to wordsplit ${files_to_sign[*]} so disable quoting check
+                # shellcheck disable=SC2086
+                parallel --no-notice --jobs 200% --halt now,fail=1 \
+                    "$GPG_BIN --batch -abq {}" ::: ${files_to_sign[*]}
+                ;;
+            sigul )
+                # We need to wordsplit ${files_to_sign[*]} so disable quoting check
+                # shellcheck disable=SC2086
+                parallel --no-notice --jobs 200% --halt now,fail=1 \
+                    "sigul --batch -c $SIGUL_CONFIG sign-data -a -o {}.asc \
+                    $SIGUL_KEY {} < $SIGUL_PASSWORD" ::: ${files_to_sign[*]}
+                ;;
+            * )
+                echo "Invalid signer: $signer" 1>&2
+                exit 1
+                ;;
+        esac
 
         echo "Signed the following files:"
         printf '%s\n' "${files_to_sign[@]}"
     else
         echo "GNU parallel not found. Signing in serial mode..."
-        for f in "${files_to_sign[@]}"; do
-            echo "Signing $f"
-            "$GPG_BIN" --batch -abq "$f"
-        done
+        case "$signer" in
+            gpg )
+                for f in "${files_to_sign[@]}"; do
+                    echo "Signing $f"
+                    "$GPG_BIN" --batch -abq "$f"
+                done
+                ;;
+            sigul )
+                for f in "${files_to_sign[@]}"; do
+                    echo "Signing $f"
+                    sigul --batch -c "$SIGUL_CONFIG" sign-data -a -o "$f.asc" \
+                        "$SIGUL_KEY" "$f" < "$SIGUL_PASSWORD"
+                done
+                ;;
+            * )
+                echo "Invalid signer: $signer" 1>&2
+                exit 1
+                ;;
+        esac
     fi
     set +e
 }
@@ -99,16 +149,18 @@ sign_nexus_usage () {
     echo ""
     echo "Options:"
     echo "    -d /path/to/store/signatures"
+    echo "    -w gpg|sigul"
 }
 
 
 sign_nexus() {
-    # Fetch and GPG sign a Nexus repo
+    # Fetch and sign Nexus repo using GPG or sigul
     #
     # The resultant output of this command is stored in
     # /tmp/gpg-signatures.XXXXXXXXXX unless the -d parameter is passed to
     # override.
-    while getopts d:h o; do
+    local signer='gpg'
+    while getopts d:w:h o; do
       case "$o" in
         h)
             sign_nexus_usage
@@ -120,6 +172,16 @@ sign_nexus() {
             mkdir -p "$sign_dir"
             ;;
 
+        w)
+            if [[ "$OPTARG" =~ ^(gpg|sigul)$ ]]
+            then
+                signer="$OPTARG"
+            else
+                sign_nexus_usage
+                exit 1
+            fi
+            ;;
+
         [?])
             sign_nexus_usage
             exit 1
@@ -171,7 +233,12 @@ sign_nexus() {
     done
 
     echo "Signing artifacts..."
-    sign_dir "$sign_dir"
+    if [ "$signer" == "gpg" ]
+    then
+        sign_dir 'gpg' "$sign_dir"
+    else
+        sign_dir 'sigul' "$sign_dir"
+    fi
 
     echo "Removing non-signature files..."
     mapfile -t remove_files < <(find . -type f -not -name '*.asc')