Skip to content

Instantly share code, notes, and snippets.

@antichris
Created March 12, 2023 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antichris/310eab3407edc37e356fe9f8a49f5ded to your computer and use it in GitHub Desktop.
Save antichris/310eab3407edc37e356fe9f8a49f5ded to your computer and use it in GitHub Desktop.
Move an `apt` keyring to the canonical storage and add as the signing keyring for a `sources.list.d/` entry.
#!/bin/sh -e
## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at https://mozilla.org/MPL/2.0/.
self=$(basename "$(readlink -f "$0")")
krDir=/etc/apt/keyrings
usage=$(cat) <<***
Usage: ${self} KEYRING SOURCELIST
Move KEYRING to ${krDir} and add as the signing keyring for SOURCELIST.
--help display this help and exit
The KEYRING is moved from its current location to ${krDir} and all
repository entries in the SOURCELIST are updated to have the Signed-By option
point to the KEYRING at its new location in ${krDir}.
KEYRING is an OpenPGP certificate (also known as "GPG key public ring") file.
SOURCELIST is a ONE-LINE-STYLE format .list file (see sources.list(5) manpage).
Example:
${self} /etc/apt/trusted.gpg.d/google-chrome.gpg \\
/etc/apt/sources.list.d/google-chrome.list
***
main() {
for arg; do
[ "$arg" = '--help' ] && dieWithUsage 0
done
krSrc=$(reqFile "$1" KEYRING) || dieWithUsage $? " "
krDst=${krDir}/$(basename "$krSrc")
sources=$(reqFile "$2" SOURCELIST) || dieWithUsage $? " "
reqFileMIME "$sources" text/plain || dieWithUsage $? " "
ss='signed-by='
rxDeb='(^\s*(#+\s*)?deb(-src)?\s+)'
sed -Ei "/${rxDeb}/{
s%${rxDeb}(\\[[^]]+)?${ss}.*\\]%\0%;t;
s%${rxDeb}(\\[[^]]+)(\\])%\1\4 ${ss}${krDst}\5%;t;
s%${rxDeb}(https?://)%\1[${ss}${krDst}] \4%;t;
}" "$sources"
if [ -e "$krDst" ]; then
printf 'not moving "%s": destination "%s" already exists\n' \
"$krSrc" "$krDst"
else
mv "$krSrc" "$krDst"
fi
}
dieWithUsage() { ## ([exit_value [error_message]])
[ "$2" ] && printf %s\\n "$2" >&2
printf '%s\n\n' "$usage"
exit "${1:-0}"
}
reqFile() { ## (filename)
if [ ! -f "$1" ]; then
printf '%s filename required\n' "$2" >&2
return 1
fi
readlink -f "$1"
}
reqFileMIME() { ## (filename MIME_type)
t=$(file -b --mime-type "$1")
if [ "$t" != "$2" ]; then
printf 'bad MIME type of "%s": "%s", want "%s"\n' >&2 \
"$1" "$t" "$2"
return 2
fi
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment