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:
Marcelo Alcantara committed 2026-09-24 16:05:38 +10:00
1 parent aa64ec9a4f
commit 90fee672ce
7 files changed
+10 -261

No files matched your search

-115
View File
@@ -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()