37 lines
1.8 KiB
Python
37 lines
1.8 KiB
Python
"""Package an explicitly selected compiled test ELF and its exact loader/libs.
|
|
|
|
This is a public qualification artifact, never installation/admission authority.
|
|
The destination is new and the binary/source hashes are retained in the receipt.
|
|
"""
|
|
import hashlib
|
|
import io
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tarfile
|
|
|
|
binary,output=map(Path,sys.argv[1:])
|
|
assert binary.is_absolute() and binary.is_file() and output.is_absolute() and output.is_dir()
|
|
compiled_sha256=hashlib.sha256(binary.read_bytes()).hexdigest()
|
|
fixture_binary=output/'native-test-elf'
|
|
assert not fixture_binary.exists()
|
|
subprocess.run(['strip','--strip-debug','-o',str(fixture_binary),str(binary)],check=True)
|
|
libraries={Path(word) for word in subprocess.check_output(['ldd',str(binary)],text=True).split() if word.startswith('/')}
|
|
files={'usr/local/bin/archipelago':fixture_binary}
|
|
for path in libraries:
|
|
source=path.resolve(strict=True)
|
|
for p in [source,*source.parents]:
|
|
meta=p.stat();assert meta.st_uid==0 and not meta.st_mode & 0o022
|
|
files[str(path).lstrip('/')]=source
|
|
manifest={}
|
|
with tarfile.open(output/'native-test.tar','x') as archive:
|
|
for target,source in sorted(files.items()):
|
|
raw=source.read_bytes();manifest[target]={'source':str(source),'sha256':hashlib.sha256(raw).hexdigest()}
|
|
info=tarfile.TarInfo(target);info.mode=0o755;info.uid=info.gid=info.mtime=0;info.size=len(raw)
|
|
archive.addfile(info,io.BytesIO(raw))
|
|
(output/'native-artifact-sha256.json').write_text(json.dumps(manifest,indent=2)+'\n')
|
|
(output/'native-derivation.json').write_text(json.dumps({'compiled_path':str(binary),'compiled_sha256':compiled_sha256,
|
|
'fixture_path':str(fixture_binary),'fixture_sha256':manifest['usr/local/bin/archipelago']['sha256'],
|
|
'command':['strip','--strip-debug','-o',str(fixture_binary),str(binary)]},indent=2)+'\n')
|