Retain blueprint as /root/blueprint.toml in built images#2274
Retain blueprint as /root/blueprint.toml in built images#2274ochosi wants to merge 2 commits intoosbuild:mainfrom
/root/blueprint.toml in built images#2274Conversation
This change follows Anaconda's established pattern of retaining kickstarts in /root and a pattern in bootc disk image creation that retains Containerfiles in /root. For end-users, this is intended as an easy and accessible way of rebuilding an image. Encode the blueprint used to build an image as TOML and write it to /root/blueprint.toml inside the image filesystem as build provenance. This uses the existing inline-data copy stage mechanism, the same pattern used for modularity failsafe files. The blueprint is always retained, for all distros. The TOML-encoded blueprint flows through a dedicated BlueprintTOML field on OSCustomizations (not mixed with user-provided Files).
Deep-copy the blueprint and nil out all User[].Password fields before TOML-marshaling into BlueprintTOML. This prevents plaintext or hashed passwords from being written to /root/blueprint.toml in the image. The original blueprint passed to the rest of the pipeline is not modified; DeepCopy() performs a JSON round-trip to produce an independent copy.
280fb57 to
681d7a8
Compare
supakeen
left a comment
There was a problem hiding this comment.
Looking at this purely from a functional standpoint, not the implementation:
This is nice to have though there are some concerns.
One is that we'd need to have this functionality gated behind an ImageOption (BuildOption) so we can turn it off for any images produced in build systems that use customizations (e.g. RHUI, LVMified images for clouds, etc). Initially off by default for the cli as we will want to plumb through/make the option available in koji-image-builder and pungi for those systems while the service can toggle it on.
The other is secrets, any file, first-boot, or many of the other customizations can potentially contain secrets. While those secrets would usually be able to be found by root anyhow it'd need quite some thought.
|
That all makes sense! Fwiw I had considered many of those angles already, but mostly wanted to get us to decide if this is something we want to do. I totally agree with gating this (but maybe "on by default"?) and more things may have to be redacted. First boot customizations etc are tricky because we cannot know what to redact. Might be easiest to just not retain those at all. Ofc that somewhat diminishes the value of the blueprint retention. |
|
On by default should be the end goal but we'd need to start with off by default until we have deployed and configured versions of koji-image-builder and pungi that turn it off. After that it can be turned on by default in the library if we want to. This is to make sure that blueprints don't start showing up in Fedora, CentOS, and RHEL composes and marketplace images where blueprints are also used in the pungi configs. |
Why
This change follows the established patter of Anaconda which retains a kickstart in
/rootand a similar pattern in bootc disk images that retains Containerfiles in/root.Today, users who receive a built image have no easy way to know what blueprint produced it or to rebuild it. The RHSM facts we already embed provide some provenance metadata (API type, blueprint ID), but not the full blueprint itself.
This PR writes the complete blueprint to
/root/blueprint.tomlin every built image. This serves two purposes:What
BlueprintTOML []bytefield onOSCustomizationscarries the TOML-encoded blueprint through the manifest pipeline.osCustomizations()encodes the blueprint usingtoml.Marshal()(theBlueprintstruct already hastoml:"..."tags, andBurntSushi/tomlis already a dependency).OS.serialize()writes it to/root/blueprint.tomlvia the existing inline-data copy stage mechanism (same pattern as modularity failsafe files).Customizations.User[].Password) are redacted before marshaling -- the blueprint is deep-copied and passwords are nilled out so they never appear in the image, whether plaintext or hashed.Design decision
Since this is a proposal, I opted for a minimal implementation. If we decide we want to go ahead and do this, but the architecture is wrong, I'm happy to rework this PR.
Testing
image-builder-cliand verified/root/blueprint.tomlexists with expected content/root/blueprint.tomlosCustomizations()