1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
"""Generate jail.conf.d entries."""
from __future__ import annotations
from .config import JailConfig, MainConfig
def _format_value(value: object) -> str:
if isinstance(value, str):
return f"\"{value}\""
if isinstance(value, bool):
return "true" if value else "false"
if isinstance(value, (int, float)):
return str(value)
raise ValueError(f"unsupported jailconf value type: {type(value).__name__}")
def _flatten(prefix: str, value: object, out: list[tuple[str, object]]) -> None:
if isinstance(value, dict):
for key, val in value.items():
new_prefix = f"{prefix}.{key}" if prefix else str(key)
_flatten(new_prefix, val, out)
else:
out.append((prefix, value))
def render_jail_conf(
main: MainConfig,
jail: JailConfig,
*,
jailname: str | None = None,
root: str | None = None,
) -> str:
"""Render jail.conf content for the jail."""
name = jailname or jail.name
if not root:
raise ValueError("root path is required to render jail.conf")
lines = [
f"{name} {{",
f" host.hostname = \"{name}\";",
f" path = \"{root}\";",
" exec.start = \"/bin/sh /etc/rc\";",
" exec.stop = \"/bin/sh /etc/rc.shutdown jail\";",
]
if jail.jailconf:
flattened: list[tuple[str, object]] = []
_flatten("", jail.jailconf, flattened)
for key, value in flattened:
if value is True:
lines.append(f" {key};")
continue
if value is False:
continue
lines.append(f" {key} = {_format_value(value)};")
# Exec commands from [cmds], with env prefix
env_prefix = ""
if jail.env:
pairs = [f"{k}={v}" for k, v in jail.env.items()]
env_prefix = "env " + " ".join(pairs) + " "
cmd_map = {
"prestart": "exec.prestart",
"poststart": "exec.poststart",
"prestop": "exec.prestop",
"poststop": "exec.poststop",
"start": "exec.start",
"stop": "exec.stop",
}
for key, jailconf_key in cmd_map.items():
cmd = jail.cmds.get(key)
if cmd:
if env_prefix and not cmd.startswith("env "):
cmd_value = f"{env_prefix}{cmd}"
else:
cmd_value = cmd
lines.append(f" {jailconf_key} = \"{cmd_value}\";")
lines.append("}")
return "\n".join(lines) + "\n"
|