mirror of
https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git
synced 2025-12-14 19:02:45 +03:00
split alpine-config out of cloud-config
This commit is contained in:
parent
e75ec5b4f6
commit
b8218bd1f0
@ -11,13 +11,13 @@ works with multiple cloud providers. Currently, the following are supported:
|
||||
* [AWS](https://aws.amazon.com) - Amazon Web Services
|
||||
* [Azure](https://azure.microsoft.com) - Microsoft Azure
|
||||
* [GCP](https://cloud.google.com) - Google Cloud Platform
|
||||
* [Hetzner](https://www.hetzner.com)
|
||||
* [Incus](https://linuxcontainers.org/incus)
|
||||
* [Hetzner](https://www.hetzner.com) - Hetzner Cloud
|
||||
* [Incus](https://linuxcontainers.org/incus) - Incus Containers and Virtual Machines
|
||||
* [NoCloud](
|
||||
https://cloudinit.readthedocs.io/en/latest/reference/datasources/nocloud.html
|
||||
) - cloud-init's NoCloud AWS-compatible user provided data source
|
||||
* [OCI](https://cloud.oracle.com) - Oracle Cloud Infrastructure
|
||||
[Scaleway](https://www.scaleway.com)
|
||||
[Scaleway](https://www.scaleway.com) - Scaleway Cloud
|
||||
|
||||
Tiny Cloud is also used for Alpine Linux's experimental "auto-install" feature.
|
||||
|
||||
@ -52,9 +52,6 @@ As Tiny Cloud is meant to be tiny, it has few dependencies:
|
||||
* `sfdisk`
|
||||
* [`yx`](https://gitlab.com/tomalok/yx) (for extracting data from YAML files)
|
||||
|
||||
Optional dependencies:
|
||||
* `nvme-cli` (for AWS nitro NVMe symlinks)
|
||||
|
||||
_Tiny Cloud has been developed specifically for use with the
|
||||
[Alpine Cloud Images](
|
||||
https://gitlab.alpinelinux.org/alpine/cloud/alpine-cloud-images)
|
||||
|
||||
4
TODO.md
4
TODO.md
@ -2,10 +2,6 @@
|
||||
|
||||
## SOON-ish
|
||||
|
||||
* Move the bulk of `#alpine-config` handler that is compatible with
|
||||
`#cloud-config` to that handler (which is currently just a stub), and only
|
||||
`#alpine-config` extensions remain there.
|
||||
|
||||
* Support cloud auto-detection, where it's possible to do so.
|
||||
|
||||
## FUTURE
|
||||
|
||||
@ -1,176 +1,14 @@
|
||||
# Script UserData Functions
|
||||
# #alpine-config UserData Functions
|
||||
# vim:set filetype=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
INIT_ACTIONS_MAIN="$(insert_before create_default_user userdata_user $INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_MAIN="$(insert_after set_hostname \
|
||||
"userdata_bootcmd userdata_groups userdata_users userdata_write_files userdata_ntp userdata_apk_cache userdata_apk_repositories userdata_package_update userdata_package_upgrade userdata_packages" \
|
||||
$INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_MAIN="$(insert_after set_ssh_keys ssh_authorized_keys $INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_FINAL="$INIT_ACTIONS_FINAL userdata_runcmd userdata_autoinstall"
|
||||
# NOTE: alpine-config extends cloud-config
|
||||
|
||||
get_userdata() {
|
||||
IFS="/"
|
||||
yx -f "$TINY_CLOUD_VAR/user-data" $1 2>/dev/null
|
||||
unset IFS
|
||||
}
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "${LIBDIR}/tiny-cloud/user-data/cloud-config"
|
||||
|
||||
init__userdata_user() {
|
||||
local name="$(get_userdata user/name)"
|
||||
if [ -z "$name" ]; then
|
||||
name="$(get_userdata user)"
|
||||
if [ -n "$(get_userdata user/$name)" ]; then
|
||||
log -s err "user/name is required"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if get_userdata | grep -q -x users; then
|
||||
local default_user="$(get_userdata users/1)"
|
||||
if [ "$default_user" != "default" ]; then
|
||||
CLOUD_USER="$(get_userdata users/1/name)"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
CLOUD_USER="${name:-$CLOUD_USER}"
|
||||
}
|
||||
|
||||
set_ssh_authorized_keys_for() {
|
||||
local user="$1"
|
||||
local userdata_path="$2"
|
||||
local sshkeys="$(get_userdata $userdata_path)"
|
||||
if [ -z "$sshkeys" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local pwent="$(getent passwd "$user")"
|
||||
if [ -z "$pwent" ]; then
|
||||
log -i -t "$phase" err "$ACTION: failed to find user $user"
|
||||
return 1
|
||||
fi
|
||||
local group=$(echo "$pwent" | cut -d: -f4)
|
||||
local ssh_dir="${ROOT}$(echo "$pwent" | cut -d: -f6)/.ssh"
|
||||
local keys_file="$ssh_dir/authorized_keys"
|
||||
|
||||
if [ ! -d "$ssh_dir" ]; then
|
||||
mkdir -p "$ssh_dir"
|
||||
chmod 700 "$ssh_dir"
|
||||
fi
|
||||
|
||||
touch "$keys_file"
|
||||
chmod 600 "$keys_file"
|
||||
$MOCK chown -R "$user:$group" "$ssh_dir"
|
||||
for i in $sshkeys; do
|
||||
local key="$(get_userdata $userdata_path/$i)"
|
||||
if [ -n "$key" ]; then
|
||||
echo "$key" >> "$keys_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
init__ssh_authorized_keys() {
|
||||
if [ -z "$CLOUD_USER" ]; then
|
||||
return
|
||||
fi
|
||||
set_ssh_authorized_keys_for "$CLOUD_USER" ssh_authorized_keys
|
||||
}
|
||||
|
||||
init__userdata_bootcmd() {
|
||||
# run bootcmd
|
||||
local bootcmds="$(get_userdata bootcmd)"
|
||||
for i in $bootcmds; do
|
||||
local cmd="$(get_userdata bootcmd/"$i")"
|
||||
sh -c "$cmd"
|
||||
done
|
||||
}
|
||||
|
||||
# write_file <path> <mode> <owner> <encoding> <append>
|
||||
write_file() {
|
||||
# Defaults used are the same as for full cloud-init "spec":
|
||||
# https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files
|
||||
local path="$1"
|
||||
local mode="${2:-0644}"
|
||||
local owner="${3:-root:root}"
|
||||
local encoding="${4:-text/plain}"
|
||||
local append="${5:-false}"
|
||||
|
||||
if [ "$append" != "true" ] && [ "$append" != "false" ]; then
|
||||
log err "append must be true or false"
|
||||
return
|
||||
fi
|
||||
|
||||
local tmpfile="$(mktemp $TINY_CLOUD_VAR/user-data.write_files.XXXXXX)"
|
||||
|
||||
case "$encoding" in
|
||||
gzip|gz|gz+base64|gzip+base64|gz+b64|gzip+b64)
|
||||
base64 -d | gzip -d > "$tmpfile"
|
||||
;;
|
||||
base64|b64)
|
||||
base64 -d > "$tmpfile"
|
||||
;;
|
||||
text/plain)
|
||||
cat > "$tmpfile"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$append" = "true" ]; then
|
||||
cat "$tmpfile" >> "$path"
|
||||
else
|
||||
cat "$tmpfile" > "$path"
|
||||
fi
|
||||
rm -f "$tmpfile"
|
||||
|
||||
chmod "$mode" "$path"
|
||||
# mocked as we do not know which users we could use in testing
|
||||
# this way we can check the proper invocation at least
|
||||
$MOCK chown "$owner" "$path"
|
||||
}
|
||||
|
||||
init__userdata_write_files() {
|
||||
local files="$(get_userdata write_files)"
|
||||
|
||||
for i in $files; do
|
||||
local path="$(get_userdata write_files/$i/path)"
|
||||
if [ -z "$path" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$ROOT/$path")"
|
||||
get_userdata write_files/$i/content | write_file "$ROOT/$path" \
|
||||
"$(get_userdata write_files/$i/permissions)" \
|
||||
"$(get_userdata write_files/$i/owner)" \
|
||||
"$(get_userdata write_files/$i/encoding)" \
|
||||
"$(get_userdata write_files/$i/append)"
|
||||
done
|
||||
}
|
||||
|
||||
init__userdata_ntp() {
|
||||
local ntp_enabled="$(get_userdata ntp/enabled)"
|
||||
if [ "$ntp_enabled" != "yes" ] && [ "$ntp_enabled" != "true" ]; then
|
||||
return
|
||||
fi
|
||||
local ntp_client="$(get_userdata ntp/ntp_client)"
|
||||
local svc= pkg=
|
||||
case "$ntp_client" in
|
||||
busybox)
|
||||
svc=ntpd
|
||||
;;
|
||||
chrony|"")
|
||||
pkg=chrony
|
||||
svc=chronyd
|
||||
;;
|
||||
openntpd)
|
||||
pkg=openntpd
|
||||
svc=openntpd
|
||||
;;
|
||||
esac
|
||||
if [ -n "$pkg" ]; then
|
||||
$MOCK apk add "$pkg"
|
||||
fi
|
||||
if [ -n "$svc" ]; then
|
||||
$MOCK rc-update add "$svc" default
|
||||
$MOCK rc-service "$svc" start
|
||||
fi
|
||||
}
|
||||
INIT_ACTIONS_MAIN="$(insert_after userdata_ntp "userdata_apk_cache userdata_apk_repositories" $INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_FINAL="$INIT_ACTIONS_FINAL userdata_autoinstall"
|
||||
|
||||
init__userdata_apk_cache() {
|
||||
local cache="$(get_userdata apk/cache)"
|
||||
@ -215,142 +53,8 @@ init__userdata_apk_repositories() {
|
||||
done
|
||||
}
|
||||
|
||||
init__userdata_package_update() {
|
||||
local update="$(get_userdata package_update)"
|
||||
if [ "$update" = "true" ]; then
|
||||
$MOCK apk update
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_package_upgrade() {
|
||||
local upgrade="$(get_userdata package_upgrade)"
|
||||
if [ "$upgrade" = "true" ]; then
|
||||
$MOCK apk upgrade
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_packages() {
|
||||
local packages="$(get_userdata packages)"
|
||||
local pkgs=
|
||||
for i in $packages; do
|
||||
pkgs="$pkgs $(get_userdata packages/$i)"
|
||||
done
|
||||
if [ -n "$pkgs" ]; then
|
||||
$MOCK apk add $pkgs
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_runcmd() {
|
||||
local runcmds="$(get_userdata runcmd)"
|
||||
for i in $runcmds; do
|
||||
local cmd="$(get_userdata runcmd/$i)"
|
||||
sh -c "$cmd"
|
||||
done
|
||||
}
|
||||
|
||||
init__userdata_groups() {
|
||||
local groups="$(get_userdata groups)"
|
||||
for i in $groups; do
|
||||
local group="$(get_userdata groups/$i)"
|
||||
$MOCK addgroup $group
|
||||
done
|
||||
}
|
||||
|
||||
in_list() {
|
||||
local i needle="$1"
|
||||
shift
|
||||
for i in "$@"; do
|
||||
if [ "$i" = "$needle" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
init__userdata_users() {
|
||||
local users="$(get_userdata users)"
|
||||
for i in $users; do
|
||||
local name gecos homedir shell primary_group groups
|
||||
local system=false no_create_home=false lock_passwd=true
|
||||
local keys="$(get_userdata users/$i)"
|
||||
if [ "$i" = 1 ] && [ "$keys" = "default" ]; then
|
||||
continue
|
||||
fi
|
||||
if in_list name $keys; then
|
||||
name="$(get_userdata users/$i/name)"
|
||||
else
|
||||
continue
|
||||
fi
|
||||
if in_list gecos $keys; then
|
||||
gecos="$(get_userdata users/$i/gecos)"
|
||||
fi
|
||||
if in_list homedir $keys; then
|
||||
homedir="$(get_userdata users/$i/homedir)"
|
||||
fi
|
||||
if in_list shell $keys; then
|
||||
shell="$(get_userdata users/$i/shell)"
|
||||
fi
|
||||
if in_list primary_group $keys; then
|
||||
primary_group="$(get_userdata users/$i/primary_group)"
|
||||
fi
|
||||
if in_list system $keys; then
|
||||
system="$(get_userdata users/$i/system)"
|
||||
fi
|
||||
if in_list no_create_home $keys; then
|
||||
no_create_home="$(get_userdata users/$i/no_create_home)"
|
||||
fi
|
||||
|
||||
if getent passwd "$user" >/dev/null; then
|
||||
log -i -t "$phase" info "$ACTION: user $user already exists"
|
||||
else
|
||||
if [ "$system" != "true" ]; then
|
||||
unset system
|
||||
fi
|
||||
if [ "$no_create_home" != "true" ]; then
|
||||
unset no_create_home
|
||||
fi
|
||||
$MOCK adduser -D ${gecos:+-g "$gecos"} ${homedir:+-h "$homedir"} ${shell:+-s "$shell"} ${primary_group:+-G "$primary_group"} ${system:+-S} ${no_create_home:+-H} "$name"
|
||||
fi
|
||||
|
||||
if in_list lock_passwd $keys; then
|
||||
lock_passwd="$(get_userdata users/$i/lock_passwd)"
|
||||
fi
|
||||
|
||||
if [ "$lock_passwd" != "false" ]; then
|
||||
echo "$name:*" | $MOCK chpasswd -e
|
||||
fi
|
||||
|
||||
if in_list ssh_authorized_keys $keys; then
|
||||
set_ssh_authorized_keys_for "$name" users/$i/ssh_authorized_keys
|
||||
fi
|
||||
|
||||
if in_list groups $keys; then
|
||||
groups="$(get_userdata users/$i/groups | tr ',' ' ')"
|
||||
local group
|
||||
for group in $groups; do
|
||||
$MOCK addgroup "$name" "$group"
|
||||
done
|
||||
fi
|
||||
if in_list doas $keys; then
|
||||
if [ -d "$ROOT/etc/doas.d" ]; then
|
||||
touch "$ROOT/etc/doas.d/$name.conf"
|
||||
chmod 660 "$ROOT/etc/doas.d/$name.conf"
|
||||
fi
|
||||
local j
|
||||
for j in $(get_userdata users/$i/doas); do
|
||||
local line="$(get_userdata users/$i/doas/$j)"
|
||||
if [ -d "$ROOT/etc/doas.d" ]; then
|
||||
echo "$line" >> "$ROOT/etc/doas.d/$name.conf"
|
||||
elif [ -f "$ROOT/etc/doas.conf" ]; then
|
||||
add_once "$ROOT/etc/doas.conf" "$line"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
find_biggest_empty_disk() {
|
||||
local d
|
||||
local d p
|
||||
for d in "$ROOT"/sys/class/block/*/device; do
|
||||
p=${d%/device}
|
||||
if [ -e "$p"/size ] && [ -z "$(blkid /dev/${p##*/})" ]; then
|
||||
|
||||
@ -1,5 +1,309 @@
|
||||
# CloudConfig UserData Functions
|
||||
# #cloud-config UserData Functions
|
||||
# vim:set filetype=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
# TODO
|
||||
# NOTE: This is only a subset of what cloud-init supports!
|
||||
|
||||
INIT_ACTIONS_MAIN="$(insert_before create_default_user userdata_user $INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_MAIN="$(insert_after set_hostname \
|
||||
"userdata_bootcmd userdata_groups userdata_users userdata_write_files userdata_ntp userdata_package_update userdata_package_upgrade userdata_packages" \
|
||||
$INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_MAIN="$(insert_after set_ssh_keys ssh_authorized_keys $INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_FINAL="$INIT_ACTIONS_FINAL userdata_runcmd"
|
||||
|
||||
get_userdata() {
|
||||
IFS="/"
|
||||
yx -f "$TINY_CLOUD_VAR/user-data" $1 2>/dev/null
|
||||
unset IFS
|
||||
}
|
||||
|
||||
init__userdata_user() {
|
||||
local name="$(get_userdata user/name)"
|
||||
if [ -z "$name" ]; then
|
||||
name="$(get_userdata user)"
|
||||
if [ -n "$(get_userdata user/$name)" ]; then
|
||||
log -s err "user/name is required"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if get_userdata | grep -q -x users; then
|
||||
local default_user="$(get_userdata users/1)"
|
||||
if [ "$default_user" != "default" ]; then
|
||||
CLOUD_USER="$(get_userdata users/1/name)"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
CLOUD_USER="${name:-$CLOUD_USER}"
|
||||
}
|
||||
|
||||
set_ssh_authorized_keys_for() {
|
||||
local user="$1"
|
||||
local userdata_path="$2"
|
||||
local sshkeys="$(get_userdata $userdata_path)"
|
||||
if [ -z "$sshkeys" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local pwent="$(getent passwd "$user")"
|
||||
if [ -z "$pwent" ]; then
|
||||
log -i -t "$phase" err "$ACTION: failed to find user $user"
|
||||
return 1
|
||||
fi
|
||||
local group=$(echo "$pwent" | cut -d: -f4)
|
||||
local ssh_dir="${ROOT}$(echo "$pwent" | cut -d: -f6)/.ssh"
|
||||
local keys_file="$ssh_dir/authorized_keys"
|
||||
|
||||
if [ ! -d "$ssh_dir" ]; then
|
||||
mkdir -p "$ssh_dir"
|
||||
chmod 700 "$ssh_dir"
|
||||
fi
|
||||
|
||||
touch "$keys_file"
|
||||
chmod 600 "$keys_file"
|
||||
$MOCK chown -R "$user:$group" "$ssh_dir"
|
||||
for i in $sshkeys; do
|
||||
local key="$(get_userdata $userdata_path/$i)"
|
||||
if [ -n "$key" ]; then
|
||||
echo "$key" >> "$keys_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
init__ssh_authorized_keys() {
|
||||
if [ -z "$CLOUD_USER" ]; then
|
||||
return
|
||||
fi
|
||||
set_ssh_authorized_keys_for "$CLOUD_USER" ssh_authorized_keys
|
||||
}
|
||||
|
||||
init__userdata_bootcmd() {
|
||||
# run bootcmd
|
||||
local bootcmds="$(get_userdata bootcmd)"
|
||||
for i in $bootcmds; do
|
||||
local cmd="$(get_userdata bootcmd/"$i")"
|
||||
sh -c "$cmd"
|
||||
done
|
||||
}
|
||||
|
||||
# write_file <path> <mode> <owner> <encoding> <append>
|
||||
write_file() {
|
||||
# Defaults used are the same as for full cloud-init "spec":
|
||||
# https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files
|
||||
local path="$1"
|
||||
local mode="${2:-0644}"
|
||||
local owner="${3:-root:root}"
|
||||
local encoding="${4:-text/plain}"
|
||||
local append="${5:-false}"
|
||||
|
||||
if [ "$append" != "true" ] && [ "$append" != "false" ]; then
|
||||
log err "append must be true or false"
|
||||
return
|
||||
fi
|
||||
|
||||
local tmpfile="$(mktemp $TINY_CLOUD_VAR/user-data.write_files.XXXXXX)"
|
||||
|
||||
case "$encoding" in
|
||||
gzip|gz|gz+base64|gzip+base64|gz+b64|gzip+b64)
|
||||
base64 -d | gzip -d > "$tmpfile"
|
||||
;;
|
||||
base64|b64)
|
||||
base64 -d > "$tmpfile"
|
||||
;;
|
||||
text/plain)
|
||||
cat > "$tmpfile"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$append" = "true" ]; then
|
||||
cat "$tmpfile" >> "$path"
|
||||
else
|
||||
cat "$tmpfile" > "$path"
|
||||
fi
|
||||
rm -f "$tmpfile"
|
||||
|
||||
chmod "$mode" "$path"
|
||||
# mocked as we do not know which users we could use in testing
|
||||
# this way we can check the proper invocation at least
|
||||
$MOCK chown "$owner" "$path"
|
||||
}
|
||||
|
||||
init__userdata_write_files() {
|
||||
local files="$(get_userdata write_files)"
|
||||
|
||||
for i in $files; do
|
||||
local path="$(get_userdata write_files/$i/path)"
|
||||
if [ -z "$path" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$ROOT/$path")"
|
||||
get_userdata write_files/$i/content | write_file "$ROOT/$path" \
|
||||
"$(get_userdata write_files/$i/permissions)" \
|
||||
"$(get_userdata write_files/$i/owner)" \
|
||||
"$(get_userdata write_files/$i/encoding)" \
|
||||
"$(get_userdata write_files/$i/append)"
|
||||
done
|
||||
}
|
||||
|
||||
init__userdata_ntp() {
|
||||
local ntp_enabled="$(get_userdata ntp/enabled)"
|
||||
if [ "$ntp_enabled" != "yes" ] && [ "$ntp_enabled" != "true" ]; then
|
||||
return
|
||||
fi
|
||||
local ntp_client="$(get_userdata ntp/ntp_client)"
|
||||
local svc= pkg=
|
||||
case "$ntp_client" in
|
||||
busybox)
|
||||
svc=ntpd
|
||||
;;
|
||||
chrony|"")
|
||||
pkg=chrony
|
||||
svc=chronyd
|
||||
;;
|
||||
openntpd)
|
||||
pkg=openntpd
|
||||
svc=openntpd
|
||||
;;
|
||||
esac
|
||||
if [ -n "$pkg" ]; then
|
||||
$MOCK apk add "$pkg"
|
||||
fi
|
||||
if [ -n "$svc" ]; then
|
||||
$MOCK rc-update add "$svc" default
|
||||
$MOCK rc-service "$svc" start
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_package_update() {
|
||||
local update="$(get_userdata package_update)"
|
||||
if [ "$update" = "true" ]; then
|
||||
$MOCK apk update
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_package_upgrade() {
|
||||
local upgrade="$(get_userdata package_upgrade)"
|
||||
if [ "$upgrade" = "true" ]; then
|
||||
$MOCK apk upgrade
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_packages() {
|
||||
local packages="$(get_userdata packages)"
|
||||
local pkgs=
|
||||
for i in $packages; do
|
||||
pkgs="$pkgs $(get_userdata packages/$i)"
|
||||
done
|
||||
if [ -n "$pkgs" ]; then
|
||||
$MOCK apk add $pkgs
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_runcmd() {
|
||||
local runcmds="$(get_userdata runcmd)"
|
||||
for i in $runcmds; do
|
||||
local cmd="$(get_userdata runcmd/$i)"
|
||||
sh -c "$cmd"
|
||||
done
|
||||
}
|
||||
|
||||
init__userdata_groups() {
|
||||
local groups="$(get_userdata groups)"
|
||||
for i in $groups; do
|
||||
local group="$(get_userdata groups/$i)"
|
||||
$MOCK addgroup $group
|
||||
done
|
||||
}
|
||||
|
||||
in_list() {
|
||||
local i needle="$1"
|
||||
shift
|
||||
for i in "$@"; do
|
||||
if [ "$i" = "$needle" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
init__userdata_users() {
|
||||
local users="$(get_userdata users)"
|
||||
for i in $users; do
|
||||
local name gecos homedir shell primary_group groups
|
||||
local system=false no_create_home=false lock_passwd=true
|
||||
local keys="$(get_userdata users/$i)"
|
||||
if [ "$i" = 1 ] && [ "$keys" = "default" ]; then
|
||||
continue
|
||||
fi
|
||||
if in_list name $keys; then
|
||||
name="$(get_userdata users/$i/name)"
|
||||
else
|
||||
continue
|
||||
fi
|
||||
if in_list gecos $keys; then
|
||||
gecos="$(get_userdata users/$i/gecos)"
|
||||
fi
|
||||
if in_list homedir $keys; then
|
||||
homedir="$(get_userdata users/$i/homedir)"
|
||||
fi
|
||||
if in_list shell $keys; then
|
||||
shell="$(get_userdata users/$i/shell)"
|
||||
fi
|
||||
if in_list primary_group $keys; then
|
||||
primary_group="$(get_userdata users/$i/primary_group)"
|
||||
fi
|
||||
if in_list system $keys; then
|
||||
system="$(get_userdata users/$i/system)"
|
||||
fi
|
||||
if in_list no_create_home $keys; then
|
||||
no_create_home="$(get_userdata users/$i/no_create_home)"
|
||||
fi
|
||||
|
||||
if getent passwd "$user" >/dev/null; then
|
||||
log -i -t "$phase" info "$ACTION: user $user already exists"
|
||||
else
|
||||
if [ "$system" != "true" ]; then
|
||||
unset system
|
||||
fi
|
||||
if [ "$no_create_home" != "true" ]; then
|
||||
unset no_create_home
|
||||
fi
|
||||
$MOCK adduser -D ${gecos:+-g "$gecos"} ${homedir:+-h "$homedir"} ${shell:+-s "$shell"} ${primary_group:+-G "$primary_group"} ${system:+-S} ${no_create_home:+-H} "$name"
|
||||
fi
|
||||
|
||||
if in_list lock_passwd $keys; then
|
||||
lock_passwd="$(get_userdata users/$i/lock_passwd)"
|
||||
fi
|
||||
|
||||
if [ "$lock_passwd" != "false" ]; then
|
||||
echo "$name:*" | $MOCK chpasswd -e
|
||||
fi
|
||||
|
||||
if in_list ssh_authorized_keys $keys; then
|
||||
set_ssh_authorized_keys_for "$name" users/$i/ssh_authorized_keys
|
||||
fi
|
||||
|
||||
if in_list groups $keys; then
|
||||
groups="$(get_userdata users/$i/groups | tr ',' ' ')"
|
||||
local group
|
||||
for group in $groups; do
|
||||
$MOCK addgroup "$name" "$group"
|
||||
done
|
||||
fi
|
||||
if in_list doas $keys; then
|
||||
if [ -d "$ROOT/etc/doas.d" ]; then
|
||||
touch "$ROOT/etc/doas.d/$name.conf"
|
||||
chmod 660 "$ROOT/etc/doas.d/$name.conf"
|
||||
fi
|
||||
local j
|
||||
for j in $(get_userdata users/$i/doas); do
|
||||
local line="$(get_userdata users/$i/doas/$j)"
|
||||
if [ -d "$ROOT/etc/doas.d" ]; then
|
||||
echo "$line" >> "$ROOT/etc/doas.d/$name.conf"
|
||||
elif [ -f "$ROOT/etc/doas.conf" ]; then
|
||||
add_once "$ROOT/etc/doas.conf" "$line"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user