Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce 'environment' header key to SCE checks #12734

Merged
merged 6 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/manual/developer/06_contributing_with_content.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<complex-check />` with
the results of this `<complex-check />`.
- `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:

Expand Down
1 change: 1 addition & 0 deletions shared/templates/sebool/sce-bash.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
# environment = bootc
# check-import = stdout
{{% if not SEBOOL_BOOL %}}
# check-export = var_{{{ SEBOOLID }}}=var_{{{ SEBOOLID }}}
Expand Down
1 change: 1 addition & 0 deletions shared/templates/service_disabled/sce-bash.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash
# check-import = stdout
# environment = bootc
if [[ $(systemctl is-enabled {{{ DAEMONNAME }}}.service) == "masked" ]] ; then
exit "$XCCDF_RESULT_PASS"
fi
Expand Down
1 change: 1 addition & 0 deletions shared/templates/service_enabled/sce-bash.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
# environment = bootc
# check-import = stdout
if [[ $(systemctl is-enabled {{{ DAEMONNAME }}}.service) == "enabled" ]] ; then
exit "$XCCDF_RESULT_PASS"
Expand Down
1 change: 1 addition & 0 deletions shared/templates/socket_disabled/sce-bash.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
# environment = bootc
# check-import = stdout
if [[ $(systemctl is-enabled {{{ SOCKETNAME }}}.socket) == "masked" ]] ; then
exit "$XCCDF_RESULT_PASS"
Expand Down
1 change: 1 addition & 0 deletions shared/templates/sysctl/sce-bash.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
# environment = bootc
# check-import = stdout
{{% if SYSCTLVAL == "" %}}
# check-export = sysctl_{{{ SYSCTLID }}}_value=sysctl_{{{ SYSCTLID }}}_value
Expand Down
1 change: 1 addition & 0 deletions shared/templates/timer_enabled/sce-bash.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
# environment = bootc
# check-import = stdout
if [[ $(systemctl is-enabled {{{ TIMERNAME }}}.timer) == "enabled" ]] ; then
exit "$XCCDF_RESULT_PASS"
Expand Down
75 changes: 59 additions & 16 deletions ssg/build_sce.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand Down
Loading