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

Support kargs.d directories for default kargs (rebased) #2217

Closed
wants to merge 2 commits into from

Conversation

agners
Copy link
Contributor

@agners agners commented Oct 14, 2020

This is a rebased version of #1836. The rebase mainly required trivial conflict fixes. There was one larger conflict with https://github.com/ostreedev/ostree/commits/52a6224606e4a057b806225d93a2d0239a004723 which required a bit more in depth changes to preserve/adhere to the idea of that change. All unit tests run by make check are passing.

We would like a method to set and update kernel arguments via vanilla OSTree updates. Besides this approach we were also considering using OSTree metadata. But it seems this approach with files in-tree is more flexible. Feedback welcome!

Add the following config directories for setting default kernel
arguments:

/etc/ostree/kargs.d (host config)
/usr/lib/ostree-boot/kargs.d (base config)

These directories contain files whose contents consist of a karg
snippet, which is a collection kernel parameter keys and values.
Example of a snippet:

KEY=FOO KEYFLAG ANOTHERKEY=VALUE1 ANOTHERKEY=VALUE2

Snippets are read in alphanumeric order of the karg snippet filename
when generating the final kernel options from the host and base config
directories. Ordering may be specified by prefixing a number, e.g.
/etc/ostree/kargs.d/4000_localhost.

The bootconfig key ostree-kargs-generated-from-config indicates
whether the kargs were generated by ostree from the kargs.d directories
(true), or copied from the previous deployment (false). Editing the
kargs through the command line (e.g. ostree admin deploy --karg=) will
set the flag to false, and kargs will be copied from the previous
deployment for subsequent deployments.

Also add support for ostree admin instutil set-kargs so that installer
programs using this command (such as Anaconda) remain managed by the
kargs.d directories from the first deployment.

Closes: #479

[rebased to master]
Signed-off-by: Stefan Agner stefan.agner@toradex.com

Instead of splitting a string of kargs with a space as the
separator, parse the string and allow spaces that are protected
by quotes in the karg value.

The next_arg() function is based on the implementation in the
Linux kernel: https://github.com/torvalds/linux/blob/8a05452ca460b05c985eadc7b5a4f040f124463e/lib/cmdline.c#L204
@openshift-ci-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: agners
To complete the pull request process, please assign pwithnall after the PR has been reviewed.
You can assign the PR to them by writing /assign @pwithnall in a comment when ready.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci-robot
Copy link
Collaborator

Hi @agners. Thanks for your PR.

I'm waiting for a ostreedev member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@rfairley
Copy link
Member

/ok-to-test

@wmanley
Copy link
Member

wmanley commented Oct 15, 2020

This is really neat. Currently we enable in-tree kargs by having a file /usr/lib/ostree-boot/kargs.env that looks like:

KARGS="console=/dev/ttyS0,115200 ..."

with a shell script to do the deploy like this:

eval "$(ostree cat "$commit_sha" /usr/lib/ostree-boot/kargs.env || true)"
KARGS_ARG="--karg-none $(/usr/bin/printf "--karg-append=%s " $KARGS)"
ostree admin deploy ... $KARGS_ARG "$commit_sha"

but an ostree built-in solution would be a lot cleaner.

Add the following config directories for setting default kernel
arguments:

/etc/ostree/kargs.d (host config)
/usr/lib/ostree-boot/kargs.d (base config)

These directories contain files whose contents consist of a karg
snippet, which is a collection kernel parameter keys and values.
Example of a snippet:

```
KEY=FOO KEYFLAG ANOTHERKEY=VALUE1 ANOTHERKEY=VALUE2
```

Snippets are read in alphanumeric order of the karg snippet filename
when generating the final kernel options from the host and base config
directories. Ordering may be specified by prefixing a number, e.g.
`/etc/ostree/kargs.d/4000_localhost`.

The bootconfig key `ostree-kargs-generated-from-config` indicates
whether the kargs were generated by ostree from the kargs.d directories
(`true`), or copied from the previous deployment (`false`). Editing the
kargs through the command line (e.g. `ostree admin deploy --karg=`) will
set the flag to `false`, and kargs will be copied from the previous
deployment for subsequent deployments.

Also add support for `ostree admin instutil set-kargs` so that installer
programs using this command (such as Anaconda) remain managed by the
kargs.d directories from the first deployment.

Closes: ostreedev#479

[rebased to master]
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
agners pushed a commit to agners/meta-updater that referenced this pull request Oct 22, 2020
Instead of setting kernel argument at deploy time use the kargs.d
mechanism. Currently, this mechanism is still a downstream change of
OSTree, but has been proposed upstream:
ostreedev/ostree#2217

Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
@agners
Copy link
Contributor Author

agners commented Oct 22, 2020

Removed a TODO and simplified tests/libtest.sh changes a bit.

Also successfully tested this changes in our OE/meta-updater based environment (with changes to meta-updater, see https://github.com/agners/meta-updater/tree/dunfell-kargs.d).

@jlebon
Copy link
Member

jlebon commented Oct 26, 2020

One concern I have about this PR which I feel like we should flesh out a bit first is how updating from older OSTree will work. At least in FCOS/RHCOS, kargs are currently all untracked. I think we'll need some sort of "adoption" scheme where untracked kargs get translated to /etc/ostree/kargs.d drop-ins? The challenge there is that there isn't really an easy way to tell what's OEM and what's user-added. Probably safest to assume everything untracked is "user-added", though that might lead to duplicate kargs once composes do start shipping kargs in /usr/lib/ostree/kargs.d.

Edit: what this PR is doing IIUC is to make it "kargs.d-managed" only for new nodes (via ostree-kargs-generated-from-config), which is probably best at the libostree layer. Though I'd like to think a bit more about how OS maintainers will actually handle this. Because they won't be able to leverage this new code until all the nodes they care about have switched over.

@kelvinfan001
Copy link
Contributor

+1 to using an "adoption scheme" where the merge deployment's kargs are translated to drop-ins in kargs.d. We can then optimize commands like ostree admin deploy --karg= to drop files into kargs.d. This way, we no longer have two potential sources of truth and we no longer need the ostree-kargs-generated-from-config marker.
Regarding potential duplicates once composes start shipping kargs in /usr/lib/ostree/kargs.d, could we make it so that during the adopting stage, where OSTree looks at the current BLS entry and generates files to drop into /etc/ostree/kargs.d, it also checks whether such kargs already exist in /usr/lib/ostree/kargs.d and skips those?
Let me know if I am overlooking anything, though!

@cgwalters
Copy link
Member

I haven't done a deep dive on this yet but the more I think about this what I'd propose is:

  • Support /usr/lib/ostree/kargs.d (allow OS vendors to change kargs naturally)
  • Don't support /etc/ostree/kargs.d - instead user config is directly added to the BLS file

IOW we're keeping the idea that the BLS file is a standard that admins and tools can edit directly and not inventing something ostree specific.

@cgwalters
Copy link
Member

We're having some live discussion on this, other topics:

  • In CoreOS at least we need to support platform-specific kargs (ignition.platform.id) so there is also a concept of kargs that need to live outside of either ostree or user configuration - for us they're part of the disk image.
  • Ordering matters for things like hugepages= - we should carefully define how ordering works. And a specific example of that where this is relevant is the console= argument which is messy because it may also cross the "ostree default" and "user configurable" worlds.

I think combining these we are going to be sure we handle the cases of both removing default kargs as well as appending.

Comment on lines +672 to +673
gboolean past_quote = FALSE;
gboolean past_equals = FALSE;
Copy link
Contributor

Choose a reason for hiding this comment

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

Were these variables here meant for handling errors if the input string (args) weren't formatted properly? Otherwise, if we can assume that args is formatted properly, these two variables seem unnecessary.

Comment on lines +2742 to 2743
bootconfig_set_kargs(bootconfig, new_options, FALSE);
ostree_bootconfig_parser_set (bootconfig, "options", new_options);
Copy link
Contributor

@kelvinfan001 kelvinfan001 Oct 28, 2020

Choose a reason for hiding this comment

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

Looks like bootconfig_set_kargs() already handles the subsequent ostree_bootconfig_parser_set()'s job.

@@ -2824,34 +2837,250 @@ get_var_dfd (OstreeSysroot *self,
return glnx_opendirat (base_dfd, base_path, TRUE, ret_fd, error);
}

/* Get a GFile* referring to the commit object at ref for the file at path. */
Copy link
Contributor

Choose a reason for hiding this comment

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

For my understanding, does this mean "Get a GFile* that points to the file at path in the content for ref"?


if (dir_exists)
{
g_autoptr(GFile) karg_file = get_file_from_repo (ostree_sysroot_repo (sysroot),
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be clearer to name karg_file something like karg_dir to clearly distinguish it from the children files in usr/lib/ostree-boot/kargs.d that contain the kargs?

Comment on lines +3068 to +3070



Copy link
Contributor

Choose a reason for hiding this comment

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

nit: looks like a lot of new lines here 😄

Comment on lines +2948 to +2950
if (karg_contents && !g_tree_lookup (kargs_configs, karg_name))
g_tree_insert (kargs_configs, g_strdup (karg_name),
g_steal_pointer (&karg_contents));
Copy link
Contributor

Choose a reason for hiding this comment

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

The way this currently works, if there is a host configured karg in /etc/ostree/kargs.d, and the vendor adds the same karg at some point in the future during an update but with a different name for the karg file, then there will be a duplicates in the BLS entry.
Additionally, it is possible that there are multiple host configured kargs all in the same karg file, and when the vendor adds a subset of these kargs at some point during an update, we would have duplicates.

To deal with these two potential problems, perhaps we can make it so that each karg file must only have one karg and the karg KEY must be in the name of the karg file. However, then we would need to have some extra logic to ignore the number preceding the karg file or add the ordering info to the karg file.

@kelvinfan001
Copy link
Contributor

kelvinfan001 commented Oct 29, 2020

Re: #2217 (comment), if we don't support /etc/ostree/kargs.d and make users directly edit the BLS entry for configuration, then user configuration would be overridden if the vendor removes and re-adds (or adds and removes) the same karg that a user manually removed (or added) in the BLS entry.

@cgwalters
Copy link
Member

Re: #2217 (comment), if we don't support /etc/ostree/kargs.d and make users directly edit the BLS entry for configuration, then user configuration would be overridden if the vendor removes and re-adds (or adds and removes) the same karg that a user manually added (or removed) in the BLS entry.

Yeah agree, and thanks for bringing this up. I think having configuration in one place (the BLS file) just fundamentally conflicts with supporting all of the general corner cases of the systemd style "split configuration" model.

My initial thought here is we just say that overriding vendor kargs isn't supported. I suspect most people who want this don't even have per-system configuration at all - they are making custom ostree builds that they control and just want a convenient mechanism to add/remove kargs at build time without needing to wrap ostree admin upgrade with a script (per above). So those cases don't care at all about this problem.

But if we do want to support this, we could have /etc/ostree/kargs.d only support removals of vendor args perhaps?

Or the other approach is to take this problem upstream to the BLS spec; something like

options-removed=foo bar
options=console=ttyS0 nosmt

And options-removed would suppress /usr/lib/ostree/kargs.d trying to inject foo.

@cgwalters
Copy link
Member

One angle to look at this from then is: Would we use vendor kargs in CoreOS? I'm not sure.

I guess one use case I can think of is for RHCOS we added random.trust_cpu=on while we waited for a kernel fix to be backported. After that's done we can safely remove the karg - so that's a perfect use case for vendor kargs. And in this case, there is absolutely no sane reason someone would want to turn that argument off.

@kelvinfan001
Copy link
Contributor

kelvinfan001 commented Oct 30, 2020

Taking the problem upstream to BLS spec with something like options-removed or using /etc just for removals addresses one side of the problem, but won't solve the other side where user configs would be overridden if vendors add and remove a karg that the user configured already. Although this might be a very specific and improbable case. (This is assuming that users add custom host kargs by directly editing the BLS entry).

If we do user karg configuration through /etc, another issue is that there are probably going to be a significant number of kargs that are neither "user configured" nor belong in /usr/ostree-boot/kargs.d. For example, in FCOS, if we dump everything that is not in /usr into /etc, then I imagine we would have a hard time doing a "factory reset" due to some essential Ignition-derived kargs or platform-specific kargs being mixed together with some purely user-configured kargs in /etc.

But in both cases, a "factory reset" doesn't seem to be easily doable unless we can reliably distinguish between user per-system configuration, vendor configuration, and everything in between (e.g. Ignition-related or platform-specific kargs in FCOS).

@kelvinfan001
Copy link
Contributor

Could we use a third directory /usr/etc/ostree/kargs.d for the purpose of storing the "everything in between" default configuration kargs that can't belong in /usr/lib/ostree-boot/kargs.d? For example, for FCOS, kargs added by Ignition could be dropped in this directory. This would essentially be a directory that marks the kargs that it contains as explicitly not user configured. Alternatively, perhaps we could put this "marker" in the karg file itself. This way. when a "factory reset" command (ostree admin deploy --no-merge) is run, we just need to remove everything in the /etc directory (or remove all kargs in /etc that have not been marked as "default config").

However, for existing nodes, the "adoption stage" might be a little tricky since it will be difficult for OSTree to distinguish between what is "default" and what is user configured in the existing BLS entry.

@jlebon
Copy link
Member

jlebon commented Nov 2, 2020

Since this is still being discussed, let's
/hold
it.

I've been thinking about this, and I have an idea which I think would resolve some of the problems mentioned earlier. The core issue is that by looking at /proc/cmdline, it's impossible to tell what kargs came from where and so it's impossible to manage them correctly. Specifically, for OSTree what we really want to know is whether a karg is "managed" or not.

One way we can easily clear this up is by introducing a separator karg like ostree.kargs which sits between managed kargs and "everything else". So then roughly the algorithm during updates to generate the new options BLS line would be:

  1. write kargs from /usr/lib/ostree/kargs.d and /etc/ostree/kargs.d (with the latter possibly overriding the former)
  2. write ostree.kargs karg
  3. pass through all the kargs after ostree.kargs from the source (in the booted sysroot case, that's /proc/cmdline)

So then, it becomes safe to upgrade to such an OSTree version because all the preexisting kargs are essentially inherited as "unmanaged".

The idea here is that the source of truth for the managed part of the BLS lives in /usr/lib/ostree/kargs.d and /etc/ostree/kargs.d and users have to work with that. But we still also support unmanaged kargs and don't have to force the world to stop editing the BLS config and moving to the new way (and e.g. rpm-ostree kargs --append would still work fine).

Now, for CoreOS at least, it's likely that we wouldn't make the kargs in image.yaml into vendor kargs because users might have already removed them (IOW, we can't safely make managed what was unmanaged). At least, we'd have to publicize a transition period. We could still use vendor kargs for new kargs though, and opening the door to "user kargs" is still fine (and that's what we're really interested in for coreos/fedora-coreos-tracker#318). And of course, other OSes with more locked down configs would still find vendor kargs useful as mentioned above.

@jlebon
Copy link
Member

jlebon commented Nov 2, 2020

(Had this comment ready earlier, but I split it out of #2217 (comment) for clarity.)

But in both cases, a "factory reset" doesn't seem to be easily doable unless we can reliably distinguish between user per-system configuration, vendor configuration, and everything in between (e.g. Ignition-related or platform-specific kargs in FCOS).

I think the concept of a "factory reset" in practice is going to have to live at a higher-level than OSTree because there are different grades possible (some discussions about that in coreos/fedora-coreos-tracker#399). And as you mentioned, a karg which looks like a "user karg" to OSTree might actually be a "integration/distro karg" (like the Ignition platform ID one). And similarly for files, you may not actually want to nuke all the files in /etc which aren't in the commit (e.g. /etc/fstab for OSes which still use that). It wouldn't be useful I think to try to establish a classification scheme for these that lives in OSTree.

@AdrianVovk
Copy link

Doesn't the per-device kernel live in the ostree commit anyway?

@cgwalters
Copy link
Member

Doesn't the per-device kernel live in the ostree commit anyway?

Yes...are you saying that e.g. if one is building a custom kernel one can already bake in command line arguments via e.g.


config CMDLINE
	string "Default kernel command string"
	default ""
	help
	  On some architectures (EBSA110 and CATS), there is currently no way
	  for the boot loader to pass arguments to the kernel. For these
	  architectures, you should supply some command-line options at build
	  time by entering them here. As a minimum, you should specify the
	  memory size and the root device (e.g., mem=64M root=/dev/nfs).

?

@cgwalters
Copy link
Member

cgwalters commented Nov 4, 2020

Having /etc support would clean up the MCO kargs support for sure; if it can change to writing files in /etc/ostree/kargs.d then all the "merge logic" lives in ostree and not the MCO. I imagine there are other cases like this.

Reference for MCO kargs code: https://github.com/openshift/machine-config-operator/blob/034afd05b6e04fd1c8df9cb7110461ea06763b0b/pkg/daemon/update.go#L805

@wmanley
Copy link
Member

wmanley commented Nov 4, 2020

Let me verify this: @wmanley do you have any per-device kargs or would it be sufficient for you to have the canonical kargs live in the ostree commit per above?

We don't have any per-device kargs because we have a different ostree commit for each device type, so kargs stored under /usr would work fine for us.

@sinnykumari
Copy link
Collaborator

Having /etc support would clean up the MCO kargs support for sure; if it can change to writing files in /etc/ostree/kargs.d then all the "merge logic" lives in ostree and not the MCO. I imagine there are other cases like this.

It feels to me that allowing kargs to write as file in /etc/ostree/kargs.d brings additional complexity for MCO. Users can directly drop a file here using MacineConfig and whenever next time ostree kargs gets called kargs will be updated. While in the current approach, MCO allows adding additional kargs only through specifying value in kernelArguments in a MachineConifg.

@cgwalters
Copy link
Member

cgwalters commented Nov 4, 2020

It feels to me that allowing kargs to write as file in /etc/ostree/kargs.d brings additional complexity for MCO. Users can directly drop a file here using MacineConfig and whenever next time ostree kargs gets called kargs will be updated. While in the current approach, MCO allows adding additional kargs only through specifying value in kernelArguments in a MachineConifg.

Right; this would be a new way to write kernel arguments via the MCO (include them in Ignition), however I was more thinking about this as a new backend for the current MCO kernel arguments logic. IOW rather than the MCO running rpm-ostree kargs it would just write /etc/ostree/kargs.d/machineconfig. So it would eventually simplify the code.

That said...to make this whole thread even more twisty, this intersects with openshift/machine-config-operator#1190 and its underlying issue #2220 - fixing that would really be a prerequisite for managing kargs via /etc I'd say.

@kelvinfan001
Copy link
Contributor

kelvinfan001 commented Nov 4, 2020

So right now, I see two main proposals for how we can tackle this PR:

Option 1: Managed vs Unmanaged Kargs
Summary:
Have a separation between managed and unamanaged kargs using an ostree.kargs karg as the separator sitting in between them. The source of truth of managed kargs lives in /usr/lib/ostree/kargs.d and /etc/ostree/kargs.d. Unmanaged kargs are still supported, where users would directly edit the BLS entry and OSTree won't be involved.

Advantages:

  • Provides a standard way to change command line options through OSTree
  • Gives OSTree more control over the merging of kargs throughout updates (host configuration will persist and be reconciled with vendor kargs across updates)

Disadvantages:

  • Introduces need for a separator karg
  • Potential confusion and unexpected behaviour if users use managed kargs and edit the BLS entry directly at the same time (e.g. duplicate kargs, karg ordering issues)

Option 2: Just support /usr/lib/ostree/kargs.d
Summary:
If /usr/lib/ostree/kargs.d exists, use that as the single source of truth for all kargs.

Advantages:

  • Simpler, less likely to break anything
  • Already has what most embedded-type users want

Disadvantages:

  • Solves fewer problems (e.g. there would still not be a standard way to change command line options through OSTree)

I think Option 1 should be safe to do and would be useful for FCOS. It does add some complexity, but for distros that don't need the extra functionality, they can easily ignore it. Should we put this to a vote on how to proceed?

@AdrianVovk
Copy link

@cgwalters I meant that having per-device kernel args shouldn't stop you from reading from /usr as the canonical location because the per-device kernel is in /usr anyways

@sinnykumari
Copy link
Collaborator

Right; this would be a new way to write kernel arguments via the MCO (include them in Ignition), however I was more thinking about this as a new backend for the current MCO kernel arguments logic. IOW rather than the MCO running rpm-ostree kargs it would just write /etc/ostree/kargs.d/machineconfig. So it would eventually simplify the code.

yes, that is my understanding as well.
My main concern is what if user learns about this feature and uses both way to apply kargs:

  1. Specifying karnelArguments field in MachinConfig
  2. Specifying ignition config to write a file into /etc/ostree/kargs.d/custom-kargs with some kargs

It is not difficult to handle both cases but creates multiple source of truth to look for all users added kargs. Debugging kargs related issues can get trickier compared to today as we would need to look for any added file into /etc/ostree/kargs.d/

@travier
Copy link
Member

travier commented Nov 5, 2020

According to me, both options currently have too many disadvantages:

Option 1: Managed vs Unmanaged Kargs

  • I think this option requires an adoption strategy, otherwise we need a transition period and manual admin action which is unwanted from my point of view.
  • Having managed kargs come first may cause ordering issues.
  • Would /etc only mask managed kargs or also override them. In both cases this seems confusing from a user point of view.

Option 2: Just support /usr/lib/ostree/kargs.d

  • If /usr owns all the kargs then we can not have per instance kargs so it's unusable for FCOS.

I think we need to stick to a single source of truth. Either it's the BLS config or the configuration in the real root (/etc & /usr).

@AdrianVovk
Copy link

AdrianVovk commented Nov 6, 2020

So if there's both /usr/lib/ostree/kargs.d, and /etc/ostree/kargs.d:

  • On pre-existing systems, on first boot with new ostree the options from the BLS are dumped into /etc, and then a distro-specific tool is invoked that can process that file and decide what to keep and what to strip out/is default in /usr
  • either the BLS is wiped on every deploy (which seems optimal) or the same logic used today with --kargs can be repurposed (as if the config files just add --kargs to the command line)
  • ostree loads from both /usr and /etc (/etc masks files in /usr if the name is the same) and then orders the files lexicographically. That's the order the keys appear in (so an admin can easily order keys before/after/I'm between the system-provided keys using the standard ##_whatever.conf pattern).

Alternatively, maybe this logic can be opt-in (or out if rpm-ostree can handle disabling this functionality on upgrade via the repo config) or maybe only enabled for newly-created repos/deployments?

@kelvinfan001
Copy link
Contributor

After some discussion with the CoreOS team, we've decided that for the non embedded use case (e.g. FCOS), attempting to create a new OSTree way of shipping vendor kargs while supporting host configured kargs simultaneously would create many problems. For this PR, I believe it should be sufficient to just support /usr/ostree/kargs.d, since that would satisfy the embedded use case. IOW, for non embedded distros using OSTree, we would want to keep the current way of doing things; we would simply check for the existence of /usr/ostree/kargs.d, and if it does not exist, the BLS would be the source of truth. This would actually simplify the implementation a bit compared to its current state. @agners what do you think? Would you be interested in making those adjustments?

@kelvinfan001
Copy link
Contributor

/unhold

@agners
Copy link
Contributor Author

agners commented Dec 1, 2020

@kelvinfan001 thanks for the update and sorry for the late reply. I no longer work in the project. Some feedback still from that use case's perspective:

For this PR, I believe it should be sufficient to just support /usr/ostree/kargs.d, since that would satisfy the embedded use case.

That might work out yes. The initial idea was to separate distro provided kargs (e.g. OS supplier) and project provided kargs (e.g. embedded product team). The way I was thinking to implement it is that the product team uses /etc (its default in /usr/etc), and the distro provider provides /usr (just like any other distro). But the use case could likely also be satisfied by defining file names in /usr/lib/ostree/kargs.d. In any case, using files inside the OSTree seems like a much better approach than deployment specified BLS defaults, which then carry on on every deployment. For the embedded use case it would be fine if the whole feature is opt-in IMHO.

I don't plan to work on this personally. If this approach is fine, I think whoever is working on it should open a new pull request with such an implementation.

@jsrc27
Copy link

jsrc27 commented Oct 25, 2021

This feature would be useful for us (for the embedded use-case).

Would this change still be of interest to everyone? Of course given the suggestions/changes from @kelvinfan001, last comment. It should be sufficient for our use case to only support the vendor-provided /usr use-case.

I just wanted to check if any other points or discussions came up related to this before I attempt to submit a new PR. For example I see FCOS implemented their own kargs system, but I assume this is specific to the FCOS use-case.

@cgwalters
Copy link
Member

Hi yes from my PoV it's totally fine to re-open/re-consider this PR.

This also came up again related to coreos/enhancements#7 since there is a natural desire to embed kargs in these container builds.

cgwalters added a commit to cgwalters/machine-config-operator that referenced this pull request Apr 22, 2022
I'm debugging https://bugzilla.redhat.com/show_bug.cgi?id=2075126
and while I haven't verified this is the case, as far as I can tell
from looking through the code and thinking about things, if we somehow
fail to apply the expected kernel arguments (which can occur if
`ostree-finalize-staged` fails) then we will (on the next boot)
drop in to `validateOnDiskState()` which has for a long time
checked that all the expected *files* exist and mark the update as
complete.  But we didn't check the kernel arguments.

That can then cause later problems because in trying to apply further
updates we'll ask rpm-ostree to try to remove kernel arguments that
aren't actually present.

Worse, often these kernel arguments are actually *quite important*
and may even have security relevant properties (e.g. `nosmt`).

Now...I am actually increasingly convinced that we *really* need
to move opinionated kernel argument handling into ostree (and rpm-ostree).

There's ye olde ostreedev/ostree#2217
and the solution may look something like that.  Particularly now
with the layering philosophy that it makes sense to support
e.g. customizations dropping content in `/usr/lib` and such.

For now though, validating that we didn't get the expected kargs
should make things go Degraded, the same as if there was a file conflict.
And *that* in turn should make it easier to debug failures.

As of right now, it will appear that updates are complete, and then
we'll only find out much later that the kargs are actually missing.
And in turn, because kubelet spams the journal, any error messages
from e.g. `ostree-finalize-staged.service` may be lost.
cgwalters added a commit to cgwalters/machine-config-operator that referenced this pull request Apr 26, 2022
I'm debugging https://bugzilla.redhat.com/show_bug.cgi?id=2075126
and while I haven't verified this is the case, as far as I can tell
from looking through the code and thinking about things, if we somehow
fail to apply the expected kernel arguments (which can occur if
`ostree-finalize-staged` fails) then we will (on the next boot)
drop in to `validateOnDiskState()` which has for a long time
checked that all the expected *files* exist and mark the update as
complete.  But we didn't check the kernel arguments.

That can then cause later problems because in trying to apply further
updates we'll ask rpm-ostree to try to remove kernel arguments that
aren't actually present.

Worse, often these kernel arguments are actually *quite important*
and may even have security relevant properties (e.g. `nosmt`).

Now...I am actually increasingly convinced that we *really* need
to move opinionated kernel argument handling into ostree (and rpm-ostree).

There's ye olde ostreedev/ostree#2217
and the solution may look something like that.  Particularly now
with the layering philosophy that it makes sense to support
e.g. customizations dropping content in `/usr/lib` and such.

For now though, validating that we didn't get the expected kargs
should make things go Degraded, the same as if there was a file conflict.
And *that* in turn should make it easier to debug failures.

As of right now, it will appear that updates are complete, and then
we'll only find out much later that the kargs are actually missing.
And in turn, because kubelet spams the journal, any error messages
from e.g. `ostree-finalize-staged.service` may be lost.
@cgwalters
Copy link
Member

cgwalters commented Nov 10, 2022

I was thinking about this more recently. ISTM what we really want to do for default kernel arguments is actually: attach them to the kernel. One can already actually build in default kernel arguments via CONFIG_CMDLINE. But, doing so requires rebuilding. It'd be nice if one could embed kargs via just relinking - but even that would AFAIK break e.g. secure boot signatures.

So...here's a strawman proposal: we only scope in image build time; we don't try to support client side stuff with e.g. /etc.

The implementation is a simple text file like
/usr/lib/modules/5.19.14-200.fc36.x86_64/cmdline
containing e.g.
console=ttyS0 nosmt
or whatever.

When tools like ostree do an upgrade from A to B they should effectively perform a 3-way merge, similar to our handling of /etc:

  • Take the current deployment's booted kernel arguments (which can include machine-local additions) i.e. the data from the options BLS entry
  • Remove arguments in A but not in B
  • Add arguments in B but not in A
  • Use the resulting merged set for the deployment of commit B (i.e. what gets written into the options field of the BLS entry or equivalent)

or so?

This seems pretty straightforward to implement and support.

@cgwalters
Copy link
Member

@martinezjavier what do you think about this?

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

Successfully merging this pull request may close these issues.

Support default kernel arguments