Skip to content

Commit

Permalink
Merge pull request #95 from dtantsur/images
Browse files Browse the repository at this point in the history
✨ Bring back CRD-level image overrides
  • Loading branch information
metal3-io-bot authored Dec 5, 2024
2 parents 92acffd + 60317f6 commit b934fea
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 29 deletions.
26 changes: 26 additions & 0 deletions api/v1alpha1/ironic_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,27 @@ type TLS struct {
DisableRPCHostValidation bool `json:"disableRPCHostValidation,omitempty"`
}

type Images struct {
// DeployRamdiskBranch is the branch of IPA to download. The main branch is used by default.
// Not used if deployRamdisk.disableDownloader is true.
// +optional
DeployRamdiskBranch string `json:"deployRamdiskBranch,omitempty"`

// DeployRamdiskDownloader is the image to be used at pod initialization to download the IPA ramdisk.
// Not used if deployRamdisk.disableDownloader is true.
// +optional
DeployRamdiskDownloader string `json:"deployRamdiskDownloader,omitempty"`

// Ironic is the Ironic image (including httpd).
// +optional
Ironic string `json:"ironic,omitempty"`

// Keepalived is the Keepalived image.
// Not used if networking.ipAddressManager is not set to keepalived.
// +optional
Keepalived string `json:"keepalived,omitempty"`
}

