arch-image-builder/builder/component/user.py

76 lines
1.8 KiB
Python
Raw Normal View History

from logging import getLogger
from builder.lib.config import ArchBuilderConfigError
from builder.lib.context import ArchBuilderContext
log = getLogger(__name__)
def parse_usergroup_item(
ctx: ArchBuilderContext,
item: str | int,
group: bool = False
) -> int:
if type(item) is int:
return int(item)
elif type(item) is str:
if group:
user = ctx.passwd.lookup_name(item)
if user is None: raise ArchBuilderConfigError(
f"user {item} not found"
)
return user.gid
else:
grp = ctx.group.lookup_name(item)
if grp is None: raise ArchBuilderConfigError(
f"group {item} not found"
)
return grp.gid
else: raise ArchBuilderConfigError("bad owner type")
def parse_owner(ctx: ArchBuilderContext, owner: str) -> tuple[int, int]:
if ":" in owner:
i = owner.find(":")
uid = parse_usergroup_item(ctx, owner[0:i], False)
gid = parse_usergroup_item(ctx, owner[i+1:], True)
else:
uid = parse_usergroup_item(ctx, owner, False)
user = ctx.passwd.lookup_uid(uid)
if user is None: raise ArchBuilderConfigError(
f"user {user} not found"
)
gid = user.gid
return uid, gid
def parse_usergroup_from(
ctx: ArchBuilderContext,
node: dict,
group: bool = False,
default: int = 0
) -> int:
kid = "uid" if not group else "gid"
kname = "owner" if not group else "group"
if kid in node: return int(node[kid])
if kname in node: return parse_usergroup_item(
ctx, node[kname], group
)
return default
def parse_user_from(
ctx: ArchBuilderContext,
node: dict,
default: tuple[int, int] = (0, -1)
) -> tuple[int, int]:
"""
Parse user/group id from config
"""
uid, gid = default
if "owner" in node: uid, gid = parse_owner(ctx, node["owner"])
uid = parse_usergroup_from(ctx, node, False, uid)
gid = parse_usergroup_from(ctx, node, True, gid)
if gid == -1:
user = ctx.passwd.lookup_uid(uid)
gid = user.gid if user else uid
return uid, gid