- name: Create missing mountpoints
shell: bash
run: |
- for p in /etc/pki/ca-trust /etc/pki/tls /etc/ssl /etc/ca-certificates /var/lib/ca-certificates /etc/crypto-policies; do
- if [[ ! -e "$p" ]]; then
- sudo mkdir -p "$p"
- fi
- done
+ sudo mkdir -p /var/lib/ca-certificates
# Both the unix-chkpwd and swtpm profiles are broken (https://gitlab.com/apparmor/apparmor/-/issues/402) so let's
# just disable and remove apparmor completely. It's not relevant in this context anyway.
die("Please specify a command to execute in the sandbox")
mounts = finalize_certificate_mounts(config, relaxed=True)
+ if config.tools() != Path("/"):
+ for f in ("passwd", "group", "shadow", "gshadow"):
+ if Path(f"/etc/{f}").exists() and (config.tools() / "etc" / f).exists():
+ mounts += ["--ro-bind", f"/etc/{f}", f"/etc/{f}"]
- if config.tools() != Path("/") and (config.tools() / "etc/crypto-policies").exists():
- mounts += ["--ro-bind", config.tools() / "etc/crypto-policies", Path("/etc/crypto-policies")]
+ if Path("/etc/nsswitch.conf").exists() and (config.tools() / "etc/nsswitch.conf").exists():
+ mounts += ["--ro-bind", "/etc/nsswitch.conf", "/etc/nsswitch.conf"]
- # Since we reuse almost every top level directory from the host except /usr, the crypto mountpoints
- # have to exist already in these directories or we'll fail with a permission error. Let's check this
- # early and show a better error and a suggestion on how users can fix this issue. We use slice
- # notation to get every 3rd item from the mounts list which is the destination path.
+ # Since we reuse almost every top level directory from the host except /usr and /etc, the crypto
+ # mountpoints have to exist already in these directories or we'll fail with a permission error. Let's
+ # check this early and show a better error and a suggestion on how users can fix this issue. We use
+ # slice notation to get every 3rd item from the mounts list which is the destination path.
for dst in mounts[2::3]:
if not Path(dst).exists():
die(
)
+def ensure_tools_tree_has_etc_resolv_conf(config: Config) -> None:
+ if not config.tools_tree:
+ return
+
+ # We can't bind mount in the hosts's /etc/resolv.conf if this file doesn't exist without making the
+ # entirety of /etc writable or messing around with overlayfs, so let's just ensure it exists.
+ path = config.tools_tree / "etc/resolv.conf"
+
+ if not path.is_symlink() and not path.exists():
+ die(
+ f"Tools tree {config.tools_tree} is missing /etc/resolv.conf",
+ hint="If you're using a default tools tree, run mkosi -f clean to remove the old tools tree "
+ "without /etc/resolv.conf",
+ )
+
+
def run_verb(args: Args, tools: Optional[Config], images: Sequence[Config], *, resources: Path) -> None:
images = list(images)
metadata_dir=Path(metadata_dir),
)
+ resolv = tools.output_dir_or_cwd() / tools.output / "etc/resolv.conf"
+ if not resolv.is_symlink() and not resolv.exists():
+ resolv.touch()
+
_, _, manifest = cache_tree_paths(tools)
manifest.write_text(dump_json(tools.cache_manifest()))
+ ensure_tools_tree_has_etc_resolv_conf(last)
+
if args.verb.needs_tools():
return {
Verb.ssh: run_ssh,
root = config.tools() if config.tools_tree_certificates else Path("/")
if not relaxed or root != Path("/"):
- mounts += [
- (root / subdir, Path("/") / subdir)
- for subdir in (
+ subdirs = [Path("var/lib/ca-certificates")]
+ if not relaxed:
+ subdirs += [
Path("etc/pki/ca-trust"),
Path("etc/pki/tls"),
Path("etc/ssl"),
Path("etc/ca-certificates"),
- Path("var/lib/ca-certificates"),
- )
+ ]
+
+ mounts += [
+ (root / subdir, Path("/") / subdir)
+ for subdir in subdirs
if (root / subdir).exists() and any(p for p in (root / subdir).rglob("*") if not p.is_dir())
]
elif p.is_dir():
cmdline += ["--ro-bind", p, Path("/") / p.relative_to(tools)]
- # If we're using /usr from a tools tree, we have to use /etc/alternatives and /etc/ld.so.cache from
- # the tools tree as well if they exists since those are directly related to /usr. In relaxed mode, we
- # only do this if the mountpoint already exists on the host as otherwise we'd modify the host's /etc
- # by creating the mountpoint ourselves (or fail when trying to create it).
- for p in (Path("etc/alternatives"), Path("etc/ld.so.cache")):
- if (tools / p).exists() and (not relaxed or (Path("/") / p).exists()):
- cmdline += ["--ro-bind", tools / p, Path("/") / p]
-
if (tools / "nix/store").exists():
cmdline += ["--bind", tools / "nix/store", "/nix/store"]
Path("/lib"),
Path("/lib32"),
Path("/lib64"),
+ Path("/etc"),
):
if p.is_symlink():
cmdline += ["--symlink", p.readlink(), p]
else:
cmdline += ["--bind", p, p]
- # /etc might be full of symlinks to /usr/share/factory, so make sure we use
- # /usr/share/factory from the host and not from the tools tree.
- if (
- tools != Path("/")
- and (tools / "usr/share/factory").exists()
- and (factory := Path("/usr/share/factory")).exists()
- ):
- cmdline += ["--bind", factory, factory]
+ cmdline += ["--ro-bind", tools / "etc", "/etc"]
else:
cmdline += [
"--dir", "/var/tmp",
else:
cmdline += ["--dev", "/dev"]
- if network:
- for p in (Path("/etc/resolv.conf"), Path("/run/systemd/resolve")):
- if p.exists():
- cmdline += ["--ro-bind", p, p]
+ # If we're using /usr from a tools tree, we have to use /etc/alternatives and /etc/ld.so.cache
+ # from the tools tree as well if they exists since those are directly related to /usr.
+ for p in (Path("etc/alternatives"), Path("etc/ld.so.cache")):
+ if (tools / p).exists():
+ cmdline += ["--ro-bind", tools / p, Path("/") / p]
+
+ if network and (p := Path("/run/systemd/resolve")).exists():
+ cmdline += ["--ro-bind", p, p]
+
+ if network and (p := Path("/etc/resolv.conf")).exists():
+ cmdline += ["--ro-bind", p, p]
path = finalize_path(
root=tools,
).stdout.strip()
stack.callback(lambda: run(["losetup", "--detach", lodev]))
run(["sfdisk", "--label", "gpt", lodev], input="type=E6D6D379-F507-44C2-A23C-238F2A3DF928 bootable")
- run(["lvm", "pvcreate", f"{lodev}p1"])
- run(["lvm", "pvs"])
- run(["lvm", "vgcreate", "-An", "vg_mkosi", f"{lodev}p1"])
- run(["lvm", "vgchange", "-ay", "vg_mkosi"])
- run(["lvm", "vgs"])
- stack.callback(lambda: run(["vgchange", "-an", "vg_mkosi"]))
- run(["lvm", "lvcreate", "-An", "-l", "100%FREE", "-n", "lv0", "vg_mkosi"])
- run(["lvm", "lvs"])
+ run(["lvm", "pvcreate", "--devicesfile", "", f"{lodev}p1"])
+ run(["lvm", "pvs", "--devicesfile", ""])
+ run(["lvm", "vgcreate", "--devicesfile", "", "-An", "vg_mkosi", f"{lodev}p1"])
+ run(["lvm", "vgchange", "--devicesfile", "", "-ay", "vg_mkosi"])
+ run(["lvm", "vgs", "--devicesfile", ""])
+ stack.callback(lambda: run(["lvm", "vgchange", "--devicesfile", "", "-an", "vg_mkosi"]))
+ run(["lvm", "lvcreate", "--devicesfile", "", "-An", "-l", "100%FREE", "-n", "lv0", "vg_mkosi"])
+ run(["lvm", "lvs", "--devicesfile", ""])
run(["udevadm", "wait", "--timeout=30", "/dev/vg_mkosi/lv0"])
run([f"mkfs.{image.config.distribution.filesystem()}", "-L", "root", "/dev/vg_mkosi/lv0"])
run(["cryptsetup", "--key-file", passphrase, "luksOpen", f"{lodev}p1", "lvm_root"])
stack.callback(lambda: run(["cryptsetup", "close", "lvm_root"]))
luks_uuid = run(["cryptsetup", "luksUUID", f"{lodev}p1"], stdout=subprocess.PIPE).stdout.strip()
- run(["lvm", "pvcreate", "/dev/mapper/lvm_root"])
- run(["lvm", "pvs"])
- run(["lvm", "vgcreate", "-An", "vg_mkosi", "/dev/mapper/lvm_root"])
- run(["lvm", "vgchange", "-ay", "vg_mkosi"])
- run(["lvm", "vgs"])
- stack.callback(lambda: run(["vgchange", "-an", "vg_mkosi"]))
- run(["lvm", "lvcreate", "-An", "-l", "100%FREE", "-n", "lv0", "vg_mkosi"])
- run(["lvm", "lvs"])
+ run(["lvm", "pvcreate", "--devicesfile", "", "/dev/mapper/lvm_root"])
+ run(["lvm", "pvs", "--devicesfile", ""])
+ run(["lvm", "vgcreate", "--devicesfile", "", "-An", "vg_mkosi", "/dev/mapper/lvm_root"])
+ run(["lvm", "vgchange", "--devicesfile", "", "-ay", "vg_mkosi"])
+ run(["lvm", "vgs", "--devicesfile", ""])
+ stack.callback(lambda: run(["lvm", "vgchange", "--devicesfile", "", "-an", "vg_mkosi"]))
+ run(["lvm", "lvcreate", "--devicesfile", "", "-An", "-l", "100%FREE", "-n", "lv0", "vg_mkosi"])
+ run(["lvm", "lvs", "--devicesfile", ""])
run(["udevadm", "wait", "--timeout=30", "/dev/vg_mkosi/lv0"])
run([f"mkfs.{image.config.distribution.filesystem()}", "-L", "root", "/dev/vg_mkosi/lv0"])