Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions ignition-server/controllers/local_ignitionprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/imageprovider"
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests"
"github.com/openshift/hypershift/support/api"
"github.com/openshift/hypershift/support/capabilities"
"github.com/openshift/hypershift/support/certs"
supportconfig "github.com/openshift/hypershift/support/config"
"github.com/openshift/hypershift/support/releaseinfo"
"github.com/openshift/hypershift/support/releaseinfo/registryclient"
"github.com/openshift/hypershift/support/util"
Expand Down Expand Up @@ -636,6 +638,42 @@ func (p *LocalIgnitionProvider) GetPayload(ctx context.Context, releaseImage, cu
return nil, fmt.Errorf("failed to execute machine-config-controller: %w", err)
}

// Check if image registry capability is enabled for the hosted cluster.
// If enabled, write the root CA as the image registry CA so it can be
// passed to MCS via --bootstrap-certs, placing the CA at
// /etc/docker/certs.d/<registry>/ca.crt in the ignition payload.
imageRegistryCAFile := ""
func() {
hcpList := &hyperv1.HostedControlPlaneList{}
if err := p.Client.List(ctx, hcpList, client.InNamespace(p.Namespace)); err != nil {
log.Error(err, "failed to list HostedControlPlanes for image registry CA check")
return
}
if len(hcpList.Items) == 0 {
log.Info("no HostedControlPlane found, skipping image registry CA")
return
}
hcp := &hcpList.Items[0]
if !capabilities.IsImageRegistryCapabilityEnabled(hcp.Spec.Capabilities) {
log.Info("image registry capability is disabled, skipping bootstrap-certs")
return
}
// In HyperShift, the image registry serving cert is signed by the root CA.
// Write the root CA cert as the image registry CA file for --bootstrap-certs.
caData := mcsConfig.Data["root-ca.crt"]
if caData == "" {
log.Info("root-ca.crt not found in MCS config, skipping bootstrap-certs")
return
}
caFile := filepath.Join(mcsBaseDir, "image-registry-ca.crt")
if err := os.WriteFile(caFile, []byte(caData), 0644); err != nil {
log.Error(err, "failed to write image registry CA file")
return
}
imageRegistryCAFile = caFile
log.Info("wrote image registry CA for bootstrap-certs", "file", caFile)
}()

// Finally, run the MCS to generate a payload.
payload, err := func() ([]byte, error) {
start := time.Now()
Expand Down Expand Up @@ -671,6 +709,15 @@ func (p *LocalIgnitionProvider) GetPayload(ctx context.Context, releaseImage, cu
)
}

// Pass the image registry CA via --bootstrap-certs so the MCS includes it
// in the ignition payload at /etc/docker/certs.d/<registry>/ca.crt.
// The --bootstrap-certs flag was introduced in MCO PR #3876 (OCP 4.14+).
if imageRegistryCAFile != "" && payloadVersion.Minor >= 14 {
args = append(args,
fmt.Sprintf("--bootstrap-certs=%s=%s", supportconfig.DefaultImageRegistryHostname, imageRegistryCAFile),
)
}

// Spin up the MCS process and ensure it's signaled to terminate when
// the function returns
mcsCtx, cancel := context.WithCancel(ctx)
Expand Down