1
0
mirror of https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git synced 2025-12-15 11:22:43 +03:00

Fixes for tiny-cloud Wrapper

* switch early/main/init functions --> variables containing list of actions
* functions usable as init actions are named starting with 'init__'
* fix/refine output during init
This commit is contained in:
Jake Buchholz Göktürk 2023-05-01 21:29:41 -07:00
parent 3894cd9f8d
commit 4b86923358
2 changed files with 103 additions and 114 deletions

View File

@ -8,19 +8,28 @@
: "${SKIP_INIT_ACTIONS:=}"
: "${HOTPLUG_TYPE:=mdev}"
# TODO: default phase actions
### default phase actions (without leading 'init__')
# ensure existence of output directories
[ ! -d "$TINY_CLOUD_LOGS" ] && mkdir -p "$TINY_CLOUD_LOGS"
[ ! -d "$TINY_CLOUD_VAR" ] && mkdir -p "$TINY_CLOUD_VAR"
INIT_ACTIONS_EARLY="
expand_root
install_hotplugs
"
INIT_ACTIONS_MAIN="
save_userdata
set_hostname
set_ssh_keys
"
INIT_ACTIONS_FINAL="
run_userdata
"
### NOTE: init-early functions...
# try to ensure existence of output directories, but otherwise don't panic
[ ! -d "$TINY_CLOUD_LOGS" ] && mkdir -p "$TINY_CLOUD_LOGS" || true
[ ! -d "$TINY_CLOUD_VAR" ] && mkdir -p "$TINY_CLOUD_VAR" || true
expand_root() {
skip_action expand_root && return
echo "Expanding Root Volume/ Partition"
### init-early functions...
init__expand_root() {
local dev=$(awk '$2 == "/" {print $1}' "$ROOT"/proc/mounts)
local partition=$(cat "$ROOT/sys/class/block/${dev#/dev/}/partition" 2>/dev/null)
@ -35,36 +44,29 @@ expand_root() {
$MOCK resize2fs "$dev"
}
install_hotplugs() {
skip_action install_hotplugs && return
[ ! -n "$HOTPLUG_MODULES" ] && return
echo "Installing Cloud Hotplugs"
init__install_hotplugs() {
local result rc=0
[ ! -n "$HOTPLUG_MODULES" ] && return
if [ -f "$LIBDIR/tiny-cloud/$HOTPLUG_TYPE" ]; then
. "$LIBDIR/tiny-cloud/$HOTPLUG_TYPE"
. "$LIBDIR/tiny-cloud/$HOTPLUG_TYPE"
fi
printf ':' >&2
for module in $HOTPLUG_MODULES; do
result='-'
printf " $module"
result='?'
printf "$module" >&2
if type "mod__$module" | grep -q -w "function"; then
"mod__$module" && result='+' || { result='!'; rc=1; }
fi
printf "($result)"
printf '(%s) ' $result >&2
done
return $rc
}
### NOTE: init-main functions
set_hostname() {
skip_action set_hostname && return
echo "Setting Instance Hostname"
### init-main functions
init__set_hostname() {
local fqdn=$(imds @hostname)
local host="${fqdn%%\.*}"
@ -74,11 +76,7 @@ set_hostname() {
echo -e "127.0.1.1\t$fqdn $host" >> "$ROOT"/etc/hosts
}
set_ssh_keys() {
skip_action set_ssh_keys && return
echo "Installing SSH Keys for $CLOUD_USER User"
init__set_ssh_keys() {
local user="$CLOUD_USER"
local pwent="$(getent passwd "$user")"
local group=$(echo "$pwent" | cut -d: -f4)
@ -96,87 +94,61 @@ set_ssh_keys() {
imds @ssh-keys > "$keys_file"
}
save_userdata() {
skip_action save_userdata && return
# TODO: this trips save_userdata_* and run_userdata tests: "stdout not empty"
#echo "Saving Instance UserData"
init__save_userdata() {
local userdata="$TINY_CLOUD_VAR/user-data"
local tmpfile=$(mktemp "$userdata.XXXXXX")
local cmd
imds -e @userdata > "$tmpfile"
cmd="cat"
if ! skip_action decompress_userdata; then
if printf '\037\213\010' | cmp -s -n 3 "$tmpfile"; then
gzip -dc "$tmpfile" > "$userdata"
elif printf 'BZh' | cmp -s -n 3 "$tmpfile"; then
bzip2 -dc "$tmpfile" > "$userdata"
elif printf '\375\067\172\130\132\000' | cmp -s -n 6 "$tmpfile"; then
unxz -c "$tmpfile" > "$userdata"
elif printf '\135\000\000' | cmp -s -n 3 "$tmpfile"; then
lzma -dc "$tmpfile" > "$userdata"
elif printf '\211\114\132' | cmp -s -n 3 "$tmpfile"; then
lzop -dc "$tmpfile" > "$userdata"
elif printf '\004\042\115\030' | cmp -s -n 4 "$tmpfile"; then
lz4 -dc "$tmpfile" > "$userdata"
elif printf '(\265/\375' | cmp -s -n 4 "$tmpfile"; then
zstd -dc "$tmpfile" > "$userdata"
else
cp "$tmpfile" "$userdata"
fi
if printf '\037\213\010' | cmp -s -n 3 "$tmpfile"; then
gzip -dc "$tmpfile" > "$userdata"
elif printf 'BZh' | cmp -s -n 3 "$tmpfile"; then
bzip2 -dc "$tmpfile" > "$userdata"
elif printf '\375\067\172\130\132\000' | cmp -s -n 6 "$tmpfile"; then
unxz -c "$tmpfile" > "$userdata"
elif printf '\135\000\000' | cmp -s -n 3 "$tmpfile"; then
lzma -dc "$tmpfile" > "$userdata"
elif printf '\211\114\132' | cmp -s -n 3 "$tmpfile"; then
lzop -dc "$tmpfile" > "$userdata"
elif printf '\004\042\115\030' | cmp -s -n 4 "$tmpfile"; then
lz4 -dc "$tmpfile" > "$userdata"
elif printf '(\265/\375' | cmp -s -n 4 "$tmpfile"; then
zstd -dc "$tmpfile" > "$userdata"
else
cp "$tmpfile" "$userdata"
fi
rm "$tmpfile"
}
### TODO: init-final functions
run_userdata() {
skip_action run_userdata && return
if [ $(userdata_type) != "script" ]; then
echo "UserData is not executable"
return
fi
echo "Executing UserData Script"
### init-final functions
init__run_userdata() {
local log="$TINY_CLOUD_LOGS/user-data.log"
local exit="$TINY_CLOUD_LOGS/user-data.exit"
local userdata="$TINY_CLOUD_VAR/user-data"
if [ $(userdata_type) != "script" ]; then
printf '(Not Executable) ' >&2
return
fi
chmod +x "$userdata"
{ "$userdata" 2>& 1; echo $? > "$exit"; } | tee "$log"
return $(cat "$exit")
}
### potentially override the above, per cloud
# load cloud-specific init functions / vars
if [ -f "$LIBDIR/tiny-cloud/cloud/$CLOUD/init" ]; then
. "$LIBDIR/tiny-cloud/cloud/$CLOUD/init"
. "$LIBDIR/tiny-cloud/cloud/$CLOUD/init"
fi
# TODO: load user-data type-specific init functions / vars
### non-overrideable functions
# should we skip this action?
skip_action() {
local action="$1"
for i in $SKIP_INIT_ACTIONS; do
if [ "$i" = "$action" ]; then
printf " SKIPPING"
return 0
fi
done
return 1
}
# this should be non-overrideable, but need this before we...
userdata_type() {
if [ -f "$TINY_CLOUD_VAR/user-data" ]; then
header=$(head -n1 "$TINY_CLOUD_VAR/user-data")
header=$(head -n1 "$TINY_CLOUD_VAR/user-data" | sed -e 's/[[:space:]].*//g')
case "$header" in
'#cloud-config') echo cloud-config;;
'#!'*) echo script;;
@ -186,3 +158,6 @@ userdata_type() {
echo missing
fi
}
# ...load user-data type-specific init functions / vars
# TODO

View File

@ -14,18 +14,15 @@ Usage: ${0##*/} [-h | --help] { early | main | final | --bootstrap {complete|inc
EOF
}
bootstrap_complete() {
echo "Marking Instance Bootstrap Complete"
init__bootstrap_complete() {
touch "$TINY_CLOUD_VAR/.bootstrap-complete"
}
bootstrap_incomplete() {
echo "Marking Instance Bootstrap Incomplete"
init__bootstrap_incomplete() {
rm -f "$TINY_CLOUD_VAR/.bootstrap-complete"
}
args=$(getopt -o hb: --long help,bootstrap: -n ${0##*/} -- "$@")
if [ $? -ne 0 ]; then
if [ $? -ne 0 ] || [ $# -eq 0 ]; then
usage >&2
exit 1
fi
@ -36,11 +33,12 @@ while true; do
-b|--bootstrap) shift
case "$1" in
complete) # indicate bootstrap is done
bootstrap_complete;;
init__bootstrap_complete;;
incomplete) # indicate bootstrap isn't done
bootstrap_incomplete;;
init__bootstrap_incomplete;;
*) usage >&2; exit 1;;
esac
printf ' bootstrap marked "%s"\n' "$1" >&2
exit 0;;
--) shift; break;;
*) usage >&2; exit 1;;
@ -58,32 +56,48 @@ esac
# is initial bootstrap already done?
if [ -f "$TINY_CLOUD_VAR/.bootstrap-complete" ]; then
log -s "Already bootstrapped"
printf ' already bootstrapped\n' >&2
exit 0;
fi
### default phase actions
# TODO? represent as vars containing lists of funcs?
early() {
expand_root
install_hotplugs
}
main() {
save_userdata
set_hostname
set_ssh_keys
}
final() {
run_userdata
bootstrap_complete
}
# load init functions
. "$LIBDIR/tiny-cloud/init"
# TODO? for loop over list of funcs? -- better for ebegin/eend-ish output
echo $phase "$@"
### non-overrideable stuff
# should we skip this action?
skip_action() {
local action="$1"
for i in $SKIP_INIT_ACTIONS; do
if [ "$i" = "$action" ]; then
return 0
fi
done
return 1
}
# mandatory final action...
INIT_ACTIONS_FINAL="${INIT_ACTIONS_FINAL} bootstrap_complete"
### let's do stuff!
case "$phase" in
early) INIT_ACTIONS="$INIT_ACTIONS_EARLY";;
main) INIT_ACTIONS="$INIT_ACTIONS_MAIN";;
final) INIT_ACTIONS="$INIT_ACTIONS_FINAL";;
*) usage >&2; exit 1
esac
for ACTION in $INIT_ACTIONS; do
if skip_action "$ACTION"; then
printf '\n -- %s : [SKIP]' $ACTION >&2
continue
fi
printf '\n ++ %s ' $ACTION >&2
RESULT="UNKNOWN"
if type "init__$ACTION" | grep -q -w "function"; then
"init__$ACTION" "$@" && RESULT="DONE" || RESULT="FAIL"
fi
printf ': [%s]' $RESULT >&2
done
echo >&2