--- /dev/null
+[Output]
+CacheDirectory=mkosi.cache
+KernelCommandLine=console=hvc0
+ systemd.unit=mkosi-check-and-shutdown.service
+ systemd.log_target=console
+ systemd.default_standard_output=journal+console
+
+[Host]
+Autologin=yes
--- /dev/null
+[Match]
+Distribution=alma
+
+[Distribution]
+Repositories=epel
+
+[Content]
+Packages=kernel
+ systemd
+ systemd-boot
+ systemd-udev
+ dracut
--- /dev/null
+[Match]
+Distribution=arch
+
+[Content]
+Packages=linux
+ systemd
+ dracut
--- /dev/null
+[Match]
+Distribution=centos
+
+[Content]
+Packages=kernel
+ systemd
+ systemd-boot
+ systemd-udev
+ dracut
--- /dev/null
+[Match]
+Distribution=debian
+
+[Content]
+Packages=linux-image-cloud-amd64
+ systemd
+ systemd-boot
+ systemd-sysv
+ udev
+ dracut
+ dbus
--- /dev/null
+[Match]
+Distribution=fedora
+
+[Content]
+Packages=kernel
+ systemd
+ systemd-boot
+ systemd-udev
+ dracut
+ util-linux
--- /dev/null
+[Match]
+Distribution=opensuse
+
+[Content]
+Packages=kernel-default
+ dracut
+ systemd
+ udev
--- /dev/null
+[Match]
+Distribution=rocky
+
+[Distribution]
+Repositories=epel
+
+[Content]
+Packages=kernel
+ systemd
+ systemd-boot
+ systemd-udev
+ dracut
--- /dev/null
+[Match]
+Distribution=ubuntu
+
+[Distribution]
+Repositories=main,universe
+
+[Content]
+Packages=linux-virtual
+ systemd
+ systemd-sysv
+ udev
+ dracut
+ dbus
concurrency:
group: ${{ github.workflow }}-${{ matrix.distro }}-${{ matrix.format }}-${{ matrix.prebuilt-initrd }}-${{ github.ref }}
cancel-in-progress: true
+ defaults:
+ run:
+ working-directory: ./.github
strategy:
fail-fast: false
matrix:
- no
- yes
exclude:
- # Debian prebuilt initrds are so large they cause OOMs.
- # TODO: Revisit this if Debian ever decides to compress their kernel modules.
- - distro: debian
- prebuilt-initrd: yes
- distro: gentoo
prebuilt-initrd: yes
# Do a manual install so we have the latest changes from the pull request available.
- name: Install
- run: sudo python3 -m pip install .
+ run: sudo python3 -m pip install ..
- name: Build ${{ matrix.distro }} initrd
if: matrix.prebuilt-initrd == 'yes'
+ # Run the build in .github/workflows/ so we don't pick up any of the configuration files in .github/
run: python3 -m mkosi -d ${{ matrix.distro }} -t cpio -p systemd -p udev -p kmod -o $PWD/initrd build
+ working-directory: ./.github/workflows
- name: Configure ${{ matrix.distro }}/${{ matrix.format }}
run: |
- mkdir -p mkosi.conf.d
-
- tee mkosi.conf.d/mkosi.conf <<- EOF
+ tee mkosi.conf.d/00-ci.conf <<- EOF
[Distribution]
Distribution=${{ matrix.distro }}
[Output]
Format=${{ matrix.format }}
- Bootable=yes
- KernelCommandLine=systemd.unit=mkosi-check-and-shutdown.service
- systemd.log_target=console
- systemd.default_standard_output=journal+console
-
- [Host]
- Autologin=yes
-
- [Content]
- ExtraTrees=.github/mkosi.extra
- EOF
-
- mkdir -p mkosi.skeleton/etc/portage
-
- tee mkosi.skeleton/etc/portage/binrepos.conf <<- EOF
- [binhost]
- sync-uri = https://raw.githubusercontent.com/257/binpkgs/master
EOF
- name: Configure ${{ matrix.distro }}/${{ matrix.format }} initrd
if: matrix.prebuilt-initrd == 'yes'
run: |
- tee mkosi.conf.d/initrd.conf <<- EOF
- [Distribution]
- Initrds=initrd.zst
- EOF
-
- - name: Configure EPEL
- if: matrix.distro == 'centos' || matrix.distro == 'rocky' || matrix.distro == 'alma'
- run: |
- tee mkosi.conf.d/epel.conf <<- EOF
+ tee mkosi.conf.d/00-initrd.conf <<- EOF
[Distribution]
- Repositories=epel
+ Initrds=workflows/initrd.zst
EOF
- name: Build ${{ matrix.distro }}/${{ matrix.format }}
# FIXME: Remove when Arch/Debian/Ubuntu ship systemd v253
- name: Mask systemd-resolved
if: matrix.format == 'directory'
- run: sudo systemctl --root mkosi.output/${{ matrix.distro }}~*/image mask systemd-resolved
+ run: sudo systemctl --root image mask systemd-resolved
- name: Boot ${{ matrix.distro }}/${{ matrix.format }} systemd-nspawn
if: matrix.format == 'disk' || matrix.format == 'directory'
- Removed `--qcow2` option in favor of supporting only raw disk images as the disk image output format.
- Removed `--bmap` option as it can be trivially added manually by utilizing a finalize script.
- The `never` value for `--with-network` was spun of into its own custom option `--cache-only`.
+- Removed `--bootable` in favor of automatically generating a bootable image if all the necessary packages
+ are installed. Documentation was added in docs/bootable.ld on how a bootable image can be generated on
+ mainstream distros.
## v14
--- /dev/null
+# Building a bootable image on different distros
+
+To build a bootable image, you'll need to install a list of packages that differs depending on the
+distribution. We give an overview here of what's needed to generate a bootable image for some common
+distributions:
+
+## Arch
+
+```
+[Content]
+Packages=linux
+ systemd
+ dracut
+```
+
+## Fedora
+
+```
+[Content]
+Packages=kernel
+ systemd
+ systemd-boot
+ systemd-udev
+ dracut
+ util-linux
+```
+
+## CentOS
+
+```
+[Content]
+Packages=kernel
+ systemd
+ systemd-boot
+ systemd-udev
+ dracut
+```
+
+## Debian
+
+```
+[Content]
+Packages=linux-image-generic
+ systemd
+ systemd-boot
+ systemd-sysv
+ udev
+ dracut
+ dbus
+```
+
+## Ubuntu
+
+```
+[Content]
+Repositories=main,universe
+Packages=linux-image-generic
+ systemd
+ systemd-sysv
+ udev
+ dracut
+ dbus
+```
+
+## Opensuse
+
+```
+[Content]
+Packages=kernel-default
+ dracut
+ systemd
+ udev
+```
: Similar to `boot`, but uses `qemu` to boot up the image, i.e. instead of
container virtualization virtual machine virtualization is used. This verb is
- only supported for images that contain a boot loader, i.e. those built with
- `Bootable=yes` (see below). This command must be executed as `root` unless
- the image already exists and `-f` is not specified. Any options specified
+ only supported for disk images that contain a boot loader. Any options specified
after the `qemu` verb are appended to the `qemu` invocation.
`ssh`
<!-- FIXME: allow `Force=<n>` -->
-`Bootable=`, `--bootable`, `-b`
-
-: Generate a bootable image for UEFI systems.
-
`KernelCommandLine=`, `--kernel-command-line=`
-: Use the specified kernel command line when building bootable
- images. By default command line arguments get appended. To remove all
- arguments from the current list pass "!\*". To remove specific arguments
- add a space separated list of "!" prefixed arguments.
- For example adding "!\* console=ttyS0 rw" to a `mkosi.conf` file or the
- command line arguments passes "console=ttyS0 rw" to the kernel in any
- case. Just adding "console=ttyS0 rw" would append these two arguments
- to the kernel command line created by lower priority configuration
- files or previous `KernelCommandLine=` command line arguments.
+: Use the specified kernel command line when building images. By default
+ command line arguments get appended. To remove all arguments from the
+ current list pass "!\*". To remove specific arguments add a space
+ separated list of "!" prefixed arguments. For example adding
+ "!\* console=ttyS0 rw" to a `mkosi.conf` file or the command line
+ arguments passes "console=ttyS0 rw" to the kernel in any case. Just
+ adding "console=ttyS0 rw" would append these two arguments to the kernel
+ command line created by lower priority configuration files or previous
+ `KernelCommandLine=` command line arguments.
`SecureBoot=`, `--secure-boot`
Currently, *Fedora Linux* packages all relevant tools as of Fedora 28.
-## Compatibility
-
-Legacy concepts are avoided: generated images use *GPT* disk labels
-(and no *MBR* labels), and only systemd-based images may be generated.
-
-All generated *GPT* disk images may be booted in a local
-container directly with:
-
-```bash
-systemd-nspawn -bi image.raw
-```
-
-Additionally, bootable *GPT* disk images (as created with the
-`--bootable` flag) work when booted directly by *EFI* systems,
-for example in *KVM* via:
-
-```bash
-qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -drive format=raw,file=image.raw
-```
-
-*EFI* bootable *GPT* images are larger than plain *GPT* images, as
-they additionally carry an *EFI* system partition containing a
-boot loader, as well as a kernel, kernel modules, udev and
-more.
-
-All directory or btrfs subvolume images may be booted directly
-with:
-
-```bash
-systemd-nspawn -bD image
-```
-
# Files
To make it easy to build images for development versions of your
Create and run a raw *GPT* image with *ext4*, as `image.raw`:
```bash
-# mkosi --bootable --incremental boot
+# mkosi -p systemd --incremental boot
```
Create and run a bootable *GPT* image, as `foobar.raw`:
```bash
-# mkosi --format disk --bootable -o foobar.raw
+# mkosi -d fedora -p kernel -p systemd -p udev -o foobar.raw
# mkosi --output foobar.raw boot
# mkosi --output foobar.raw qemu
```
[Output]
Format=disk
-Bootable=yes
[Content]
-Packages=openssh-clients,httpd
+Packages=kernel,systemd,systemd-udev,openssh-clients,httpd
BuildPackages=make,gcc,libcurl-devel
EOF
# cat >mkosi.build <<EOF
make install
EOF
# chmod +x mkosi.build
-# mkosi --bootable --incremental boot
+# mkosi --incremental boot
# systemd-nspawn -bi image.raw
```
MKOSI_COMMANDS_SUDO = (Verb.shell, Verb.boot)
MKOSI_COMMANDS_CMDLINE = (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.ssh)
-DRACUT_SYSTEMD_EXTRAS = [
- "/usr/bin/systemd-ask-password",
- "/usr/bin/systemd-repart",
- "/usr/bin/systemd-tty-ask-password-agent",
- "/usr/lib/systemd/system-generators/systemd-veritysetup-generator",
- "/usr/lib/systemd/system/initrd-root-fs.target.wants/systemd-repart.service",
- "/usr/lib/systemd/system/initrd-usr-fs.target",
- "/usr/lib/systemd/system/initrd.target.wants/systemd-pcrphase-initrd.service",
- "/usr/lib/systemd/system/sysinit.target.wants/veritysetup.target",
- "/usr/lib/systemd/system/systemd-pcrphase-initrd.service",
- "/usr/lib/systemd/system/systemd-repart.service",
- "/usr/lib/systemd/system/systemd-volatile-root.service",
- "/usr/lib/systemd/system/veritysetup.target",
- "/usr/lib/systemd/systemd-pcrphase",
- "/usr/lib/systemd/systemd-veritysetup",
- "/usr/lib/systemd/systemd-volatile-root",
- "/usr/lib64/libtss2-esys.so.0",
- "/usr/lib64/libtss2-mu.so.0",
- "/usr/lib64/libtss2-rc.so.0",
- "/usr/lib64/libtss2-tcti-device.so.0",
-]
-
T = TypeVar("T")
etc_hostname.write_text(state.config.hostname + "\n")
-def configure_dracut(state: MkosiState, cached: bool) -> None:
- if not state.config.bootable or state.config.initrds:
- return
-
- if not state.config.cache_initrd and state.for_cache:
- return
-
- if state.config.cache_initrd and cached:
- return
-
- dracut_dir = state.root / "etc/dracut.conf.d"
- dracut_dir.mkdir(mode=0o755, exist_ok=True)
-
- dracut_dir.joinpath("30-mkosi-qemu.conf").write_text('add_dracutmodules+=" qemu "\n')
-
- with dracut_dir.joinpath("30-mkosi-systemd-extras.conf").open("w") as f:
- for extra in DRACUT_SYSTEMD_EXTRAS:
- f.write(f'install_optional_items+=" {extra} "\n')
- f.write('install_optional_items+=" /etc/systemd/system.conf "\n')
- if state.root.joinpath("etc/systemd/system.conf.d").exists():
- for conf in state.root.joinpath("etc/systemd/system.conf.d").iterdir():
- f.write(f'install_optional_items+=" {Path("/") / conf.relative_to(state.root)} "\n')
-
- # efivarfs must be present in order to GPT root discovery work
- dracut_dir.joinpath("30-mkosi-efivarfs.conf").write_text(
- '[[ $(modinfo -k "$kernel" -F filename efivarfs 2>/dev/null) == /* ]] && add_drivers+=" efivarfs "\n'
- )
-
-
def prepare_tree_root(state: MkosiState) -> None:
if state.config.output_format == OutputFormat.subvolume:
with complete_step("Setting up OS tree root…"):
def install_boot_loader(state: MkosiState) -> None:
- if not state.config.bootable or state.for_cache:
+ if state.for_cache:
+ return
+
+ directory = state.root / "usr/lib/systemd/boot/efi"
+ if not directory.exists():
return
if state.config.secure_boot:
assert state.config.secure_boot_key
assert state.config.secure_boot_certificate
- p = state.root / "usr/lib/systemd/boot/efi"
-
with complete_step("Signing systemd-boot binaries…"):
- for f in itertools.chain(p.glob('*.efi'), p.glob('*.EFI')):
+ for f in itertools.chain(directory.glob('*.efi'), directory.glob('*.EFI')):
run(
[
"sbsign",
# benefit that they can be signed like normal EFI binaries, and can encode everything necessary to boot a
# specific root device, including the root hash.
- if not state.config.bootable:
- return
-
# The roothash is specific to the final image so we cannot cache this step.
if state.for_cache:
return
if args.cmdline and args.verb not in MKOSI_COMMANDS_CMDLINE:
die(f"Parameters after verb are only accepted for {list_to_string(verb.name for verb in MKOSI_COMMANDS_CMDLINE)}.")
- if args.bootable:
- if args.verb == Verb.qemu and args.output_format in (
- OutputFormat.directory,
- OutputFormat.subvolume,
- OutputFormat.tar,
- OutputFormat.cpio,
- ):
- die("Directory, subvolume, tar, cpio, and plain squashfs images cannot be booted.", MkosiNotSupportedException)
+ if args.verb == Verb.qemu and args.output_format in (
+ OutputFormat.directory,
+ OutputFormat.subvolume,
+ OutputFormat.tar,
+ OutputFormat.cpio,
+ ):
+ die("Directory, subvolume, tar, cpio, and plain squashfs images cannot be booted in qemu.", MkosiNotSupportedException)
if shutil.which("bsdtar") and args.distribution == Distribution.openmandriva and args.tar_strip_selinux_context:
die("Sorry, bsdtar on OpenMandriva is incompatible with --tar-strip-selinux-context", MkosiNotSupportedException)
if not args.output_format == OutputFormat.disk:
die("Sorry, can't boot non-disk images with qemu.", MkosiNotSupportedException)
- if needs_build(args) and args.verb == Verb.qemu and not args.bootable:
- die("Images built without the --bootable option cannot be booted using qemu", MkosiNotSupportedException)
-
if args.repo_dirs and not (is_dnf_distribution(args.distribution) or args.distribution == Distribution.arch):
die("--repo-dir is only supported on DNF based distributions and Arch")
print(" Incremental:", yes_no(config.incremental))
print(" Compression:", should_compress_output(config) or "no")
- print(" Bootable:", yes_no(config.bootable))
-
- if config.bootable:
- print(" Kernel Command Line:", " ".join(config.kernel_command_line))
- print(" UEFI SecureBoot:", yes_no(config.secure_boot))
+ print(" Kernel Command Line:", " ".join(config.kernel_command_line))
+ print(" UEFI SecureBoot:", yes_no(config.secure_boot))
if config.secure_boot_key:
print(" SecureBoot Sign Key:", config.secure_boot_key)
def run_kernel_install(state: MkosiState, cached: bool) -> None:
- if not state.config.bootable:
- return
-
if not state.config.cache_initrd and state.for_cache:
return
if state.config.cache_initrd and cached:
return
+ if state.config.initrds:
+ return
+
# CentOS Stream 8 has an old version of kernel-install that unconditionally writes initrds to
# /boot/<machine-id>/<kver>, so let's detect that and move them to the correct location.
else:
machine_id = None
- # Fedora unconditionally pulls in dracut when installing a kernel and upstream dracut refuses to skip
- # running when implement KERNEL_INSTALL_INITRD_GENERATOR support so let's disable it manually here if the
- # user provided initrds.
-
- if state.config.initrds:
- for p in state.root.joinpath("usr/lib/kernel/install.d").iterdir():
- if "dracut" in p.name:
- install = state.root.joinpath("etc/kernel/install.d")
- install.mkdir(parents=True, exist_ok=True)
- install.joinpath(p.name).symlink_to("/dev/null")
+ # kernel-install on Debian/Ubuntu does not rebuild the dracut initrd, so we do it manually here.
+ if (state.root.joinpath("usr/bin/dracut").exists() and
+ state.config.distribution in (Distribution.ubuntu, Distribution.debian) and
+ not state.root.joinpath("usr/lib/kernel/install.d/50-dracut.install").exists() and
+ not state.root.joinpath("etc/kernel/install.d/50-dracut.install").exists()):
+ with complete_step("Running dpkg-reconfigure dracut…"):
+ run_workspace_command(state, ["dpkg-reconfigure", "dracut"], env=dict(hostonly_l="no"))
+ return
with complete_step("Running kernel-install…"):
for kver, kimg in gen_kernel_images(state):
if ARG_DEBUG:
cmd += ["--verbose"]
- run_workspace_command(state, cmd)
+ # Make dracut think --no-host-only was passed via the CLI.
+ run_workspace_command(state, cmd, env=dict(hostonly_l="no"))
if machine_id and (p := state.root / "boot" / machine_id / kver / "initrd").exists():
shutil.move(p, state.root / state.installer.initrd_path(kver))
- if state.config.initrds:
- for p in state.root.joinpath("etc/kernel/install.d").iterdir():
- if "dracut" in p.name:
- os.unlink(p)
-
if machine_id and (p := state.root / "boot" / machine_id).exists():
shutil.rmtree(p)
cmdline += ["--private-key", state.config.secure_boot_key]
if state.config.secure_boot_certificate:
cmdline += ["--certificate", state.config.secure_boot_certificate]
- if not state.config.bootable:
- cmdline += ["--exclude-partitions=esp,xbootldr"]
if skip:
cmdline += ["--defer-partitions", ",".join(skip)]
if split and state.config.split_artifacts:
definitions = state.workspace / "repart-definitions"
if not definitions.exists():
definitions.mkdir()
- definitions.joinpath("00-esp.conf").write_text(
- dedent(
- """\
- [Partition]
- Type=esp
- Format=vfat
- CopyFiles=/boot:/
- SizeMinBytes=1024M
- SizeMaxBytes=1024M
- """
+ bootdir = state.root.joinpath("boot/EFI/BOOT")
+
+ if bootdir.exists() and any(bootdir.iterdir()) and any(gen_kernel_images(state)):
+ # If we have at least one kernel images and a bootloader, let's generate an ESP partition.
+ definitions.joinpath("00-esp.conf").write_text(
+ dedent(
+ """\
+ [Partition]
+ Type=esp
+ Format=vfat
+ CopyFiles=/boot:/
+ SizeMinBytes=1024M
+ SizeMaxBytes=1024M
+ """
+ )
)
- )
+
definitions.joinpath("10-root.conf").write_text(
dedent(
f"""\
configure_hostname(state)
configure_root_password(state)
configure_autologin(state)
- configure_dracut(state, cached)
configure_initrd(state)
run_build_script(state)
install_build_dest(state)
manifest_format: list[ManifestFormat]
output: Path
output_dir: Optional[Path]
- bootable: bool
kernel_command_line: list[str]
secure_boot: bool
secure_boot_key: Optional[Path]
parse=config_make_path_parser(required=False),
paths=("mkosi.workspace",),
),
- MkosiConfigSetting(
- dest="bootable",
- section="Output",
- parse=config_parse_boolean,
- ),
MkosiConfigSetting(
dest="kernel_command_line",
section="Output",
help="Workspace directory",
action=action,
)
- group.add_argument(
- "-b", "--bootable",
- metavar="BOOL",
- help="Make image bootable on EFI",
- nargs="?",
- action=action,
- )
group.add_argument(
"--kernel-command-line",
metavar="OPTIONS",
packages = state.config.packages.copy()
add_packages(state.config, packages, "filesystem")
- if state.config.bootable and not state.config.initrds:
- add_packages(state.config, packages, "dracut")
-
- official_kernel_packages = {
- "linux",
- "linux-lts",
- "linux-hardened",
- "linux-zen",
- }
-
- has_kernel_package = official_kernel_packages.intersection(state.config.packages)
- if state.config.bootable and not has_kernel_package:
- # No user-specified kernel
- add_packages(state.config, packages, "linux")
-
if state.config.ssh:
add_packages(state.config, packages, "openssh")
invoke_pacman(state, packages)
- state.root.joinpath("etc/pacman.d/mirrorlist").write_text(f"Server = {state.config.mirror}/$repo/os/$arch\n")
-
def invoke_pacman(state: MkosiState, packages: Sequence[str]) -> None:
cmdline: list[PathString] = [
# systemd-gpt-auto-generator only started applying the GPT partition read-only flag to gpt-auto
# mounts from v240 onwards, while CentOS Stream 8 ships systemd v239, so we have to nudge gpt-auto to
# mount the root partition rw by default.
- if state.config.bootable and int(state.config.release) <= 8:
+ if int(state.config.release) <= 8:
kcl += ["rw"]
return kcl + DistributionInstaller.kernel_command_line(state)
packages = state.config.packages.copy()
add_packages(state.config, packages, "filesystem")
- if state.config.bootable:
- add_packages(state.config, packages, "kernel")
- if not state.config.initrds:
- add_packages(state.config, packages, "dracut", "dracut-config-generic")
- add_packages(state.config, packages, "systemd-udev", conditional="systemd")
- if release >= 9:
- add_packages(state.config, packages, "systemd-boot", conditional="systemd")
if state.config.ssh:
add_packages(state.config, packages, "openssh-server")
from mkosi.backend import MkosiState, add_packages
from mkosi.distributions import DistributionInstaller
-from mkosi.install import install_skeleton_trees, write_resource
+from mkosi.install import install_skeleton_trees
from mkosi.run import run, run_with_apivfs
from mkosi.types import _FILE, CompletedProcess, PathString
class DebianInstaller(DistributionInstaller):
needs_skeletons_after_bootstrap = True
- repositories_for_boot: set[str] = set()
-
- @classmethod
- def _add_default_kernel_package(cls, state: MkosiState, packages: list[str]) -> None:
- # Don't pull in a kernel if users specify one, but otherwise try to pick a default
- # one - try to infer from the architecture.
- if not any(package.startswith("linux-image") for package in packages):
- add_packages(state.config, packages, f"linux-image-{DEBIAN_KERNEL_ARCHITECTURES[state.config.architecture]}")
@classmethod
def filesystem(cls) -> str:
dpkg_io_conf.write_text("force-unsafe-io\n")
repos = {"main", *state.config.repositories}
- # Ubuntu needs the 'universe' repo to install 'dracut'
- if state.config.bootable:
- repos |= cls.repositories_for_boot
# debootstrap fails if a base image is used with an already populated root, so skip it.
if state.config.base_image is None:
packages = state.config.packages.copy()
add_packages(state.config, packages, "base-files")
- if state.config.bootable:
- if not state.config.initrds:
- add_packages(state.config, packages, "dracut", "dracut-config-generic")
- cls._add_default_kernel_package(state, packages)
-
if state.config.ssh:
add_packages(state.config, packages, "openssh-server")
with dpkg_nodoc_conf.open("w") as f:
f.writelines(f"path-exclude {d}/*\n" for d in doc_paths)
- if state.config.bootable and state.config.base_image is None:
+ if state.config.base_image is None:
# systemd-boot won't boot unified kernel images generated without a BUILD_ID or VERSION_ID in
# /etc/os-release. Build one with the mtime of os-release if we don't find them.
with state.root.joinpath("etc/os-release").open("r+") as f:
invoke_apt(state, "get", "update", ["--assume-yes"])
- if state.config.bootable:
- # Ensure /efi exists so that the ESP is mounted there, and we never run dpkg -i on vfat
- state.root.joinpath("efi").mkdir(mode=0o755)
-
- if state.config.bootable:
- add_apt_package_if_exists(state, packages, "systemd-boot")
+ # Ensure /efi exists so that the ESP is mounted there, and we never run dpkg -i on vfat
+ state.root.joinpath("efi").mkdir(mode=0o755, exist_ok=True)
invoke_apt(state, "get", "install", ["--assume-yes", "--no-install-recommends", *packages])
presetdir.mkdir(exist_ok=True, mode=0o755)
presetdir.joinpath("99-mkosi-disable.preset").write_text("disable *")
- if state.config.bootable and not state.config.initrds:
- write_resource(state.root / "etc/kernel/install.d/50-mkosi-dpkg-reconfigure-dracut.install",
- "mkosi.resources", "dpkg-reconfigure-dracut.install", executable=True)
-
@classmethod
def install_packages(cls, state: MkosiState, packages: Sequence[str]) -> None:
invoke_apt(state, "get", "install", ["--assume-yes", "--no-install-recommends", *packages])
APT_CONFIG=config_file,
DEBIAN_FRONTEND="noninteractive",
DEBCONF_INTERACTIVE_SEEN="true",
+ KERNEL_INSTALL_BYPASS="1",
INITRD="No",
)
packages = state.config.packages.copy()
add_packages(state.config, packages, "filesystem")
- if state.config.bootable:
- add_packages(state.config, packages, "kernel-core", "kernel-modules")
- add_packages(state.config, packages, "systemd-udev", conditional="systemd")
- if not state.config.initrds:
- add_packages(state.config, packages, "dracut", "dracut-config-generic")
if state.config.ssh:
add_packages(state.config, packages, "openssh-server")
profile_path: Path
root: Path
pkgs: dict[str, list[str]] = {}
- dracut_atom = "sys-kernel/dracut"
EMERGE_UPDATE_OPTS = [
"--update",
packages = state.config.packages.copy()
add_packages(state.config, packages, "filesystem")
- if state.config.bootable and not state.config.initrds:
- add_packages(state.config, packages, "dracut")
- # Mageia ships /etc/50-mageia.conf that omits systemd from the initramfs and disables hostonly.
- # We override that again so our defaults get applied correctly on Mageia as well.
- state.root.joinpath("etc/dracut.conf.d/51-mkosi-override-mageia.conf").write_text(
- 'hostonly=no\n'
- 'omit_dracutmodules=""\n'
- )
if state.config.ssh:
add_packages(state.config, packages, "openssh-server")
packages = state.config.packages.copy()
# well we may use basesystem here, but that pulls lot of stuff
add_packages(state.config, packages, "filesystem")
- if state.config.bootable:
- add_packages(state.config, packages, "systemd-boot", "systemd-cryptsetup", conditional="systemd")
- add_packages(state.config, packages, "kernel-release-server", "timezone")
- if not state.config.initrds:
- add_packages(state.config, packages, "dracut")
if state.config.ssh:
add_packages(state.config, packages, "openssh-server")
with_apivfs: bool = False) -> None:
cmdline: list[PathString] = ["zypper", "--root", state.root, *global_opts, verb, *verb_opts, *args]
- env={"ZYPP_CONF": state.root.joinpath("etc/zypp/zypp.conf")}
+ env = dict(ZYPP_CONF=str(state.root / "etc/zypp/zypp.conf"), KERNEL_INSTALL_BYPASS="1")
if with_apivfs:
run_with_apivfs(state, cmdline, env=env)
if state.config.base_image is None:
add_packages(state.config, packages, "filesystem")
- if state.config.bootable:
- add_packages(state.config, packages, "kernel-default")
- if not state.config.initrds:
- add_packages(state.config, packages, "dracut")
-
if state.config.ssh:
add_packages(state.config, packages, "openssh-server")
return line
patch_file(state.root / "etc/pam.d/common-auth", jj)
-
- if state.config.bootable and not state.config.initrds:
- dracut_dir = state.root / "etc/dracut.conf.d"
- dracut_dir.mkdir(mode=0o755, exist_ok=True)
- dracut_dir.joinpath("30-mkosi-opensuse.conf").write_text('hostonly=no\n')
# SPDX-License-Identifier: LGPL-2.1+
-from collections.abc import Sequence
-
-from mkosi.backend import MkosiState, add_packages
+from mkosi.backend import MkosiState
from mkosi.distributions.debian import DebianInstaller
class UbuntuInstaller(DebianInstaller):
- repositories_for_boot = {"universe"}
-
- @classmethod
- def _add_default_kernel_package(cls, state: MkosiState, packages: list[str]) -> None:
- # use the global metapckage linux-generic if the user didn't pick one
- if ("linux-generic" not in packages and
- not any(package.startswith("linux-image") for package in packages)):
- add_packages(state.config, packages, "linux-generic")
-
@classmethod
def _add_apt_auxiliary_repos(cls, state: MkosiState, repos: set[str]) -> None:
if state.config.release in ("unstable", "sid"):
+++ /dev/null
-#!/bin/sh
-
-set -e
-
-COMMAND="${1:?}"
-ENTRY_DIR_ABS="${3:?}"
-
-case "$COMMAND" in
- add)
- # Make sure the directory the kernel image and initrd will be written to exists.
- mkdir -p "$ENTRY_DIR_ABS"
-
- if [ "$#" -ge 5 ]; then
- # An explicit initrd path was passed so no need to regenerate the default initrd.
- exit 0
- fi
-
- # Running kernel-install on Debian/Ubuntu doesn't regenerate the initramfs. Instead, we can trigger
- # regeneration of the initramfs via "dpkg-reconfigure dracut".
- dpkg-reconfigure dracut
- ;;
- *)
- exit 0
- ;;
-esac
assert parse(["build"]).verb == Verb.build
assert parse(["shell"]).verb == Verb.shell
assert parse(["boot"]).verb == Verb.boot
- assert parse(["--bootable", "qemu"]).verb == Verb.qemu
+ assert parse(["qemu"]).verb == Verb.qemu
with pytest.raises(SystemExit):
parse(["invalid"])