Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework configuration parsing (again) #2847

Merged
merged 12 commits into from
Jul 9, 2024
Merged

Conversation

DaanDeMeyer
Copy link
Contributor

@DaanDeMeyer DaanDeMeyer commented Jul 7, 2024

As explained in #2846, there are multiple issues with the current
implementation of mkosi.images. Let's take what we learned from the
default initrd and the default tools tree and apply it mkosi.images.

Specifically, all issues arise from the fact that we apply every option
from the global configuration (including CLI arguments) to the images
from mkosi.images/. To avoid the issues that arise from this (e.g --package
abc installing abc in all images), we made configuration values override
CLI arguments again so that we could override faulty CLI arguments again
in subimages so that they would only apply to the main image (e.g. set
Format= explicitly for each subimage so that --format on the command line
only applies to the main image).

Because we still wanted to allow configurable settings that can be modified
via the command line, we introduced the default specifier '@' which can be
prefixed to a setting to set a default value instead of overriding the value.
The '@' specifier is generally used in the global image independent
configuration to specify default values that can be overridden from the command
line. This specifier has led to a lot of confusion, along with the behavior that
the CLI does not override the configuration.

From the default tools tree and default initrd, we learned that what works
very well is to only have specific settings from the main image configuration
apply to the default tools tree and default initrd. For example, the distribution,
release, mirror and architecture should be the same for the main image and the
initrd, but the packages from the main image should not all be installed in the
initrd.

We can apply this idea to the images from mkosi.images/ as well, if we
introduce the assumption that all images defined in mkosi.images are
subimages intended to be included in some way or form in the main image.
This assumption allows us to divide all settings into either image specific
settings or "universal" settings that should apply to the main image and all
its subimages. The universal settings are passed on to each subimage. The image
specific settings are not.

This idea also allows us to define the "main" image outside of mkosi.images
again. Since only "universal" settings are passed on, we can safely define
an output format and such again in the global configuration, as we know this
won't be passed on to subimages.

It also allows us to make CLI arguments override configuration again. Since
there is no need anymore for subimages to override the CLI configuration as
inappropriate CLI configuration such as extra packages will only apply to the
main image and not any subimages from mkosi.images/. Because CLI configuration
overrides file configuration again, we also don't need the '@' specifier anymore,
as default values can simply be set without '@', since the CLI will override
the configuration file values by default.

We also lose the need for --append, because the sole use for --append was again
to override file based configuration.

This commit implements all of what's mentioned above, specifically:

  • CLI configuration now always trumps file based configuration.
  • The '@' specifier is dropped automatically during parsing
  • The main image is now always added from global configuration, even
    if there are images in mkosi.images/. The main image is always built
    last, and cannot be used as a dependency in the Dependencies= setting
    for images defined in mkosi.images/.
  • The Dependencies= setting for the main image now is used to specify
    which subimages from mkosi.images/ to build. By default all subimages
    are built.
  • A universal tag is introduced for settings and appropriate settings
    are marked as universal. Universal settings are passed on from the
    main image configuration to subimage configuration.
  • The Images= setting is removed, as it's role is replaced by
    Dependencies=.
  • The old name mkosi.presets and the Preset section name are removed
    as they have been deprecated for a long time now.
  • The config parsing tests are extended to cover more cases.
  • All builtin configuration is adapted to stop using the '@' specifier.
  • The documentation is updated in accordance with the changes.

Fits what the function does better.
We don't need to keep track of the current amount of includes since
those includes are already tracked in parsed_includes and will be
ignored. Slightly less efficient but this shouldn't matter here.

We also store the inode in parsed_includes before we parse the config
to make sure we don't try to parse it more than once.
Doesn't change behavior, just slightly easier to read.
@DaanDeMeyer DaanDeMeyer force-pushed the config branch 4 times, most recently from 05fb034 to 239ca7c Compare July 7, 2024 20:41
@DaanDeMeyer DaanDeMeyer changed the title WIP Rework configuration parsing (again) Jul 7, 2024
@DaanDeMeyer DaanDeMeyer marked this pull request as ready for review July 7, 2024 20:49
@DaanDeMeyer
Copy link
Contributor Author

This breaks backwards compat in the following ways:

  • @ is removed, fix is to just remove the @. We can do this in mkosi itself and log a warning
  • Images is removed, which is only applicable when building multiple images with mkosi.images/, which is rare
  • Main image is now always included even when mkosi.images is used. Fix is to move the main image configuration from mkosi.images to the global configuration.
  • --append is removed, which is only used by the systemd integration tests I think
  • mkosi.images can only be used to build subimages now, with more restrictions put on them (same distribution, release, mirror, ...). Not all CLI settings apply to mkosi.images/ anymore (which is a good thing).

