Last active
June 15, 2020 03:10
-
-
Save bryanjhv/a357fc6bbc44eeeb788ee029400a9600 to your computer and use it in GitHub Desktop.
Get PPA .gpg and .list files easily on Ubuntu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# USAGE: | |
# getppa git-core/ppa bionic | |
# getppa certbot/certbot bionic | |
# getppa git-core/ppa bionic git.%s | |
# getppa certbot/certbot bionic certbot.%s | |
from shutil import rmtree | |
from sys import argv, exit | |
from atexit import register | |
from tempfile import mkdtemp | |
from json import dumps, loads | |
from subprocess import Popen, PIPE | |
from urllib.error import HTTPError | |
from urllib.request import Request, urlopen | |
DEB_URL = 'deb http://ppa.launchpad.net/%s/%s/ubuntu %s main' | |
PPA_URL = 'https://launchpad.net/api/1.0/~%s/+archive/ubuntu/%s' | |
KEY_URL = 'https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&exact=on&search=0x%s' | |
def req(url, json=False): | |
res = urlopen(Request(url)) | |
data = res.read().decode('utf-8', 'strict') | |
return loads(data) if json else data | |
h = mkdtemp() | |
register(lambda: rmtree(h)) | |
def gpg(args, stdin): | |
cmd = 'gpg -q --homedir %s --no-default-keyring --no-options --import --import-options %s' % (h, args) | |
p = Popen(cmd.split(), stdin=PIPE, stdout=PIPE) | |
(stdout, _) = p.communicate(stdin) | |
return (p.returncode, stdout) | |
def download(ppa, code, base=None): | |
try: | |
(owner, name) = ppa.split('/') | |
info = req(PPA_URL % (owner, name), True) | |
if not base: base = '%s__%s.%%s' % (owner, name) | |
ppa_list = DEB_URL % (owner, name, code) + '\n' | |
ppa_list += ppa_list.replace('deb', '# deb-src', 1) | |
fingerprint = info['signing_key_fingerprint'] | |
armored_key = req(KEY_URL % fingerprint, False) | |
(r, minimal_key) = gpg('import-minimal,import-export', armored_key.encode()) | |
if r != 0: | |
print('ERROR: Cannot minify GPG key.') | |
exit(2) | |
fingerprints = [] | |
(r, output) = gpg('show-only --fingerprint --batch --with-colons', minimal_key) | |
if r == 0: | |
for line in output.decode('utf-8').splitlines(): | |
if line.startswith('fpr:'): | |
fingerprints.append(line.split(':')[9]) | |
if len(fingerprints) != 1: | |
print('ERROR: There are many GPG fingerprints.') | |
exit(2) | |
if fingerprint != fingerprints[0]: | |
print('ERROR: GPG fingerprints not matching.') | |
exit(2) | |
ppa_gpg = minimal_key | |
with open(base % 'list', 'w') as f: | |
f.write(ppa_list) | |
with open(base % 'gpg', 'wb') as f: | |
f.write(ppa_gpg) | |
print('SUCCESS!') | |
print() | |
print('Run the following:') | |
print() | |
print(' sudo chmod 644 %s' % (base % '*')) | |
print(' sudo chown root:root %s' % (base % '*')) | |
print(' sudo mv %s /etc/apt/trusted.gpg.d' % (base % 'gpg')) | |
print(' sudo mv %s /etc/apt/sources.list.d' % (base % 'list')) | |
print(' sudo apt update') | |
print() | |
except HTTPError as e: | |
if e.code == 404: | |
print('ERROR: PPA does not exist.') | |
exit(2) | |
print('ERROR: Unknown network error.') | |
exit(2) | |
if __name__ == '__main__': | |
if len(argv) < 3: | |
print('USAGE: %s user/repo code [base]' % argv[0]) | |
exit(1) | |
download(*argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment