Files
archy/scripts/tests/os_update_debian_chain.py

52 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""Read/download-only Debian chain qualification. Does not invoke apt or dpkg.
Externally selected unsigned test metadata exercises repository.acquire only;
it cannot appoint a production release or call Executor.apply.
"""
import json
import lzma
import pathlib
import sys
import urllib.request
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
from os_update_plan import digest
from os_update_repository import KEYRING, NoRedirect, acquire, command, fetch, paragraphs
def main():
root = pathlib.Path(sys.argv[1]).resolve()
assert not root.exists() and root.parent.is_dir()
root.mkdir(mode=0o700)
pocket = 'bookworm-updates'
base = 'https://deb.debian.org/debian/dists/' + pocket + '/'
with urllib.request.build_opener(NoRedirect).open(base + 'InRelease', timeout=60) as response:
raw = response.read(8 * 1024**2)
(root / 'InRelease').write_bytes(raw)
command(['/usr/bin/gpgv', '--keyring', KEYRING, '--output', str(root / 'Release'), str(root / 'InRelease')])
release = paragraphs((root / 'Release').read_bytes())[0]
wanted = 'main/binary-amd64/Packages.xz'
match = [line.split() for line in release['SHA256'].splitlines() if line.strip() and line.split()[2] == wanted]
assert len(match) == 1
sha, size, path = match[0]
index = fetch(base + path, sha, int(size))
rows = paragraphs(lzma.decompress(index))
eligible = [r for r in rows if r.get('Architecture') in ('all', 'amd64') and int(r.get('Size', '0')) > 0]
row = min(eligible, key=lambda r: int(r['Size']))
package = dict(name=row['Package'], version=row['Version'], architecture=row['Architecture'],
sha256=row['SHA256'], size=int(row['Size']), filename=row['Filename'], pocket=pocket)
plan = dict(repositories=[dict(pocket=pocket, inrelease_sha256=digest(raw),
indexes=[dict(path=path, sha256=sha, size=int(size))])], packages=[package],
boot={'package': package}) # Only repository chain, not a valid production OS plan.
(root / 'unsigned-chain-fixture.json').write_text(json.dumps(plan, indent=2) + '\n')
acquire(plan, root / 'mirror')
result = dict(debian_signature_index_archive_chain=True, package=package,
production_manifest_authenticated=False, package_installation=False)
(root / 'result.json').write_text(json.dumps(result, indent=2) + '\n')
print(json.dumps(result, sort_keys=True))
if __name__ == '__main__':
main()