Anyone building single images without using mkosi.images/ will not be affected if we automatically remove @ from settings within mkosi. This makes me think that breaking compat here is worth it given the substantial simplification of config parsing we get from it.

@NekkoDroid
Copy link
Contributor

NekkoDroid commented Jul 7, 2024

Just went to test it out (adjusting my config for this) and noticed that %i was being ignored in subimages. ImageId and ImageVersion probably should also have the universal tag applied.

  1. Is there any reason to keep the symlinks for subimages around now that they aren't used for qemu/shell/...? They can't really be used as base trees for anything since the mounting depends on the extension.
  2. Is there some way to apply a global RemoveFiles= list to the image & subimages? I was using it globally to clean up directories & files that are shipped as part of Packages= and are needed for builds to work, but aren't needed any output image.

@DaanDeMeyer DaanDeMeyer force-pushed the config branch 2 times, most recently from c77e18a to 491c5e6 Compare July 8, 2024 07:29
@DaanDeMeyer
Copy link
Contributor Author

Just went to test it out (adjusting my config for this) and noticed that %i was being ignored in subimages. ImageId and ImageVersion probably should also have the universal tag applied.

Added both as universal settings.

  1. Is there any reason to keep the symlinks for subimages around now that they aren't used for qemu/shell/...? They can't really be used as base trees for anything since the mounting depends on the extension.

I've fixed that now by making sure we resolve symlinks in mount_base_trees()

  1. Is there some way to apply a global RemoveFiles= list to the image & subimages? I was using it globally to clean up directories & files that are shipped as part of Packages= and are needed for builds to work, but aren't needed any output image.

Have a shared snippet with the RemoveFiles= and Include= it in every subimage.

@DaanDeMeyer
Copy link
Contributor Author

Also changed the behavior to automatically drop the '@' specifier in mkosi itself to reduce the breakage caused by this PR

@DaanDeMeyer DaanDeMeyer force-pushed the config branch 2 times, most recently from e070b95 to 9249677 Compare July 8, 2024 08:16
We don't read configuration for the genkey verb anymore so this can
be dropped.
We want to check the extension on the resolved path, not on any
symlinks, so let's make sure we resolve the path first.
Instead of sharing the build directory between all images, let's
use a subdirectory of the build directory for subimages.

This requires us to unshare the user namespace in run_build() before
we create the directories so that we always have permissions to create
any nested build directories.
mkosi/resources/mkosi.md Outdated Show resolved Hide resolved
mkosi/config.py Outdated Show resolved Hide resolved
mkosi/config.py Outdated Show resolved Hide resolved
mkosi/config.py Outdated Show resolved Hide resolved
@DaanDeMeyer DaanDeMeyer force-pushed the config branch 3 times, most recently from 55e6cb7 to b1efe11 Compare July 8, 2024 09:51
@DaanDeMeyer
Copy link
Contributor Author

Added one more fix to make sure that mkosi.local.conf still overrides configuration that is parsed later.

Let's also chown the directory to be user owned if located in /tmp
or /var/tmp.
DaanDeMeyer added a commit to DaanDeMeyer/systemd that referenced this pull request Jul 8, 2024
In systemd/mkosi#2847, the '@' specifier is
removed, CLI arguments take priority over configuration files again
and the "main" image is defined at the top level instead of in
mkosi.images/. Additionally, not every setting from the top level
configuration is inherited by the images in mkosi.images/ anymore,
only settings which make sense to be inherited are inherited.

This commit gets rid of all the usages of '@', moves the "main" image
configuration from mkosi.images/system to the top level and gets rid
of various hacks we had in place to deal with quirks of the old
configuration parsing logic.

We also remove usages of Images= and --append as these options are
removed by the mentioned PR.
@DaanDeMeyer DaanDeMeyer force-pushed the config branch 2 times, most recently from 4830f1d to 513d638 Compare July 8, 2024 18:46
DaanDeMeyer added a commit to DaanDeMeyer/systemd that referenced this pull request Jul 8, 2024
In systemd/mkosi#2847, the '@' specifier is
removed, CLI arguments take priority over configuration files again
and the "main" image is defined at the top level instead of in
mkosi.images/. Additionally, not every setting from the top level
configuration is inherited by the images in mkosi.images/ anymore,
only settings which make sense to be inherited are inherited.

This commit gets rid of all the usages of '@', moves the "main" image
configuration from mkosi.images/system to the top level and gets rid
of various hacks we had in place to deal with quirks of the old
configuration parsing logic.

We also remove usages of Images= and --append as these options are
removed by the mentioned PR.
Parse functions should return None to pick the default value. Also,
we don't get any values at all if unescape=True and the empty string
is passed so make sure we handle that case as well.
As explained in systemd#2846, there are multiple issues with the current
implementation of mkosi.images. Let's take what we learned from the
default initrd and the default tools tree and apply it mkosi.images.

