Skip to content

Commit

Permalink
[WIP] Support extracting from bootc edpm images
Browse files Browse the repository at this point in the history
  • Loading branch information
steveb committed Dec 8, 2024
1 parent caecc88 commit 10f92dd
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 35 deletions.
12 changes: 11 additions & 1 deletion api/bases/baremetal.openstack.org_openstackbaremetalsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,22 @@ spec:
type: object
type: object
type: object
osContainerImageType:
default: self-extracting
description: OSContainerImageType - Whether the OS container image
is a self-extracting or a bootc based image
enum:
- self-extracting
- bootc
type: string
osContainerImageUrl:
description: OSContainerImageURL - Container image URL for init with
the OS qcow2 image (osImage)
type: string
osImage:
description: OSImage - OS qcow2 image Name
description: OSImage - For osContainerImageType=self-extracting, the
name of the OS qcow2 file to extract from the image. For osContainerImageType=bootc,
the name of the qcow2 file to write to for bootc install.
type: string
passwordSecret:
description: 'PasswordSecret the name of the secret used to optionally
Expand Down
13 changes: 11 additions & 2 deletions api/bases/baremetal.openstack.org_openstackprovisionservers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,22 @@ spec:
description: NodeSelector to target subset of worker nodes running
this provision server
type: object
osContainerImageType:
default: self-extracting
description: OSContainerImageType - Whether the OS container image
is a self-extracting or a bootc based image
enum:
- self-extracting
- bootc
type: string
osContainerImageUrl:
description: OSContainerImageURL - Container image URL for init with
the OS qcow2 image (osImage)
type: string
osImage:
description: OSImage - OS qcow2 image (compressed as gz, or uncompressed)
description: OSImage - For osContainerImageType=self-extracting, the
name of the OS qcow2 file to extract from the image. For osContainerImageType=bootc,
the name of the qcow2 file to write to for bootc install.
type: string
osImageDir:
default: /usr/local/apache2/htdocs
Expand Down Expand Up @@ -143,7 +153,6 @@ spec:
- agentImageUrl
- apacheImageUrl
- osContainerImageUrl
- osImage
- osImageDir
type: object
status:
Expand Down
6 changes: 5 additions & 1 deletion api/v1beta1/openstackbaremetalset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,15 @@ type OpenStackBaremetalSetSpec struct {
// BaremetalHosts - Map of hostname to Instance Spec for all nodes to provision
BaremetalHosts map[string]InstanceSpec `json:"baremetalHosts,omitempty"`
// +kubebuilder:validation:Optional
// OSImage - OS qcow2 image Name
// OSImage - For osContainerImageType=self-extracting, the name of the OS qcow2 file to extract from the image. For osContainerImageType=bootc, the name of the qcow2 file to write to for bootc install.
OSImage string `json:"osImage,omitempty"`
// +kubebuilder:validation:Optional
// OSContainerImageURL - Container image URL for init with the OS qcow2 image (osImage)
OSContainerImageURL string `json:"osContainerImageUrl,omitempty"`
// +kubebuilder:validation:Enum=self-extracting;bootc
// +kubebuilder:default=self-extracting
// OSContainerImageType - Whether the OS container image is a self-extracting or a bootc based image
OSContainerImageType string `json:"osContainerImageType,omitempty"`
// +kubebuilder:validation:Optional
// ApacheImageURL - Container image URL for the main container that serves the downloaded OS qcow2 image (osImage)
ApacheImageURL string `json:"apacheImageUrl,omitempty"`
Expand Down
27 changes: 18 additions & 9 deletions api/v1beta1/openstackprovisionserver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const (
const (
// OSContainerImage - default fall-back image for OpenStackProvisionServer int container
OSContainerImage = "quay.io/podified-antelope-centos9/edpm-hardened-uefi:current-podified"
// OSContainerImageType - default fall-back image type for OSContainerImage
OSContainerImageType = "self-extracting"
// AgentImage - default fall-back image for OpenStackProvisionServer agent
AgentImage = "quay.io/openstack-k8s-operators/openstack-baremetal-operator-agent:latest"
// ApacheImage - default fall-back image for Apache
Expand All @@ -61,14 +63,19 @@ type OpenStackProvisionServerSpec struct {
// +kubebuilder:validation:Optional
// Interface - An optional interface to use instead of the cluster's default provisioning interface (if any)
Interface string `json:"interface,omitempty"`
// OSImage - OS qcow2 image (compressed as gz, or uncompressed)
// +kubebuilder:validation:Optional
// OSImage - For osContainerImageType=self-extracting, the name of the OS qcow2 file to extract from the image. For osContainerImageType=bootc, the name of the qcow2 file to write to for bootc install.
OSImage string `json:"osImage"`
// +kubebuilder:validation:Required
// +kubebuilder:default=/usr/local/apache2/htdocs
// OSImageDir - Directory on the container which holds the OS qcow2 image and checksum
OSImageDir *string `json:"osImageDir"`
// OSContainerImageURL - Container image URL for init with the OS qcow2 image (osImage)
OSContainerImageURL string `json:"osContainerImageUrl"`
// +kubebuilder:validation:Enum=self-extracting;bootc
// +kubebuilder:default=self-extracting
// OSContainerImageType - Whether the OS container image is a self-extracting or a bootc based image
OSContainerImageType string `json:"osContainerImageType,omitempty"`
// ApacheImageURL - Container image URL for the main container that serves the downloaded OS qcow2 image (osImage)
ApacheImageURL string `json:"apacheImageUrl"`
// AgentImageURL - Container image URL for the sidecar container that discovers provisioning network IPs
Expand Down Expand Up @@ -138,10 +145,11 @@ type OpenStackProvisionServerList struct {

// OpenStackProvisionServerDefaults -
type OpenStackProvisionServerDefaults struct {
OSContainerImageURL string
AgentImageURL string
ApacheImageURL string
OSImage string
OSContainerImageURL string
OSContainerImageType string
AgentImageURL string
ApacheImageURL string
OSImage string
}

func init() {
Expand All @@ -168,10 +176,11 @@ func (instance OpenStackProvisionServer) RbacResourceName() string {
func SetupDefaults() {
// Acquire environmental defaults and initialize OpenStackProvisionServer defaults with them
openstackProvisionServerDefaults := OpenStackProvisionServerDefaults{
OSContainerImageURL: util.GetEnvVar("RELATED_IMAGE_OS_CONTAINER_IMAGE_URL_DEFAULT", OSContainerImage),
AgentImageURL: util.GetEnvVar("RELATED_IMAGE_AGENT_IMAGE_URL_DEFAULT", AgentImage),
ApacheImageURL: util.GetEnvVar("RELATED_IMAGE_APACHE_IMAGE_URL_DEFAULT", ApacheImage),
OSImage: util.GetEnvVar("OS_IMAGE_DEFAULT", OSImage),
OSContainerImageURL: util.GetEnvVar("RELATED_IMAGE_OS_CONTAINER_IMAGE_URL_DEFAULT", OSContainerImage),
OSContainerImageType: util.GetEnvVar("RELATED_IMAGE_OS_CONTAINER_IMAGE_TYPE_DEFAULT", OSContainerImageType),
AgentImageURL: util.GetEnvVar("RELATED_IMAGE_AGENT_IMAGE_URL_DEFAULT", AgentImage),
ApacheImageURL: util.GetEnvVar("RELATED_IMAGE_APACHE_IMAGE_URL_DEFAULT", ApacheImage),
OSImage: util.GetEnvVar("OS_IMAGE_DEFAULT", OSImage),
}

SetupOpenStackProvisionServerDefaults(openstackProvisionServerDefaults)
Expand Down
3 changes: 3 additions & 0 deletions api/v1beta1/openstackprovisionserver_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ func (r *OpenStackProvisionServer) Default() {
if r.Spec.OSContainerImageURL == "" {
r.Spec.OSContainerImageURL = openstackProvisionServerDefaults.OSContainerImageURL
}
if r.Spec.OSContainerImageType == "" {
r.Spec.OSContainerImageType = openstackProvisionServerDefaults.OSContainerImageType
}
if r.Spec.AgentImageURL == "" {
r.Spec.AgentImageURL = openstackProvisionServerDefaults.AgentImageURL
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,22 @@ spec:
type: object
type: object
type: object
osContainerImageType:
default: self-extracting
description: OSContainerImageType - Whether the OS container image
is a self-extracting or a bootc based image
enum:
- self-extracting
- bootc
type: string
osContainerImageUrl:
description: OSContainerImageURL - Container image URL for init with
the OS qcow2 image (osImage)
type: string
osImage:
description: OSImage - OS qcow2 image Name
description: OSImage - For osContainerImageType=self-extracting, the
name of the OS qcow2 file to extract from the image. For osContainerImageType=bootc,
the name of the qcow2 file to write to for bootc install.
type: string
passwordSecret:
description: 'PasswordSecret the name of the secret used to optionally
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,22 @@ spec:
description: NodeSelector to target subset of worker nodes running
this provision server
type: object
osContainerImageType:
default: self-extracting
description: OSContainerImageType - Whether the OS container image
is a self-extracting or a bootc based image
enum:
- self-extracting
- bootc
type: string
osContainerImageUrl:
description: OSContainerImageURL - Container image URL for init with
the OS qcow2 image (osImage)
type: string
osImage:
description: OSImage - OS qcow2 image (compressed as gz, or uncompressed)
description: OSImage - For osContainerImageType=self-extracting, the
name of the OS qcow2 file to extract from the image. For osContainerImageType=bootc,
the name of the qcow2 file to write to for bootc install.
type: string
osImageDir:
default: /usr/local/apache2/htdocs
Expand Down Expand Up @@ -143,7 +153,6 @@ spec:
- agentImageUrl
- apacheImageUrl
- osContainerImageUrl
- osImage
- osImageDir
type: object
status:
Expand Down
1 change: 1 addition & 0 deletions controllers/openstackbaremetalset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ func (r *OpenStackBaremetalSetReconciler) provisionServerCreateOrUpdate(
}
provisionServer.Spec.OSImage = instance.Spec.OSImage
provisionServer.Spec.OSContainerImageURL = instance.Spec.OSContainerImageURL
provisionServer.Spec.OSContainerImageType = instance.Spec.OSContainerImageType
provisionServer.Spec.ApacheImageURL = instance.Spec.ApacheImageURL
provisionServer.Spec.AgentImageURL = instance.Spec.AgentImageURL
provisionServer.Spec.NodeSelector = instance.Spec.ProvisonServerNodeSelector
Expand Down
8 changes: 5 additions & 3 deletions pkg/openstackprovisionserver/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,11 @@ func Deployment(
}

initContainerDetails := InitContainerDetails{
OsImageDir: *instance.Spec.OSImageDir,
ContainerImage: instance.Spec.OSContainerImageURL,
VolumeMounts: getInitVolumeMounts(instance),
OsImageDir: *instance.Spec.OSImageDir,
OsImage: instance.Spec.OSImage,
ContainerImage: instance.Spec.OSContainerImageURL,
ContainerImageType: instance.Spec.OSContainerImageType,
VolumeMounts: getInitVolumeMounts(instance),
}
deployment.Spec.Template.Spec.InitContainers = InitContainer(initContainerDetails)

Expand Down
35 changes: 31 additions & 4 deletions pkg/openstackprovisionserver/initcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,45 @@ package openstackprovisionserver
import (
"github.com/openstack-k8s-operators/lib-common/modules/common/env"
corev1 "k8s.io/api/core/v1"
"path/filepath"
"strings"
)

// InitContainerDetails information
type InitContainerDetails struct {
ContainerImage string
OsImageDir string
Privileged bool
VolumeMounts []corev1.VolumeMount
ContainerImage string
ContainerImageType string
OsImageDir string
OsImage string
Privileged bool
VolumeMounts []corev1.VolumeMount
}

// InitContainer - init container for provision server pods
func InitContainer(init InitContainerDetails) []corev1.Container {
if init.ContainerImageType == "bootc" {

osImage := init.OsImage
osImageExtension := filepath.Ext(osImage)
osImageNoExtension := strings.TrimSuffix(osImage, osImageExtension)
osImagePathRaw := filepath.Join(init.OsImageDir, osImageNoExtension+".raw")

// TODO(sbaker) if the extension is qcow2 add an init container which runs "qemu-img convert" on the raw image
return []corev1.Container{
{
Name: "init",
Image: init.ContainerImage,
Command: []string{"bootc", "install", "to-disk", "--generic-image", "--via-loopback", osImagePathRaw},
SecurityContext: &corev1.SecurityContext{
Privileged: &init.Privileged,
SELinuxOptions: &corev1.SELinuxOptions{
Type: "unconfined_t",
},
},
VolumeMounts: init.VolumeMounts,
},
}
}
envs := []corev1.EnvVar{
{
Name: "DEST_DIR",
Expand Down
7 changes: 4 additions & 3 deletions pkg/openstackprovisionserver/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ func ChecksumJob(
}

initContainerDetails := InitContainerDetails{
OsImageDir: *instance.Spec.OSImageDir,
ContainerImage: instance.Spec.OSContainerImageURL,
VolumeMounts: getInitVolumeMounts(instance),
OsImageDir: *instance.Spec.OSImageDir,
ContainerImage: instance.Spec.OSContainerImageURL,
ContainerImageType: instance.Spec.OSContainerImageType,
VolumeMounts: getInitVolumeMounts(instance),
}
job.Spec.Template.Spec.InitContainers = InitContainer(initContainerDetails)

Expand Down
24 changes: 24 additions & 0 deletions pkg/openstackprovisionserver/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ func getInitVolumes() []corev1.Volume {
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
{
Name: "var-lib-containers",
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/var/lib/containers",
},
},
},
{
Name: "dev",
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/dev",
},
},
},
}
}

Expand All @@ -54,6 +70,14 @@ func getInitVolumeMounts(instance *baremetalv1.OpenStackProvisionServer) []corev
Name: "image-data",
MountPath: *instance.Spec.OSImageDir,
},
{
Name: "var-lib-containers",
MountPath: "/var/lib/containers",
},
{
Name: "dev",
MountPath: "/dev",
},
}
}

Expand Down
20 changes: 11 additions & 9 deletions tests/functional/openstackbaremetalset_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ var _ = Describe("BaremetalSet Test", func() {
},
OSImage: "",
OSContainerImageURL: "",
OSContainerImageType: "",
ApacheImageURL: "",
AgentImageURL: "",
AutomatedCleaningMode: "metadata",
Expand Down Expand Up @@ -177,15 +178,16 @@ var _ = Describe("BaremetalSet Test", func() {

provServer := GetProvisionServer(baremetalSetName)
spec := baremetalv1.OpenStackProvisionServerSpec{
Port: 6190,
Interface: "eth1",
OSImage: "edpm-hardened-uefi.qcow2",
OSImageDir: &osImageDir,
OSContainerImageURL: "quay.io/podified-antelope-centos9/edpm-hardened-uefi@latest",
ApacheImageURL: "registry.redhat.io/rhel8/httpd-24@latest",
AgentImageURL: "quay.io/openstack-k8s-operators/openstack-baremetal-operator-agent@latest",
NodeSelector: nil,
Resources: corev1.ResourceRequirements{Limits: nil, Requests: nil, Claims: nil},
Port: 6190,
Interface: "eth1",
OSImage: "edpm-hardened-uefi.qcow2",
OSImageDir: &osImageDir,
OSContainerImageURL: "quay.io/podified-antelope-centos9/edpm-hardened-uefi@latest",
OSContainerImageType: "self-extracting",
ApacheImageURL: "registry.redhat.io/rhel8/httpd-24@latest",
AgentImageURL: "quay.io/openstack-k8s-operators/openstack-baremetal-operator-agent@latest",
NodeSelector: nil,
Resources: corev1.ResourceRequirements{Limits: nil, Requests: nil, Claims: nil},
}
Expect(provServer.Spec).Should(Equal(spec))
})
Expand Down

0 comments on commit 10f92dd

Please sign in to comment.