Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1395,7 +1395,11 @@ def fixup_vmlinuz_location(context: Context) -> None:

# Some architectures ship an uncompressed vmlinux (ppc64el, riscv64)
for type in ("vmlinuz", "vmlinux"):
for d in context.root.glob(f"boot/{type}-*"):
todo = [*context.root.glob(f"boot/{type}-*")]
if (p := context.root / "boot" / type).exists():
todo += [p]

for d in todo:
if d.is_symlink():
continue

Expand Down
1 change: 1 addition & 0 deletions mkosi/distribution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Distribution(StrEnum):
rocky = enum.auto()
alma = enum.auto()
azure = enum.auto()
buildstream = enum.auto()
custom = enum.auto()

def is_centos_variant(self) -> bool:
Expand Down
61 changes: 61 additions & 0 deletions mkosi/distribution/buildstream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: LGPL-2.1-or-later

from mkosi.config import Config
from mkosi.context import Context

from mkosi.log import die
from mkosi.config import Architecture
from mkosi.installer.bst import BST
from mkosi.distribution import (
Distribution,
DistributionInstaller,
PackageType,
)

class Installer(DistributionInstaller, distribution=Distribution.buildstream):
@classmethod
def pretty_name(cls) -> str:
return "BuildStream"

@classmethod
def filesystem(cls) -> str:
return "btrfs"

@classmethod
def package_type(cls) -> PackageType:
return PackageType.none

@classmethod
def default_release(cls) -> str:
return "snapshot"

@classmethod
def package_manager(cls, config: "Config") -> type[BST]:
return BST

@classmethod
def setup(cls, context: Context) -> None:
pass

@classmethod
def install(cls, context: Context) -> None:
pass

@classmethod
def architecture(cls, arch: Architecture) -> str:
a = {
Architecture.x86_64: "x86_64",
}.get(arch) # fmt: skip

if not a:
die(f"Architecture {a} is not supported by {cls.pretty_name()}")

return a

@classmethod
def latest_snapshot(cls, config: Config) -> str:
die(f"Latest snapshot not supported by {cls.pretty_name()}")

@classmethod
def is_kernel_package(cls, package: str) -> bool:
return False
73 changes: 73 additions & 0 deletions mkosi/installer/bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# SPDX-License-Identifier: LGPL-2.1-or-later

from collections.abc import Sequence
from pathlib import Path

from mkosi.config import Config
from mkosi.context import Context
from mkosi.installer import PackageManager
from mkosi.run import run
from mkosi.log import die


class BST(PackageManager):
@classmethod
def executable(cls, config: Config) -> str:
return "bst"

@classmethod
def subdir(cls, config: Config) -> Path:
return Path("bst")

@classmethod
def architecture(cls, context: Context) -> str:
return context.config.distribution.installer.architecture(context.config.architecture)

@classmethod
def setup(cls, context: Context) -> None:
if len(context.config.packages) > 1:
die("Only a single element can be specified in Packages= when using bst")

@classmethod
def install(
cls,
context: Context,
packages: Sequence[str],
*,
apivfs: bool = True,
allow_downgrade: bool = False,
) -> None:
options = [
"--same-dir",
*context.rootoptions(),
# bst might need to lookup files/paths across the user's home directory so make sure it is
Comment on lines +39 to +43

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) -> None:
options = [
"--same-dir",
*context.rootoptions(),
# bst might need to lookup files/paths across the user's home directory so make sure it is
) -> None:
options = [
"--same-dir",
*context.rootoptions(),
# we are passing --same-dir. Ensure the current working directory to make chdir() reliable.
"--bind", Path.cwd(), Path.cwd(),
# bst might need to lookup files/paths across the user's home directory so make sure it is

I needed this to run it properly, I'm running it from distrobox and it does weird things to the home directory. Regardless, passing the directory we run it from seems sound.

# available.
"--bind", Path.home(), Path.home(),
"--setenv", "HOME", Path.home(),
]

# We don't really want to run bst as (fake) root but it uses bubblewrap which stubbornly refuses to
# run when invoked unprivileged but with capabilities. We get around this by running as fake root but
# still setting $HOME to the user's home to reuse the buildstream cache directory.
run(
["bst", "build", *packages],
sandbox=cls.sandbox(context, apivfs=apivfs, options=options),
env=cls.finalize_environment(context),
)
run(
["bst", "artifact", "checkout", "--force", "--directory=/buildroot", *packages],
sandbox=cls.sandbox(context, apivfs=apivfs, options=options),
env=cls.finalize_environment(context),
)

