]> git.saurik.com Git - apt.git/commitdiff
tests: cache the apt-key homedir used for Release signing
authorDavid Kalnischkies <david@kalnischkies.de>
Sun, 18 Dec 2016 16:42:17 +0000 (17:42 +0100)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 21 Dec 2016 18:36:10 +0000 (19:36 +0100)
Importing a new secret key into gpg(2) can be increadibly slow which
prolongs the test runs significantly – by caching the homedir we gain a
significant speedbonus as reimporting already present keys seems like a
far less costly operation.

Git-Dch: Ignore

cmdline/apt-key.in
test/integration/framework
test/integration/run-tests

index c9ff4b3f44c4277bcdb0c247d71021510c905fb1..76fa371236ad43dca018e2df5b6e1b81d807e9b5 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 set -e
-unset GREP_OPTIONS
+unset GREP_OPTIONS GPGHOMEDIR CURRENTTRAP
 export IFS="$(printf "\n\b")"
 
 MASTER_KEYRING='&keyring-master-filename;'
@@ -526,6 +526,11 @@ while [ -n "$1" ]; do
         # … other more complicated ones pipe gpg into gpg.
        aptkey_execute() { echo >&2 'EXEC:' "$@"; sh "$@"; }
        ;;
+      --homedir)
+        # force usage of a specific homedir instead of creating a temporary
+        shift
+        GPGHOMEDIR="$1"
+       ;;
       --*)
         echo >&2 "Unknown option: $1"
         usage
@@ -593,9 +598,13 @@ cleanup_gpg_home() {
     rm -rf "$GPGHOMEDIR"
 }
 