Specifically, all issues arise from the fact that we apply every option
from the global configuration (including CLI arguments) to the images
from mkosi.images/. To avoid the issues that arise from this (e.g --package
abc installing abc in all images), we made configuration values override
CLI arguments again so that we could override faulty CLI arguments again
in subimages so that they would only apply to the main image (e.g. set
Format= explicitly for each subimage so that --format on the command line
only applies to the main image).

Because we still wanted to allow configurable settings that can be modified
via the command line, we introduced the default specifier '@' which can be
prefixed to a setting to set a default value instead of overriding the value.
The '@' specifier is generally used in the global image independent
configuration to specify default values that can be overridden from the command
line. This specifier has led to a lot of confusion, along with the behavior that
the CLI does not override the configuration.

From the default tools tree and default initrd, we learned that what works
very well is to only have specific settings from the main image configuration
apply to the default tools tree and default initrd. For example, the distribution,
release, mirror and architecture should be the same for the main image and the
initrd, but the packages from the main image should not all be installed in the
initrd.

We can apply this idea to the images from mkosi.images/ as well, if we
introduce the assumption that all images defined in mkosi.images are
subimages intended to be included in some way or form in the main image.
This assumption allows us to divide all settings into either image specific
settings or "universal" settings that should apply to the main image and all
its subimages. The universal settings are passed on to each subimage. The image
specific settings are not.

This idea also allows us to define the "main" image outside of mkosi.images
again. Since only "universal" settings are passed on, we can safely define
an output format and such again in the global configuration, as we know this
won't be passed on to subimages.

It also allows us to make CLI arguments override configuration again. Since
there is no need anymore for subimages to override the CLI configuration as
inappropriate CLI configuration such as extra packages will only apply to the
main image and not any subimages from mkosi.images/. Because CLI configuration
overrides file configuration again, we also don't need the '@' specifier anymore,
as default values can simply be set without '@', since the CLI will override
the configuration file values by default.

We also lose the need for --append, because the sole use for --append was again
to override file based configuration.

Note that configuration from mkosi.local.conf is special in that it
should override settings from other configuration files, but not settings
that are specified on the CLI.

This commit implements all of what's mentioned above, specifically:

- CLI configuration now always trumps file based configuration.
- The '@' specifier is dropped automatically during parsing
- The main image is now always added from global configuration, even
if there are images in mkosi.images/. The main image is always built
last, and cannot be used as a dependency in the Dependencies= setting
for images defined in mkosi.images/.
- The Dependencies= setting for the main image now is used to specify
which subimages from mkosi.images/ to build. By default all subimages
are built.
- A universal tag is introduced for settings and appropriate settings
are marked as universal. Universal settings are passed on from the
main image configuration to subimage configuration.
- The Images= setting is removed, as it's role is replaced by
Dependencies=.
- The old name mkosi.presets and the Preset section name are removed
as they have been deprecated for a long time now.
- The config parsing tests are extended to cover more cases.
- All builtin configuration is adapted to stop using the '@' specifier.
- The documentation is updated in accordance with the changes.
DaanDeMeyer added a commit to DaanDeMeyer/systemd that referenced this pull request Jul 8, 2024
In systemd/mkosi#2847, the '@' specifier is
removed, CLI arguments take priority over configuration files again
and the "main" image is defined at the top level instead of in
mkosi.images/. Additionally, not every setting from the top level
configuration is inherited by the images in mkosi.images/ anymore,
only settings which make sense to be inherited are inherited.

This commit gets rid of all the usages of '@', moves the "main" image
configuration from mkosi.images/system to the top level and gets rid
of various hacks we had in place to deal with quirks of the old
configuration parsing logic.

We also remove usages of Images= and --append as these options are
removed by the mentioned PR.
@DaanDeMeyer DaanDeMeyer merged commit 6b66aa9 into systemd:main Jul 9, 2024
30 of 32 checks passed
@DaanDeMeyer DaanDeMeyer deleted the config branch July 9, 2024 06:06
DaanDeMeyer added a commit to systemd/systemd that referenced this pull request Jul 9, 2024
In systemd/mkosi#2847, the '@' specifier is
removed, CLI arguments take priority over configuration files again
and the "main" image is defined at the top level instead of in
mkosi.images/. Additionally, not every setting from the top level
configuration is inherited by the images in mkosi.images/ anymore,
only settings which make sense to be inherited are inherited.

This commit gets rid of all the usages of '@', moves the "main" image
configuration from mkosi.images/system to the top level and gets rid
of various hacks we had in place to deal with quirks of the old
configuration parsing logic.

We also remove usages of Images= and --append as these options are
removed by the mentioned PR.
DaanDeMeyer added a commit to DaanDeMeyer/systemd that referenced this pull request Jul 9, 2024
In systemd/mkosi#2847, the '@' specifier is
removed, CLI arguments take priority over configuration files again
and the "main" image is defined at the top level instead of in
mkosi.images/. Additionally, not every setting from the top level
configuration is inherited by the images in mkosi.images/ anymore,
only settings which make sense to be inherited are inherited.