@classmethod
def remove(cls, context: Context, packages: Sequence[str]) -> None:
die("Removing packages is not supported for bst")

@classmethod
def sync(cls, context: Context, force: bool) -> None:
pass

@classmethod
def createrepo(cls, context: Context) -> None:
die("Creating package repositories is not supported for bst")
7 changes: 4 additions & 3 deletions mkosi/resources/man/mkosi.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,9 +488,9 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
: The distribution to install in the image. Takes one of the following
arguments: `fedora`, `debian`, `kali`, `ubuntu`, `arch`, `opensuse`,
`mageia`, `centos`, `rhel`, `rhel-ubi`, `openmandriva`, `rocky`, `alma`,
`azure` or `custom`. If not specified, defaults to the distribution of
the host or `custom` if the distribution of the host is not a supported
distribution.
`azure`, `buildstream` or `custom`. If not specified, defaults to the
distribution of the host or `custom` if the distribution of the host is
not a supported distribution.

`Release=`, `--release=`, `-r`
: The release of the distribution to install in the image. The precise
Expand Down Expand Up @@ -536,6 +536,7 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
| `mageia` | https://www.mageia.org | |
| `openmandriva` | http://mirrors.openmandriva.org | |
| `azure` | https://packages.microsoft.com/ | |
| `buildstream` | | |

`Snapshot=`
: Download packages from the given snapshot instead of downloading the latest
Expand Down
9 changes: 9 additions & 0 deletions mkosi/resources/mkosi-initrd/mkosi.conf.d/buildstream.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later

[Match]
Distribution=buildstream

[Content]
# BuildStream is a generic distribution so we don't know which package to install, hence override to the
# empty list.
Packages=

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the issue: this file gets loaded last (after mkosi-initrd/mkosi.conf and after the user provided mkosi.conf and mkosi.initrd.conf) so it overrides the packages to the empty list.

(as I workaround I removed this line, and the Packages list from mkosi-initrd/mkosi.conf, which obviously breaks other distros)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the suggestion from @behrmann on matrix, I made a fix

Details

diff --git a/mkosi/resources/mkosi-initrd/mkosi.conf b/mkosi/resources/mkosi-initrd/mkosi.conf
index ab76f73a..ca1afddb 100644
--- a/mkosi/resources/mkosi-initrd/mkosi.conf
+++ b/mkosi/resources/mkosi-initrd/mkosi.conf
@@ -10,12 +10,6 @@ SplitArtifacts=
 Bootable=no
 MakeInitrd=yes
 CleanPackageMetadata=yes
-Packages=
-        systemd                   # sine qua non
-        udev
-        bash                      # for emergency logins
-        less                      # this makes 'systemctl' much nicer to use ;)
-        gzip                      # For compressed keymap unpacking by loadkeys
 
 RemoveFiles=
         # we don't need this after the binary catalogs have been built
diff --git a/mkosi/resources/mkosi-initrd/mkosi.conf.d/buildstream.conf b/mkosi/resources/mkosi-initrd/mkosi.conf.d/buildstream.conf
deleted file mode 100644
index 1e76355e..00000000
--- a/mkosi/resources/mkosi-initrd/mkosi.conf.d/buildstream.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-[Match]
-Distribution=buildstream
-
-[Content]
-# BuildStream is a generic distribution so we don't know which package to install, hence override to the
-# empty list.
-Packages=
diff --git a/mkosi/resources/mkosi-initrd/mkosi.conf.d/default-packages.conf b/mkosi/resources/mkosi-initrd/mkosi.conf.d/default-packages.conf
new file mode 100644
index 00000000..5dc12408
--- /dev/null
+++ b/mkosi/resources/mkosi-initrd/mkosi.conf.d/default-packages.conf
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+[Match]
+# BuildStream is a generic distribution so we don't know which package to install.
+Distribution=!buildstream
+
+Packages=
+        systemd                   # sine qua non
+        udev
+        bash                      # for emergency logins
+        less                      # this makes 'systemctl' much nicer to use ;)
+        gzip                      # For compressed keymap unpacking by loadkeys
diff --git a/mkosi/resources/mkosi-tools/mkosi.conf b/mkosi/resources/mkosi-tools/mkosi.conf
index b597d0a0..5ccf8f46 100644
--- a/mkosi/resources/mkosi-tools/mkosi.conf
+++ b/mkosi/resources/mkosi-tools/mkosi.conf
@@ -2,22 +2,3 @@
 
 [Output]
 Output=mkosi.tools
