Skip to content

Commit

Permalink
Use /usr/share/truenas/sysext-extensions/functioning-dpkg.raw to te…
Browse files Browse the repository at this point in the history
…mporarily allow `dpkg` (#14958)
  • Loading branch information
themylogin authored Nov 21, 2024
1 parent 5762c79 commit 575560c
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions src/middlewared/middlewared/utils/rootfs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass
import contextlib
from dataclasses import dataclass
from functools import cached_property
import json
import os
Expand Down Expand Up @@ -37,6 +37,7 @@ def __init__(self, root="/"):

self.initialized = False
self.datasets: dict[str, Dataset] = {}
self.use_functioning_dpkg_sysext = False

def __enter__(self):
return self
Expand All @@ -49,6 +50,7 @@ def make_writeable(self):
for name, dataset in self.datasets.items()
if dataset.readonly.current
})
self._set_dpkg_sysext_state(True)

def __exit__(self, exc_type, exc_val, exc_tb):
if not self.initialized:
Expand All @@ -59,6 +61,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
for name, dataset in self.datasets.items()
if dataset.readonly.current != dataset.readonly.initial
})
self._set_dpkg_sysext_state(False)

def _initialize(self):
if self.initialized:
Expand All @@ -72,7 +75,13 @@ def _initialize(self):
("", usr_ds.rsplit("/", 1)[0]),
("usr", usr_ds),
]:
mountpoint = "/".join(filter(None, (self.root, dataset)))
mountpoint = os.path.realpath("/".join(filter(None, (self.root, dataset))))

if mountpoint == "/usr":
# We make `/usr` writeable only to be able to temporary enable `dpkg` (`update-initramfs` needs it).
# If we are on live system, it's better to use `systemd-sysext`
self.use_functioning_dpkg_sysext = True
continue

st_mnt_id = stat_x.statx(mountpoint).stx_mnt_id
readonly = "RO" in getmntinfo(mnt_id=st_mnt_id)[st_mnt_id]["super_opts"]
Expand Down Expand Up @@ -109,10 +118,6 @@ def _set_state(self, state: dict[str, bool]):

def _handle_usr(self, readonly):
binaries = (
# Used in `nvidia.install`
"apt",
"apt-config",
"apt-key",
# Some initramfs scripts use `dpkg --print-architecture` or similar calls
"dpkg",
)
Expand All @@ -128,3 +133,16 @@ def _handle_usr(self, readonly):
with contextlib.suppress(FileNotFoundError):
os.rename(os.path.join(self.root, f"usr/local/bin/{binary}"),
os.path.join(self.root, f"usr/local/bin/{binary}.bak"))

def _set_dpkg_sysext_state(self, enabled):
if self.use_functioning_dpkg_sysext:
os.makedirs("/run/extensions", exist_ok=True)
sysext_dst = "/run/extensions/functioning-dpkg.raw"
if enabled:
with contextlib.suppress(FileExistsError):
os.symlink("/usr/share/truenas/sysext-extensions/functioning-dpkg.raw", sysext_dst)
else:
with contextlib.suppress(FileNotFoundError):
os.unlink(sysext_dst)

subprocess.run(["systemd-sysext", "refresh"], capture_output=True, check=True, text=True)

0 comments on commit 575560c

Please sign in to comment.