diff --git a/controllers/clusterversion_controller.go b/controllers/clusterversion_controller.go index 9a40fa4f9..f95eea98e 100644 --- a/controllers/clusterversion_controller.go +++ b/controllers/clusterversion_controller.go @@ -16,6 +16,7 @@ package controllers import ( "bytes" "context" + "strconv" "strings" // The embed package is required for the prometheus rule files @@ -51,7 +52,9 @@ import ( var pvcPrometheusRules string const ( - operatorConfigMapName = "ocs-client-operator-config" + operatorConfigMapName = "ocs-client-operator-config" + csiSidecarConfigMapName = "ceph-csi-sidecar-config" + csiOMAPGeneratorKey = "CSI_ENABLE_OMAP_GENERATOR" // ClusterVersionName is the name of the ClusterVersion object in the // openshift cluster. clusterVersionName = "version" @@ -86,7 +89,7 @@ func (c *ClusterVersionReconciler) SetupWithManager(mgr ctrl.Manager) error { func(client client.Object) bool { namespace := client.GetNamespace() name := client.GetName() - return ((namespace == c.OperatorNamespace) && (name == operatorConfigMapName)) + return namespace == c.OperatorNamespace && (name == operatorConfigMapName || name == csiSidecarConfigMapName) }, ), ) @@ -203,6 +206,25 @@ func (c *ClusterVersionReconciler) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, err } + sideCarConfig := &corev1.ConfigMap{} + sideCarConfig.Name = csiSidecarConfigMapName + sideCarConfig.Namespace = c.OperatorNamespace + + err = c.get(sideCarConfig) + if err != nil && !k8serrors.IsNotFound(err) { + c.log.Error(err, "failed to get csi side car configmap", "name", sideCarConfig) + return ctrl.Result{}, err + } + + enableOMAPGenerator := false + if value, ok := sideCarConfig.Data[csiOMAPGeneratorKey]; ok { + enableOMAPGenerator, err = strconv.ParseBool(value) + if err != nil { + c.log.Error(err, "failed to parse configmap entry", "ConfigMap", sideCarConfig, csiOMAPGeneratorKey, value) + return ctrl.Result{}, err + } + } + c.cephFSDeployment = &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: csi.CephFSDeploymentName, @@ -249,7 +271,7 @@ func (c *ClusterVersionReconciler) Reconcile(ctx context.Context, req ctrl.Reque if err := c.own(c.rbdDeployment); err != nil { return err } - csi.SetRBDDeploymentDesiredState(c.rbdDeployment) + csi.SetRBDDeploymentDesiredState(c.rbdDeployment, enableOMAPGenerator) return nil }) if err != nil { @@ -337,6 +359,10 @@ func (c *ClusterVersionReconciler) create(obj client.Object) error { return c.Client.Create(c.ctx, obj) } +func (c *ClusterVersionReconciler) get(obj client.Object) error { + return c.Client.Get(c.ctx, client.ObjectKeyFromObject(obj), obj) +} + // applyLabels adds labels to object meta, overwriting keys that are already defined. func applyLabels(label string, t *metav1.ObjectMeta) { // Create a map to store the configuration @@ -366,6 +392,15 @@ func (c *ClusterVersionReconciler) getOperatorConfig() (*corev1.ConfigMap, error return cm, nil } +func (c *ClusterVersionReconciler) getSideCarConfig() (*corev1.ConfigMap, error) { + cm := &corev1.ConfigMap{} + err := c.Client.Get(c.ctx, types.NamespacedName{Name: csiSidecarConfigMapName, Namespace: c.OperatorNamespace}, cm) + if err != nil && !k8serrors.IsNotFound(err) { + return nil, err + } + return cm, nil +} + func (c *ClusterVersionReconciler) ensureConsolePlugin() error { c.consoleDeployment = &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ diff --git a/controllers/storageclassclaim_controller.go b/controllers/storageclassclaim_controller.go index a658091e6..d6fba960f 100644 --- a/controllers/storageclassclaim_controller.go +++ b/controllers/storageclassclaim_controller.go @@ -306,6 +306,24 @@ func (r *StorageClassClaimReconciler) reconcilePhases() (reconcile.Result, error return reconcile.Result{}, fmt.Errorf("failed to extract monitor data: %v", err) } csiClusterConfigEntry.Monitors = append(csiClusterConfigEntry.Monitors, monitorIps...) + } else if eResource.Kind == "ConfigMap" && eResource.Name == csiSidecarConfigMapName { + csiSideCarConfig := &corev1.ConfigMap{} + csiSideCarConfig.Name = eResource.Name + csiSideCarConfig.Namespace = r.OperatorNamespace + + data := map[string]string{} + err = json.Unmarshal(eResource.Data, &data) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to unmarshal csi-sidecar-config configuration response: %v", err) + } + + _, err := controllerutil.CreateOrUpdate(r.ctx, r.Client, csiSideCarConfig, func() error { + csiSideCarConfig.Data = data + return nil + }) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to create or update configMap %v: %s", csiSideCarConfig, err) + } } } // Go over the received objects and operate on them accordingly. diff --git a/pkg/csi/rbddeployment.go b/pkg/csi/rbddeployment.go index 821834cae..0b1982129 100644 --- a/pkg/csi/rbddeployment.go +++ b/pkg/csi/rbddeployment.go @@ -105,11 +105,11 @@ var rbdDeploymentSpec = appsv1.DeploymentSpec{ }, { Name: "ceph-csi-configs", - MountPath: "/etc/ceph-csi-config", + MountPath: templates.DefaultCephCSIConfigPath, }, { Name: "keys-tmp-dir", - MountPath: "/tmp/csi/keys", + MountPath: templates.DefaultTmpDir, }, { Name: "ceph-csi-kms-config", @@ -214,7 +214,7 @@ var rbdDeploymentSpec = appsv1.DeploymentSpec{ }, } -func SetRBDDeploymentDesiredState(deploy *appsv1.Deployment) { +func SetRBDDeploymentDesiredState(deploy *appsv1.Deployment, enableOMAPGenerator bool) { // Copy required labels for key := range rbdDaemonsetLabels { deploy.Labels[key] = cephfsDaemonsetLabels[key] @@ -223,6 +223,12 @@ func SetRBDDeploymentDesiredState(deploy *appsv1.Deployment) { // Update the deployment set with desired spec rbdDeploymentSpec.DeepCopyInto(&deploy.Spec) + if enableOMAPGenerator { + deploy.Spec.Template.Spec.Containers = append( + deploy.Spec.Template.Spec.Containers, + corev1.Container{Name: templates.OMAPGeneratorContainer.Name}) + } + // Find and Update placeholder containers with desired state leaderElectionArg := fmt.Sprintf("--leader-election-namespace=%s", deploy.Namespace) @@ -255,6 +261,11 @@ func SetRBDDeploymentDesiredState(deploy *appsv1.Deployment) { c.Image = sidecarImages.ContainerImages.CSIADDONSImageURL c.Args = append(c.Args, leaderElectionArg) + case templates.OMAPGeneratorContainer.Name: + templates.OMAPGeneratorContainer.DeepCopyInto(c) + c.Image = sidecarImages.ContainerImages.CephCSIImageURL + c.Args = append(c.Args, fmt.Sprintf("--drivername=%s", GetRBDDriverName())) + case rbdDeploymentContainerName: c.Image = sidecarImages.ContainerImages.CephCSIImageURL } diff --git a/pkg/templates/csisidecars.go b/pkg/templates/csisidecars.go index 2250a0e39..89789ba94 100644 --- a/pkg/templates/csisidecars.go +++ b/pkg/templates/csisidecars.go @@ -162,6 +162,36 @@ var CSIAddonsContainer = corev1.Container{ ImagePullPolicy: corev1.PullIfNotPresent, } +var OMAPGeneratorContainer = corev1.Container{ + Name: "csi-omap-generator", + ImagePullPolicy: corev1.PullIfNotPresent, + Args: []string{ + "--type=controller", + "--drivernamespace=$(DRIVER_NAMESPACE)", + "--v=5", + }, + Env: []corev1.EnvVar{ + { + Name: "DRIVER_NAMESPACE", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.namespace", + }, + }, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "ceph-csi-configs", + MountPath: DefaultCephCSIConfigPath, + }, + { + Name: "keys-tmp-dir", + MountPath: DefaultTmpDir, + }, + }, +} + var DriverRegistrar = corev1.Container{ Name: "csi-driver-registrar", ImagePullPolicy: corev1.PullIfNotPresent, diff --git a/pkg/templates/defaults.go b/pkg/templates/defaults.go index ccfbce7c7..9f5609eef 100644 --- a/pkg/templates/defaults.go +++ b/pkg/templates/defaults.go @@ -24,7 +24,8 @@ const ( DefaultCSIAddonsSocketPath = "unix:///csi/csi-addons.sock" DefaultSocketDir = "/csi" DefaultStagingPath = "/var/lib/kubelet/plugins/kubernetes.io/csi/" - + DefaultCephCSIConfigPath = "/etc/ceph-csi-config" + DefaultTmpDir = "/tmp/csi/keys" // configmap names MonConfigMapName = "ceph-csi-configs" EncryptionConfigMapName = "ceph-csi-kms-config"