-
-[Content]
-Packages=
-        bash
-        ca-certificates
-        coreutils
-        cpio
-        curl
-        dosfstools
-        e2fsprogs
-        keyutils
-        kmod
-        mtools
-        opensc
-        openssl
-        systemd
-        tar
-        xfsprogs
-        zstd
diff --git a/mkosi/resources/mkosi-tools/mkosi.conf.d/buildstream.conf b/mkosi/resources/mkosi-tools/mkosi.conf.d/buildstream.conf
deleted file mode 100644
index 1e76355e..00000000
--- a/mkosi/resources/mkosi-tools/mkosi.conf.d/buildstream.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-[Match]
-Distribution=buildstream
-
-[Content]
-# BuildStream is a generic distribution so we don't know which package to install, hence override to the
-# empty list.
-Packages=
diff --git a/mkosi/resources/mkosi-tools/mkosi.conf.d/default-packages.conf b/mkosi/resources/mkosi-tools/mkosi.conf.d/default-packages.conf
new file mode 100644
index 00000000..e20e4bd4
--- /dev/null
+++ b/mkosi/resources/mkosi-tools/mkosi.conf.d/default-packages.conf
@@ -0,0 +1,22 @@
+[Match]
+# BuildStream is a generic distribution so we don't know which package to install.
+Distribution=!buildstream
+
+[Content]
+Packages=
+        bash
+        ca-certificates
+        coreutils
+        cpio
+        curl
+        dosfstools
+        e2fsprogs
+        keyutils
+        kmod
+        mtools
+        opensc
+        openssl
+        systemd
+        tar
+        xfsprogs
+        zstd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that works for you, that looks like a reasonable workaround to me, though that empty Packages= doesn't reset the package list to empty, seems like a bug in our config parsing that needs investigating.

1 change: 1 addition & 0 deletions mkosi/resources/mkosi-initrd/mkosi.conf.d/stub.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[Match]
Format=uki
Distribution=!arch
Distribution=!buildstream

[Content]
Packages=systemd-boot
9 changes: 9 additions & 0 deletions mkosi/resources/mkosi-tools/mkosi.conf.d/buildstream.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later

[Match]
Distribution=buildstream

[Content]
# BuildStream is a generic distribution so we don't know which package to install, hence override to the
# empty list.
Packages=
61 changes: 44 additions & 17 deletions mkosi/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,24 +652,51 @@ def sandbox_cmd(
elif p.is_dir():
cmdline += ["--ro-bind", p, Path("/") / p.relative_to(tools)]

# Always bind mount in everything that isn't a well-known directory. We assume that not mounting
# these in has a higher chance of causing issues than mounting these in.
for p in Path("/").iterdir():
if p not in (
Path("/bin"),
Path("/boot"),
Path("/dev"),
Path("/etc"),
Path("/home"),
Path("/lib"),
Path("/lib32"),
Path("/lib64"),
Path("/nix"),
Path("/opt"),
Path("/proc"),
Path("/root"),
Path("/run"),
Path("/sbin"),
Path("/srv"),
Path("/sys"),
Path("/tmp"),
Path("/usr"),
Path("/var"),
):
if p.is_symlink():
cmdline += ["--symlink", p.readlink(), p]
else:
cmdline += ["--bind", p, p]

if relaxed:
for p in Path("/").iterdir():
if p not in (
Path("/proc"),
Path("/usr"),
Path("/opt"),
Path("/nix"),
Path("/bin"),
Path("/sbin"),
Path("/lib"),
Path("/lib32"),
Path("/lib64"),
Path("/etc"),
):
if p.is_symlink():
cmdline += ["--symlink", p.readlink(), p]
else:
cmdline += ["--bind", p, p]
for p in (
Path("/boot"),
Path("/dev"),
Path("/home"),
Path("/root"),
Path("/run"),
Path("/srv"),
Path("/sys"),
Path("/tmp"),
Path("/var"),
):
if p.is_symlink():
cmdline += ["--symlink", p.readlink(), p]
elif p.exists():
cmdline += ["--bind", p, p]

cmdline += ["--ro-bind", tools / "etc", "/etc"]

Expand Down
Loading