diff --git a/docs/manual/developer/06_contributing_with_content.md b/docs/manual/developer/06_contributing_with_content.md
index e1f5e4f906e..ab5c430c7e9 100644
--- a/docs/manual/developer/06_contributing_with_content.md
+++ b/docs/manual/developer/06_contributing_with_content.md
@@ -825,6 +825,13 @@ are unique to SCE:
it is not necessary. Additionally, OCIL checks, if any is present in the
`rule.yml`, are added as a top-level OR-operator `` with
the results of this ``.
+ - `environment`: can be `normal`, `bootc`, `any`.
+ The default value that is used when this key is not set is `any`.
+ This key specifies the environment in which the SCE check can run in.
+ This way you can restrict some SCE checks to run or not run in Image mode.
+ If set to `bootc`, the SCE check code will be modified to not run outside of the bootable image build process.
+ If set to `normal`, the SCE check code will be modified to not run during the bootable image build process.
+ If set to `any`, the SCE check code will not be modified and therefore will run in any environment.
For an example of SCE content, consider the check:
diff --git a/shared/templates/sebool/sce-bash.template b/shared/templates/sebool/sce-bash.template
index 143aedfe1d8..87a442ecbcc 100644
--- a/shared/templates/sebool/sce-bash.template
+++ b/shared/templates/sebool/sce-bash.template
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
+# environment = bootc
# check-import = stdout
{{% if not SEBOOL_BOOL %}}
# check-export = var_{{{ SEBOOLID }}}=var_{{{ SEBOOLID }}}
diff --git a/shared/templates/service_disabled/sce-bash.template b/shared/templates/service_disabled/sce-bash.template
index 84addf8e8cc..4d86b9fdc99 100644
--- a/shared/templates/service_disabled/sce-bash.template
+++ b/shared/templates/service_disabled/sce-bash.template
@@ -1,5 +1,6 @@
#!/bin/bash
# check-import = stdout
+# environment = bootc
if [[ $(systemctl is-enabled {{{ DAEMONNAME }}}.service) == "masked" ]] ; then
exit "$XCCDF_RESULT_PASS"
fi
diff --git a/shared/templates/service_enabled/sce-bash.template b/shared/templates/service_enabled/sce-bash.template
index 5d33a00d3a6..03254c17170 100644
--- a/shared/templates/service_enabled/sce-bash.template
+++ b/shared/templates/service_enabled/sce-bash.template
@@ -1,4 +1,5 @@
#!/bin/bash
+# environment = bootc
# check-import = stdout
if [[ $(systemctl is-enabled {{{ DAEMONNAME }}}.service) == "enabled" ]] ; then
exit "$XCCDF_RESULT_PASS"
diff --git a/shared/templates/socket_disabled/sce-bash.template b/shared/templates/socket_disabled/sce-bash.template
index 2b27cd73ba6..3b0cca18f0c 100644
--- a/shared/templates/socket_disabled/sce-bash.template
+++ b/shared/templates/socket_disabled/sce-bash.template
@@ -1,4 +1,5 @@
#!/bin/bash
+# environment = bootc
# check-import = stdout
if [[ $(systemctl is-enabled {{{ SOCKETNAME }}}.socket) == "masked" ]] ; then
exit "$XCCDF_RESULT_PASS"
diff --git a/shared/templates/sysctl/sce-bash.template b/shared/templates/sysctl/sce-bash.template
index 54a120e983e..352b701f9b0 100644
--- a/shared/templates/sysctl/sce-bash.template
+++ b/shared/templates/sysctl/sce-bash.template
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
+# environment = bootc
# check-import = stdout
{{% if SYSCTLVAL == "" %}}
# check-export = sysctl_{{{ SYSCTLID }}}_value=sysctl_{{{ SYSCTLID }}}_value
diff --git a/shared/templates/timer_enabled/sce-bash.template b/shared/templates/timer_enabled/sce-bash.template
index 53101b496dd..a09354aa387 100644
--- a/shared/templates/timer_enabled/sce-bash.template
+++ b/shared/templates/timer_enabled/sce-bash.template
@@ -1,4 +1,5 @@
#!/bin/bash
+# environment = bootc
# check-import = stdout
if [[ $(systemctl is-enabled {{{ TIMERNAME }}}.timer) == "enabled" ]] ; then
exit "$XCCDF_RESULT_PASS"
diff --git a/ssg/build_sce.py b/ssg/build_sce.py
index 110a73f7617..17906a0f560 100644
--- a/ssg/build_sce.py
+++ b/ssg/build_sce.py
@@ -34,26 +34,34 @@ def load_sce_and_metadata(file_path, local_env_yaml):
return load_sce_and_metadata_parsed(raw_content)
-def load_sce_and_metadata_parsed(raw_content):
+def _process_raw_content_line(line, sce_content, metadata):
+ found_metadata = False
+ keywords = ['platform', 'check-import', 'check-export', 'complex-check', 'environment']
+ for keyword in keywords:
+ if not line.startswith('# ' + keyword + ' = '):
+ continue
+ found_metadata = True
+ # Strip off the initial comment marker
+ _, value = line[2:].split('=', maxsplit=1)
+ metadata[keyword] = value.strip()
+
+ if not found_metadata:
+ sce_content.append(line)
+
+
+def _parse_metadata(raw_content):
metadata = dict()
sce_content = []
-
- keywords = ['platform', 'check-import', 'check-export', 'complex-check']
+ shebang = "#!/usr/bin/bash"
for line in raw_content.split("\n"):
- found_metadata = False
- for keyword in keywords:
- if not line.startswith('# ' + keyword + ' = '):
- continue
-
- found_metadata = True
+ if line.startswith("#!"):
+ shebang = line
+ continue
+ _process_raw_content_line(line, sce_content, metadata)
+ return shebang, "\n".join(sce_content), metadata
- # Strip off the initial comment marker
- _, value = line[2:].split('=', maxsplit=1)
- metadata[keyword] = value.strip()
-
- if not found_metadata:
- sce_content.append(line)
+def _set_metadata_default_values(metadata):
if 'check-export' in metadata:
# Special case for the variables exposed to the SCE script: prepend
# the OSCAP_VALUE prefix to reference the variable
@@ -66,7 +74,42 @@ def load_sce_and_metadata_parsed(raw_content):
if 'platform' in metadata:
metadata['platform'] = metadata['platform'].split(',')
- return "\n".join(sce_content), metadata
+ if "environment" not in metadata:
+ metadata["environment"] = "any"
+ environment_options = ["normal", "bootc", "any"]
+ if metadata["environment"] not in environment_options:
+ raise RuntimeError(
+ "Wrong value of the 'environment' headers: '%s'. It needs to be "
+ "one of %s" % (
+ metadata["environment"], ", ".join(environment_options))
+ )
+
+
+def _modify_sce_with_environment(sce_content, environment):
+ if environment == "any":
+ return sce_content
+ if environment == "bootc":
+ condition = "(rpm -q --quiet bootc && [ -e /run/.containerenv ])"
+ if environment == "normal":
+ condition = "! (rpm -q --quiet bootc && [ -e /run/.containerenv ])"
+ lines = list(sce_content.split("\n"))
+ for i in range(len(lines)):
+ if len(lines[i]) > 0:
+ lines[i] = (4 * " ") + lines[i]
+ lines.insert(0, "if " + condition + " ; then")
+ lines.append("else")
+ lines.append(" echo \"The SCE check can't run in this environment.\"")
+ lines.append(" exit \"$XCCDF_RESULT_ERROR\"")
+ lines.append("fi")
+ return "\n".join(lines)
+
+
+def load_sce_and_metadata_parsed(raw_content):
+ shebang, sce_content, metadata = _parse_metadata(raw_content)
+ _set_metadata_default_values(metadata)
+ sce_content = _modify_sce_with_environment(sce_content, metadata["environment"])
+ sce_content = shebang + "\n" + sce_content
+ return sce_content, metadata
def _check_is_applicable_for_product(metadata, product):