Keep systemd-managed directories inside root snapshots
This commit is contained in:
@@ -266,6 +266,42 @@ def brand_os_release(root):
|
||||
write(root, 'etc/os-release', '\n'.join(retained) + '\n')
|
||||
|
||||
|
||||
def configure_managed_root_tmpfiles(root):
|
||||
"""Keep automatic systemd directories inside the recoverable root snapshot.
|
||||
|
||||
Same-name overrides retain the installed vendor policy, changing only the
|
||||
three subvolume-creation rules. Do not mask nspawn cleanup/socket rules or
|
||||
the separately mounted /home. Unexpected vendor changes need a review.
|
||||
"""
|
||||
overrides = []
|
||||
for filename, target in (('home.conf', '/srv'),
|
||||
('portables.conf', '/var/lib/portables'),
|
||||
('systemd-nspawn.conf', '/var/lib/machines')):
|
||||
vendor = root_path(root, 'usr/lib/tmpfiles.d/' + filename)
|
||||
destination = 'etc/tmpfiles.d/' + filename
|
||||
override = root_path(root, destination, follow_leaf=False)
|
||||
if vendor.is_symlink() or not vendor.is_file():
|
||||
raise ImageError(f'Required ordinary vendor tmpfiles policy is missing: {filename}')
|
||||
if override.is_symlink() or override.exists():
|
||||
raise ImageError(f'Refusing to replace an existing tmpfiles override: {filename}')
|
||||
lines = vendor.read_text().splitlines(keepends=True)
|
||||
matches = []
|
||||
for index, line in enumerate(lines):
|
||||
fields = line.split()
|
||||
if fields and not fields[0].startswith('#') and len(fields) > 1 and fields[1] == target:
|
||||
matches.append((index, fields[0]))
|
||||
if len(matches) != 1 or matches[0][1] not in ('q', 'Q'):
|
||||
raise ImageError(f'Expected one vendor tmpfiles q/Q rule for {target}: {filename}')
|
||||
index = matches[0][0]
|
||||
line = lines[index]
|
||||
start = len(line) - len(line.lstrip(' \t'))
|
||||
lines[index] = line[:start] + 'd' + line[start + 1:]
|
||||
overrides.append((destination, ''.join(lines)))
|
||||
# Validate the complete policy before publishing any same-name overrides.
|
||||
for destination, content in overrides:
|
||||
write(root, destination, content)
|
||||
|
||||
|
||||
def configure_rootfs(root, source):
|
||||
root, source = Path(root), Path(source)
|
||||
# Refuse incomplete integrations before changing the exported copy.
|
||||
@@ -281,6 +317,7 @@ def configure_rootfs(root, source):
|
||||
alias.symlink_to(kernel.name)
|
||||
sanitize_rootfs(root)
|
||||
copy_overlay(root, source / 'image/rootfs')
|
||||
configure_managed_root_tmpfiles(root)
|
||||
brand_os_release(root)
|
||||
write(root, 'etc/hydra/live-mode/dracut.conf', (source / 'image/dracut.conf').read_text())
|
||||
root_path(root, 'etc/hydra/live-mode/dracut.conf.d').mkdir()
|
||||
|
||||
Reference in New Issue
Block a user