// IronicSpec defines the desired state of Ironic
type IronicSpec struct {
// APICredentialsName is a reference to the secret with Ironic API credentials.
Expand All @@ -195,7 +216,12 @@ type IronicSpec struct {
// +optional
HighAvailability bool `json:"highAvailability,omitempty"`

// Images is a collection of container images to deploy from.
// +optional
Images Images `json:"images,omitempty"`

// Inspection defines inspection settings
// +optional
Inspection Inspection `json:"inspection,omitempty"`

// Networking defines networking settings for Ironic.
Expand Down
2 changes: 0 additions & 2 deletions api/v1alpha1/ironicdatabase_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ type IronicDatabaseSpec struct {
CredentialsName string `json:"credentialsName,omitempty"`

// Image is the MariaDB image.
// +kubebuilder:default=quay.io/metal3-io/mariadb
// +kubebuilder:validation:MinLength=1
// +optional
Image string `json:"image,omitempty"`

Expand Down
16 changes: 16 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func main() {
Scheme: mgr.GetScheme(),
Log: ctrl.Log.WithName("controllers").WithName("Ironic"),
Domain: clusterDomain,
VersionInfo: ironic.VersionInfoWithDefaults(versionInfo),
VersionInfo: versionInfo.WithDefaults(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Ironic")
os.Exit(1)
Expand All @@ -204,10 +204,11 @@ func main() {
}
}
if err = (&controller.IronicDatabaseReconciler{
Client: mgr.GetClient(),
KubeClient: kubeClient,
Scheme: mgr.GetScheme(),
Log: ctrl.Log.WithName("controllers").WithName("IronicDatabase"),
Client: mgr.GetClient(),
KubeClient: kubeClient,
Scheme: mgr.GetScheme(),
Log: ctrl.Log.WithName("controllers").WithName("IronicDatabase"),
VersionInfo: versionInfo.WithDefaults(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "IronicDatabase")
os.Exit(1)
Expand Down
2 changes: 0 additions & 2 deletions config/crd/bases/ironic.metal3.io_ironicdatabases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ spec:
A new secret will be created if this field is empty.
type: string
image:
default: quay.io/metal3-io/mariadb
description: Image is the MariaDB image.
minLength: 1
type: string
tlsCertificateName:
description: TLSCertificateName is a reference to the secret with
Expand Down
23 changes: 23 additions & 0 deletions config/crd/bases/ironic.metal3.io_ironics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,29 @@ spec:
Requires database to be installed and linked to DatabaseName.
EXPERIMENTAL: do not use (validation will fail)!
type: boolean
images:
description: Images is a collection of container images to deploy
from.
properties:
deployRamdiskBranch:
description: |-
DeployRamdiskBranch is the branch of IPA to download. The main branch is used by default.
Not used if deployRamdisk.disableDownloader is true.
type: string
deployRamdiskDownloader:
description: |-
DeployRamdiskDownloader is the image to be used at pod initialization to download the IPA ramdisk.
Not used if deployRamdisk.disableDownloader is true.
type: string
ironic:
description: Ironic is the Ironic image (including httpd).
type: string
keepalived:
description: |-
Keepalived is the Keepalived image.
Not used if networking.ipAddressManager is not set to keepalived.
type: string
type: object
inspection:
description: Inspection defines inspection settings
properties:
Expand Down
18 changes: 10 additions & 8 deletions internal/controller/ironicdatabase_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ const (
// IronicDatabaseReconciler reconciles a IronicDatabase object
type IronicDatabaseReconciler struct {
client.Client
KubeClient kubernetes.Interface
Scheme *runtime.Scheme
Log logr.Logger
KubeClient kubernetes.Interface
Scheme *runtime.Scheme
Log logr.Logger
VersionInfo ironic.VersionInfo
}

//+kubebuilder:rbac:groups=ironic.metal3.io,resources=ironicdatabases,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -62,11 +63,12 @@ func (r *IronicDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Reque
logger.Info("starting reconcile")

cctx := ironic.ControllerContext{
Context: ctx,
Client: r.Client,
KubeClient: r.KubeClient,
Scheme: r.Scheme,
Logger: logger,
Context: ctx,
Client: r.Client,
KubeClient: r.KubeClient,
Scheme: r.Scheme,
Logger: logger,
VersionInfo: r.VersionInfo,
}

db, err := getDatabase(cctx, req.NamespacedName)
Expand Down
18 changes: 10 additions & 8 deletions pkg/ironic/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,11 +448,13 @@ func newIronicPodTemplate(cctx ControllerContext, ironic *metal3api.Ironic, db *
htpasswd = apiSecret.Name
}

versionInfo := cctx.VersionInfo.withIronicOverrides(&ironic.Spec.Images)

var ipaDownloaderVars []corev1.EnvVar
ipaDownloaderVars = appendStringEnv(ipaDownloaderVars,
"IPA_BASEURI", cctx.VersionInfo.AgentDownloadURL)
"IPA_BASEURI", versionInfo.AgentDownloadURL)
ipaDownloaderVars = appendStringEnv(ipaDownloaderVars,
"IPA_BRANCH", cctx.VersionInfo.AgentBranch)
"IPA_BRANCH", versionInfo.AgentBranch)

volumes, mounts := buildIronicVolumesAndMounts(ironic, db)
sharedVolumeMount := mounts[0]
Expand All @@ -461,7 +463,7 @@ func newIronicPodTemplate(cctx ControllerContext, ironic *metal3api.Ironic, db *
if !ironic.Spec.DeployRamdisk.DisableDownloader {
initContainers = append(initContainers, corev1.Container{
Name: "ramdisk-downloader",
Image: cctx.VersionInfo.RamdiskDownloaderImage,
Image: versionInfo.RamdiskDownloaderImage,
Env: ipaDownloaderVars,
VolumeMounts: []corev1.VolumeMount{sharedVolumeMount},
SecurityContext: &corev1.SecurityContext{
Expand All @@ -482,7 +484,7 @@ func newIronicPodTemplate(cctx ControllerContext, ironic *metal3api.Ironic, db *
containers := []corev1.Container{
{
Name: "ironic",
Image: cctx.VersionInfo.IronicImage,
Image: versionInfo.IronicImage,
Command: []string{"/bin/runironic"},
Env: buildIronicEnvVars(ironic, db, htpasswd, domain),
VolumeMounts: mounts,
Expand All @@ -499,7 +501,7 @@ func newIronicPodTemplate(cctx ControllerContext, ironic *metal3api.Ironic, db *
},
{
Name: "httpd",
Image: cctx.VersionInfo.IronicImage,
Image: versionInfo.IronicImage,
Command: []string{"/bin/runhttpd"},
Env: buildHttpdEnvVars(ironic, htpasswd),
VolumeMounts: mounts,
Expand All @@ -516,7 +518,7 @@ func newIronicPodTemplate(cctx ControllerContext, ironic *metal3api.Ironic, db *
},
{
Name: "ramdisk-logs",
Image: cctx.VersionInfo.IronicImage,
Image: versionInfo.IronicImage,
Command: []string{"/bin/runlogwatch.sh"},
VolumeMounts: []corev1.VolumeMount{sharedVolumeMount},
SecurityContext: &corev1.SecurityContext{
Expand All @@ -534,11 +536,11 @@ func newIronicPodTemplate(cctx ControllerContext, ironic *metal3api.Ironic, db *
if err != nil {
return corev1.PodTemplateSpec{}, err
}
containers = append(containers, newDnsmasqContainer(cctx.VersionInfo, ironic))
containers = append(containers, newDnsmasqContainer(versionInfo, ironic))
}

if ironic.Spec.Networking.IPAddressManager == metal3api.IPAddressManagerKeepalived {
containers = append(containers, newKeepalivedContainer(cctx.VersionInfo, ironic))
containers = append(containers, newKeepalivedContainer(versionInfo, ironic))
}

return corev1.PodTemplateSpec{
Expand Down
55 changes: 55 additions & 0 deletions pkg/ironic/containers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,58 @@ func TestExpectedContainers(t *testing.T) {
})
}
}

func TestImageOverrides(t *testing.T) {
cctx := ControllerContext{}
secret := &corev1.Secret{
Data: map[string][]byte{"htpasswd": []byte("abcd")},
}
expectedImages := map[string]string{
"httpd": "myorg/myironic:test",
"ironic": "myorg/myironic:test",
"keepalived": "myorg/mykeepalived:test",
"ramdisk-downloader": "myorg/mydownloader:test",
"ramdisk-logs": "myorg/myironic:test",
}
ironic := &metal3api.Ironic{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: metal3api.IronicSpec{
Images: metal3api.Images{
DeployRamdiskBranch: "stable/x.y",
DeployRamdiskDownloader: "myorg/mydownloader:test",
Ironic: "myorg/myironic:test",
Keepalived: "myorg/mykeepalived:test",
},
Networking: metal3api.Networking{
Interface: "eth0",
IPAddress: "192.0.2.2",
IPAddressManager: metal3api.IPAddressManagerKeepalived,
},
},
}

podTemplate, err := newIronicPodTemplate(cctx, ironic, nil, secret, "test-domain.example.com")
assert.NoError(t, err)

images := make(map[string]string, len(expectedImages))
var actualBranch string
for _, cont := range podTemplate.Spec.InitContainers {
images[cont.Name] = cont.Image
if cont.Name == "ramdisk-downloader" {
for _, env := range cont.Env {
if env.Name == "IPA_BRANCH" {
actualBranch = env.Value
}
}
}
}
for _, cont := range podTemplate.Spec.Containers {
images[cont.Name] = cont.Image
}

assert.Equal(t, expectedImages, images)
assert.Equal(t, "stable/x.y", actualBranch)
}
11 changes: 8 additions & 3 deletions pkg/ironic/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func commonDatabaseVars(db *metal3api.IronicDatabase) []corev1.EnvVar {

}

func newDatabasePodTemplate(db *metal3api.IronicDatabase) corev1.PodTemplateSpec {
func newDatabasePodTemplate(db *metal3api.IronicDatabase, versionInfo VersionInfo) corev1.PodTemplateSpec {
volumes := []corev1.Volume{}
mounts := []corev1.VolumeMount{}

Expand Down Expand Up @@ -101,10 +101,15 @@ func newDatabasePodTemplate(db *metal3api.IronicDatabase) corev1.PodTemplateSpec
},
})

image := db.Spec.Image
if image == "" {
image = versionInfo.MariaDBImage
}

containers := []corev1.Container{
{
Name: "mariadb",
Image: db.Spec.Image,
Image: image,
Env: envVars,
VolumeMounts: mounts,
SecurityContext: &corev1.SecurityContext{
Expand Down Expand Up @@ -145,7 +150,7 @@ func ensureDatabaseDeployment(cctx ControllerContext, db *metal3api.IronicDataba
matchLabels := map[string]string{metal3api.IronicOperatorLabel: databaseDeploymentName(db)}
deploy.Spec.Selector = &metav1.LabelSelector{MatchLabels: matchLabels}
deploy.Spec.Replicas = ptr.To(int32(1))
mergePodTemplates(&deploy.Spec.Template, newDatabasePodTemplate(db))
mergePodTemplates(&deploy.Spec.Template, newDatabasePodTemplate(db, cctx.VersionInfo))
return controllerutil.SetControllerReference(db, deploy, cctx.Scheme)
})
if err != nil {
Expand Down
20 changes: 19 additions & 1 deletion pkg/ironic/version.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ironic

import metal3api "github.com/metal3-io/ironic-standalone-operator/api/v1alpha1"

const (
installedVersion string = "latest"
defaultRegistry string = "quay.io/metal3-io/"
Expand All @@ -22,7 +24,23 @@ type VersionInfo struct {
KeepalivedImage string
}

func VersionInfoWithDefaults(versionInfo VersionInfo) VersionInfo {
func (versionInfo VersionInfo) withIronicOverrides(images *metal3api.Images) VersionInfo {
if images.DeployRamdiskBranch != "" {
versionInfo.AgentBranch = images.DeployRamdiskBranch
}
if images.DeployRamdiskDownloader != "" {
versionInfo.RamdiskDownloaderImage = images.DeployRamdiskDownloader
}
if images.Ironic != "" {
versionInfo.IronicImage = images.Ironic
}
if images.Keepalived != "" {
versionInfo.KeepalivedImage = images.Keepalived
}
return versionInfo
}

func (versionInfo VersionInfo) WithDefaults() VersionInfo {
if versionInfo.InstalledVersion == "" {
versionInfo.InstalledVersion = installedVersion
}
Expand Down

0 comments on commit b934fea

Please sign in to comment.