stages/kickstart: support for users and groups

Add support for creating groups and users during the installation
via the corresponding kickstart directives.
This commit is contained in:
Christian Kellner 2021-07-14 11:36:40 +00:00 committed by Tom Gundersen
parent 403dd5e2ec
commit 887e1bd8aa

View file

@ -13,6 +13,8 @@ commands are supported here.
import sys
import os
from typing import Dict, List
import osbuild.api
@ -52,11 +54,135 @@ SCHEMA = """
"type": "string"
}
}
},
"groups": {
"type": "object",
"additionalProperties": false,
"description": "Keys are group names, values are objects with group info",
"patternProperties": {
"^[A-Za-z0-9_][A-Za-z0-9_-]{0,31}$": {
"type": "object",
"properties": {
"gid": {
"type": "number",
"description": "GID for this group"
}
}
}
}
},
"users": {
"additionalProperties": false,
"type": "object",
"description": "Keys are usernames, values are objects giving user info.",
"patternProperties": {
"^[A-Za-z0-9_][A-Za-z0-9_-]{0,31}$": {
"type": "object",
"properties": {
"uid": {
"description": "User UID",
"type": "number"
},
"gid": {
"description": "User GID",
"type": "number"
},
"groups": {
"description": "Array of group names for this user",
"type": "array",
"items": {
"type": "string"
}
},
"description": {
"description": "User account description (or full name)",
"type": "string"
},
"home": {
"description": "Path to user's home directory",
"type": "string"
},
"shell": {
"description": "User's login shell",
"type": "string"
},
"password": {
"description": "User's encrypted password, as returned by crypt(3)",
"type": "string"
},
"key": {
"description": "SSH Public Key to add to ~/.ssh/authorized_keys",
"type": "string"
}
}
}
}
}
}
"""
def make_groups(groups: Dict) -> List[str]:
# group --name NAME [--gid GID]
res = []
for name, opts in groups.items():
gid = opts.get("gid")
arguments = [f"group --name {name}"]
if gid:
arguments += ["--gid", str(gid)]
res.append(" ".join(arguments))
return res
def make_users(users: Dict) -> List[str]:
# user [--homedir HOMEDIR] [--iscrypted] --name NAME [--password PASSWORD]
# [--shell SHELL] [--uid INT] [--lock] [--plaintext] [--gecos GECOS]
# [--gid INT] [--groups GROUPS]
res = []
for name, opts in users.items():
arguments = [f"user --name {name}"]
password = opts.get("password")
if password is not None:
arguments += ["--password", password or '""']
shell = opts.get("shell")
if shell:
arguments += ["--shell", shell]
uid = opts.get("uid")
if uid is not None:
arguments += ["--uid", str(uid)]
gid = opts.get("gid")
if gid is not None:
arguments += ["--gid", str(gid)]
groups = opts.get("groups")
if groups:
arguments += ["--groups", ",".join(groups)]
home = opts.get("home")
if home:
arguments += ["--homedir", home]
res.append(" ".join(arguments))
key = opts.get("key")
if key:
res.append(f"sshkey --username {name} {key}")
return res
def main(tree, options):
path = options["path"].lstrip("/")
ostree = options.get("ostree")
@ -83,6 +209,9 @@ def main(tree, options):
url = liveimg["url"]
config += [f"liveimg --url {url}"]
config += make_groups(options.get("groups", {}))
config += make_users(options.get("users", {}))
target = os.path.join(tree, path)
base = os.path.dirname(target)
os.makedirs(base, exist_ok=True)