diff --git a/api/v1beta1/openstackprovisionserver_types.go b/api/v1beta1/openstackprovisionserver_types.go index 27bb576..0e4e46d 100644 --- a/api/v1beta1/openstackprovisionserver_types.go +++ b/api/v1beta1/openstackprovisionserver_types.go @@ -23,6 +23,17 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// ProvisioningNetwork is the boot mode of the system +// +kubebuilder:validation:Enum=Managed;Unmanaged;Disabled +type ProvisioningNetwork string + +// ProvisioningNetwork modes +const ( + ProvisioningNetworkManaged ProvisioningNetwork = "Managed" + ProvisioningNetworkUnmanaged ProvisioningNetwork = "Unmanaged" + ProvisioningNetworkDisabled ProvisioningNetwork = "Disabled" +) + const ( // OSContainerImage - default fall-back image for OpenStackProvisionServer int container OSContainerImage = "quay.io/podified-antelope-centos9/edpm-hardened-uefi:current-podified" diff --git a/controllers/openstackprovisionserver_controller.go b/controllers/openstackprovisionserver_controller.go index 5424df5..e147b05 100644 --- a/controllers/openstackprovisionserver_controller.go +++ b/controllers/openstackprovisionserver_controller.go @@ -27,6 +27,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8s_labels "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" @@ -339,7 +340,12 @@ func (r *OpenStackProvisionServerReconciler) reconcileNormal(ctx context.Context err.Error())) return ctrl.Result{}, err } - instance.Status.Conditions.MarkTrue(baremetalv1.OpenStackProvisionServerProvIntfReadyCondition, baremetalv1.OpenStackProvisionServerProvIntfReadyMessage) + + if provInterfaceName != "" { + instance.Status.Conditions.MarkTrue(baremetalv1.OpenStackProvisionServerProvIntfReadyCondition, baremetalv1.OpenStackProvisionServerProvIntfReadyMessage) + } else { + instance.Status.Conditions.Remove(baremetalv1.OpenStackProvisionServerProvIntfReadyCondition) + } serviceLabels := labels.GetLabels(instance, openstackprovisionserver.AppLabel, map[string]string{ common.AppSelector: instance.Name + "-deployment", @@ -416,22 +422,14 @@ func (r *OpenStackProvisionServerReconciler) reconcileNormal(ctx context.Context } // create Deployment - end - // - // Check whether instance.Status.ProvisionIp has been set by the side-car agent container - // that is created with the deployment above and generate the LocalImageURL if so - // - // Provision IP Discovery Agent sets status' ProvisionIP - if instance.Status.ProvisionIP == "" { - instance.Status.Conditions.Set(condition.FalseCondition( - baremetalv1.OpenStackProvisionServerLocalImageURLReadyCondition, - condition.RequestedReason, - condition.SeverityInfo, - baremetalv1.OpenStackProvisionServerLocalImageURLReadyRunningMessage)) - return ctrlResult, nil + instance.Status.LocalImageURL, err = r.getLocalImageURL(ctx, helper, instance) + if err != nil { + instance.Status.Conditions.MarkFalse( + baremetalv1.OpenStackProvisionServerLocalImageURLReadyCondition, condition.ErrorReason, condition.SeverityError, + baremetalv1.OpenStackBaremetalSetBmhProvisioningReadyErrorMessage, err.Error()) + return ctrl.Result{}, err } - instance.Status.LocalImageURL = r.getLocalImageURL(instance) - if oldLocalImageURL != instance.Status.LocalImageURL { r.Log.Info(fmt.Sprintf("OpenStackProvisionServer LocalImageURL changed: %s", instance.Status.LocalImageURL)) } @@ -525,10 +523,6 @@ func (r *OpenStackProvisionServerReconciler) getProvisioningInterfaceName( if err != nil { return "", err } - - if provInterfaceName == "" { - return "", fmt.Errorf("metal3 provisioning interface configuration not found") - } } return provInterfaceName, nil @@ -561,8 +555,12 @@ func (r *OpenStackProvisionServerReconciler) getProvisioningInterface( provisioningSpecIntf := provisioning.Object["spec"] if provisioningSpec, ok := provisioningSpecIntf.(map[string]interface{}); ok { - interfaceIntf := provisioningSpec["provisioningInterface"] + bootMode := provisioningSpec["provisioningNetwork"] + if bootMode == nil || bootMode != baremetalv1.ProvisioningNetworkManaged { + return "", nil + } + interfaceIntf := provisioningSpec["provisioningInterface"] if provInterfaceName, ok := interfaceIntf.(string); ok { r.Log.Info(fmt.Sprintf("Found provisioning interface %s in Metal3 config", provInterfaceName)) return provInterfaceName, nil @@ -572,7 +570,22 @@ func (r *OpenStackProvisionServerReconciler) getProvisioningInterface( return "", nil } -func (r *OpenStackProvisionServerReconciler) getLocalImageURL(instance *baremetalv1.OpenStackProvisionServer) string { +func (r *OpenStackProvisionServerReconciler) getLocalImageURL( + ctx context.Context, helper *helper.Helper, instance *baremetalv1.OpenStackProvisionServer) (string, error) { baseFilename := instance.Spec.OSImage - return fmt.Sprintf("http://%s:%d/%s", instance.Status.ProvisionIP, instance.Spec.Port, baseFilename) + host := instance.Status.ProvisionIP + if host == "" { + serviceLabels := labels.GetLabels(instance, openstackprovisionserver.AppLabel, map[string]string{ + common.AppSelector: instance.Name + "-deployment"}) + podSelectorString := k8s_labels.Set(serviceLabels).String() + // Get the pod for provisionserver + provisionPods, err := helper.GetKClient().CoreV1().Pods( + instance.Namespace).List(ctx, metav1.ListOptions{LabelSelector: podSelectorString}) + if err != nil { + return "", err + } + //We're using hostNetwork for the provisionserver pod + host = provisionPods.Items[0].Status.HostIP + } + return fmt.Sprintf("http://%s:%d/%s", host, instance.Spec.Port, baseFilename), nil } diff --git a/pkg/openstackprovisionserver/deployment.go b/pkg/openstackprovisionserver/deployment.go index 361f18e..b4d2c54 100644 --- a/pkg/openstackprovisionserver/deployment.go +++ b/pkg/openstackprovisionserver/deployment.go @@ -81,6 +81,46 @@ func Deployment( replicas := int32(1) + containers := []corev1.Container{ + { + Name: "osp-httpd", + Command: []string{ + "/bin/bash", + }, + Args: args, + Image: instance.Spec.ApacheImageURL, + VolumeMounts: getVolumeMounts(), + Resources: instance.Spec.Resources, + StartupProbe: startupProbe, + ReadinessProbe: readinessProbe, + LivenessProbe: livenessProbe, + }, + } + + if provInterfaceName != "" { + discoveryContainer := corev1.Container{ + Name: "osp-provision-ip-discovery-agent", + Command: []string{"/openstack-baremetal-agent", "provision-ip-discovery"}, + Image: instance.Spec.AgentImageURL, + ImagePullPolicy: corev1.PullAlways, + Env: []corev1.EnvVar{ + { + Name: "PROV_INTF", + Value: provInterfaceName, + }, + { + Name: "PROV_SERVER_NAME", + Value: instance.GetName(), + }, + { + Name: "PROV_SERVER_NAMESPACE", + Value: instance.GetNamespace(), + }, + }, + } + containers = append(containers, discoveryContainer) + } + deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%s-openstackprovisionserver", instance.Name), @@ -106,41 +146,7 @@ func Deployment( Spec: corev1.PodSpec{ ServiceAccountName: instance.RbacResourceName(), HostNetwork: true, - Containers: []corev1.Container{ - { - Name: "osp-httpd", - Command: []string{ - "/bin/bash", - }, - Args: args, - Image: instance.Spec.ApacheImageURL, - VolumeMounts: getVolumeMounts(), - Resources: instance.Spec.Resources, - StartupProbe: startupProbe, - ReadinessProbe: readinessProbe, - LivenessProbe: livenessProbe, - }, - { - Name: "osp-provision-ip-discovery-agent", - Command: []string{"/openstack-baremetal-agent", "provision-ip-discovery"}, - Image: instance.Spec.AgentImageURL, - ImagePullPolicy: corev1.PullAlways, - Env: []corev1.EnvVar{ - { - Name: "PROV_INTF", - Value: provInterfaceName, - }, - { - Name: "PROV_SERVER_NAME", - Value: instance.GetName(), - }, - { - Name: "PROV_SERVER_NAMESPACE", - Value: instance.GetNamespace(), - }, - }, - }, - }, + Containers: containers, }, }, },