Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Support extracting from bootc edpm images #240

Closed
wants to merge 1 commit into from
Closed
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: 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
2 changes: 1 addition & 1 deletion controllers/openstackprovisionserver_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type OpenStackProvisionServerReconciler struct {
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch
// service account permissions that are needed to grant permission to the above
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=hostnetwork,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid;privileged;hostnetwork,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch

// +kubebuilder:rbac:groups=baremetal.openstack.org,resources=openstackprovisionservers,verbs=get;list;watch;create;update;patch;delete
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
36 changes: 32 additions & 4 deletions pkg/openstackprovisionserver/initcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,46 @@ 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