Skip to content

Commit ef1a6b1

Browse files
tmshortclaude
andauthored
fix(test): make e2e test bundle compatible with restricted SCC (#2711)
The e2e test operator ran busybox httpd on port 80 writing to /var/www/, both of which require root. Restricted SCC enforces non-root UIDs from a namespace-assigned range, causing the pod to crash with Permission denied. Similarly, several feature files hardcoded runAsUser:1000 which falls outside the allowed UID range on some k8s implementations. Changes: - bundle.go: switch httpd from port 80+/var/www to port 8080+/tmp/www so the pod starts under any SCC without root privileges - steps.go: match the /tmp/www path in the readiness exec probe; add OLM_NAMESPACE as a substitution variable; make per-step timeout configurable via E2E_STEP_TIMEOUT env var (default 5m unchanged) - install.feature: replace hardcoded "olmv1-system" with ${OLM_NAMESPACE} so referred-secret lookups work when OLM is deployed in a different namespace - revision.feature, recover.feature: remove runAsUser:1000 from pod/ container specs; keep runAsNonRoot:true Signed-off-by: Todd Short <tshort@redhat.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5a1207d commit ef1a6b1

5 files changed

Lines changed: 21 additions & 15 deletions

File tree

test/e2e/features/install.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ Feature: Install ClusterExtension
564564
Then ClusterExtension is rolled out
565565
And ClusterExtension is available
566566
And ClusterObjectSet "${NAME}-1" phase objects are managed in Kubernetes secrets
567-
And ClusterObjectSet "${NAME}-1" referred secrets exist in "olmv1-system" namespace
567+
And ClusterObjectSet "${NAME}-1" referred secrets exist in "${OLM_NAMESPACE}" namespace
568568
And ClusterObjectSet "${NAME}-1" referred secrets are immutable
569569
And ClusterObjectSet "${NAME}-1" referred secrets contain labels
570570
| key | value |

test/e2e/features/recover.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ Feature: Recover cluster extension from errors that might occur during its lifet
8585
name: busybox
8686
securityContext:
8787
runAsNonRoot: true
88-
runAsUser: 1000
8988
allowPrivilegeEscalation: false
9089
capabilities:
9190
drop:

test/e2e/features/revision.feature

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,6 @@ Feature: Install ClusterObjectSet
309309
imagePullPolicy: IfNotPresent
310310
name: busybox
311311
securityContext:
312-
runAsNonRoot: true
313-
runAsUser: 1000
314312
allowPrivilegeEscalation: false
315313
capabilities:
316314
drop:
@@ -397,8 +395,6 @@ Feature: Install ClusterObjectSet
397395
"command": ["httpd"],
398396
"args": ["-f", "-p", "8080"],
399397
"securityContext": {
400-
"runAsNonRoot": true,
401-
"runAsUser": 1000,
402398
"allowPrivilegeEscalation": false,
403399
"capabilities": {
404400
"drop": ["ALL"]
@@ -729,8 +725,6 @@ Feature: Install ClusterObjectSet
729725
command: ["true"]
730726
initialDelaySeconds: 65
731727
securityContext:
732-
runAsNonRoot: true
733-
runAsUser: 1000
734728
allowPrivilegeEscalation: false
735729
capabilities:
736730
drop:

test/e2e/steps/steps.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,22 @@ import (
5252
const (
5353
olmDeploymentName = "operator-controller-controller-manager"
5454
catalogdDeploymentName = "catalogd-controller-manager"
55-
timeout = 5 * time.Minute
55+
defaultTimeout = 5 * time.Minute
5656
tick = 1 * time.Second
5757
)
5858

59+
// timeout is the per-step wait timeout. It defaults to defaultTimeout (5m) but
60+
// can be overridden via E2E_STEP_TIMEOUT to accommodate runtimes (e.g.
61+
// BoxcutterRuntime) that take longer to complete an installation.
62+
var timeout = func() time.Duration {
63+
if s := os.Getenv("E2E_STEP_TIMEOUT"); s != "" {
64+
if d, err := time.ParseDuration(s); err == nil {
65+
return d
66+
}
67+
}
68+
return defaultTimeout
69+
}()
70+
5971
var (
6072
olmNamespace = "olmv1-system"
6173
componentNamespaces = map[string]string{} // keyed by component label (e.g. "catalogd"); falls back to olmNamespace
@@ -337,6 +349,7 @@ func substituteScenarioVars(content string, sc *scenarioContext) string {
337349
"NAME": sc.clusterExtensionName,
338350
"COS_NAME": sc.clusterObjectSetName,
339351
"SCENARIO_ID": sc.id,
352+
"OLM_NAMESPACE": olmNamespace,
340353
}
341354
for orig, param := range sc.catalogPackageNames {
342355
vars[fmt.Sprintf("PACKAGE:%s", orig)] = param
@@ -1833,7 +1846,7 @@ func MarkDeploymentReadiness(ctx context.Context, deploymentName, state string)
18331846
default:
18341847
return fmt.Errorf("invalid state %s", state)
18351848
}
1836-
_, err = k8sClient("exec", podName, "-n", sc.namespace, "--", op, "/var/www/ready")
1849+
_, err = k8sClient("exec", podName, "-n", sc.namespace, "--", op, "/tmp/www/ready")
18371850
return err
18381851
}
18391852

test/internal/catalog/bundle.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func buildBundle(scenarioID, packageName, version string, opts []BundleOption) (
238238
Name: scriptCMName,
239239
},
240240
Data: map[string]string{
241-
"httpd.sh": "#!/bin/sh\necho true > /var/www/started\necho true > /var/www/ready\necho true > /var/www/live\nexec httpd -f -h /var/www -p 80\n",
241+
"httpd.sh": "#!/bin/sh\nmkdir -p /tmp/www\necho true > /tmp/www/started\necho true > /tmp/www/ready\necho true > /tmp/www/live\nexec httpd -f -h /tmp/www -p 8080\n",
242242
},
243243
}).
244244
WithBundleResource("networkpolicy.yaml", &networkingv1.NetworkPolicy{
@@ -338,7 +338,7 @@ func buildDeploymentSpec(
338338
Image: containerImage,
339339
Command: []string{"/scripts/httpd.sh"},
340340
Ports: []corev1.ContainerPort{
341-
{ContainerPort: 80},
341+
{ContainerPort: 8080},
342342
},
343343
VolumeMounts: []corev1.VolumeMount{
344344
{
@@ -351,7 +351,7 @@ func buildDeploymentSpec(
351351
ProbeHandler: corev1.ProbeHandler{
352352
HTTPGet: &corev1.HTTPGetAction{
353353
Path: "/started",
354-
Port: intstr.FromInt32(80),
354+
Port: intstr.FromInt32(8080),
355355
},
356356
},
357357
FailureThreshold: 30,
@@ -361,7 +361,7 @@ func buildDeploymentSpec(
361361
ProbeHandler: corev1.ProbeHandler{
362362
HTTPGet: &corev1.HTTPGetAction{
363363
Path: "/live",
364-
Port: intstr.FromInt32(80),
364+
Port: intstr.FromInt32(8080),
365365
},
366366
},
367367
FailureThreshold: 1,
@@ -371,7 +371,7 @@ func buildDeploymentSpec(
371371
ProbeHandler: corev1.ProbeHandler{
372372
HTTPGet: &corev1.HTTPGetAction{
373373
Path: "/ready",
374-
Port: intstr.FromInt32(80),
374+
Port: intstr.FromInt32(8080),
375375
},
376376
},
377377
InitialDelaySeconds: 1,

0 commit comments

Comments
 (0)