extra/skeleton trees are defined.
- mkosi doesn't install any default packages anymore aside from the base filesystem layout package. In
practice, this means systemd and other basic tools have to be installed explicitly from now on.
+- Removed `--base-packages` as it's not needed anymore since we don't install any packages by default anymore
+ aside from the base filesystem layout package.
- 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`.
### [Content] Section
-`BasePackages=`, `--base-packages`
-
-: Takes a boolean or the special value `conditional`. If true,
- automatically install packages to ensure basic functionality, as
- appropriate for the given image type. For example, `systemd` is
- always included, `systemd-udev` and `dracut` if the image is
- bootable, and so on.
-
-: If false, only packages specified with `Packages=` will be
- installed.
-
-: If `conditional`, the list of packages to install will be extended
- with boolean dependencies
- (c.f. https://rpm.org/user_doc/boolean_dependencies.html), to
- install specific packages when *other* packages are in the list. For
- example, `systemd-udev` may be automatically included if the image
- is bootable and `systemd` is installed. With this, various "base"
- packages still need to be specified if they should be included, but
- the corresponding "extension" packages will be added automatically
- when appropriate. This feature depends on support in the package
- manager, so it is not implemented for all distributions.
-
`Packages=`, `--package=`, `-p`
: Install the specified distribution packages (i.e. RPM, DEB, …) in the
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")
- # If we are building a sysext we don't want to add base packages to the
- # extension image, as they will already be in the base image.
- if args.base_image is not None:
- args.base_packages = False
-
if args.qemu_kvm is True and not qemu_check_kvm_support():
die("Sorry, the host machine does not support KVM acceleration.")
tar_strip_selinux_context: bool
incremental: bool
cache_initrd: bool
- base_packages: Union[str, bool]
packages: list[str]
remove_packages: list[str]
with_docs: bool
tar.extractall(path, members=members, numeric_owner=numeric_owner)
-def add_packages(
- config: MkosiConfig, packages: list[str], *names: str, conditional: Optional[str] = None
-) -> None:
-
- """Add packages in @names to @packages, if enabled by --base-packages.
-
- If @conditional is specified, rpm-specific syntax for boolean
- dependencies will be used to include @names if @conditional is
- satisfied.
- """
- assert config.base_packages is True or config.base_packages is False or config.base_packages == "conditional"
-
- if config.base_packages is True or (config.base_packages == "conditional" and conditional):
- for name in names:
- packages.append(f"({name} if {conditional})" if conditional else name)
-
-
def sort_packages(packages: Iterable[str]) -> list[str]:
"""Sorts packages: normal first, paths second, conditional third"""
return parse_boolean(value) if value else None
-def config_parse_base_packages(dest: str, value: Optional[str], namespace: argparse.Namespace) -> Union[bool, str]:
- if dest in namespace:
- return getattr(namespace, dest) # type: ignore
-
- if value == "conditional":
- return value
-
- return parse_boolean(value) if value else False
-
-
def config_default_release(namespace: argparse.Namespace) -> Any:
# If we encounter Release in [Match] and no distribution has been set yet, configure the default
# distribution as well since the default release depends on the selected distribution.
section="Output",
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(required=False)),
),
- MkosiConfigSetting(
- dest="base_packages",
- section="Content",
- parse=config_parse_base_packages,
- default=True,
- ),
MkosiConfigSetting(
dest="packages",
section="Content",
)
group = parser.add_argument_group("Content options")
- group.add_argument(
- "--base-packages",
- metavar="OPTION",
- help="Automatically inject basic packages in the system (systemd, kernel, …)",
- action=action,
- )
group.add_argument(
"-p", "--package",
metavar="PACKAGE",
from collections.abc import Sequence
from textwrap import dedent
-from mkosi.backend import MkosiState, add_packages, sort_packages
+from mkosi.backend import MkosiState, sort_packages
from mkosi.distributions import DistributionInstaller
from mkosi.log import complete_step
from mkosi.run import run_with_apivfs
for d in state.config.repo_dirs:
f.write(f"Include = {d}/*\n")
- packages = state.config.packages.copy()
- add_packages(state.config, packages, "filesystem")
-
- invoke_pacman(state, packages)
+ invoke_pacman(state, ["filesystem", *state.config.packages])
def invoke_pacman(state: MkosiState, packages: Sequence[str]) -> None:
from collections.abc import Sequence
from pathlib import Path
-from mkosi.backend import Distribution, MkosiConfig, MkosiState, add_packages
+from mkosi.backend import Distribution, MkosiConfig, MkosiState
from mkosi.distributions import DistributionInstaller
from mkosi.distributions.fedora import Repo, invoke_dnf, setup_dnf
from mkosi.log import complete_step, die
else:
env = {}
- packages = state.config.packages.copy()
- add_packages(state.config, packages, "filesystem")
-
- invoke_dnf(state, "install", packages, env)
+ invoke_dnf(state, "install", ["filesystem", *state.config.packages], env)
syslog = state.root.joinpath("etc/systemd/system/syslog.service")
if release <= 8 and syslog.is_symlink():
from pathlib import Path
from textwrap import dedent
-from mkosi.backend import MkosiState, add_packages
+from mkosi.backend import MkosiState
from mkosi.distributions import DistributionInstaller
from mkosi.install import install_skeleton_trees
from mkosi.run import run, run_with_apivfs
# Pretend we're lxc so debootstrap skips its mknod check.
run_with_apivfs(state, cmdline, env=dict(container="lxc"))
- # Install extra packages via the secondary APT run, because it is smarter and can deal better with any
- # conflicts. dbus and libpam-systemd are optional dependencies for systemd in debian so we include them
- # explicitly.
- packages = state.config.packages.copy()
- add_packages(state.config, packages, "base-files")
-
# Debian policy is to start daemons by default. The policy-rc.d script can be used choose which ones to
# start. Let's install one that denies all daemon startups.
# See https://people.debian.org/~hmh/invokerc.d-policyrc.d-specification.txt for more information.
# 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])
+ invoke_apt(state, "get", "install",
+ ["--assume-yes", "--no-install-recommends", "base-files", *state.config.packages])
# Now clean up and add the real repositories, so that the image is ready
if state.config.local_mirror:
)
return run_with_apivfs(state, cmdline, stdout=stdout, env=env)
-
-
-def add_apt_package_if_exists(state: MkosiState, packages: list[str], package: str) -> None:
- if invoke_apt(state, "cache", "search", ["--names-only", f"^{package}$"], stdout=subprocess.PIPE).stdout.strip():
- add_packages(state.config, packages, package)
from textwrap import dedent
from typing import Any, NamedTuple, Optional
-from mkosi.backend import (
- Distribution,
- MkosiState,
- add_packages,
- detect_distribution,
- sort_packages,
-)
+from mkosi.backend import Distribution, MkosiState, detect_distribution, sort_packages
from mkosi.distributions import DistributionInstaller
from mkosi.log import MkosiPrinter, complete_step, warn
from mkosi.remove import unlink_try_hard
setup_dnf(state, repos)
- packages = state.config.packages.copy()
- add_packages(state.config, packages, "filesystem")
-
- invoke_dnf(state, "install", packages)
+ invoke_dnf(state, "install", ["filesystem", *state.config.packages])
# Fedora defaults to sssd authselect profile, let's override it with the minimal profile if it exists and
# extend it with the with-homed feature if we can find it.
from collections.abc import Sequence
from pathlib import Path
-from mkosi.backend import MkosiState, add_packages
+from mkosi.backend import MkosiState
from mkosi.distributions import DistributionInstaller
from mkosi.distributions.fedora import Repo, invoke_dnf, setup_dnf
from mkosi.log import complete_step
setup_dnf(state, repos)
- packages = state.config.packages.copy()
- add_packages(state.config, packages, "filesystem")
-
- invoke_dnf(state, "install", packages)
+ invoke_dnf(state, "install", ["filesystem", *state.config.packages])
from collections.abc import Sequence
from pathlib import Path
-from mkosi.backend import MkosiState, add_packages
+from mkosi.backend import MkosiState
from mkosi.distributions import DistributionInstaller
from mkosi.distributions.fedora import Repo, invoke_dnf, setup_dnf
from mkosi.log import complete_step
setup_dnf(state, repos)
- packages = state.config.packages.copy()
- add_packages(state.config, packages, "filesystem")
-
- invoke_dnf(state, "install", packages)
+ invoke_dnf(state, "install", ["filesystem", *state.config.packages])
from pathlib import Path
from textwrap import dedent
-from mkosi.backend import MkosiState, add_packages, patch_file
+from mkosi.backend import MkosiState, patch_file
from mkosi.distributions import DistributionInstaller
from mkosi.log import complete_step
from mkosi.run import run, run_with_apivfs
zypper_init(state)
zypper_init_repositories(state)
- packages = state.config.packages.copy()
-
- if state.config.base_image is None:
- add_packages(state.config, packages, "filesystem")
-
- zypper_install(state, packages)
+ zypper_install(state, ["filesystem", *state.config.packages])
zypper_finalize_repositories(state)
if state.config.base_image is not None: