stages/kickstart: post-installation scripts
Add a new %post option to the kickstart stage that supports adding multiple post blocks to a kickstart file, with all the options supported by the directive.
This commit is contained in:
parent
68b2301daf
commit
0ac83fd421
3 changed files with 104 additions and 0 deletions
|
|
@ -170,6 +170,25 @@ def make_network(options: Dict) -> List[str]:
|
|||
return res
|
||||
|
||||
|
||||
def make_post(post_list):
|
||||
res = []
|
||||
for post in post_list:
|
||||
start = ["%post"]
|
||||
if post.get("erroronfail"):
|
||||
start.append("--erroronfail")
|
||||
if post.get("nochroot"):
|
||||
start.append("--nochroot")
|
||||
log = post.get("log")
|
||||
if log:
|
||||
start.extend(["--log", f'"{log}"'])
|
||||
interpreter = post.get("interpreter")
|
||||
if interpreter:
|
||||
start.extend(["--interpreter", f'"{interpreter}"'])
|
||||
|
||||
res.extend([" ".join(start), *post["commands"], "%end"])
|
||||
return res
|
||||
|
||||
|
||||
def main(tree, options): # pylint: disable=too-many-branches
|
||||
path = options["path"].lstrip("/")
|
||||
ostree = options.get("ostree")
|
||||
|
|
@ -242,6 +261,9 @@ def main(tree, options): # pylint: disable=too-many-branches
|
|||
kargs_append = options.get("bootloader", {}).get("append")
|
||||
if kargs_append:
|
||||
config += [f"bootloader --append='{kargs_append}'"]
|
||||
post = options.get("%post", [])
|
||||
if post:
|
||||
config += make_post(post)
|
||||
|
||||
target = os.path.join(tree, path)
|
||||
base = os.path.dirname(target)
|
||||
|
|
|
|||
|
|
@ -555,6 +555,43 @@
|
|||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"%post": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Adds arbitrary commands to run on the system once the installation is complete.",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"commands"
|
||||
],
|
||||
"properties": {
|
||||
"erroronfail": {
|
||||
"description": "Stop the installation on script failure",
|
||||
"type": "boolean"
|
||||
},
|
||||
"interpreter": {
|
||||
"description": "Allows specifying a different scripting language",
|
||||
"type": "string"
|
||||
},
|
||||
"log": {
|
||||
"description": "Log all messages from the script to the given log file",
|
||||
"type": "string"
|
||||
},
|
||||
"nochroot": {
|
||||
"description": "Run outside of the chroot environment",
|
||||
"type": "boolean"
|
||||
},
|
||||
"commands": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,6 +241,47 @@ TEST_INPUT = [
|
|||
({"ostreecontainer": {"transport": "dir", "url": "/run/install/repo/container", }, },
|
||||
"ostreecontainer --url=/run/install/repo/container --transport=dir",),
|
||||
({"bootloader": {"append": "karg1 karg2=0"}}, "bootloader --append='karg1 karg2=0'"),
|
||||
|
||||
# %post
|
||||
({"%post": [{"commands": ["mkdir /scratch"]}]}, "%post\nmkdir /scratch\n%end"),
|
||||
(
|
||||
{
|
||||
"%post": [
|
||||
{"commands": ["mkdir /scratch"]},
|
||||
{"commands": ["print('DONE!!!')"], "interpreter": "/usr/bin/python3"},
|
||||
]
|
||||
},
|
||||
"%post\nmkdir /scratch\n%end\n" +
|
||||
"%post --interpreter \"/usr/bin/python3\"\nprint('DONE!!!')\n%end"
|
||||
),
|
||||
(
|
||||
{
|
||||
"%post": [
|
||||
{"commands": ["mkdir /scratch"]},
|
||||
{
|
||||
"erroronfail": True,
|
||||
"nochroot": True,
|
||||
"interpreter": "/usr/bin/bash",
|
||||
"log": "/mnt/sysimage/var/log/ks-p2.log",
|
||||
"commands": [
|
||||
"echo 'Starting post2'",
|
||||
"if [ ! -e /mnt/sysimage/etc/resolv.conf ]; then",
|
||||
" cp /etc/resolv.conf /mnt/sysimage/etc/resolv.conf",
|
||||
"fi",
|
||||
]
|
||||
},
|
||||
{"commands": ["print('DONE!!!')"], "interpreter": "/usr/bin/python3"},
|
||||
]
|
||||
},
|
||||
"%post\nmkdir /scratch\n%end\n" +
|
||||
"%post --erroronfail --nochroot --log \"/mnt/sysimage/var/log/ks-p2.log\" --interpreter \"/usr/bin/bash\"\n" +
|
||||
"echo 'Starting post2'\n" +
|
||||
"if [ ! -e /mnt/sysimage/etc/resolv.conf ]; then\n" +
|
||||
" cp /etc/resolv.conf /mnt/sysimage/etc/resolv.conf\n" +
|
||||
"fi\n" +
|
||||
"%end\n" +
|
||||
"%post --interpreter \"/usr/bin/python3\"\nprint('DONE!!!')\n%end"
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -387,6 +428,10 @@ def test_kickstart_valid(tmp_path, stage_module, test_input, expected): # pylin
|
|||
{"rootpw": {"iscrypted": True, "plaintext": True, "password": "pass"}},
|
||||
"is not valid under any of the given schemas"
|
||||
),
|
||||
# bad %post blocks
|
||||
({"%post": []}, re.compile(r"\[\] should be non-empty|\[\] is too short")),
|
||||
({"%post": [{}]}, "'commands' is a required property"),
|
||||
({"%post": [{"commands": []}]}, re.compile(r"\[\] should be non-empty|\[\] is too short")),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("stage_schema", ["1"], indirect=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue