Skip to content

Commit 54df9de

Browse files
authored
Merge pull request #99 from desultory/dev
Add a separate overlayfs and livegui module
2 parents 91b64d9 + 674e064 commit 54df9de

File tree

11 files changed

+96
-50
lines changed

11 files changed

+96
-50
lines changed

docs/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Modules write to a shared config dict that is accessible by other modules.
2626

2727
> The main module, mostly pulls basic binaries and pulls the `core`, `mounts`, and `cpio` module.
2828
29+
* `switch_root_target` Set the target filesystem for `switch_root`, defaults to the root mountpoint if not set.
2930
* `init_target` Sets the init target for `switch_root`.
3031
* `autodetect_init` (true) Automatically set the init target based `which init`.
3132
* `loglevel` (5) Sets the kernel log level in the init script.

examples/livegui.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
modules = [ "ugrd.fs.livecd" ]
2+
livecd_label = "gentoo-amd64-livegui"

src/ugrd/base/base.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__author__ = "desultory"
2-
__version__ = "5.1.4"
2+
__version__ = "5.2.0"
33

44
from importlib.metadata import version
55
from pathlib import Path
@@ -46,12 +46,20 @@ def autodetect_init(self) -> None:
4646
raise FileNotFoundError("init_target is not specified and could not be detected.")
4747

4848

