Skip to content

Commit 0496128

Browse files
committed
Add BuildStream support
The GnomeOS folks are looking into mkosi to build their images instead of BuildStream. While BuildStream will still take care of providing the rootfs tree, mkosi would take over the responsibility of packaging that directory tree into a disk image. Let's add support for BuildStream to mkosi to make this possible. Unlike the other supported distributions, BuildStream is not intended to be consumed by installing individual packages. Instead, BuildStream elements should be exposed which provide the full rootfs that should go into the image. That's why we limit the number of packages that can be specified to a single one, which should always provide all contents that should go into the image.
1 parent f02d8d0 commit 0496128

7 files changed

Lines changed: 158 additions & 3 deletions

File tree

mkosi/distribution/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Distribution(StrEnum):
4242
rocky = enum.auto()
4343
alma = enum.auto()
4444
azure = enum.auto()
45+
buildstream = enum.auto()
4546
custom = enum.auto()
4647

4748
def is_centos_variant(self) -> bool:

mkosi/distribution/buildstream.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
from mkosi.config import Config
4+
from mkosi.context import Context
5+
6+
from mkosi.log import die
7+
from mkosi.config import Architecture
8+
from mkosi.installer.bst import BST
9+
from mkosi.distribution import (
10+
Distribution,
11+
DistributionInstaller,
12+
PackageType,
13+
)
14+
15+
class Installer(DistributionInstaller, distribution=Distribution.buildstream):
16+
@classmethod
17+
def pretty_name(cls) -> str:
18+
return "BuildStream"
19+
20+
@classmethod
21+
def filesystem(cls) -> str:
22+
return "btrfs"
23+
24+
@classmethod
25+
def package_type(cls) -> PackageType:
26+
return PackageType.none
27+
28+
@classmethod
29+
def default_release(cls) -> str:
30+
return "snapshot"
31+
32+
@classmethod
33+
def package_manager(cls, config: "Config") -> type[BST]:
34+
return BST
35+
36+
@classmethod
37+
def setup(cls, context: Context) -> None:
38+
pass
39+
40+
@classmethod
41+
def install(cls, context: Context) -> None:
42+
pass
43+
44+
@classmethod
45+
def architecture(cls, arch: Architecture) -> str:
46+
a = {
47+
Architecture.x86_64: "x86_64",
48+
}.get(arch) # fmt: skip
49+
50+
if not a:
51+
die(f"Architecture {a} is not supported by {cls.pretty_name()}")
52+
53+
return a
54+
55+
@classmethod
56+
def latest_snapshot(cls, config: Config) -> str:
57+
die(f"Latest snapshot not supported by {cls.pretty_name()}")
58+
59+
@classmethod
60+
def is_kernel_package(cls, package: str) -> bool:
61+
return False

mkosi/installer/bst.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
from collections.abc import Sequence
4+
from pathlib import Path
5+
6+
from mkosi.config import Config
7+
from mkosi.context import Context
8+
from mkosi.installer import PackageManager
9+
from mkosi.run import run
10+
from mkosi.log import die
11+
12+
13+
class BST(PackageManager):
14+
@classmethod
15+
def executable(cls, config: Config) -> str:
16+
return "bst"
17+
18+
@classmethod
19+
def subdir(cls, config: Config) -> Path:
20+
return Path("bst")
21+
22+
@classmethod
23+
def architecture(cls, context: Context) -> str:
24+
return context.config.distribution.installer.architecture(context.config.architecture)
25+
26+
@classmethod
27+
def setup(cls, context: Context) -> None:
28+
if len(context.config.packages) > 1:
29+
die("Only a single element can be specified in Packages= when using bst")
30+
31+
@classmethod
32+
def install(
33+
cls,
34+
context: Context,
35+
packages: Sequence[str],
36+
*,
37+
apivfs: bool = True,
38+
allow_downgrade: bool = False,
39+
) -> None:
40+
options = [
41+
"--same-dir",
42+
*context.rootoptions(),
43+
# bst might need to lookup files/paths across the user's home directory so make sure it is
44+
# available.
45+
"--bind", Path.home(), Path.home(),
46+
"--setenv", "HOME", Path.home(),
47+
]
48+
49+
# We don't really want to run bst as (fake) root but it uses bubblewrap which stubbornly refuses to
50+
# run when invoked unprivileged but with capabilities. We get around this by running as fake root but
51+
# still setting $HOME to the user's home to reuse the buildstream cache directory.
52+
run(
53+
["bst", "build", *packages],
54+
sandbox=cls.sandbox(context, apivfs=apivfs, options=options),
55+
env=cls.finalize_environment(context),
56+
)
57+
run(
58+
["bst", "artifact", "checkout", "--force", "--directory=/buildroot", *packages],
59+
sandbox=cls.sandbox(context, apivfs=apivfs, options=options),
60+
env=cls.finalize_environment(context),
61+
)
62+
63+
@classmethod
64+
def remove(cls, context: Context, packages: Sequence[str]) -> None:
65+
die("Removing packages is not supported for bst")
66+
67+
@classmethod
68+
def sync(cls, context: Context, force: bool) -> None:
69+
pass
70+
71+
@classmethod
72+
def createrepo(cls, context: Context) -> None:
73+
die("Creating package repositories is not supported for bst")

mkosi/resources/man/mkosi.1.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,9 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
488488
: The distribution to install in the image. Takes one of the following
489489
arguments: `fedora`, `debian`, `kali`, `ubuntu`, `arch`, `opensuse`,
490490
`mageia`, `centos`, `rhel`, `rhel-ubi`, `openmandriva`, `rocky`, `alma`,
491-
`azure` or `custom`. If not specified, defaults to the distribution of
492-
the host or `custom` if the distribution of the host is not a supported
493-
distribution.
491+
`azure`, `buildstream` or `custom`. If not specified, defaults to the
492+
distribution of the host or `custom` if the distribution of the host is
493+
not a supported distribution.
494494

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

540541
`Snapshot=`
541542
: Download packages from the given snapshot instead of downloading the latest
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
[Match]
4+
Distribution=buildstream
5+
6+
[Content]
7+
# BuildStream is a generic distribution so we don't know which package to install, hence override to the
8+
# empty list.
9+
Packages=

mkosi/resources/mkosi-initrd/mkosi.conf.d/stub.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
[Match]
44
Format=uki
55
Distribution=!arch
6+
Distribution=!buildstream
67

78
[Content]
89
Packages=systemd-boot
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
[Match]
4+
Distribution=buildstream
5+
6+
[Content]
7+
# BuildStream is a generic distribution so we don't know which package to install, hence override to the
8+
# empty list.
9+
Packages=

0 commit comments

Comments
 (0)