initial commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify VM inputs and install small helper tools into the VM workspace only."""
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import urllib.request
|
||||
import zipfile
|
||||
|
||||
root = Path(os.environ.get('DOCVIEW_VM_WORK', 'build-ubuntu-vm')).resolve()
|
||||
downloads = root / 'downloads'
|
||||
keyring = root / 'private/gnupg'
|
||||
keyring.mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||
fingerprint = 'D2EB44626FDDC30B513D5BB71A5D6C4C7DB87C81'
|
||||
|
||||
|
||||
def run(command, log):
|
||||
result = subprocess.run(command, capture_output=True, text=True)
|
||||
(root / 'logs' / log).write_text(result.stdout + result.stderr)
|
||||
result.check_returncode()
|
||||
return result.stdout + result.stderr
|
||||
|
||||
|
||||
run(['gpg', '--homedir', str(keyring), '--batch', '--import',
|
||||
str(downloads / 'ubuntu-cloud-key.asc')], 'ubuntu-key-import.txt')
|
||||
identity = run(['gpg', '--homedir', str(keyring), '--batch', '--with-colons',
|
||||
'--fingerprint'], 'ubuntu-key-fingerprint.txt')
|
||||
assert 'fpr:::::::::' + fingerprint + ':' in identity
|
||||
verification = run(['gpg', '--homedir', str(keyring), '--batch', '--status-fd', '1',
|
||||
'--verify', str(downloads / 'SHA256SUMS.gpg'),
|
||||
str(downloads / 'SHA256SUMS')], 'ubuntu-sha-signature.txt')
|
||||
assert 'VALIDSIG ' + fingerprint + ' ' in verification
|
||||
filename = 'noble-server-cloudimg-amd64.img'
|
||||
expected = next(line.split()[0] for line in (downloads / 'SHA256SUMS').read_text().splitlines()
|
||||
if line.split()[1].lstrip('*') == filename)
|
||||
with (downloads / filename).open('rb') as stream:
|
||||
actual = hashlib.file_digest(stream, 'sha256').hexdigest()
|
||||
assert actual == expected
|
||||
qemu = downloads / 'qemu-img-11.1.1-2-x86_64.pkg.tar.zst'
|
||||
with qemu.open('rb') as stream:
|
||||
assert hashlib.file_digest(stream, 'sha256').hexdigest() == 'a095493f3fffa82cc5db3a8409950124e67e45cb6ca30456a5851362be5c396a'
|
||||
# This host-only bootstrap recipe was tested on Arch. Its trusted repository
|
||||
# keyring is read-only; an Ubuntu guest does not use this host package.
|
||||
run(['gpgv', '--keyring', '/etc/pacman.d/gnupg/pubring.gpg', str(qemu) + '.sig',
|
||||
str(qemu)], 'qemu-package-signature.txt')
|
||||
subprocess.run(['bsdtar', '-xf', str(qemu), '-C', str(root / 'tools'),
|
||||
'usr/bin/qemu-img'], check=True)
|
||||
package = json.loads((downloads / 'pycdlib.json').read_text())
|
||||
wheel = next(item for item in package['urls'] if item['filename'].endswith('.whl'))
|
||||
target = downloads / wheel['filename']
|
||||
if not target.exists():
|
||||
with urllib.request.urlopen(wheel['url'], timeout=45) as response:
|
||||
target.write_bytes(response.read(300000))
|
||||
with target.open('rb') as stream:
|
||||
assert hashlib.file_digest(stream, 'sha256').hexdigest() == wheel['digests']['sha256']
|
||||
assert target.stat().st_size == wheel['size']
|
||||
with zipfile.ZipFile(target) as archive:
|
||||
archive.extractall(root / 'tools/python')
|
||||
report = {'ubuntuImageSignatureValid': True, 'ubuntuSigningFingerprint': fingerprint,
|
||||
'ubuntuImageSha256': actual, 'ubuntuImageSize': (downloads / filename).stat().st_size,
|
||||
'qemuPackageSha256MatchesLocalRepositoryDatabase': True, 'qemuPackageSignatureValid': True}
|
||||
(root / 'metadata/verification.json').write_text(json.dumps(report, indent=2) + '\n')
|
||||
print('Verified Ubuntu signed checksum/image, QEMU package and local ISO helper.')
|
||||
Reference in New Issue
Block a user