49+
def export_switch_root_target(self) -> None:
50+
"""Adds SWITCH_ROOT_TARGET to exports.
51+
Uses switch_root_target if set, otherwise uses the rootfs."""
52+
switch_root_target = self["switch_root_target"]
53+
if str(switch_root_target) == ".": # Handle empty Path
54+
switch_root_target = self["mounts"]["root"]["destination"]
55+
self["exports"]["SWITCH_ROOT_TARGET"] = switch_root_target
56+
4957
def _find_init(self) -> str:
5058
"""Returns bash to find the init_target."""
5159
return [
5260
'for init_path in "/sbin/init" "/bin/init" "/init"; do',
53-
' if [ -e "$(readvar MOUNTS_ROOT_TARGET)$init_path" ] ; then',
54-
' einfo "Found init at: $(readvar MOUNTS_ROOT_TARGET)$init_path"',
61+
' if [ -e "$(readvar SWITCH_ROOT_TARGET)$init_path" ] ; then',
62+
' einfo "Found init at: $(readvar SWITCH_ROOT_TARGET)$init_path"',
5563
' setvar init "$init_path"',
5664
" return",
5765
" fi",
@@ -68,9 +76,8 @@ def set_loglevel(self) -> list[str]:
6876

6977
@contains("init_target", "init_target must be set.", raise_exception=True)
7078
def do_switch_root(self) -> list[str]:
71-
"""
72-
Should be the final statement, switches root.
73-
Checks if the root mount is mounted and that it contains an init.
79+
"""Should be the final statement, switches root.
80+
Checks if the switch_root target is mounted, and that it contains an init.
7481
If not, it restarts UGRD.
7582
"""
7683
return [
@@ -79,21 +86,21 @@ def do_switch_root(self) -> list[str]:
7986
" exit 1",
8087
"fi",
8188
'init_target=$(readvar init) || rd_fail "init_target not set."', # should be set, if unset, checks fail
82-
'einfo "Checking root mount: $(readvar MOUNTS_ROOT_TARGET)"',
83-
'if ! grep -q " $(readvar MOUNTS_ROOT_TARGET) " /proc/mounts ; then',
84-
' rd_fail "Root not found at: $(readvar MOUNTS_ROOT_TARGET)"',
85-
'elif [ ! -e "$(readvar MOUNTS_ROOT_TARGET)${init_target}" ] ; then',
86-
' ewarn "$init_target not found at: $(readvar MOUNTS_ROOT_TARGET)"',
87-
r' einfo "Target root contents:\n$(ls -l "$(readvar MOUNTS_ROOT_TARGET)")"',
89+
'einfo "Checking root mount: $(readvar SWITCH_ROOT_TARGET)"',
90+
'if ! grep -q " $(readvar SWITCH_ROOT_TARGET) " /proc/mounts ; then',
91+
' rd_fail "Root not found at: $(readvar SWITCH_ROOT_TARGET)"',
92+
'elif [ ! -e "$(readvar SWITCH_ROOT_TARGET)${init_target}" ] ; then',
93+
' ewarn "$init_target not found at: $(readvar SWITCH_ROOT_TARGET)"',
94+
r' einfo "Target root contents:\n$(ls -l "$(readvar SWITCH_ROOT_TARGET)")"',
8895
" if _find_init ; then", # This redefineds the var, so readvar instaed of using $init_target
89-
' einfo "Switching root to: $(readvar MOUNTS_ROOT_TARGET) $(readvar init)"',
90-
' exec switch_root "$(readvar MOUNTS_ROOT_TARGET)" "$(readvar init)"',
96+
' einfo "Switching root to: $(readvar SWITCH_ROOT_TARGET) $(readvar init)"',
97+
' exec switch_root "$(readvar SWITCH_ROOT_TARGET)" "$(readvar init)"',
9198
" fi",
9299
' rd_fail "Unable to find init."',
93100
"else",
94101
f' einfo "Completed UGRD v{version("ugrd")}."',
95-
' einfo "Switching root to: $(readvar MOUNTS_ROOT_TARGET) $init_target"',
96-
' exec switch_root "$(readvar MOUNTS_ROOT_TARGET)" "$init_target"',
102+
' einfo "Switching root to: $(readvar SWITCH_ROOT_TARGET) $init_target"',
103+
' exec switch_root "$(readvar SWITCH_ROOT_TARGET)" "$init_target"',
97104
"fi",
98105
]
99106

src/ugrd/base/base.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ autodetect_init = true
2020
[imports.build_enum]
2121
"ugrd.base.base" = [ "autodetect_init" ]
2222

23+
[imports.build_tasks]
24+
"ugrd.base.base" = [ "export_switch_root_target" ]
25+
2326
[imports.init_early]
2427
"ugrd.base.base" = [ "set_loglevel" ]
2528

@@ -32,6 +35,7 @@ autodetect_init = true
3235
"rd_fail", "rd_restart", "_find_init" ]
3336

3437
[custom_parameters]
38+
switch_root_target = "Path" # Specifies the location of the new root filesystem
3539
init_target = "Path" # Specifies the location of the system init file
3640
autodetect_init = "bool" # If set to true, the init_target will be autodetected based on the system's init system
3741
loglevel = "int" # Set the kernel log level at /proc/sys/kernel/printk

src/ugrd/fs/livecd.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
__author__ = "desultory"
2-
__version__ = "0.3.0"
2+
__version__ = "0.5.0"
33

44
from zenlib.util import contains
55

66

77
@contains("livecd_label", "livecd_label must be set to the label of the livecd.", raise_exception=True)
88
def generate_livecd_mount(self):
9-
""" Makes the mounts entry for livecd base. """
10-
self['mounts'] = {'livecd': {'label': self.livecd_label, 'no_validate': True}}
9+
"""Makes the mounts entry for livecd base."""
10+
self["mounts"] = {"livecd": {"label": self.livecd_label, "no_validate": True}}
11+
12+
13+
def prepare_squashfs_mount(self) -> str:
14+
"""Create the folder for the squashfs mount in /run"""
15+
return "edebug $(mkdir -pv /run/squashfs)"
1116

1217

1318
@contains("squashfs_image", "squashfs_image must be set to the path of the squashfs image to mount.", raise_exception=True)
14-
def mount_squashfs(self):
15-
"""
16-
Returns bash lines to mount squashfs image.
17-
Creates /run/squashfs directory to mount squashfs image.
18-
Creates /run/upperdir and /run/workdir directories for overlayfs.
19-
"""
20-
return ["einfo $(mkdir -pv /run/squashfs)",
21-
f"mount -t squashfs -o loop /livecd/{self.squashfs_image} /run/squashfs || rd_fail 'Failed to mount squashfs image: {self.squashfs_image}'",
22-
"edebug $(mkdir -pv /run/upperdir)",
23-
"edebug $(mkdir -pv /run/workdir)",
24-
f"mount -t overlay overlay -o lowerdir=/run/squashfs,upperdir=/run/upperdir,workdir=/run/workdir {self.mounts['root']['destination']} || rd_fail 'Failed to mount overlayfs'"]
19+
def set_squashfs_mount(self):
20+
"""Updates the root mount entry to use the squashfs image."""
21+
self["mounts"] = {
22+
"root": {
23+
"type": "squashfs",
24+
"options": ["loop"],
25+
"path": f"/livecd/{self.squashfs_image}",
26+
"destination": "/run/squashfs",
27+
"no_validate": True,
28+
}
29+
}

src/ugrd/fs/livecd.toml

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
autodetect_root = false
2-
autodetect_root_dm = false
1+
modules = ["ugrd.fs.overlayfs"]
32

43
squashfs_image = 'image.squashfs'
4+
lowerdir = "/run/squashfs"
5+
hostonly = false
56

6-
kmod_init = ['hfsplus', 'nls_utf8', 'squashfs', 'overlay', 'isofs', 'loop']
7+
kmod_init = ['hfsplus', 'nls_utf8', 'squashfs', 'isofs', 'loop']
78

89
[imports.build_pre]
9-
"ugrd.fs.livecd" = ["generate_livecd_mount"]
10+
"ugrd.fs.livecd" = ["generate_livecd_mount", "set_squashfs_mount"]
1011

11-
[imports.init_mount]
12-
"ugrd.fs.livecd" = ["mount_squashfs"]
13-
14-
[masks]
15-
init_mount = "mount_cmdline_root" # Don't use the normal mount process
16-
build_tasks = "export_mount_info"
17-
functions = "mount_root"
12+
[imports.init_early]
13+
"ugrd.fs.livecd" = ["prepare_squashfs_mount"]
1814

1915
[custom_parameters]
2016
squashfs_image = "Path" # the path to the squashfs image (at runtime)

src/ugrd/fs/mounts.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__author__ = "desultory"
2-
__version__ = "5.4.0"
2+
__version__ = "5.4.2"
33

44
from pathlib import Path
55

@@ -216,7 +216,7 @@ def umount_fstab(self) -> list[str]:
216216
for mount_info in self["mounts"].values():
217217
if mount_info.get("base_mount"):
218218
continue
219-
if str(mount_info.get("destination")) == "/target_rootfs":
219+
if str(mount_info.get("destination")) == str(self["mounts"]["root"]["destination"]):
220220
continue
221221

222222
mountpoints.append(str(mount_info["destination"]))
@@ -729,10 +729,6 @@ def export_mount_info(self) -> None:
729729
self["exports"]["MOUNTS_ROOT_SOURCE"] = _get_mount_str(self, self["mounts"]["root"])
730730
self["exports"]["MOUNTS_ROOT_TYPE"] = self["mounts"]["root"].get("type", "auto")
731731
self["exports"]["MOUNTS_ROOT_OPTIONS"] = ",".join(self["mounts"]["root"]["options"])
732-
733-
734-
def export_root_target(self) -> None:
735-
"""Exports the root target path to /run/MOUNTS_ROOT_TARGET"""
736732
self["exports"]["MOUNTS_ROOT_TARGET"] = self["mounts"]["root"]["destination"]
737733

738734

src/ugrd/fs/mounts.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ late_fstab = "/etc/fstab.late"
3030
"autodetect_root", "autodetect_mounts", "autodetect_root_dm", "autodetect_init_mount" ]
3131

3232
[imports.build_tasks]
33-
"ugrd.fs.mounts" = [ "export_mount_info", "export_root_target" ]
33+
"ugrd.fs.mounts" = [ "export_mount_info" ]
3434

3535
[imports.build_final]
3636
"ugrd.fs.mounts" = [ "check_mounts", "generate_fstab" ]

src/ugrd/fs/overlayfs.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from zenlib.util import unset
2+
3+
@unset('lowerdir', "lowerdir is already set, skipping detection.")
4+
def detect_lowerdir(self):
5+
"""Detect the lowerdir using the mounts['root']['destination']"""
6+
self['lowerdir'] = self.mounts['root']['destination']
7+
self.logger.info("Detected lowerdir: %s" % self['lowerdir'])
8+
9+
10+
def init_overlayfs(self) -> list[str]:
11+
"""Returns bash lines to create the upperdir and workdir
12+
Uses /run/upperdir and /run/workdir."""
13+
return ["edebug $(mkdir -pv /run/upperdir /run/workdir)"]
14+
15+
def mount_overlayfs(self) -> list[str]:
16+
"""Returns bash lines to mount the overlayfs based on the lowerdir"""
17+
return [
18+
"einfo $(mount -t overlay overlay -o lowerdir=%s,upperdir=/run/upperdir,workdir=/run/workdir $(readvar SWITCH_ROOT_TARGET))" % self['lowerdir']
19+
]
20+
21+
22+

src/ugrd/fs/overlayfs.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
kmod_init = ["overlay"]
2+
3+
[imports.build_pre]
4+
"ugrd.fs.overlayfs" = ["detect_lowerdir"]
5+
6+
[imports.init_early]
7+
"ugrd.fs.overlayfs" = ["init_overlayfs"]
8+
9+
[imports.init_mount]
10+
"ugrd.fs.overlayfs" = ["mount_overlayfs"]
11+
12+
[custom_parameters]
13+
lowerdir = "Path"

0 commit comments

Comments
 (0)