adds machine-config-osimagestream bootstrap helper#5770
adds machine-config-osimagestream bootstrap helper#5770cheesesashimi wants to merge 2 commits intoopenshift:mainfrom
Conversation
|
Important Review skippedAuto reviews are limited based on label configuration. 🚫 Excluded labels (none allowed) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Skipping CI for Draft Pull Request. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: cheesesashimi The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
7904d0a to
a479290
Compare
| getCmd.PersistentFlags().StringVar(&o.outputFormat, "output-format", "json", "The output format to use: 'json' or 'yaml'.") | ||
| getCmd.PersistentFlags().StringVar(&o.outputFile, "output-file", "", "Path to write output to a file instead of stdout. Format is auto-detected from extension (.json, .yaml, .yml).") | ||
|
|
||
| getCmd.MarkPersistentFlagRequired("pull-secret") |
There was a problem hiding this comment.
While this seems good to me, I think most of the bootstrap code in the installer is thought to use default paths. The installer generated ignition for the bootstrap node takes care of placing the pull-secret, mirrot and proxy configuration in the correct file so calls to podman (or skopeo) don't need to provide those args everywhere. The only exception I've observed is rpm-ostree, that requiers the pull-secret to be passed with --authfile.
Following to the previous point, we need to make really sure mirror, proxy and custom CAs are properly loaded, no matter if it's because the defaults of container-libs do the job or because we use the builder imageutils.NewSysContextBuilder returns to craft a proper auth/tls/mirror/proxy context.
There was a problem hiding this comment.
I've done a quick search in the installer and these are my findings:
- I think the proxy env vars are automatically loaded by ignition into systemd.conf.d/10-default-env.conf and into /etc/profile.d/proxy.sh. I'd expect that the proxy env vars are present when the unit runs.
- registries.conf (mirror rules): I've seen a few places (specially in the agent, that is the workflow that relies on them, but not exclusively) where the installer generates it for the final ignition. Not too sure about this one, but my vet is that the file should be already placed in
/etc/containers/registries.confwhen the installer units run. If not, I cannot explain why rpm-ostree works. - pull-secret. Exists cause it's rendered by this template file https://github.com/openshift/installer/blob/791a41c20c5d3c72dee4aca31df817710a7d39b0/data/data/bootstrap/files/root/.docker/config.json.template (everything inside the files directory of the assets it pushed to the bootstrap by ignition)
- Custom CAs: Not 100% sure, but seems to be like the previous point: https://github.com/openshift/installer/blob/59e504062d51674fc20394ac043bf0e3e022c385/data/data/bootstrap/files/etc/pki/ca-trust/source/anchors/ca.crt.template
There was a problem hiding this comment.
As I began integrating this into the installer a bit (see: openshift/installer#10406), I began to realize that another problem we'll have to deal with is mounting things into the container this will run in. I contemplated an operational mode where we extract the binary from the image and run it natively on the bootstrap host so that it can access what it needs given the original execution context.
99a50d4 to
0de6a09
Compare
cddae24 to
50150a3
Compare
|
|
||
| // Wraps imageRegistrySecretImpl and implements UnmarshalJSON so that | ||
| // progressive JSON decoding may be used. | ||
| type dockerConfigJSONDecoder struct { |
There was a problem hiding this comment.
This implementation would need some UT testing. I know the type it's not exported so we may not want to directly test it, but test the caller with some inputs that give us good coverage of this piede of code.
| CertDir: opts.certsPath, | ||
| PerHostCertDir: opts.perHostCertsPath, | ||
| PullSecret: opts.pullSecretPath, | ||
| RegistryConfig: opts.registryConfigPath, |
There was a problem hiding this comment.
Question: Should we provide safe defaults and always pass them to container-libs or are we advocating to the container-libs defaults?
In other words, do we want to pick a default and never trust/rely on their defaults?
There was a problem hiding this comment.
I could go either way with this, honestly.
| # Get the full image pullspec from release image: | ||
| $ machine-config-osimagestream get default-node-image \ | ||
| --pull-secret /path/to/pull/secret \ | ||
| --release-image quay.io/openshift-release-dev/ocp-release:latest \ | ||
| --image-pullspec | ||
|
|
||
| # Get the image tag name from ImageStream file: | ||
| $ machine-config-osimagestream get default-node-image \ | ||
| --pull-secret /path/to/pull/secret \ | ||
| --imagestream /path/to/imagestream.json \ | ||
| --image-name | ||
|
|
||
| # Get the full image pullspec from ImageStream file: | ||
| $ machine-config-osimagestream get default-node-image \ | ||
| --pull-secret /path/to/pull/secret \ | ||
| --imagestream /path/to/imagestream.yaml \ | ||
| --image-pullspec | ||
|
|
||
| # With per-host certificates (output tag name): | ||
| $ machine-config-osimagestream get default-node-image \ | ||
| --pull-secret /path/to/pull/secret \ | ||
| --per-host-certs /etc/containers/certs.d \ | ||
| --release-image quay.io/openshift-release-dev/ocp-release:latest \ | ||
| --image-name | ||
|
|
||
| # With custom certificates and registry configuration (output pullspec): | ||
| $ machine-config-osimagestream get default-node-image \ | ||
| --pull-secret /path/to/pull/secret \ | ||
| --certs /path/to/certs \ | ||
| --registry-config /etc/containers/registries.conf \ | ||
| --release-image quay.io/openshift-release-dev/ocp-release:latest \ | ||
| --image-pullspec | ||
|
|
||
| # With additional trust bundle (single file, output tag name): | ||
| $ machine-config-osimagestream get default-node-image \ | ||
| --pull-secret /path/to/pull/secret \ | ||
| --trust-bundle /etc/pki/ca-trust/source/anchors/ca-bundle.crt \ | ||
| --release-image quay.io/openshift-release-dev/ocp-release:latest \ | ||
| --image-name | ||
|
|
||
| # With multiple trust bundles (files and directories, output pullspec): | ||
| $ machine-config-osimagestream get default-node-image \ | ||
| --pull-secret /path/to/pull/secret \ | ||
| --trust-bundle /etc/pki/ca-trust/source/anchors/ \ | ||
| --trust-bundle /opt/custom/cert.pem \ | ||
| --release-image quay.io/openshift-release-dev/ocp-release:latest \ | ||
| --image-pullspec`, |
There was a problem hiding this comment.
I've the feeling this is way too much for the help option of the binary. I'd say the examples are nice, but I see them fitting better in a doc md.
The same applies to 55c004f#diff-ad14b191f88ac54c22961ae04f78ba66ecadad7b167abeae58a377ef3d0d85c4R38
There was a problem hiding this comment.
Yeah, I agree. I'll rework the examples and produce a README file instead.
| getCmd.PersistentFlags().StringVar(&o.releaseImage, "release-image", "", "The OCP / OKD release payload image to run against.") | ||
| getCmd.PersistentFlags().StringVar(&o.imageStreamPath, "imagestream", "", "Path to the ImageStream file to run against.") | ||
|
|
||
| getCmd.MarkPersistentFlagRequired("pull-secret") |
There was a problem hiding this comment.
I think most tools tools use --authfile to provide a pull-secret, and if not given they fallback to ${XDG_RUNTIME_DIR}/containers/auth.json (among others, including the one the installer uses for everything, including podman /root/.docker./config.json https://github.com/containers/skopeo/blob/f9d4a40261d9f6dd924d22274805cd075e1fe939/vendor/go.podman.io/common/pkg/auth/auth.go#L83.
There was a problem hiding this comment.
Good call. I will change that.
| "strings" | ||
| "time" | ||
|
|
||
| "github.com/ghodss/yaml" |
There was a problem hiding this comment.
"sigs.k8s.io/yaml", that uses github.com/ghodss/yaml underneath, is a bit better fit I think:
- It's maintained
- It handles multline strings better. (not required for this use case)
There was a problem hiding this comment.
Agreed. I keep forgetting about that library. Will change my code to use that.
|
|
||
| // TODO: Not sure if this value is used by types.SystemContext or not. But | ||
| // we'll retrieve it anyway for right now. | ||
| if noProxy := os.Getenv("NO_PROXY"); noProxy != "" { |
There was a problem hiding this comment.
Unfortunately no, I introduced a change in container-libs to be able to properly consume the 3 fields https://github.com/containers/container-libs/pull/583/changes (it will allow us to provide a callback that consumes them), but given that they don't backport and we cannot upgrade we cannot use it.
There was a problem hiding this comment.
I'll remove it for now since it's going unused. But I'll leave a comment in its place containing this context.
| } | ||
|
|
||
| return getImageStreamFromReleaseImage(ctx, sysCtx, releaseImage) | ||
| } |
There was a problem hiding this comment.
I'm a bit surprissed about the content of this function, as I'd expected something more like this:
func getImageStreamProvider(ctx context.Context, imagesInspector ImagesInspector, imageStreamPath, releaseImage string) (osimagestream.ImageStreamProvider, error)
if imageStreamPath != "" {
is, err := getImageStreamFromFile(imageStreamPath)
if err != nil {
return nil, err
}
return osimagestreams.NewImageStreamProviderResource(is)
}
return osimagestreams.NewImageStreamProviderNetwork(imagesInspector, releaseImage)
}Later on you can directly pass the ImageStreamProvider to the NewImageStreamStreamSource you already have in place. The ImagesInspector you create later would be now created a bit before to provide it to this function.
There was a problem hiding this comment.
I think I originally implemented it like that. Will reconsider though.
EDIT: Here's more context:
I originally thought that we just needed the OS image tag name (e.g., rhel-coreos) instead of the OS image pullspec. To resolve that from the OSImageStream, I also needed the ImageStream itself so I could look it up. As it turns out, the image tag name is unimportant. So with that in mind, I changed it to something similar to what you suggested.
|
@pablintino Putting this here for posterity: On its own, this code doesn't adequately handle OKD. I noticed that #5714 does handle it much better. So I created a separate branch and cherry-picked it locally. Once I did that, this code handled OKD with no issues. |
50150a3 to
6a43924
Compare
Assisted-By: Claude Sonnet 4.5
This adds additional test cases for K8s secret decoding since I ran into what I thought was a bug when trying to write additional test cases for the new SysContext helper. Assisted-By: Claude Sonnet 4.5
6a43924 to
479346d
Compare
- What I did
This introduces a new helper binary called
machine-config-osimagestreamthat will examine either the given release image pullspec or the provided ImageStream file to create an OSImageStream object in either JSON or YAML format. This is mostly intended to be used by the bootstrap process, but could also be used to help debug the OSImageStream produced by a given release image or ImageStream file.There is also a
default-node-imagemode which will get the OSImageStream and then look up the name of the default OS image by matching the pullspec for the default OS image to the pullspec in the ImageStream.- How to verify it
go build -o machine-config-osimagestream ./cmd/machine-config-osimagestream./machine-config-osimagestream get osimagestream --release-image registry.ci.openshift.org/ocp/release-5:5.0.0-0.nightly-2026-03-16-164911 --pull-secret /path/to/pull/secret./machine-config-osimagestream get default-node-image --release-image registry.ci.openshift.org/ocp/release-5:5.0.0-0.nightly-2026-03-16-164911 --pull-secret /path/to/pull/secret- Description for the changelog
Adds machine-config-osimagestream