+# gpg needs (in different versions more or less) files to function correctly,
+# so we give it its own homedir and generate some valid content for it later on
 create_gpg_home() {
-    # gpg needs (in different versions more or less) files to function correctly,
-    # so we give it its own homedir and generate some valid content for it later on
+    # for cases in which we want to cache a homedir due to expensive setup
+    if [ -n "$GPGHOMEDIR" ]; then
+       return
+    fi
     if [ -n "$TMPDIR" ]; then
        # tmpdir is a directory and current user has rwx access to it
        # same tests as in apt-pkg/contrib/fileutl.cc GetTempDir()
@@ -603,7 +612,7 @@ create_gpg_home() {
            unset TMPDIR
        fi
     fi
-    GPGHOMEDIR="$(mktemp -d)"
+    GPGHOMEDIR="$(mktemp --directory --tmpdir 'apt-key-gpghome.XXXXXXXXXX')"
     CURRENTTRAP="${CURRENTTRAP} cleanup_gpg_home;"
     trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
     if [ -z "$GPGHOMEDIR" ]; then
@@ -644,6 +653,13 @@ EOF
 
     create_gpg_home
 
+    # now tell gpg that it shouldn't try to maintain this trustdb file
+    echo "#!/bin/sh
+exec '$(escape_shell "${GPG_EXE}")' --ignore-time-conflict --no-options --no-default-keyring \\
+--homedir '$(escape_shell "${GPGHOMEDIR}")' --no-auto-check-trustdb --trust-model always \"\$@\"" > "${GPGHOMEDIR}/gpg.0.sh"
+    GPG_SH="${GPGHOMEDIR}/gpg.0.sh"
+    GPG="$GPG_SH"
+
     # create the trustdb with an (empty) dummy keyring
     # older gpgs required it, newer gpgs even warn that it isn't needed,
     # but require it nonetheless for some commands, so we just play safe
@@ -655,13 +671,6 @@ EOF
        false
     fi
 
-    # now tell gpg that it shouldn't try to maintain this trustdb file
-    echo "#!/bin/sh
-exec '$(escape_shell "${GPG_EXE}")' --ignore-time-conflict --no-options --no-default-keyring \\
---homedir '$(escape_shell "${GPGHOMEDIR}")' --no-auto-check-trustdb --trust-model always \"\$@\"" > "${GPGHOMEDIR}/gpg.0.sh"
-    GPG_SH="${GPGHOMEDIR}/gpg.0.sh"
-    GPG="$GPG_SH"
-
     # We don't usually need a secret keyring, of course, but
     # for advanced operations, we might really need a secret keyring after all
     if [ -n "$FORCED_SECRET_KEYRING" ] && [ -r "$FORCED_SECRET_KEYRING" ]; then
index 05c8fcd2aeeaa4ce58edfa277295688e90f9fb1a..a0e9e759cdf6772edf780d8aca87d6ff8e8adcad 100644 (file)
@@ -1157,6 +1157,30 @@ setupaptarchive() {
        fi
 }
 
+killgpgagent() {
+       if [ -z "${TMPWORKINGDIRECTORY}" ]; then return; fi
+       local GPGHOME="${TMPWORKINGDIRECTORY}/signinghome"
+       if [ -e "${GPGHOME}" ]; then return; fi
+       # ensure the agent dies quickly as different versions have different suicide heuristics
+       GNUPGHOME="${GPGHOME}" gpgconf --kill gpg-agent >/dev/null 2>&1 || true
+       rm -rf "$GPGHOME"
+}
+dosigning() {
+       local KEY="$1"
+       shift
+       local GPGHOME="${TMPWORKINGDIRECTORY}/signinghome"
+       if [ -n "$APT_TEST_SIGNINGHOME" ]; then
+               GPGHOME="$APT_TEST_SIGNINGHOME"
+       else
+               if [ ! -e "$GPGHOME" ]; then
+                       mkdir -p --mode=700 "${GPGHOME}"
+                       addtrap 'prefix' 'killgpgagent;'
+               fi
+       fi
+       testsuccess aptkey --quiet --keyring ${KEY}.pub --secret-keyring ${KEY}.sec --readonly \
+               --homedir "${GPGHOME}" adv --batch --yes --digest-algo "${APT_TESTS_DIGEST_ALGO:-SHA512}" \
+               "$@"
+}
 signreleasefiles() {
        local SIGNERS="${1:-Joe Sixpack}"
        local REPODIR="${2:-aptarchive}"
@@ -1208,21 +1232,20 @@ signreleasefiles() {
                mv "${KEY}.new.pub" "${KEY}.pub"
                mv "${KEY}.new.sec" "${KEY}.sec"
        fi
-       local GPG="aptkey --quiet --keyring ${KEY}.pub --secret-keyring ${KEY}.sec --readonly adv --batch --yes --digest-algo ${APT_TESTS_DIGEST_ALGO:-SHA512}"
        for RELEASE in $(find "${REPODIR}/" -name Release); do
                # we might have set a specific date for the Release file, so copy it
                local DATE="$(stat --format "%y" "${RELEASE}")"
                if [ "$APT_DONT_SIGN" = 'Release.gpg' ]; then
                        rm -f "${RELEASE}.gpg"
                else
-                       testsuccess $GPG "$@" $SIGUSERS --armor --detach-sign --sign --output "${RELEASE}.gpg" "${RELEASE}"
+                       dosigning "$KEY" "$@" $SIGUSERS --armor --detach-sign --sign --output "${RELEASE}.gpg" "${RELEASE}"
                        touch -d "$DATE" "${RELEASE}.gpg"
                fi
                local INRELEASE="${RELEASE%/*}/InRelease"
                if [ "$APT_DONT_SIGN" = 'InRelease' ]; then
                        rm -f "$INRELEASE"
                else
-                       testsuccess $GPG "$@" $SIGUSERS --clearsign --output "$INRELEASE" "$RELEASE"
+                       dosigning "$KEY" "$@" $SIGUSERS --clearsign --output "$INRELEASE" "$RELEASE"
                        touch -d "$DATE" "${INRELEASE}"
                fi
        done
index 7c0b74ce238921af56cc7258970d49604f699bad..3dcacc7bd890aab31be98594f14aa1639f8dfe33 100755 (executable)
@@ -107,6 +107,16 @@ if [ -n "$APT_TEST_JOBS" ]; then
        fi
        exec $parallel -j "$APT_TEST_JOBS" "./$(basename "$0")" -- $(echo "$TESTLIST")
 fi
+
+APT_TEST_SIGNINGHOME="$(mktemp --directory --tmpdir 'apt-key-signinghome.XXXXXXXXXX')"
+removesigninghome() {
+       if [ -z "$APT_TEST_SIGNINGHOME" ]; then return; fi
+       GNUPGHOME="${APT_TEST_SIGNINGHOME}" gpgconf --kill gpg-agent >/dev/null 2>&1 || true
+       rm -rf -- "$APT_TEST_SIGNINGHOME"
+}
+trap "removesigninghome; exit 0" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
+export APT_TEST_SIGNINGHOME
+
 TOTAL="$(echo "$TESTLIST" | wc -l)"
 if [ "$MSGLEVEL" -le 1 ]; then
        printf "${CTEST}Running testcases${CRESET}: "