Files
computer-playbook/tests/unit/python/scripts/system/apparmor/test_common.py
T
kevinveenbirkenbachandClaude Opus 5.5 a6c3c1cc91 fix(apparmor): keep docker-default loaded when tearing AppArmor down
`security-apparmor-teardown` ran `aa-teardown`, which unloads every
profile including dockerd's in-memory `docker-default`. dockerd only loads
that profile when it starts, so every container start afterwards that
requests it fails until dockerd restarts. Since #1067 runs the teardown on
the GitHub runners, BuildKit failed each RUN of the swarm node image three
times (run 39332343490, 39 of 40 swarm jobs):

    runc run failed: unable to start container process: error during
    container init: unable to apply apparmor profile: apparmor failed to
    apply profile: write .../attr/apparmor/exec: no such file or directory

The teardown now removes each loaded profile by name through securityfs
and skips `docker-default` and child profiles, which leave with their
parent. Dev hosts gain the same: no dockerd restart is needed after
`make environment-bootstrap`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 12:11:14 +02:00

49 lines
1.2 KiB
Python

"""The AppArmor teardown must keep docker-default loaded.
Run 39332343490 lost 39 swarm jobs: the runner's teardown unloaded every
profile, and BuildKit then failed each node image RUN step with
`apparmor failed to apply profile: write .../attr/apparmor/exec: no such file`.
"""
from __future__ import annotations
import subprocess
import unittest
from utils.cache.files import PROJECT_ROOT
COMMON = PROJECT_ROOT / "scripts" / "system" / "apparmor" / "common.sh"
PROFILES = """wg-quick (enforce)
wg-quick//ip (enforce)
docker-default (enforce)
/usr/bin/man (enforce)
unprivileged_userns (unconfined)
docker-defaults (complain)
"""
class TestRemovableProfiles(unittest.TestCase):
def test_keeps_docker_default_and_child_profiles(self) -> None:
result = subprocess.run(
["bash", "-c", f'source "{COMMON}"; apparmor_removable_profiles'],
input=PROFILES,
capture_output=True,
text=True,
check=True,
)
self.assertEqual(
[
"wg-quick",
"/usr/bin/man",
"unprivileged_userns",
"docker-defaults",
],
result.stdout.splitlines(),
)
if __name__ == "__main__":
unittest.main()