From bfcd5a964048bfec3b55c55a578794fad963e012 Mon Sep 17 00:00:00 2001 From: Yasuo Honda Date: Thu, 4 Jun 2026 16:48:00 +0900 Subject: [PATCH 1/2] cluster: don't fail SELinux status check when getenforce is unavailable #2496 added a getenforce-based SELinux status probe in addition to the config-file check. On hosts without the SELinux userspace tools (most Debian/Ubuntu systems, including the integration-test containers), getenforce is missing, so CheckSELinuxStatus failed. With --apply that failed check triggers the SELinux fix, which runs sed -i 's/.../' /etc/selinux/config && setenforce 0 but /etc/selinux/config does not exist on those hosts, so the command errors with 'sed: can't read /etc/selinux/config: No such file or directory' and the whole check/apply run aborts. This breaks the cluster and dm integration tests on master. Treat a getenforce execution error as 'SELinux disabled' (the host has no SELinux), matching the lenient pre-#2496 behavior, instead of a failure. Enforcing still fails and Permissive still warns. The configuration is still validated independently by CheckSELinuxConf. Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/cluster/operation/check.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/cluster/operation/check.go b/pkg/cluster/operation/check.go index f0e69e111e..5928d0b410 100644 --- a/pkg/cluster/operation/check.go +++ b/pkg/cluster/operation/check.go @@ -608,9 +608,15 @@ func CheckSELinuxStatus(ctx context.Context, e ctxt.Executor, sudo bool) *CheckR Command: "getenforce", Sudo: sudo, }) - stdout, stderr, err := m.Execute(ctx, e) + stdout, _, err := m.Execute(ctx, e) if err != nil { - result.Err = fmt.Errorf("%w %s", err, stderr) + // getenforce is unavailable (e.g. SELinux userspace tools are not + // installed, as on most Debian/Ubuntu hosts), which means SELinux is + // not enforcing on this host. Treat it as disabled rather than a + // failure, so we don't trigger a fix that edits a non-existent + // /etc/selinux/config. The configuration is still checked separately + // by CheckSELinuxConf. + result.Msg = "getenforce not available, assuming SELinux is disabled" return result } out := strings.Trim(string(stdout), "\n") From 48f3e74b1960a43e8323ce01d67e9dc5e15b617b Mon Sep 17 00:00:00 2001 From: Yasuo Honda Date: Thu, 4 Jun 2026 16:58:20 +0900 Subject: [PATCH 2/2] cluster: skip grubby in THP fix when it is not installed #2498 added a persistent THP disable via grubby --update-kernel=ALL --args="transparent_hugepage=never" to the THP check auto-fix. grubby is a RHEL-family tool and is not present on Debian/Ubuntu (including the integration-test containers), so with --apply the fix aborts with 'grubby: command not found' (exit 127) and the whole check/apply run fails. Guard the grubby invocation with 'command -v grubby' so the persistent kernel argument is still set where grubby exists, but is skipped on hosts without it. The runtime THP setting (echo never > .../enabled) still applies everywhere. Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/cluster/manager/check.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/cluster/manager/check.go b/pkg/cluster/manager/check.go index 0559aa8f90..99addd799e 100644 --- a/pkg/cluster/manager/check.go +++ b/pkg/cluster/manager/check.go @@ -686,7 +686,10 @@ func fixFailedChecks(host string, res *operator.CheckResult, t *task.Builder, sy case operator.CheckNameTHP: t.Shell(host, fmt.Sprintf( - `if [ -d %[1]s ]; then echo never > %[1]s/enabled; fi && %s`, + // grubby only exists on RHEL-family distros; skip the persistent + // kernel argument when it's not available (e.g. Debian/Ubuntu) + // instead of failing the whole apply. + `if [ -d %[1]s ]; then echo never > %[1]s/enabled; fi && if command -v grubby >/dev/null 2>&1; then %s; fi`, "/sys/kernel/mm/transparent_hugepage", `grubby --update-kernel=ALL --args="transparent_hugepage=never"`, ),