This commit gets rid of all the usages of '@', moves the "main" image
configuration from mkosi.images/system to the top level and gets rid
of various hacks we had in place to deal with quirks of the old
configuration parsing logic.

We also remove usages of Images= and --append as these options are
removed by the mentioned PR.

(cherry picked from commit 20345a8)
@septatrix
Copy link
Contributor

  • Main image is now always included even when mkosi.images is used. Fix is to move the main image configuration from mkosi.images to the global configuration.
  • mkosi.images can only be used to build subimages now, with more restrictions put on them (same distribution, release, mirror, ...). Not all CLI settings apply to mkosi.images/ anymore (which is a good thing).

I have two images which are strongly related but neither is a subimage or dependency of the other. What is the best way to have such a configuration with the new config mechanism?

More specifically I have a system image and a separate installer. If I move the former to the main image I will not be able to build the latter separate if I understand correctly (or at least I have no clue what to pass on the command line to only build the installer).

@DaanDeMeyer
Copy link
Contributor Author

  • Main image is now always included even when mkosi.images is used. Fix is to move the main image configuration from mkosi.images to the global configuration.
  • mkosi.images can only be used to build subimages now, with more restrictions put on them (same distribution, release, mirror, ...). Not all CLI settings apply to mkosi.images/ anymore (which is a good thing).

I have two images which are strongly related but neither is a subimage or dependency of the other. What is the best way to have such a configuration with the new config mechanism?

More specifically I have a system image and a separate installer. If I move the former to the main image I will not be able to build the latter separate if I understand correctly (or at least I have no clue what to pass on the command line to only build the installer).

@septatrix My suggestion here is to have two different configuration which you build separate using mkosi --directory <...>. Shared configuration between the two images can be handled with Include=.

@septatrix
Copy link
Contributor

@septatrix My suggestion here is to have two different configuration which you build separate using mkosi --directory <...>. Shared configuration between the two images can be handled with Include=.

I came up with a different solution in the meantime. I set Format=none for the main image (which should completely ignore it?) and use a profile to swap out the Dependencies= as well as a [Match] in the system image which checks for the profile and adjusts Format=, SplitArtifacts= accordingly. However, I am not sure if this is intended or bound to be broken at some later point.

The directory approach seems a bit annoying because in the installer I need to reference the split artifacts from the system image

@septatrix
Copy link
Contributor

Also: Will mkosi qemu/boot now always start the main image? Using mkosi.images but not being able to start nothing but the main image seems a bit of a misnomer if that limitation really exists...

@DaanDeMeyer
Copy link
Contributor Author

@septatrix Yes we'll always start the main image now. We had to introduce limitations to the feature to make it usable. We're not aiming for mkosi to be a general purpose build system. If mkosi.images doesn't fit your needs, you'll need to add something on top to orchestrate multiple image builds.

@septatrix
Copy link
Contributor

Okay, in that case I will need to resort to -C, understood. It just feels like mkosi.images is now a misnomer. Similarly mkosi summary still talk about "default" images but if there is no way to start different images that might be confusing. The way this directory is now handled is more akin to mkosi.components or something like it because the sub"images" are intended to be used standalone but instead are more like glorified build scripts

@septatrix
Copy link
Contributor

It also seems like I need a separate mkosi.version, mkosi.crt, and mkosi.key files for each of them then... :/

@DaanDeMeyer
Copy link
Contributor Author

It also seems like I need a separate mkosi.version, mkosi.crt, and mkosi.key files for each of them then... :/

Include= is your friend, you can have a directory containing all of those and simply Include= it wherever needed.

@septatrix
Copy link
Contributor

It also seems like I need a separate mkosi.version, mkosi.crt, and mkosi.key files for each of them then... :/

Include= is your friend, you can have a directory containing all of those and simply Include= it wherever needed.

This works only to a certain degree. mkosi bump does not work and mkosi genkey still places it in the individual directories (even when settings SshCertificate=). It is better than nothing but its fair to say that my use case and current workflow has definitely been hit by this change (though I can understand why it was done)

@DaanDeMeyer
Copy link
Contributor Author

It also seems like I need a separate mkosi.version, mkosi.crt, and mkosi.key files for each of them then... :/

Include= is your friend, you can have a directory containing all of those and simply Include= it wherever needed.

This works only to a certain degree. mkosi bump does not work and mkosi genkey still places it in the individual directories (even when settings SshCertificate=). It is better than nothing but its fair to say that my use case and current workflow has definitely been hit by this change (though I can understand why it was done)

Yeah I'm sorry about that, but we had to consider all the users not using mkosi.images as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants