diff --git a/api/bases/ovn.openstack.org_ovncontrollers.yaml b/api/bases/ovn.openstack.org_ovncontrollers.yaml index 8f436fc1..28eae86b 100644 --- a/api/bases/ovn.openstack.org_ovncontrollers.yaml +++ b/api/bases/ovn.openstack.org_ovncontrollers.yaml @@ -212,7 +212,7 @@ spec: hash: additionalProperties: type: string - description: Map of hashes to track e.g. job status + description: Map of hashes to track type: object networkAttachments: additionalProperties: diff --git a/api/v1beta1/ovncontroller_types.go b/api/v1beta1/ovncontroller_types.go index 82205f37..cd2d05e8 100644 --- a/api/v1beta1/ovncontroller_types.go +++ b/api/v1beta1/ovncontroller_types.go @@ -99,7 +99,7 @@ type OVNControllerStatus struct { // Conditions Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"` - // Map of hashes to track e.g. job status + // Map of hashes to track Hash map[string]string `json:"hash,omitempty"` // NetworkAttachments status of the deployment pods @@ -145,7 +145,7 @@ func (instance OVNController) IsReady() bool { type OVSExternalIDs struct { // +kubebuilder:validation:Optional // +kubebuilder:default="random" - SystemID string `json:"system-id,omitempty"` + SystemID string `json:"system-id,omitempty"` // +kubebuilder:validation:Optional // +kubebuilder:default="br-int" diff --git a/config/crd/bases/ovn.openstack.org_ovncontrollers.yaml b/config/crd/bases/ovn.openstack.org_ovncontrollers.yaml index 8f436fc1..28eae86b 100644 --- a/config/crd/bases/ovn.openstack.org_ovncontrollers.yaml +++ b/config/crd/bases/ovn.openstack.org_ovncontrollers.yaml @@ -212,7 +212,7 @@ spec: hash: additionalProperties: type: string - description: Map of hashes to track e.g. job status + description: Map of hashes to track type: object networkAttachments: additionalProperties: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 296ae9d7..0012f470 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -63,18 +63,6 @@ rules: - patch - update - watch -- apiGroups: - - batch - resources: - - jobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - "" resources: diff --git a/controllers/ovncontroller_controller.go b/controllers/ovncontroller_controller.go index 99cb439b..24eab7e9 100644 --- a/controllers/ovncontroller_controller.go +++ b/controllers/ovncontroller_controller.go @@ -41,7 +41,6 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/daemonset" "github.com/openstack-k8s-operators/lib-common/modules/common/env" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" - "github.com/openstack-k8s-operators/lib-common/modules/common/job" "github.com/openstack-k8s-operators/lib-common/modules/common/labels" nad "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" common_rbac "github.com/openstack-k8s-operators/lib-common/modules/common/rbac" @@ -49,7 +48,6 @@ import ( "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" "github.com/openstack-k8s-operators/ovn-operator/pkg/ovncontroller" appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" ) @@ -94,7 +92,6 @@ func (r *OVNControllerReconciler) GetClient() client.Client { //+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete; //+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list; //+kubebuilder:rbac:groups=apps,resources=daemonsets,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;patch;update;delete; //+kubebuilder:rbac:groups=ovn.openstack.org,resources=ovndbclusters,verbs=get;list;watch; //+kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=create;delete;get;list;patch;update;watch @@ -205,7 +202,6 @@ func (r *OVNControllerReconciler) SetupWithManager(mgr ctrl.Manager, ctx context return ctrl.NewControllerManagedBy(mgr). For(&v1beta1.OVNController{}). Owns(&corev1.ConfigMap{}). - Owns(&batchv1.Job{}). Owns(&netattdefv1.NetworkAttachmentDefinition{}). Owns(&appsv1.DaemonSet{}). Owns(&corev1.ServiceAccount{}). @@ -405,8 +401,19 @@ func (r *OVNControllerReconciler) reconcileNormal(ctx context.Context, instance return ctrlResult, nil } + sbCluster, err := v1beta1.GetDBClusterByType(ctx, helper, instance.Namespace, map[string]string{}, v1beta1.SBDBType) + if err != nil { + Log.Info("No SB OVNDBCluster defined, deleting external ConfigMap") + cleanupConfigMapErr := r.deleteExternalConfigMaps(ctx, helper, instance) + if cleanupConfigMapErr != nil { + Log.Error(cleanupConfigMapErr, "Failed to delete external ConfigMap") + return ctrl.Result{}, cleanupConfigMapErr + } + return ctrl.Result{}, err + } + // Define a new DaemonSet object - ovnDaemonSet, err := ovncontroller.DaemonSet(instance, inputHash, serviceLabels, serviceAnnotations) + ovnDaemonSet, err := ovncontroller.DaemonSet(instance, sbCluster, inputHash, serviceLabels, serviceAnnotations) if err != nil { Log.Error(err, "Failed to create OVNController DaemonSet") return ctrl.Result{}, err @@ -463,17 +470,6 @@ func (r *OVNControllerReconciler) reconcileNormal(ctx context.Context, instance } // create DaemonSet - end - sbCluster, err := v1beta1.GetDBClusterByType(ctx, helper, instance.Namespace, map[string]string{}, v1beta1.SBDBType) - if err != nil { - Log.Info("No SB OVNDBCluster defined, deleting external ConfigMap") - cleanupConfigMapErr := r.deleteExternalConfigMaps(ctx, helper, instance) - if cleanupConfigMapErr != nil { - Log.Error(cleanupConfigMapErr, "Failed to delete external ConfigMap") - return ctrl.Result{}, cleanupConfigMapErr - } - return ctrl.Result{}, nil - } - ep, err := sbCluster.GetExternalEndpoint() if err != nil || ep == "" { Log.Info("No external endpoint defined for SB OVNDBCluster, deleting external ConfigMap") @@ -494,60 +490,6 @@ func (r *OVNControllerReconciler) reconcileNormal(ctx context.Context, instance } } - // create OVN Config Job - start - if instance.Status.NumberReady == instance.Status.DesiredNumberScheduled { - jobsDef, err := ovncontroller.ConfigJob(ctx, helper, r.Client, instance, sbCluster, serviceLabels) - if err != nil { - Log.Error(err, "Failed to create OVN controller configuration Job") - return ctrl.Result{}, err - } - for _, jobDef := range jobsDef { - configHashKey := v1beta1.OvnConfigHash + "-" + jobDef.Spec.Template.Spec.NodeName - configHash := instance.Status.Hash[configHashKey] - configJob := job.NewJob( - jobDef, - configHashKey, - false, - time.Duration(5)*time.Second, - configHash, - ) - ctrlResult, err = configJob.DoJob(ctx, helper) - if (ctrlResult != ctrl.Result{}) { - instance.Status.Conditions.Set( - condition.FalseCondition( - condition.ServiceConfigReadyCondition, - condition.RequestedReason, - condition.SeverityInfo, - condition.ServiceConfigReadyMessage, - ), - ) - return ctrlResult, nil - } - if err != nil { - Log.Error(err, "Failed to configure OVN controller") - instance.Status.Conditions.Set( - condition.FalseCondition( - condition.ServiceConfigReadyCondition, - condition.RequestedReason, - condition.SeverityInfo, - condition.ServiceConfigReadyErrorMessage, - err.Error(), - ), - ) - return ctrl.Result{}, err - } - if configJob.HasChanged() { - instance.Status.Hash[configHashKey] = configJob.GetHash() - Log.Info(fmt.Sprintf("Job %s hash added - %s", jobDef.Name, instance.Status.Hash[configHashKey])) - } - } - instance.Status.Conditions.MarkTrue(condition.ServiceConfigReadyCondition, condition.ServiceConfigReadyMessage) - } else { - Log.Info("OVNController DaemonSet not ready yet. Configuration job cannot be started.") - return ctrl.Result{Requeue: true}, nil - } - // create OVN Config Job - end - Log.Info("Reconciled Service successfully") return ctrl.Result{}, nil diff --git a/pkg/ovncontroller/configjob.go b/pkg/ovncontroller/configjob.go deleted file mode 100644 index a4188611..00000000 --- a/pkg/ovncontroller/configjob.go +++ /dev/null @@ -1,110 +0,0 @@ -/* -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ovncontroller - -import ( - "context" - "fmt" - - "github.com/openstack-k8s-operators/lib-common/modules/common/env" - "github.com/openstack-k8s-operators/lib-common/modules/common/helper" - "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" - "sigs.k8s.io/controller-runtime/pkg/client" - - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ConfigJob - prepare job to configure ovn-controller -func ConfigJob( - ctx context.Context, - h *helper.Helper, - k8sClient client.Client, - instance *v1beta1.OVNController, - sbCluster *v1beta1.OVNDBCluster, - labels map[string]string, -) ([]*batchv1.Job, error) { - - var jobs []*batchv1.Job - runAsUser := int64(0) - privileged := true - // NOTE(slaweq): set TTLSecondsAfterFinished=0 will clean done - // configuration job automatically right after it will be finished - jobTTLAfterFinished := int32(0) - - ovnPods, err := getOVNControllerPods( - ctx, - k8sClient, - instance, - ) - if err != nil { - return nil, err - } - - internalEndpoint, err := sbCluster.GetInternalEndpoint() - if err != nil { - return nil, err - } - - envVars := map[string]env.Setter{} - envVars["OvnBridge"] = env.SetValue(instance.Spec.ExternalIDS.OvnBridge) - envVars["OvnRemote"] = env.SetValue(internalEndpoint) - envVars["OvnEncapType"] = env.SetValue(instance.Spec.ExternalIDS.OvnEncapType) - envVars["EnableChassisAsGateway"] = env.SetValue(fmt.Sprintf("%t", instance.Spec.ExternalIDS.EnableChassisAsGateway)) - envVars["PhysicalNetworks"] = env.SetValue(getPhysicalNetworks(instance)) - envVars["OvnHostName"] = EnvDownwardAPI("spec.nodeName") - - for _, ovnPod := range ovnPods.Items { - jobs = append( - jobs, - &batchv1.Job{ - ObjectMeta: metav1.ObjectMeta{ - Name: ovnPod.Name + "-config", - Namespace: instance.Namespace, - Labels: labels, - }, - Spec: batchv1.JobSpec{ - TTLSecondsAfterFinished: &jobTTLAfterFinished, - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyOnFailure, - ServiceAccountName: instance.RbacResourceName(), - Containers: []corev1.Container{ - { - Name: "ovn-config", - Image: instance.Spec.OvnContainerImage, - Command: []string{ - "/usr/local/bin/container-scripts/init.sh", - }, - Args: []string{}, - SecurityContext: &corev1.SecurityContext{ - RunAsUser: &runAsUser, - Privileged: &privileged, - }, - Env: env.MergeEnvs([]corev1.EnvVar{}, envVars), - VolumeMounts: GetOvnControllerVolumeMounts(), - Resources: instance.Spec.Resources, - }, - }, - Volumes: GetVolumes(instance.Name, instance.Namespace), - NodeName: ovnPod.Spec.NodeName, - }, - }, - }, - }, - ) - } - - return jobs, nil -} diff --git a/pkg/ovncontroller/daemonset.go b/pkg/ovncontroller/daemonset.go index ac89981a..ae3b3f3f 100644 --- a/pkg/ovncontroller/daemonset.go +++ b/pkg/ovncontroller/daemonset.go @@ -13,6 +13,8 @@ limitations under the License. package ovncontroller import ( + "fmt" + "github.com/openstack-k8s-operators/lib-common/modules/common" "github.com/openstack-k8s-operators/lib-common/modules/common/env" "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" @@ -25,6 +27,7 @@ import ( // DaemonSet func func DaemonSet( instance *v1beta1.OVNController, + sbCluster *v1beta1.OVNDBCluster, configHash string, labels map[string]string, annotations map[string]string, @@ -123,7 +126,7 @@ func DaemonSet( } ovnControllerArgs = []string{ - "/usr/local/bin/container-scripts/net_setup.sh && ovn-controller --pidfile unix:/run/openvswitch/db.sock", + "/usr/local/bin/container-scripts/init.sh && /usr/local/bin/container-scripts/net_setup.sh && ovn-controller --pidfile unix:/run/openvswitch/db.sock", } // sleep is required as workaround for https://github.com/kubernetes/kubernetes/issues/39170 ovnControllerPreStopCmd = []string{ @@ -131,8 +134,20 @@ func DaemonSet( } } + internalEndpoint, err := sbCluster.GetInternalEndpoint() + if err != nil { + return nil, err + } + envVars := map[string]env.Setter{} envVars["CONFIG_HASH"] = env.SetValue(configHash) + envVars["OVN_RUNDIR"] = env.SetValue("/tmp") + envVars["OvnBridge"] = env.SetValue(instance.Spec.ExternalIDS.OvnBridge) + envVars["OvnRemote"] = env.SetValue(internalEndpoint) + envVars["OvnEncapType"] = env.SetValue(instance.Spec.ExternalIDS.OvnEncapType) + envVars["EnableChassisAsGateway"] = env.SetValue(fmt.Sprintf("%t", instance.Spec.ExternalIDS.EnableChassisAsGateway)) + envVars["PhysicalNetworks"] = env.SetValue(getPhysicalNetworks(instance)) + envVars["OvnHostName"] = EnvDownwardAPI("spec.nodeName") daemonset := &appsv1.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/ovncontroller/volumes.go b/pkg/ovncontroller/volumes.go index 0b576799..f94eb782 100644 --- a/pkg/ovncontroller/volumes.go +++ b/pkg/ovncontroller/volumes.go @@ -2,6 +2,7 @@ package ovncontroller import ( "fmt" + corev1 "k8s.io/api/core/v1" ) @@ -13,22 +14,6 @@ func GetVolumes(name string, namespace string) []corev1.Volume { //source_type := corev1.HostPathDirectoryOrCreate return []corev1.Volume{ - { - Name: "etc-machine-id", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: "/etc/machine-id", - }, - }, - }, - { - Name: "etc-localtime", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: "/etc/localtime", - }, - }, - }, { Name: "etc-ovs", VolumeSource: corev1.VolumeSource{ @@ -41,46 +26,7 @@ func GetVolumes(name string, namespace string) []corev1.Volume { { Name: "var-run", VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: fmt.Sprintf("/var/home/core/%s/var/run/openvswitch", namespace), - Type: &directoryOrCreate, - }, - }, - }, - { - Name: "var-log", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: fmt.Sprintf("/var/home/core/%s/var/log/openvswitch", namespace), - Type: &directoryOrCreate, - }, - }, - }, - { - Name: "var-lib", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: fmt.Sprintf("/var/home/core/%s/var/lib/openvswitch", namespace), - Type: &directoryOrCreate, - }, - }, - }, - { - Name: "var-run-ovn", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: fmt.Sprintf("/var/home/core/%s/var/run/ovn", namespace), - Type: &directoryOrCreate, - }, - }, - }, - { - Name: "var-log-ovn", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: fmt.Sprintf("/var/home/core/%s/var/log/ovn", namespace), - Type: &directoryOrCreate, - }, + EmptyDir: &corev1.EmptyDirVolumeSource{}, }, }, { @@ -101,16 +47,6 @@ func GetVolumes(name string, namespace string) []corev1.Volume { // GetOvsDbVolumeMounts - ovsdb-server VolumeMounts func GetOvsDbVolumeMounts() []corev1.VolumeMount { return []corev1.VolumeMount{ - { - Name: "etc-machine-id", - MountPath: "/etc/machine-id", - ReadOnly: true, - }, - { - Name: "etc-localtime", - MountPath: "/etc/localtime", - ReadOnly: true, - }, { Name: "etc-ovs", MountPath: "/etc/openvswitch", @@ -121,16 +57,6 @@ func GetOvsDbVolumeMounts() []corev1.VolumeMount { MountPath: "/var/run/openvswitch", ReadOnly: false, }, - { - Name: "var-log", - MountPath: "/var/log/openvswitch", - ReadOnly: false, - }, - { - Name: "var-lib", - MountPath: "/var/lib/openvswitch", - ReadOnly: false, - }, { Name: "scripts", MountPath: "/usr/local/bin/container-scripts", @@ -142,62 +68,22 @@ func GetOvsDbVolumeMounts() []corev1.VolumeMount { // GetVswitchdVolumeMounts - ovs-vswitchd VolumeMounts func GetVswitchdVolumeMounts() []corev1.VolumeMount { return []corev1.VolumeMount{ - { - Name: "etc-machine-id", - MountPath: "/etc/machine-id", - ReadOnly: true, - }, - { - Name: "etc-localtime", - MountPath: "/etc/localtime", - ReadOnly: true, - }, { Name: "var-run", MountPath: "/var/run/openvswitch", ReadOnly: false, }, - { - Name: "var-log", - MountPath: "/var/log/openvswitch", - ReadOnly: false, - }, - { - Name: "var-lib", - MountPath: "/var/lib/openvswitch", - ReadOnly: false, - }, } } // GetOvnControllerVolumeMounts - ovn-controller VolumeMounts func GetOvnControllerVolumeMounts() []corev1.VolumeMount { return []corev1.VolumeMount{ - { - Name: "etc-machine-id", - MountPath: "/etc/machine-id", - ReadOnly: true, - }, - { - Name: "etc-localtime", - MountPath: "/etc/localtime", - ReadOnly: true, - }, { Name: "var-run", MountPath: "/var/run/openvswitch", ReadOnly: false, }, - { - Name: "var-run-ovn", - MountPath: "/var/run/ovn", - ReadOnly: false, - }, - { - Name: "var-log-ovn", - MountPath: "/var/log/ovn", - ReadOnly: false, - }, { Name: "scripts", MountPath: "/usr/local/bin/container-scripts", diff --git a/tests/functional/ovncontroller_controller_test.go b/tests/functional/ovncontroller_controller_test.go index 8f29e5de..27219db3 100644 --- a/tests/functional/ovncontroller_controller_test.go +++ b/tests/functional/ovncontroller_controller_test.go @@ -25,7 +25,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" - batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -91,18 +90,6 @@ var _ = Describe("OVNController controller", func() { th.AssertConfigMapDoesNotExist(externalCM) }) - It("should not create a config job", func() { - daemonSetName := types.NamespacedName{ - Namespace: namespace, - Name: "ovn-controller", - } - configJob := types.NamespacedName{ - Namespace: OVNControllerName.Namespace, - Name: daemonSetName.Name + "-config", - } - th.AssertJobDoesNotExist(configJob) - }) - // TODO(ihar) introduce a new condition for the external config? It("should be in input ready condition", func() { th.ExpectCondition( @@ -130,24 +117,6 @@ var _ = Describe("OVNController controller", func() { } }) - It("should create a config job", func() { - daemonSetName := types.NamespacedName{ - Namespace: namespace, - Name: "ovn-controller", - } - SimulateDaemonsetNumberReadyWithPods( - daemonSetName, - map[string][]string{}, - ) - configJob := types.NamespacedName{ - Namespace: OVNControllerName.Namespace, - Name: daemonSetName.Name + "-config", - } - Eventually(func() batchv1.Job { - return *th.GetJob(configJob) - }, timeout, interval).ShouldNot(BeNil()) - }) - It("should create a ConfigMap for net_setup.sh with eth0 as Interface Name", func() { Eventually(func() corev1.ConfigMap { return *th.GetConfigMap(scriptsCM) @@ -197,16 +166,6 @@ var _ = Describe("OVNController controller", func() { } }) - It("should create a config job", func() { - configJob := types.NamespacedName{ - Namespace: OVNControllerName.Namespace, - Name: daemonSetName.Name + "-config", - } - Eventually(func() batchv1.Job { - return *th.GetJob(configJob) - }, timeout, interval).ShouldNot(BeNil()) - }) - It("should create an external config map", func() { Eventually(func() corev1.ConfigMap { return *th.GetConfigMap(configCM) @@ -286,25 +245,6 @@ var _ = Describe("OVNController controller", func() { DeferCleanup(th.DeleteInstance, instance) }) - It("should create a config job", func() { - daemonSetName := types.NamespacedName{ - Namespace: namespace, - Name: "ovn-controller", - } - - SimulateDaemonsetNumberReadyWithPods( - daemonSetName, - map[string][]string{namespace + "/internalapi": {"10.0.0.1"}}, - ) - configJob := types.NamespacedName{ - Namespace: OVNControllerName.Namespace, - Name: daemonSetName.Name + "-config", - } - Eventually(func() batchv1.Job { - return *th.GetJob(configJob) - }, timeout, interval).ShouldNot(BeNil()) - }) - It("reports that network attachment is missing", func() { daemonSetName := types.NamespacedName{ diff --git a/tests/functional/suite_test.go b/tests/functional/suite_test.go index 2392cce6..2900186d 100644 --- a/tests/functional/suite_test.go +++ b/tests/functional/suite_test.go @@ -40,7 +40,6 @@ import ( networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" test "github.com/openstack-k8s-operators/lib-common/modules/test" @@ -110,8 +109,6 @@ var _ = BeforeSuite(func() { // in the test env. err = ovnv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = batchv1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) err = corev1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = appsv1.AddToScheme(scheme.Scheme)