From 0490d68bb5ddb11a6c37a9f2506c395f0bdd4d13 Mon Sep 17 00:00:00 2001 From: Valentin Daviot Date: Tue, 17 Mar 2026 15:17:39 +0100 Subject: [PATCH 1/3] reapplied change above rebase Signed-off-by: Valentin Daviot --- cmd/main.go | 11 ++++++++++ config/manager/manager.yaml | 24 ++++++++++++++++++++-- go.mod | 16 +++++++-------- go.sum | 27 ++++++++++++------------- pkg/infrastructure/di/command_runner.go | 8 ++++---- pkg/infrastructure/di/container.go | 18 +++++++++++++---- 6 files changed, 71 insertions(+), 33 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index b3f6a13..cd6c4f2 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -57,6 +57,14 @@ var ( setupLog = ctrl.Log.WithName("setup") ) +func getEnvOrDefault(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + + return defaultValue +} + func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) @@ -222,6 +230,9 @@ func main() { mgr.GetClient(), nodeName, podNamespace, + getEnvOrDefault("STORCLI_PATH", "/host/libexec/MegaRAID/storcli/storcli64"), + getEnvOrDefault("PERCCLI_PATH", "/host/libexec/MegaRAID/perccli/perccli64"), + getEnvOrDefault("SSACLI_PATH", "/host/libexec/ssacli"), ) discoverUseCase := container.GetDiscoverPhysicalDrivesUseCase() reconcileUseCase := container.GetReconcileDiscoveredPhysicalDiskUseCase() diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 8006b3d..01cc106 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -76,6 +76,12 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: STORCLI_PATH + value: "/host/libexec/MegaRAID/storcli/storcli64" + - name: PERCCLI_PATH + value: "/host/libexec/MegaRAID/perccli/perccli64" + - name: SSACLI_PATH + value: "/host/libexec/ssacli" ports: [] securityContext: allowPrivilegeEscalation: false @@ -103,7 +109,21 @@ spec: requests: cpu: 10m memory: 64Mi - volumeMounts: [] - volumes: [] + volumeMounts: + - name: megaraid + mountPath: /host/libexec/MegaRAID + readOnly: true + - name: ssacli + mountPath: /host/libexec/ssacli + readOnly: true + volumes: + - name: megaraid + hostPath: + path: /opt/MegaRAID/ + type: DirectoryOrCreate + - name: ssacli + hostPath: + path: /usr/bin/ssacli + type: FileOrCreate serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 diff --git a/go.mod b/go.mod index 3675b73..2901f97 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 github.com/pkg/errors v0.9.1 - github.com/scality/raidmgmt v0.13.0 + github.com/scality/raidmgmt v0.14.0 github.com/stretchr/testify v1.11.1 k8s.io/api v0.33.0 k8s.io/apimachinery v0.33.0 @@ -64,20 +64,17 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/zerolog v1.34.0 // indirect - github.com/sagikazarmark/locafero v0.10.0 // indirect - github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect - github.com/spf13/afero v1.14.0 // indirect - github.com/spf13/cast v1.9.2 // indirect + github.com/sagikazarmark/locafero v0.12.0 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/spf13/viper v1.20.1 // indirect + github.com/spf13/viper v1.21.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/stretchr/objx v0.5.3 // indirect - github.com/stretchr/testify v1.11.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/vektra/mockery/v2 v2.53.5 // indirect + github.com/vektra/mockery/v2 v2.53.6 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect @@ -90,6 +87,7 @@ require ( go.opentelemetry.io/proto/otlp v1.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/net v0.50.0 // indirect diff --git a/go.sum b/go.sum index 10ddabd..f86c129 100644 --- a/go.sum +++ b/go.sum @@ -145,23 +145,21 @@ github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.10.0 h1:FM8Cv6j2KqIhM2ZK7HZjm4mpj9NBktLgowT1aN9q5Cc= -github.com/sagikazarmark/locafero v0.10.0/go.mod h1:Ieo3EUsjifvQu4NZwV5sPd4dwvu0OCgEQV7vjc9yDjw= -github.com/scality/raidmgmt v0.13.0 h1:GXE041qd0ETmKq1pJloD+hFhsATzDvIDVo2mE4rZPXY= -github.com/scality/raidmgmt v0.13.0/go.mod h1:l8nxgoGV4AQyxZebXZii327ASaWLjGo5ZTxROs3Nmpo= -github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= -github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= -github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= -github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= -github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= -github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= +github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= +github.com/scality/raidmgmt v0.14.0 h1:xwAVC1U7taSqMVkOGLbamZiF9HDtHkyBEWb2A9eOJxs= +github.com/scality/raidmgmt v0.14.0/go.mod h1:QbPOSKWNhPHNlza9CL3hH5wWuUuESZz/kB0oH/gIomY= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= -github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -177,8 +175,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/vektra/mockery/v2 v2.53.5 h1:iktAY68pNiMvLoHxKqlSNSv/1py0QF/17UGrrAMYDI8= -github.com/vektra/mockery/v2 v2.53.5/go.mod h1:hIFFb3CvzPdDJJiU7J4zLRblUMv7OuezWsHPmswriwo= +github.com/vektra/mockery/v2 v2.53.6 h1:qfUB6saauu652ZlMF/mEdlj7B/A0fw2XR0XBACBrf7Y= +github.com/vektra/mockery/v2 v2.53.6/go.mod h1:fjxC+mskIZqf67+z34pHxRRyyZnPnWNA36Cirf01Pkg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -207,6 +205,7 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/pkg/infrastructure/di/command_runner.go b/pkg/infrastructure/di/command_runner.go index a3f3485..83d37d7 100644 --- a/pkg/infrastructure/di/command_runner.go +++ b/pkg/infrastructure/di/command_runner.go @@ -25,7 +25,7 @@ import ( func (c *Container) getMegaRAIDPerccliCommandRunner() *megaraid.MegaRAIDRunner { if c.megaraidPerccliCommandRunner == nil { - runner, err := megaraid.NewMegaRAIDRunner(megaraid.PERCCLI) + runner, err := megaraid.NewMegaRAIDRunner(c.perccliPath) if err != nil { c.logger.Error(err, "Failed to create MegaRAID perccli runner") os.Exit(1) @@ -39,7 +39,7 @@ func (c *Container) getMegaRAIDPerccliCommandRunner() *megaraid.MegaRAIDRunner { func (c *Container) getMegaRAIDStorcliCommandRunner() *megaraid.MegaRAIDRunner { if c.megaraidStorcliCommandRunner == nil { - runner, err := megaraid.NewMegaRAIDRunner(megaraid.STORCLI) + runner, err := megaraid.NewMegaRAIDRunner(c.storcliPath) if err != nil { c.logger.Error(err, "Failed to create MegaRAID storcli runner") os.Exit(1) @@ -53,7 +53,7 @@ func (c *Container) getMegaRAIDStorcliCommandRunner() *megaraid.MegaRAIDRunner { func (c *Container) getSSACLICommandRunner() *commandrunner.SSACLI { if c.ssacliCommandRunner == nil { - c.ssacliCommandRunner = commandrunner.NewSSACLI() + c.ssacliCommandRunner = commandrunner.NewSSACLI(&c.ssacliPath) } return c.ssacliCommandRunner @@ -61,7 +61,7 @@ func (c *Container) getSSACLICommandRunner() *commandrunner.SSACLI { func (c *Container) getLSBLKCommandRunner() *commandrunner.LSBLK { if c.lsblkCommandRunner == nil { - c.lsblkCommandRunner = commandrunner.NewLSBLK() + c.lsblkCommandRunner = commandrunner.NewLSBLK(nil) } return c.lsblkCommandRunner diff --git a/pkg/infrastructure/di/container.go b/pkg/infrastructure/di/container.go index 447152a..753fa54 100644 --- a/pkg/infrastructure/di/container.go +++ b/pkg/infrastructure/di/container.go @@ -36,6 +36,10 @@ type Container struct { nodeName string namespace string + storcliPath string + perccliPath string + ssacliPath string + megaraidPerccliCommandRunner *megaraid.MegaRAIDRunner megaraidStorcliCommandRunner *megaraid.MegaRAIDRunner ssacliCommandRunner *commandrunner.SSACLI @@ -65,11 +69,17 @@ func NewContainer( k8sClient client.Client, nodeName string, namespace string, + storcliPath string, + perccliPath string, + ssacliPath string, ) *Container { return &Container{ - logger: logger, - k8sClient: k8sClient, - nodeName: nodeName, - namespace: namespace, + logger: logger, + k8sClient: k8sClient, + nodeName: nodeName, + namespace: namespace, + storcliPath: storcliPath, + perccliPath: perccliPath, + ssacliPath: ssacliPath, } } From f5f196d6886ddb0505fba1b0fe581a3e60c14adc Mon Sep 17 00:00:00 2001 From: Valentin Daviot Date: Tue, 31 Mar 2026 16:25:38 +0200 Subject: [PATCH 2/3] run as root and mount /dev for megaraid communication Signed-off-by: Valentin Daviot --- config/manager/manager.yaml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 01cc106..efe4df5 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -50,10 +50,7 @@ spec: # values: # - linux securityContext: - # Projects are configured by default to adhere to the "restricted" Pod Security Standards. - # This ensures that deployments meet the highest security requirements for Kubernetes. - # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - runAsNonRoot: true + runAsNonRoot: false seccompProfile: type: RuntimeDefault containers: @@ -84,10 +81,8 @@ spec: value: "/host/libexec/ssacli" ports: [] securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" + privileged: true + runAsUser: 0 livenessProbe: httpGet: path: /healthz @@ -116,6 +111,8 @@ spec: - name: ssacli mountPath: /host/libexec/ssacli readOnly: true + - name: dev + mountPath: /dev volumes: - name: megaraid hostPath: @@ -125,5 +122,9 @@ spec: hostPath: path: /usr/bin/ssacli type: FileOrCreate + - name: dev + hostPath: + path: /dev + type: Directory serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 From 1964f1734464b0472df7a355557032d9193aaa11 Mon Sep 17 00:00:00 2001 From: Valentin Daviot Date: Tue, 31 Mar 2026 17:20:46 +0200 Subject: [PATCH 3/3] cr naming collision fix (again, might have been broken by prior merge) Signed-off-by: Valentin Daviot --- cmd/main.go | 4 +--- pkg/domain/physicaldrive_test.go | 8 ++++++++ pkg/infrastructure/di/container.go | 2 -- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 6f85218..0283d10 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -223,13 +223,10 @@ func main() { os.Exit(1) } - podNamespace := os.Getenv("POD_NAMESPACE") - container := di.NewContainer( ctrl.Log.WithName("di"), mgr.GetClient(), nodeName, - podNamespace, getEnvOrDefault("STORCLI_PATH", "/host/libexec/MegaRAID/storcli/storcli64"), getEnvOrDefault("PERCCLI_PATH", "/host/libexec/MegaRAID/perccli/perccli64"), getEnvOrDefault("SSACLI_PATH", "/host/libexec/ssacli"), @@ -265,6 +262,7 @@ func main() { // As a side note: // In the future, we'll implement proper role based access control in metalk8s. // A solution like kyverno could be used to enforce RBAC policies. + podNamespace := os.Getenv("POD_NAMESPACE") podServiceAccount := os.Getenv("POD_SERVICE_ACCOUNT") if podNamespace == "" || podServiceAccount == "" { setupLog.Info("WARNING: POD_NAMESPACE and/or POD_SERVICE_ACCOUNT environment variables are not set; " + diff --git a/pkg/domain/physicaldrive_test.go b/pkg/domain/physicaldrive_test.go index f554e26..81785f4 100644 --- a/pkg/domain/physicaldrive_test.go +++ b/pkg/domain/physicaldrive_test.go @@ -63,6 +63,14 @@ func TestComputeCRName(t *testing.T) { slotID: "252:0", expected: "node-2-megaraid-0-252-0", }, + { + name: "no collision between different slot hierarchies", + nodeName: "node-1", + controllerType: "MegaRAID", + controllerID: 0, + slotID: "25:2:0", + expected: "node-1-megaraid-0-25-2-0", + }, } for _, tt := range tests { diff --git a/pkg/infrastructure/di/container.go b/pkg/infrastructure/di/container.go index 0f204a4..a3c03b7 100644 --- a/pkg/infrastructure/di/container.go +++ b/pkg/infrastructure/di/container.go @@ -67,7 +67,6 @@ func NewContainer( logger logr.Logger, k8sClient client.Client, nodeName string, - namespace string, storcliPath string, perccliPath string, ssacliPath string, @@ -76,7 +75,6 @@ func NewContainer( logger: logger, k8sClient: k8sClient, nodeName: nodeName, - namespace: namespace, storcliPath: storcliPath, perccliPath: perccliPath, ssacliPath: ssacliPath,