Skip to content
Merged
Show file tree
Hide file tree
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
12 changes: 12 additions & 0 deletions cmd/machine-config-daemon/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/client-go/tools/clientcmd"

"github.com/openshift/api/features"
"github.com/openshift/machine-config-operator/internal/clients"
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
"github.com/openshift/machine-config-operator/pkg/daemon"
"github.com/openshift/machine-config-operator/pkg/daemon/constants"
"github.com/openshift/machine-config-operator/pkg/daemon/cri"
"github.com/openshift/machine-config-operator/pkg/daemon/internalreleaseimage"
"github.com/openshift/machine-config-operator/pkg/version"
"github.com/spf13/cobra"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -233,6 +235,16 @@ func runStartCmd(_ *cobra.Command, _ []string) {
)
go pinnedImageSetManager.Run(2, stopCh)

if ctrlctx.FeatureGatesHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
internalReleaseImageManager := internalreleaseimage.New(
startOpts.nodeName,
ctrlctx.ClientBuilder.MachineConfigClientOrDie(componentName),
ctrlctx.InformerFactory.Machineconfiguration().V1alpha1().InternalReleaseImages(),
ctrlctx.InformerFactory.Machineconfiguration().V1().MachineConfigNodes(),
)
go internalReleaseImageManager.Run(1, stopCh)
}

ctrlctx.KubeInformerFactory.Start(stopCh)
ctrlctx.KubeNamespacedInformerFactory.Start(stopCh)
ctrlctx.InformerFactory.Start(stopCh)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ require (
github.com/onsi/gomega v1.38.2
github.com/opencontainers/go-digest v1.0.0
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818
github.com/openshift/api v0.0.0-20260304160726-df03ea1d00f4
github.com/openshift/client-go v0.0.0-20260302182750-20813ce71ca6
github.com/openshift/api v0.0.0-20260326111139-30c2ef7a272e
github.com/openshift/client-go v0.0.0-20260330134249-7e1499aaacd7
github.com/openshift/library-go v0.0.0-20260303171201-5d9eb6295ff6
github.com/openshift/runtime-utils v0.0.0-20230921210328-7bdb5b9c177b
github.com/prometheus/client_golang v1.23.2
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,10 @@ github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+L
github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s=
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 h1:jJLE/aCAqDf8U4wc3bE1IEKgIxbb0ICjCNVFA49x/8s=
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M=
github.com/openshift/api v0.0.0-20260304160726-df03ea1d00f4 h1:ftsNdfcCuNp7Ft0gv7qXkwskggQlIyJoNKA8jPdBlLI=
github.com/openshift/api v0.0.0-20260304160726-df03ea1d00f4/go.mod h1:pyVjK0nZ4sRs4fuQVQ4rubsJdahI1PB94LnQ8sGdvxo=
github.com/openshift/client-go v0.0.0-20260302182750-20813ce71ca6 h1:wJv4Ia+R4OxoaJcTUyvMtBc5rWFvfTiEA8d5f1MBPqI=
github.com/openshift/client-go v0.0.0-20260302182750-20813ce71ca6/go.mod h1:3lkVff575BlbDUUhMsrD1IyvfkZ+oKUB7iZuVy1m0W0=
github.com/openshift/api v0.0.0-20260326111139-30c2ef7a272e h1:SbgwHvkc6vgiqHOfGrbumjPvtOvJmCwJoFEwr7rAKzY=
github.com/openshift/api v0.0.0-20260326111139-30c2ef7a272e/go.mod h1:pyVjK0nZ4sRs4fuQVQ4rubsJdahI1PB94LnQ8sGdvxo=
github.com/openshift/client-go v0.0.0-20260330134249-7e1499aaacd7 h1:5GSoQlywIwYsRCw3qN+ZDmN6HrXTMZfI33bdRNm2jRQ=
github.com/openshift/client-go v0.0.0-20260330134249-7e1499aaacd7/go.mod h1:HhXTUIMhgzxR3Ln/zEkr4QjTL0NN7A+t9Py/we9j2ug=
github.com/openshift/kubernetes v1.30.1-0.20260305123649-d18f3f005eaa h1:/gPMWR7fdCC3S4wHALD6Em+vztl1q9/cOpdMkFZwDus=
github.com/openshift/kubernetes v1.30.1-0.20260305123649-d18f3f005eaa/go.mod h1:1r2FIoYrPU0110cjYlWAwNcbiqRPLWAgmZK4d0YeEZw=
github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa h1:ifOqAFthJWnT1HS6Sq2AcLQWNSJ1+XEiyA9eo+PIcR0=
Expand Down
4 changes: 2 additions & 2 deletions manifests/machineconfigdaemon/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ rules:
resources: ["machineconfigs", "controllerconfigs"]
verbs: ["get", "list", "watch"]
- apiGroups: ["machineconfiguration.openshift.io"]
resources: ["machineconfigpools", "pinnedimagesets"]
resources: ["machineconfigpools", "pinnedimagesets", "internalreleaseimages"]
verbs: ["get", "list", "watch"]
- apiGroups: ["machineconfiguration.openshift.io"]
resources: ["machineconfignodes", "machineconfignodes/status"]
verbs: ["create", "update", "patch", "get"]
verbs: ["create", "update", "patch", "get", "list", "watch"]
- apiGroups: ["security.openshift.io"]
resourceNames: ["privileged"]
resources: ["securitycontextconstraints"]
Expand Down
15 changes: 15 additions & 0 deletions pkg/daemon/internalreleaseimage/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md

approvers:
- andfasano
- bfournie
- pawanpinjarkar
- rwsu
- zaneb
reviewers:
- andfasano
- bfournie
- pawanpinjarkar
- rwsu
- zaneb

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think you added a newline entirely, instead of a newline character, but we can fix it later

Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package internalreleaseimage

import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"log"
"math/big"
"net"
"net/http"
"net/http/httptest"
"time"
)

