Add a new stage for setting kernel parameters via sysctl.d

Add a new stage `org.osbuild.sysctld` for setting kernel parameters at
boot by creating a configuration file in /usr/lib/sysctl.d. At least
one parameter must be specified for the stage.

Add unit test for the new stage.

Fix #790

Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
Tomas Hozza 2021-09-08 16:17:30 +02:00 committed by Achilleas Koutsou
parent 5d7316757b
commit 187681f17d
6 changed files with 1660 additions and 0 deletions

106
stages/org.osbuild.sysctld Executable file
View file

@ -0,0 +1,106 @@
#!/usr/bin/python3
"""
Configure kernel parameters at boot via sysctl.d.
This stage creates a sysctl.d configuration file with the given name in
/usr/lib/sysctl.d. Provided list of parameters is written as separate lines
into the configuration file. At least one parameter must be specified.
The syntax of the sysctl.d file is simply:
<token> = <value>
If a line begins with a single "-", any attempts to set the value that fail
will be ignored. (from sysct.conf(5) man page)
The <token> can be a glob pattern.
A key may be explicitly excluded from being set by any matching glob patterns
by specifying the key name prefixed with a "-" character and not followed
by "=". (from sysctl.d(5) man page)
"""
import sys
import osbuild.api
SCHEMA = r"""
"definitions": {
"parameter": {
"type": "object",
"additionalProperties": false,
"required": ["key", "value"],
"description": "Kernel parameter to set.",
"properties": {
"key": {
"type": "string",
"description": "Kernel parameter name."
},
"value": {
"type": "string",
"description": "Kernel parameter value."
}
}
},
"parameter-excluded": {
"type": "object",
"additionalProperties": false,
"required": ["key"],
"description": "Parameter to exclude from being set by a matching glob",
"properties": {
"key": {
"type": "string",
"pattern": "^-.+$",
"description": "Key to exclude from being set by a matching glob"
}
}
}
},
"additionalProperties": false,
"required": ["filename", "config"],
"properties": {
"filename": {
"type": "string",
"description": "Name of the sysctl.d configuration file to create.",
"pattern": "^[\\w.-]{1,250}\\.conf$"
},
"config": {
"additionalProperties": false,
"type": "array",
"description": "List of kernel parameters to write into the configuration file.",
"minItems": 1,
"items": {
"anyOf": [
{"$ref": "#/definitions/parameter"},
{"$ref": "#/definitions/parameter-excluded"}
]
}
}
}
"""
def main(tree, options):
filename = options["filename"]
cfg = options["config"]
sysctld_config_dir = f"{tree}/usr/lib/sysctl.d"
cfg_lines = []
for cfg_item in cfg:
key = cfg_item["key"]
value = cfg_item.get("value")
cfg_line = f"{key} = {value}\n" if value else f"{key}\n"
cfg_lines.append(cfg_line)
with open(f"{sysctld_config_dir}/{filename}", "w") as f:
f.writelines(cfg_lines)
return 0
if __name__ == '__main__':
args = osbuild.api.arguments()
r = main(args["tree"], args["options"])
sys.exit(r)