Register 32-bit ARM binfmt rules and keep QEMU changes package-local
qemu-binfmt-conf.sh groups arm with aarch64 and skipped it; Apple Silicon has no AArch32 execution, so --ignore-family is needed for ARM32 programs. The bin/sync-upstream extension, its tests and the Tests workflow edit are reverted; QEMU updates become reviewed pins.
This commit is contained in:
1 parent
aa64ec9a4f
commit
90fee672ce
7 files changed
+10
-261
No files matched your search
@@ -1,115 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import lzma
|
||||
import re
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
PACKAGE = ROOT / 'pkgbuilds/qemu-user-static'
|
||||
spec = importlib.util.spec_from_file_location('qemu', PACKAGE / '.omarchy/upstream.py')
|
||||
q = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(q)
|
||||
CURRENT = '1:10.0.11+ds-0+deb13u1+b1'
|
||||
|
||||
class Updates(unittest.TestCase):
|
||||
def fixtures(self, version):
|
||||
blob = b'fixture package bytes'
|
||||
sha = hashlib.sha256(blob).hexdigest()
|
||||
snap = hashlib.sha1(blob).hexdigest()
|
||||
row = f'Package: qemu-user\nArchitecture: arm64\nVersion: {version}\nSHA256: {sha}\nSize: {len(blob)}\n'
|
||||
feeds = {url: lzma.compress(row.encode()) for url in q.FEEDS}
|
||||
def get(url):
|
||||
if url in feeds: return feeds[url]
|
||||
if '/mr/' in url:
|
||||
return json.dumps({'binary':'qemu-user', 'binary_version':version,
|
||||
'result':[{'architecture':'arm64','hash':snap}]}).encode()
|
||||
return blob
|
||||
return get, feeds, sha
|
||||
|
||||
def test_versions(self):
|
||||
for old, new in [(CURRENT,'1:10.0.11+ds-0+deb13u1+b2'),
|
||||
(CURRENT,'1:10.0.11+ds-0+deb13u2'),
|
||||
(CURRENT,'1:10.0.12+ds-1'),
|
||||
(CURRENT,'2:9.0.0+ds-1')]:
|
||||
with self.subTest(new=new):
|
||||
get,_,_=self.fixtures(new)
|
||||
result=q.discover(old,q.package_version(old),'0'*64,get)
|
||||
self.assertEqual(result['variables']['_debver'],new)
|
||||
self.assertGreater(q.compare(new,old),0)
|
||||
self.assertLess(q.compare('1:10.0~rc1-1','1:10.0-1'),0)
|
||||
self.assertLess(q.compare('1:10.0-2','1:10.0-10'),0)
|
||||
|
||||
def test_security_wins(self):
|
||||
newer='1:10.0.11+ds-0+deb13u2'
|
||||
get,feeds,_=self.fixtures(newer)
|
||||
_,oldfeeds,_=self.fixtures(CURRENT)
|
||||
feeds[q.FEEDS[0]]=oldfeeds[q.FEEDS[0]]
|
||||
self.assertEqual(q.discover(CURRENT,q.package_version(CURRENT),'0'*64,get)['variables']['_debver'],newer)
|
||||
|
||||
def test_unchanged(self):
|
||||
get,_,sha=self.fixtures(CURRENT)
|
||||
self.assertEqual(q.discover(CURRENT,q.package_version(CURRENT),sha,get),{})
|
||||
with self.assertRaisesRegex(ValueError,'Checksum changed'):
|
||||
q.discover(CURRENT,q.package_version(CURRENT),'0'*64,get)
|
||||
|
||||
def test_bad_metadata(self):
|
||||
get,feeds,_=self.fixtures('1:10.0.12+ds-1')
|
||||
feeds[q.FEEDS[0]]=lzma.compress(b'Package: qemu-user\nArchitecture: arm64\nVersion: invalid\n')
|
||||
with self.assertRaises(ValueError): q.discover(CURRENT,q.package_version(CURRENT),'0'*64,get)
|
||||
|
||||
def test_snapshot_failures(self):
|
||||
for failure in ['missing','bytes','metadata']:
|
||||
get,_,_=self.fixtures('1:10.0.12+ds-1')
|
||||
def bad(url):
|
||||
if '/file/' in url:
|
||||
if failure=='missing': raise OSError('unavailable snapshot')
|
||||
if failure=='bytes': return b'corrupt'
|
||||
if '/mr/' in url and failure=='metadata': return b'{}'
|
||||
return get(url)
|
||||
with self.subTest(failure=failure), self.assertRaises((ValueError,OSError)):
|
||||
q.discover(CURRENT,q.package_version(CURRENT),'0'*64,bad)
|
||||
|
||||
def sync(self, recipe, release):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
p=Path(tmp)/'fixture'; (p/'.omarchy').mkdir(parents=True)
|
||||
(p/'PKGBUILD').write_text(recipe)
|
||||
(p/'.omarchy/package.json').write_text('{"source":"local"}')
|
||||
(p/'.omarchy/upstream.sh').write_text("#!/bin/bash\ncat <<'JSON'\n"+json.dumps(release)+"\nJSON\n")
|
||||
# Load production functions, excluding only the command dispatch.
|
||||
prefix=(ROOT/'bin/sync-upstream').read_text().split('if [[ ${#SPECIFIC_PACKAGES[@]} -gt 0 &&')[0]
|
||||
prefix=prefix.replace('BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")', 'BUILD_ROOT='+str(ROOT))
|
||||
command=prefix+'\nPKGBUILDS_DIR='+tmp+'\nSPECIFIC_MODE=true\nsync_package fixture\n((FAILED == 0))\n'
|
||||
result=subprocess.run(['bash','-c',command],capture_output=True,text=True)
|
||||
return result,(p/'PKGBUILD').read_text()
|
||||
|
||||
def test_atomic_sync_and_idempotence(self):
|
||||
get,_,_=self.fixtures('1:10.0.11+ds-0+deb13u2')
|
||||
release=q.discover(CURRENT,q.package_version(CURRENT),'0'*64,get)
|
||||
before=(PACKAGE/'PKGBUILD').read_text()
|
||||
before=re.sub(r'^pkgver=.*$', 'pkgver='+q.package_version(CURRENT), before, flags=re.M)
|
||||
before=re.sub(r'^_debver=.*$', '_debver='+CURRENT, before, flags=re.M)
|
||||
result,after=self.sync(before,release)
|
||||
self.assertEqual(result.returncode,0,result.stdout+result.stderr)
|
||||
self.assertIn('_debver='+release['variables']['_debver'],after)
|
||||
self.assertIn('_snapshot='+release['variables']['_snapshot'],after)
|
||||
self.assertIn(release['sha256sums']['aarch64'][0],after)
|
||||
result,again=self.sync(after,release)
|
||||
self.assertEqual(result.returncode,0,result.stdout+result.stderr)
|
||||
self.assertEqual(again,after)
|
||||
|
||||
def test_invalid_variables_leave_recipe_unchanged(self):
|
||||
before=(PACKAGE/'PKGBUILD').read_text()
|
||||
for variables in [{'_debver':'$(touch /tmp/qemu-injection)'}, {'pkgver':'2'},
|
||||
{'_absent':'1'}, {'_snapshot':'abc\ncommand'}, {'_snapshot':'https://bad'}]:
|
||||
with self.subTest(variables=variables):
|
||||
result,after=self.sync(before,{'pkgver':'99','variables':variables,'sha256sums':{'aarch64':['a'*64]}})
|
||||
self.assertNotEqual(result.returncode,0)
|
||||
self.assertEqual(before,after)
|
||||
|
||||
if __name__=='__main__': unittest.main()
|
||||
Reference in new issue
Block a user