type FakeIRIRegistry struct {
mux *http.ServeMux
server *httptest.Server
responses map[string][]registryResponse
}

type registryResponse struct {
statusCode int
body string
}

// NewFakeIRIRegistry creates a new instance of the fake registry.
func NewFakeIRIRegistry() *FakeIRIRegistry {
return &FakeIRIRegistry{
responses: make(map[string][]registryResponse),
}
}

func (fr *FakeIRIRegistry) AddResponse(endpoint string, statusCode int, body string) *FakeIRIRegistry {
epReplies, found := fr.responses[endpoint]
if !found {
epReplies = []registryResponse{}
}

epReplies = append(epReplies, registryResponse{
statusCode: statusCode,
body: body,
})
fr.responses[endpoint] = epReplies

return fr
}

// Start configures the handlers, brings up the local server for the
// registry.
func (fr *FakeIRIRegistry) Start() error {
fr.mux = http.NewServeMux()

// Ping handler
fr.mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
epReplies, found := fr.responses[r.URL.Path]
if !found || len(epReplies) == 0 {
log.Fatalf("unexpected endpoint call received: %s", r.URL.Path)
}
reply := epReplies[0]
fr.responses[r.URL.Path] = epReplies[1:]

w.Header().Set("Content-Type", "application/json")
w.Header().Set("Docker-Distribution-Api-Version", "registry/2.0")
w.WriteHeader(reply.statusCode)

if _, err := w.Write([]byte(reply.body)); err != nil {
log.Fatal(err)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
})

err := fr.newTLSServer(fr.mux.ServeHTTP)
if err != nil {
return err
}
fr.server.StartTLS()

return nil
}

func (fr *FakeIRIRegistry) newTLSServer(handler http.HandlerFunc) error {
listener, err := net.Listen("tcp", "127.0.0.1:22625")
Comment thread
andfasano marked this conversation as resolved.
if err != nil {
return fmt.Errorf("failed to bind port: %v", err)
}
fr.server = httptest.NewUnstartedServer(handler)
fr.server.Listener = listener
cert, err := fr.generateSelfSignedCert()
if err != nil {
return fmt.Errorf("error configuring server cert: %w", err)
}
fr.server.TLS = &tls.Config{
MinVersion: tls.VersionTLS13,
Certificates: []tls.Certificate{cert},
}
return nil
}

func (fr *FakeIRIRegistry) generateSelfSignedCert() (tls.Certificate, error) {
// Generate the private key
pk, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return tls.Certificate{}, err
}
// Generate the serial number
sn, err := rand.Int(rand.Reader, big.NewInt(1000000))
if err != nil {
return tls.Certificate{}, err
}
// Create the certificate template
template := x509.Certificate{
SerialNumber: sn,
Subject: pkix.Name{
Organization: []string{"IRI Tester"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(1 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
DNSNames: []string{"localhost"},
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
}
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &pk.PublicKey, pk)
if err != nil {
return tls.Certificate{}, err
}

certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)})
return tls.X509KeyPair(certPEM, keyPEM)
}

// Close shutdowns the fake registry server.
func (fr *FakeIRIRegistry) Close() {
fr.server.Close()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package internalreleaseimage

import (
mcfgv1 "github.com/openshift/api/machineconfiguration/v1"
mcfgv1alpha1 "github.com/openshift/api/machineconfiguration/v1alpha1"
"github.com/openshift/machine-config-operator/pkg/controller/common"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// iriBuilder simplifies the creation of an InternalReleaseImage resource in the test.
type iriBuilder struct {
obj *mcfgv1alpha1.InternalReleaseImage
}

func iri() *iriBuilder {
return &iriBuilder{
obj: &mcfgv1alpha1.InternalReleaseImage{
ObjectMeta: v1.ObjectMeta{
Name: common.InternalReleaseImageInstanceName,
},
Spec: mcfgv1alpha1.InternalReleaseImageSpec{
Releases: []mcfgv1alpha1.InternalReleaseImageRef{
{
Name: "ocp-release-bundle-4.21.5-x86_64",
},
},
},
},
}
}

func (ib *iriBuilder) build() runtime.Object {
return ib.obj
}

// mcnBuilder simplifies the creation of a MachineConfigNode resource in the test.
type mcnBuilder struct {
obj *mcfgv1.MachineConfigNode
}

func machineConfigNode(name string) *mcnBuilder {
return &mcnBuilder{
obj: &mcfgv1.MachineConfigNode{
ObjectMeta: v1.ObjectMeta{
Name: name,
},
},
}
}

func (mb *mcnBuilder) withIRIBundle(bundleName string, image string) *mcnBuilder {
mb.obj.Status = mcfgv1.MachineConfigNodeStatus{
Conditions: []v1.Condition{
{
Type: string(mcfgv1.MachineConfigNodeInternalReleaseImageDegraded),
Status: metav1.ConditionFalse,
},
},
InternalReleaseImage: mcfgv1.MachineConfigNodeStatusInternalReleaseImage{
Releases: []mcfgv1.MachineConfigNodeStatusInternalReleaseImageRef{
{
Name: bundleName,
Image: image,
Conditions: []v1.Condition{
{
Type: string(mcfgv1alpha1.InternalReleaseImageConditionTypeDegraded),
Status: metav1.ConditionFalse,
},
{
Type: string(mcfgv1alpha1.InternalReleaseImageConditionTypeAvailable),
Status: metav1.ConditionTrue,
},
},
},
},
},
}
return mb
}

func (mb *mcnBuilder) build() runtime.Object {
return mb.obj
}
Loading