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
|
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
|
def main(tree, options): # pylint: disable=too-many-branches
|
||||||
path = options["path"].lstrip("/")
|
path = options["path"].lstrip("/")
|
||||||
ostree = options.get("ostree")
|
ostree = options.get("ostree")
|
||||||
|
|
@ -242,6 +261,9 @@ def main(tree, options): # pylint: disable=too-many-branches
|
||||||
kargs_append = options.get("bootloader", {}).get("append")
|
kargs_append = options.get("bootloader", {}).get("append")
|
||||||
if kargs_append:
|
if kargs_append:
|
||||||
config += [f"bootloader --append='{kargs_append}'"]
|
config += [f"bootloader --append='{kargs_append}'"]
|
||||||
|
post = options.get("%post", [])
|
||||||
|
if post:
|
||||||
|
config += make_post(post)
|
||||||
|
|
||||||
target = os.path.join(tree, path)
|
target = os.path.join(tree, path)
|
||||||
base = os.path.dirname(target)
|
base = os.path.dirname(target)
|
||||||
|
|
|
||||||
|
|
@ -555,6 +555,43 @@
|
||||||
"type": "string"
|
"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": {"transport": "dir", "url": "/run/install/repo/container", }, },
|
||||||
"ostreecontainer --url=/run/install/repo/container --transport=dir",),
|
"ostreecontainer --url=/run/install/repo/container --transport=dir",),
|
||||||
({"bootloader": {"append": "karg1 karg2=0"}}, "bootloader --append='karg1 karg2=0'"),
|
({"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"}},
|
{"rootpw": {"iscrypted": True, "plaintext": True, "password": "pass"}},
|
||||||
"is not valid under any of the given schemas"
|
"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)
|
@pytest.mark.parametrize("stage_schema", ["1"], indirect=True)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue