diff --git a/charts/gardener-extension-csi-driver-lvm/templates/deployment.yaml b/charts/gardener-extension-csi-driver-lvm/templates/deployment.yaml index 96b1e45..e821a9d 100644 --- a/charts/gardener-extension-csi-driver-lvm/templates/deployment.yaml +++ b/charts/gardener-extension-csi-driver-lvm/templates/deployment.yaml @@ -20,10 +20,7 @@ spec: checksum/configmap-{{ include "name" . }}-config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} labels: networking.gardener.cloud/to-runtime-apiserver: allowed - networking.gardener.cloud/to-dns: allowed - networking.gardener.cloud/to-public-networks: allowed networking.gardener.cloud/to-private-networks: allowed - networking.resources.gardener.cloud/to-all-shoots-kube-apiserver-tcp-443: allowed {{ include "labels" . | indent 8 }} spec: containers: @@ -49,12 +46,6 @@ spec: - --log-level={{ .Values.logLevel | default "info" }} - --log-format={{ .Values.logFormat | default "json" }} env: - - name: BACKEND_SECRET_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: BACKEND_SECRET_PREFIX - value: default-backend-secret- - name: LEADER_ELECTION_NAMESPACE valueFrom: fieldRef: diff --git a/charts/gardener-extension-csi-driver-lvm/templates/poddisruptionbudget.yaml b/charts/gardener-extension-csi-driver-lvm/templates/poddisruptionbudget.yaml index 6a135cc..0e757eb 100644 --- a/charts/gardener-extension-csi-driver-lvm/templates/poddisruptionbudget.yaml +++ b/charts/gardener-extension-csi-driver-lvm/templates/poddisruptionbudget.yaml @@ -1,5 +1,5 @@ {{- if gt (int .Values.replicaCount) 1 }} -apiVersion: policy/v1beta1 +apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: {{ include "name" . }} diff --git a/charts/gardener-extension-csi-driver-lvm/values.yaml b/charts/gardener-extension-csi-driver-lvm/values.yaml index d9cce6e..5d0f219 100644 --- a/charts/gardener-extension-csi-driver-lvm/values.yaml +++ b/charts/gardener-extension-csi-driver-lvm/values.yaml @@ -37,7 +37,7 @@ config: qps: 100 burst: 130 - devicePattern: /dev/loop10[0,1] + devicePattern: /dev/nvme[0-1]n[0-9] hostWritePath: /etc/lvm gardener: diff --git a/cmd/gardener-extension-csi-driver-lvm/app/options.go b/cmd/gardener-extension-csi-driver-lvm/app/options.go index 60f82c3..e5a34b2 100644 --- a/cmd/gardener-extension-csi-driver-lvm/app/options.go +++ b/cmd/gardener-extension-csi-driver-lvm/app/options.go @@ -115,22 +115,19 @@ func (options *Options) run(ctx context.Context) error { if err != nil { return fmt.Errorf("could not instantiate controller-manager: %w", err) } - log.Info("completed rest-options") err = extensionscontroller.AddToScheme(mgr.GetScheme()) if err != nil { return fmt.Errorf("could not add mgr-scheme to extension-controller: %w", err) } - log.Info("added mgr-scheme to extensionscontroller") err = install.AddToScheme(mgr.GetScheme()) if err != nil { return fmt.Errorf("could not add mgr-scheme to installation") } - - log.Info("added mgr-schme to installation") + log.Info("added mgr-scheme to installation") ctrlConfig := options.csidriverlvmOptions.Completed() ctrlConfig.Apply(&controller.DefaultAddOptions.Config) @@ -142,24 +139,21 @@ func (options *Options) run(ctx context.Context) error { if err := options.controllerSwitches.Completed().AddToManager(ctx, mgr); err != nil { return fmt.Errorf("could not add controllers to manager: %w", err) } + log.Info("added controllers to manager") if err := mgr.AddReadyzCheck("informer-sync", ghealth.NewCacheSyncHealthz(mgr.GetCache())); err != nil { return fmt.Errorf("could not add ready check for informers: %w", err) } - log.Info("added readyzcheck") if err := mgr.AddHealthzCheck("ping", healthz.Ping); err != nil { return fmt.Errorf("could not add health check to manager: %w", err) } - log.Info("added healthzcheck") if err := mgr.Start(ctx); err != nil { return fmt.Errorf("error running manager: %w", err) } - log.Info("started successfully") - return nil } diff --git a/docs/migration.md b/docs/migration.md index d92f397..2ed4beb 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -32,7 +32,7 @@ The migration solution so far has been tested manually: 5. install new controller & provisioner with helm 6. add additional storage class with name `csi-lvm` and type linear 1. mimics old storage class - 2. default storage class + 2. default storage class (not supported yet -> see default storage class of `gardener-extension-provider-metal`) 7. create new pvcs 8. create new pod with old and new pvcs and test @@ -41,4 +41,4 @@ The migration solution so far has been tested manually: To achieve this behaviour for csi-lvm, provided by [gardener-extension-provider-metal](https://github.com/metal-stack/gardener-extension-provider-metal/tree/master), we need to add the following workflow: 1. Add a feature gate to `gardener-extension-provider-metal` to disable csi-lvm. -2. When deploying `gardener-extension-csi-driver-lvm`, stop reconciliation if old provisioner is still available. \ No newline at end of file +2. When deploying `gardener-extension-csi-driver-lvm`, stop reconciliation if old provisioner is still available. diff --git a/example/controller-registration.yaml b/example/controller-registration.yaml index 1b58a3f..e276a8f 100644 --- a/example/controller-registration.yaml +++ b/example/controller-registration.yaml @@ -4,7 +4,7 @@ kind: ControllerDeployment metadata: name: csi-driver-lvm helm: - rawChart: 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 + rawChart: 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 values: image: tag: v0.0.1 diff --git a/go.mod b/go.mod index 1dcc3cc..47d55e7 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/onsi/ginkgo v1.16.5 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.9.0 k8s.io/api v0.31.1 k8s.io/apimachinery v0.31.1 k8s.io/code-generator v0.31.1 @@ -77,12 +78,14 @@ require ( github.com/nxadm/tail v1.4.8 // indirect github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect diff --git a/go.sum b/go.sum index 7ca464b..047855c 100644 --- a/go.sum +++ b/go.sum @@ -1058,6 +1058,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= diff --git a/pkg/apis/csidriverlvm/types.go b/pkg/apis/csidriverlvm/types.go index e9e0ccb..bd61f46 100644 --- a/pkg/apis/csidriverlvm/types.go +++ b/pkg/apis/csidriverlvm/types.go @@ -10,6 +10,9 @@ import ( type CsiDriverLvmConfig struct { metav1.TypeMeta + // DevicePattern can be used to configure the glob pattern for the devices used by the LVM driver DevicePattern *string + + // HostWritePath can be used to configure the host write path - used on read-only filesystems (Talos OS "/var/etc/lvm") HostWritePath *string } diff --git a/pkg/apis/csidriverlvm/v1alpha1/types.go b/pkg/apis/csidriverlvm/v1alpha1/types.go index 47cfe76..ebe7cc7 100644 --- a/pkg/apis/csidriverlvm/v1alpha1/types.go +++ b/pkg/apis/csidriverlvm/v1alpha1/types.go @@ -1,8 +1,9 @@ package v1alpha1 import ( - "regexp" + "path/filepath" + "github.com/go-logr/logr" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -16,7 +17,12 @@ const ( type CsiDriverLvmConfig struct { metav1.TypeMeta `json:",inline"` + // DevicePattern can be used to configure the glob pattern for the devices used by the LVM driver + // +optional DevicePattern *string `json:"devicePattern,omitempty"` + + // HostWritePath can be used to configure the host write path - used on read-only filesystems (Talos OS "/var/etc/lvm") + // +optional HostWritePath *string `json:"hostWritePath,omitempty"` } @@ -29,13 +35,29 @@ func (config *CsiDriverLvmConfig) ConfigureDefaults(hostWritePath *string, devic } } -func (config *CsiDriverLvmConfig) IsValid() bool { - re := regexp.MustCompile(`^(/[^/ ]*)+/?$`) - +func (config *CsiDriverLvmConfig) IsValid(log logr.Logger) bool { if (config.HostWritePath == nil) || (config.DevicePattern == nil) { - println("HostWritePath or DevicePattern is nil", config.HostWritePath, config.DevicePattern) + log.Info("hostWritePath or devicePattern is nil", config.HostWritePath, config.DevicePattern) + return false + } + + if *config.HostWritePath == "" || *config.DevicePattern == "" { + log.Info("hostWritePath or devicePattern is empty", config.HostWritePath, config.DevicePattern) + return false + } + + //glob pattern validation could be problematic -> go glob interpretation can be different from bash + _, err := filepath.Match(*config.DevicePattern, "") + if err != nil { + log.Info("bad device pattern") + return false + } + + hasValidHostWritePath := filepath.IsAbs(*config.HostWritePath) + if !hasValidHostWritePath { + log.Info("hostWritePath is not absolute") return false } - return re.MatchString(*config.HostWritePath) && re.MatchString(*config.DevicePattern) + return true } diff --git a/pkg/apis/csidriverlvm/v1alpha1/types_test.go b/pkg/apis/csidriverlvm/v1alpha1/types_test.go new file mode 100644 index 0000000..d983ff7 --- /dev/null +++ b/pkg/apis/csidriverlvm/v1alpha1/types_test.go @@ -0,0 +1,112 @@ +package v1alpha1 + +import ( + "testing" + + "github.com/go-logr/logr" + "github.com/stretchr/testify/assert" +) + +var log = logr.New(logr.Discard().GetSink()) + +func stringPtr(s string) *string { + return &s +} + +func TestConfig(t *testing.T) { + + tt := []struct { + desc string + customData *CsiDriverLvmConfig + valid bool + }{ + { + desc: "test nil config", + customData: &CsiDriverLvmConfig{ + DevicePattern: nil, + HostWritePath: nil, + }, + valid: false, + }, + { + desc: "test devicePattern nil config", + customData: &CsiDriverLvmConfig{ + DevicePattern: nil, + HostWritePath: stringPtr("/etc/lvm"), + }, + valid: false, + }, + { + desc: "test hostWritePath nil config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr("/dev/loop100"), + HostWritePath: nil, + }, + valid: false, + }, + { + desc: "test empty config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr(""), + HostWritePath: stringPtr(""), + }, + valid: false, + }, + { + desc: "test empty devicePattern config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr(""), + HostWritePath: stringPtr("/etc/lvm"), + }, + valid: false, + }, + { + desc: "test empty hostWritePath config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr("/dev/loop1"), + HostWritePath: stringPtr(""), + }, + valid: false, + }, + { + desc: "test invalid devicePattern config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr("[a-"), + HostWritePath: stringPtr("/etc/lvm"), + }, + valid: false, + }, + { + desc: "test not absolute hostWritePath config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr("[a-z]"), + HostWritePath: stringPtr("./etc/lvm"), + }, + valid: false, + }, + { + desc: "test not absolute hostWritePath config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr("[a-z]"), + HostWritePath: stringPtr("etc/lvm"), + }, + valid: false, + }, + { + desc: "test valid config", + customData: &CsiDriverLvmConfig{ + DevicePattern: stringPtr("/dev/loop10[0,1]"), + HostWritePath: stringPtr("/etc/lvm"), + }, + valid: true, + }, + } + + for _, tc := range tt { + t.Run(tc.desc, func(t *testing.T) { + println(tc.desc) + isConfigValid := tc.customData.IsValid(log) + assert.Equal(t, tc.valid, isConfigValid) + }) + } +} diff --git a/pkg/controller/csi-driver-lvm/actuator.go b/pkg/controller/csi-driver-lvm/actuator.go index 525d0d0..2305f51 100644 --- a/pkg/controller/csi-driver-lvm/actuator.go +++ b/pkg/controller/csi-driver-lvm/actuator.go @@ -34,12 +34,14 @@ import ( ) const ( - namespace string = "kube-system" - provisioner string = "lvm.csi.metal-stack.io" + shootNamespace string = "kube-system" + provisioner string = "lvm.csi.metal-stack.io" oldName string = "csi-lvm" oldNamespace string = "csi-lvm" oldProvisioner string = "metal-stack.io/csi-lvm" + + pullPolicy string = "IfNotPresent" ) // NewActuator returns an actuator responsible for Extension resources. @@ -68,7 +70,7 @@ func (a *actuator) Reconcile(ctx context.Context, log logr.Logger, ex *extension } csidriverlvmConfig.ConfigureDefaults(a.config.DefaultHostWritePath, a.config.DefaultDevicePattern) - if !csidriverlvmConfig.IsValid() { + if !csidriverlvmConfig.IsValid(log) { return fmt.Errorf("invalid csi-driver-lvm configuration") } @@ -81,12 +83,12 @@ func (a *actuator) Reconcile(ctx context.Context, log logr.Logger, ex *extension return nil } - controllerObjects, err := a.controllerObjects(namespace) + controllerObjects, err := a.controllerObjects() if err != nil { return err } - pluginObjects, err := a.pluginObjects(namespace, csidriverlvmConfig) + pluginObjects, err := a.pluginObjects(csidriverlvmConfig) if err != nil { return err } @@ -149,19 +151,19 @@ func (a *actuator) Migrate(ctx context.Context, log logr.Logger, ex *extensionsv return nil } -func (a *actuator) controllerObjects(namespace string) ([]client.Object, error) { +func (a *actuator) controllerObjects() ([]client.Object, error) { csidriverlvmServiceAccountController := &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-controller", - Namespace: namespace, + Namespace: shootNamespace, }, } csidriverlvmClusterRoleController := &rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-controller", - Namespace: namespace, + Namespace: shootNamespace, }, Rules: []rbacv1.PolicyRule{ { @@ -220,13 +222,13 @@ func (a *actuator) controllerObjects(namespace string) ([]client.Object, error) csidriverlvmClusterRoleBindingController := &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-controller", - Namespace: namespace, + Namespace: shootNamespace, }, Subjects: []rbacv1.Subject{ { Kind: "ServiceAccount", Name: "csi-driver-lvm-controller", - Namespace: namespace, + Namespace: shootNamespace, }, }, RoleRef: rbacv1.RoleRef{ @@ -256,7 +258,7 @@ func (a *actuator) controllerObjects(namespace string) ([]client.Object, error) csidriverlvmStatefulsetController := &appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-controller", - Namespace: namespace, + Namespace: shootNamespace, Annotations: map[string]string{}, Labels: map[string]string{}, }, @@ -294,14 +296,12 @@ func (a *actuator) controllerObjects(namespace string) ([]client.Object, error) }, }, }, - NodeSelector: map[string]string{}, - Tolerations: []corev1.Toleration{}, ServiceAccountName: "csi-driver-lvm-controller", Containers: []corev1.Container{ { Name: "csi-attacher", Image: csiAttacherImage.String(), - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "pullPolicy", Args: []string{"--v=5", "--csi-address=/csi/csi.sock"}, SecurityContext: &corev1.SecurityContext{ ReadOnlyRootFilesystem: pointer.Pointer(true), @@ -314,7 +314,7 @@ func (a *actuator) controllerObjects(namespace string) ([]client.Object, error) { Name: "csi-provisioner", Image: csiProvisionerImage.String(), - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "pullPolicy", Args: []string{"--v=5", "--csi-address=/csi/csi.sock", "--feature-gates=Topology=true"}, SecurityContext: &corev1.SecurityContext{ ReadOnlyRootFilesystem: pointer.Pointer(true), @@ -327,7 +327,7 @@ func (a *actuator) controllerObjects(namespace string) ([]client.Object, error) { Name: "csi-resizer", Image: csiResizerImage.String(), - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "pullPolicy", Args: []string{"--v=5", "--csi-address=/csi/csi.sock"}, SecurityContext: &corev1.SecurityContext{ ReadOnlyRootFilesystem: pointer.Pointer(true), @@ -364,12 +364,12 @@ func (a *actuator) controllerObjects(namespace string) ([]client.Object, error) return objects, nil } -func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1.CsiDriverLvmConfig) ([]client.Object, error) { +func (a *actuator) pluginObjects(csidriverlvmConfig *v1alpha1.CsiDriverLvmConfig) ([]client.Object, error) { csidriverlvmDriver := &storagev1.CSIDriver{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm", - Namespace: namespace, + Namespace: shootNamespace, }, Spec: storagev1.CSIDriverSpec{ VolumeLifecycleModes: []storagev1.VolumeLifecycleMode{"Persistent", "Ephemeral"}, @@ -381,14 +381,14 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. csidriverlvmServiceAccountPlugin := &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-plugin", - Namespace: namespace, + Namespace: shootNamespace, }, } csidriverlvmClusterRolePlugin := &rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-plugin", - Namespace: namespace, + Namespace: shootNamespace, }, Rules: []rbacv1.PolicyRule{ { @@ -427,13 +427,13 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. csidriverlvmClusterRoleBindingPlugin := &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-plugin", - Namespace: namespace, + Namespace: shootNamespace, }, Subjects: []rbacv1.Subject{ { Kind: "ServiceAccount", Name: "csi-driver-lvm-plugin", - Namespace: namespace, + Namespace: shootNamespace, }, }, RoleRef: rbacv1.RoleRef{ @@ -518,7 +518,7 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. return nil, fmt.Errorf("failed to find csi-driver-lvm-provisioner image: %w", err) } - // var terminationPolicy corev1.TerminationMessagePolicy = corev1.TerminationMessageReadFile + var terminationPolicy corev1.TerminationMessagePolicy = corev1.TerminationMessageReadFile var mountPropagation corev1.MountPropagationMode = corev1.MountPropagationBidirectional var hostPathTypeCreate corev1.HostPathType = corev1.HostPathDirectoryOrCreate @@ -527,7 +527,7 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. csidriverlvmDaemonSetPlugin := &appsv1.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ Name: "csi-driver-lvm-plugin", - Namespace: namespace, + Namespace: shootNamespace, }, Spec: appsv1.DaemonSetSpec{ RevisionHistoryLimit: ptr.To(int32(10)), @@ -543,17 +543,15 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. }, }, Spec: corev1.PodSpec{ ServiceAccountName: "csi-driver-lvm-plugin", - Tolerations: []corev1.Toleration{}, - NodeSelector: map[string]string{}, Containers: []corev1.Container{ { Name: "csi-node-driver-registrar", Image: csiNodeDriverRegistrarImage.String(), - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "pullPolicy", Args: []string{"--v=5", "--csi-address=/csi/csi.sock", "--kubelet-registration-path=/var/lib/kubelet/plugins/csi-driver-lvm/csi.sock"}, SecurityContext: &corev1.SecurityContext{ ReadOnlyRootFilesystem: pointer.Pointer(false), - // Privileged: pointer.Pointer(true), + Privileged: pointer.Pointer(true), }, Env: []corev1.EnvVar{ { @@ -566,8 +564,8 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. }, }, }, - // TerminationMessagePath: "/dev/termination-log", - // TerminationMessagePolicy: terminationPolicy, + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: terminationPolicy, VolumeMounts: []corev1.VolumeMount{ {MountPath: "/csi", Name: "socket-dir"}, {MountPath: "/var/lib/kubelet/plugins/csi-driver-lvm/csi.sock", Name: "socket-dir"}, @@ -577,7 +575,7 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. { Name: "csi-driver-lvm-plugin", Image: csiDriverLvmImage.String(), - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "pullPolicy", Args: []string{ "--drivername=lvm.csi.metal-stack.io", "--endpoint=unix:///csi/csi.sock", @@ -587,7 +585,7 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. "--vgname=csi-lvm", "--namespace=kube-system", "--provisionerimage=" + csiDriverLvmProvisionerImage.String(), - "--pullpolicy=IfNotPresent", + "--pullpolicy=pullPolicy", }, SecurityContext: &corev1.SecurityContext{ ReadOnlyRootFilesystem: pointer.Pointer(false), @@ -623,8 +621,8 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. Protocol: corev1.ProtocolTCP, ContainerPort: 9898, }}, - // TerminationMessagePath: "/dev/termination-log", - // TerminationMessagePolicy: terminationPolicy, + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: terminationPolicy, VolumeMounts: []corev1.VolumeMount{ {MountPath: "/csi", Name: "socket-dir"}, {MountPath: "/var/lib/kubelet/pods", Name: "mountpoint-dir", MountPropagation: &mountPropagation}, @@ -640,7 +638,7 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. { Name: "livenessprobe", Image: livenessprobeImage.String(), - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "pullPolicy", Args: []string{ "--csi-address=/csi/csi.sock", "--health-port=9898", @@ -648,8 +646,8 @@ func (a *actuator) pluginObjects(namespace string, csidriverlvmConfig *v1alpha1. SecurityContext: &corev1.SecurityContext{ ReadOnlyRootFilesystem: pointer.Pointer(true), }, - // TerminationMessagePath: "/dev/termination-log", - // TerminationMessagePolicy: terminationPolicy, + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: terminationPolicy, VolumeMounts: []corev1.VolumeMount{ {MountPath: "/csi", Name: "socket-dir"}, }, @@ -778,7 +776,6 @@ func (a *actuator) isOldCsiLvmExisting(ctx context.Context, shootNamespace strin Name: oldNamespace, }, } - err = shootClient.Get(ctx, client.ObjectKeyFromObject(namespace), namespace) if err == nil { @@ -787,21 +784,16 @@ func (a *actuator) isOldCsiLvmExisting(ctx context.Context, shootNamespace strin return true, fmt.Errorf("error while getting old csi-lvm namespace: %w", err) } - storageClass := &storagev1.StorageClass{ - ObjectMeta: metav1.ObjectMeta{ - Name: oldName, - }, + storageClassList := &storagev1.StorageClassList{} + err = shootClient.List(ctx, storageClassList) + if err != nil { + return false, fmt.Errorf("failed to list storage classes: %w", err) } - err = shootClient.Get(ctx, client.ObjectKeyFromObject(storageClass), storageClass, &client.GetOptions{}) - if err == nil { - if storageClass.Provisioner == provisioner { - return false, nil - } else { + for _, sc := range storageClassList.Items { + if sc.Provisioner == oldProvisioner { return true, nil } - } else if !apierrors.IsNotFound(err) { - return true, fmt.Errorf("error while getting old csi-lvm storageclass: %w", err) } return false, nil }