Files
archy/scripts/tests/with_exec_profile.py

60 lines
2.4 KiB
Python

"""Provide the exact C01 execution profile for disposable backend tests only."""
from contextlib import contextmanager
import hashlib
import json
from pathlib import Path
import subprocess
import sys
def inventory():
return json.loads(subprocess.check_output(['sudo', '-n', 'aa-status', '--json'], timeout=15))
def parser(action, policy):
result = subprocess.run(['sudo', '-n', '/usr/sbin/apparmor_parser', action, '--skip-cache'],
input=policy, capture_output=True, timeout=15)
if result.returncode:
raise RuntimeError(f'Execution-profile fixture {action} failed (exit {result.returncode}): '
+ result.stderr.decode(errors='replace'))
@contextmanager
def loaded_profile(repo):
template = (Path(repo) / 'image-recipe/configs/archipelago-manager-exec.profile.in').read_bytes()
name = 'archipelago-manager-exec-' + hashlib.sha256(template).hexdigest()
policy = template.replace(b'@PROFILE@', name.encode())
before = inventory()
if name in before['profiles']:
if before['profiles'][name] != 'enforce':
raise RuntimeError('Existing execution profile is not enforcing; refusing to replace it')
# An installed policy belongs to its existing owner. Never replace/remove it.
yield name
return
parser('-a', policy)
try:
if inventory()['profiles'].get(name) != 'enforce':
raise RuntimeError('Fixture execution profile was not loaded in enforce mode')
yield name
finally:
current = inventory()
if any(item['profile'] == name for rows in current['processes'].values() for item in rows):
raise RuntimeError('Execution-profile fixture still has bound processes; retaining policy')
parser('-R', policy)
after = inventory()
if name in after['profiles'] or after['profiles'] != before['profiles']:
raise RuntimeError('Execution-profile cleanup did not preserve the original policy set')
print('PASS temporary C01 execution profile removed; original policy set preserved', flush=True)
def main():
if len(sys.argv) < 4 or sys.argv[2] != '--':
raise SystemExit('usage: with_exec_profile.py SOURCE_ROOT -- COMMAND [ARG...]')
with loaded_profile(sys.argv[1]):
result = subprocess.run(sys.argv[3:])
return result.returncode
if __name__ == '__main__':
raise SystemExit(main())