mirror of
https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git
synced 2025-12-14 19:02:45 +03:00
Consolidate init functionality in /sbin/tiny-cloud
This commit is contained in:
parent
762fe36bb8
commit
81869cefcc
21
CHANGELOG.md
21
CHANGELOG.md
@ -1,10 +1,25 @@
|
||||
# NEXT
|
||||
# CHANGELOG
|
||||
|
||||
* `nvme-ebs-symlinks` hase been _deprecated_ and disabled by default. The **mdev-conf** package, as of v4.4 is now responsible for maintaining NVMe device symlinks for AWS.
|
||||
## 2023-04-XX - Tiny Cloud v3.0.0
|
||||
|
||||
***WARNING:*** The behavior of **mdev-conf** is slightly different -- only **/dev/sd** or **/dev/xvd** symlinks are created, *not both*!
|
||||
* Tiny Cloud init functionality has been consolidated into **/sbin/tiny-cloud**
|
||||
and init scripts should use `tiny-cloud <phase>` to indicate whether `early`,
|
||||
`main`, or `final` actions should be taken. Additionally, it is now possible
|
||||
for clouds to specify their own (or supercede the default) init functions
|
||||
and/or change which init phase they are executed in.
|
||||
|
||||
The example OpenRC init scripts been updated and moved to **dist/openrc/**.
|
||||
|
||||
* Tiny Cloud configuration has moved to **/etc/tiny-cloud.conf**.
|
||||
|
||||
* `nvme-ebs-symlinks` has been _deprecated_ and disabled by default. The
|
||||
**mdev-conf** package, as of v4.4 is now responsible for maintaining NVMe
|
||||
device symlinks for AWS.
|
||||
|
||||
***WARNING:*** The behavior of **mdev-conf** is slightly different -- either
|
||||
**/dev/sd** or **/dev/xvd** symlinks are created as indicated in NVMe device
|
||||
metadata, *but NOT both*!
|
||||
|
||||
|
||||
----
|
||||
_CHANGELOG begins 2023-04-29_
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2017-2022 Jake Buchholz Göktürk, Michael Crute
|
||||
Copyright (c) 2017-2023 Jake Buchholz Göktürk, Michael Crute
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
||||
7
Makefile
7
Makefile
@ -11,11 +11,13 @@ core:
|
||||
bin/imds
|
||||
install -Dm644 -t "$(PREFIX)"/lib/tiny-cloud \
|
||||
lib/tiny-cloud/common \
|
||||
lib/tiny-cloud/init-* \
|
||||
lib/tiny-cloud/init \
|
||||
lib/tiny-cloud/mdev \
|
||||
lib/tiny-cloud/tiny-cloud.conf
|
||||
install -Dm644 lib/tiny-cloud/tiny-cloud.conf \
|
||||
"$(PREFIX)"/etc/tiny-cloud.conf
|
||||
install -Dm755 -t "$(PREFIX)"/sbin \
|
||||
sbin/tiny-cloud
|
||||
|
||||
network:
|
||||
install -Dm644 -t "$(PREFIX)"/etc/network/interfaces.d \
|
||||
@ -23,7 +25,8 @@ network:
|
||||
install -Dm755 -t "$(PREFIX)"/lib/mdev \
|
||||
lib/mdev/vnic-eth-hotplug
|
||||
install -Dm755 -t "$(PREFIX)"/sbin \
|
||||
sbin/*
|
||||
sbin/assemble-interfaces \
|
||||
sbin/imds-net-sync
|
||||
install -Dm755 -t "$(PREFIX)"/usr/libexec/ifupdown-ng \
|
||||
usr/libexec/ifupdown-ng/imds
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ instance:
|
||||
Optional features, which may not be universally necessary:
|
||||
* manage hotpluggable network interfaces
|
||||
* sync IMDS-provided secondary IPv4 and IPv6 addresses network interfaces
|
||||
* manage symlinks from NVMe block devices to `/dev/xvd` and `/dev/sd` devices
|
||||
* manage symlinks from NVMe block devices to `/dev/xvd` or `/dev/sd` devices
|
||||
(i.e. AWS Nitro instances)
|
||||
|
||||
Also included is a handy `imds` client script for easy access to an instance's
|
||||
|
||||
18
TODO.md
Normal file
18
TODO.md
Normal file
@ -0,0 +1,18 @@
|
||||
# TODO
|
||||
|
||||
## Tiny Cloud v3.0.0
|
||||
|
||||
* Support for Alpine Linux ISO auto-install via NoCloud `CIDATA` volumes, which
|
||||
have pre-network access to UserData and MetaData. Adjust phase actions as
|
||||
appropriate.
|
||||
|
||||
* Detect UserData content type. In addition to handling `#!` scripts and raw
|
||||
data, provide basic handling a subset of `#cloud-config` directives.
|
||||
|
||||
## FUTURE
|
||||
|
||||
* `imds-net-sync` improvements
|
||||
* Feature parity with current [amazon-ec2-net-utils](
|
||||
https://github.com/amazonlinux/amazon-ec2-net-utils)
|
||||
* Support for non-AWS clouds
|
||||
* daemonize to pick up IMDS network changes between reboots
|
||||
24
dist/openrc/tiny-cloud
vendored
24
dist/openrc/tiny-cloud
vendored
@ -4,31 +4,17 @@
|
||||
description="Tiny Cloud Bootstrap - main phase"
|
||||
extra_commands="complete incomplete"
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR"/tiny-cloud/init-main
|
||||
|
||||
depend() {
|
||||
need net
|
||||
before sshd
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
is_bootstrapped && return 0
|
||||
|
||||
ebegin "Saving Instance UserData"
|
||||
save_userdata
|
||||
eend $?
|
||||
|
||||
ebegin "Setting Instance Hostname"
|
||||
set_hostname
|
||||
eend $?
|
||||
|
||||
ebegin "Installing SSH Keys for $CLOUD_USER User"
|
||||
set_ssh_keys "$CLOUD_USER"
|
||||
ebegin "Tiny Cloud - main phase"
|
||||
tiny-cloud main
|
||||
eend $?
|
||||
}
|
||||
|
||||
# allow setting / unsetting of bootstrap state
|
||||
complete() { bootstrap_complete ; }
|
||||
incomplete() { bootstrap_incomplete ; }
|
||||
# allow setting / unsetting of bootstrapped state
|
||||
complete() { tiny-cloud --bootstrap complete ; }
|
||||
incomplete() { tiny-cloud --bootstrap incomplete ; }
|
||||
|
||||
18
dist/openrc/tiny-cloud-early
vendored
18
dist/openrc/tiny-cloud-early
vendored
@ -3,25 +3,13 @@
|
||||
|
||||
description="Tiny Cloud Bootstrap - early phase"
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
|
||||
depend() {
|
||||
after root
|
||||
after root logger
|
||||
before net
|
||||
}
|
||||
|
||||
start() {
|
||||
. "$LIBDIR"/tiny-cloud/init-early
|
||||
|
||||
is_bootstrapped && return 0
|
||||
|
||||
ebegin "Expanding Root Volume/Partition"
|
||||
expand_root
|
||||
ebegin "Tiny Cloud - early phase"
|
||||
tiny-cloud early
|
||||
eend $?
|
||||
|
||||
if has_cloud_hotplugs; then
|
||||
ebegin "Installing Cloud Hotplugs"
|
||||
install_hotplugs
|
||||
eend $?
|
||||
fi
|
||||
}
|
||||
|
||||
16
dist/openrc/tiny-cloud-final
vendored
16
dist/openrc/tiny-cloud-final
vendored
@ -3,25 +3,13 @@
|
||||
|
||||
description="Tiny Cloud Bootstrap - final phase"
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
|
||||
depend() {
|
||||
after *
|
||||
provide cloud-final
|
||||
}
|
||||
|
||||
start() {
|
||||
. "$LIBDIR"/tiny-cloud/init-final
|
||||
|
||||
is_bootstrapped && return 0
|
||||
|
||||
if is_userdata_script; then
|
||||
ebegin "Executing UserData Script"
|
||||
run_userdata
|
||||
eend $?
|
||||
fi
|
||||
|
||||
ebegin "Marking Instance Bootstrap Complete"
|
||||
bootstrap_complete
|
||||
ebegin "Tiny Cloud - final phase"
|
||||
tiny-cloud final
|
||||
eend $?
|
||||
}
|
||||
|
||||
188
lib/tiny-cloud/init
Normal file
188
lib/tiny-cloud/init
Normal file
@ -0,0 +1,188 @@
|
||||
# Tiny Cloud - Init Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
|
||||
# set defaults
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR"/tiny-cloud/common
|
||||
|
||||
: "${SKIP_INIT_ACTIONS:=}"
|
||||
: "${HOTPLUG_TYPE:=mdev}"
|
||||
|
||||
# TODO: default phase actions
|
||||
|
||||
# ensure existence of output directories
|
||||
[ ! -d "$TINY_CLOUD_LOGS" ] && mkdir -p "$TINY_CLOUD_LOGS"
|
||||
[ ! -d "$TINY_CLOUD_VAR" ] && mkdir -p "$TINY_CLOUD_VAR"
|
||||
|
||||
### NOTE: init-early functions...
|
||||
|
||||
expand_root() {
|
||||
skip_action expand_root && return
|
||||
|
||||
echo "Expanding Root Volume/ Partition"
|
||||
|
||||
local dev=$(awk '$2 == "/" {print $1}' "$ROOT"/proc/mounts)
|
||||
local partition=$(cat "$ROOT/sys/class/block/${dev#/dev/}/partition" 2>/dev/null)
|
||||
|
||||
if [ -n "$partition" ]; then
|
||||
# it's a partition, resize it
|
||||
local volume=$(readlink -f "$ROOT/sys/class/block/${dev#/dev/}/..")
|
||||
volume="/dev/${volume##*/}"
|
||||
echo ", +" | $MOCK sfdisk -q --no-reread -N "$partition" "$volume"
|
||||
$MOCK partx -u "$volume"
|
||||
fi
|
||||
# resize filesystem
|
||||
$MOCK resize2fs "$dev"
|
||||
}
|
||||
|
||||
install_hotplugs() {
|
||||
skip_action install_hotplugs && return
|
||||
[ ! -n "$HOTPLUG_MODULES" ] && return
|
||||
|
||||
echo "Installing Cloud Hotplugs"
|
||||
|
||||
local result rc=0
|
||||
|
||||
if [ -f "$LIBDIR"/tiny-cloud/"$HOTPLUG_TYPE" ]; then
|
||||
. "$LIBDIR"/tiny-cloud/"$HOTPLUG_TYPE"
|
||||
fi
|
||||
|
||||
for module in $HOTPLUG_MODULES; do
|
||||
result='-'
|
||||
printf " $module"
|
||||
if type "mod__$module" | grep -q -w "function"; then
|
||||
"mod__$module" && result='+' || { result='!'; rc=1; }
|
||||
fi
|
||||
printf "($result)"
|
||||
done
|
||||
return $rc
|
||||
}
|
||||
|
||||
### NOTE: init-main functions
|
||||
|
||||
set_hostname() {
|
||||
skip_action set_hostname && return
|
||||
|
||||
echo "Setting Instance Hostname"
|
||||
|
||||
local fqdn=$(imds @hostname)
|
||||
local host="${fqdn%%\.*}"
|
||||
|
||||
mkdir -p "$ROOT"/etc
|
||||
echo "$host" > "$ROOT"/etc/hostname
|
||||
$MOCK hostname -F "$ROOT"/etc/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"
|
||||
|
||||
local user="$CLOUD_USER"
|
||||
local pwent="$(getent passwd "$user")"
|
||||
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"
|
||||
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"
|
||||
|
||||
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
|
||||
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"
|
||||
|
||||
local log="$TINY_CLOUD_LOGS/user-data.log"
|
||||
local exit="$TINY_CLOUD_LOGS/user-data.exit"
|
||||
local userdata="$TINY_CLOUD_VAR/user-data"
|
||||
|
||||
chmod +x "$userdata"
|
||||
{ "$userdata" 2>& 1; echo $? > "$exit"; } | tee "$log"
|
||||
|
||||
return $(cat "$exit")
|
||||
}
|
||||
|
||||
# load cloud-specific init functions / vars
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
if [ -f "$LIBDIR"/tiny-cloud/"$CLOUD"/init ]; then
|
||||
. "$LIBDIR"/tiny-cloud/"$CLOUD"/init
|
||||
fi
|
||||
|
||||
|
||||
### 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
|
||||
}
|
||||
|
||||
userdata_type() {
|
||||
if [ -f "$TINY_CLOUD_VAR/user-data" ]; then
|
||||
header=$(head -n1 "$TINY_CLOUD_VAR/user-data")
|
||||
case "$header" in
|
||||
'#cloud-config') echo cloud-config;;
|
||||
'#!'*) echo script;;
|
||||
*) echo unknown;;
|
||||
esac
|
||||
else
|
||||
echo missing
|
||||
fi
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
# Tiny Cloud - Common Initialization
|
||||
# vim:set ts=4 et ft=sh:
|
||||
|
||||
# set defaults
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR"/tiny-cloud/common
|
||||
|
||||
: "${SKIP_INIT_ACTIONS:=}"
|
||||
|
||||
# is initial bootstrap already done?
|
||||
is_bootstrapped() { [ -f "$TINY_CLOUD_VAR"/.bootstrap-complete ] ; }
|
||||
|
||||
# indicate bootstrap is done
|
||||
bootstrap_complete() { touch "$TINY_CLOUD_VAR"/.bootstrap-complete ; }
|
||||
|
||||
# indicate bootstrap isn't done
|
||||
bootstrap_incomplete() { rm -f "$TINY_CLOUD_VAR"/.bootstrap-complete ; }
|
||||
|
||||
# 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
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
# Tiny Cloud - Early Phase Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR"/tiny-cloud/init-common
|
||||
|
||||
expand_root() {
|
||||
skip_action expand_root && return
|
||||
|
||||
local dev=$(awk '$2 == "/" {print $1}' "$ROOT"/proc/mounts)
|
||||
local partition=$(cat "$ROOT/sys/class/block/${dev#/dev/}/partition" 2>/dev/null)
|
||||
|
||||
if [ -n "$partition" ]; then
|
||||
# it's a partition, resize it
|
||||
local volume=$(readlink -f "$ROOT/sys/class/block/${dev#/dev/}/..")
|
||||
volume="/dev/${volume##*/}"
|
||||
echo ", +" | $MOCK sfdisk -q --no-reread -N "$partition" "$volume"
|
||||
$MOCK partx -u "$volume"
|
||||
fi
|
||||
# resize filesystem
|
||||
$MOCK resize2fs "$dev"
|
||||
}
|
||||
|
||||
has_cloud_hotplugs() { [ -n "$HOTPLUG_MODULES" ]; }
|
||||
|
||||
install_hotplugs() {
|
||||
skip_action install_hotplugs && return
|
||||
|
||||
local result rc=0
|
||||
|
||||
for module in $HOTPLUG_MODULES; do
|
||||
result='-'
|
||||
printf " $module"
|
||||
if type "mod__$module" | grep -q -w "function"; then
|
||||
"mod__$module" && result='+' || { result='!'; rc=1; }
|
||||
fi
|
||||
printf "($result)"
|
||||
done
|
||||
return $rc
|
||||
}
|
||||
|
||||
: "${HOTPLUG_TYPE:=mdev}"
|
||||
if [ -f "$LIBDIR"/tiny-cloud/"$HOTPLUG_TYPE" ]; then
|
||||
. "$LIBDIR"/tiny-cloud/"$HOTPLUG_TYPE"
|
||||
fi
|
||||
@ -1,22 +0,0 @@
|
||||
# Tiny Cloud - Final Phase Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR"/tiny-cloud/init-common
|
||||
|
||||
is_userdata_script() {
|
||||
head -n1 "$TINY_CLOUD_VAR/user-data" | grep -q "#!/"
|
||||
}
|
||||
|
||||
run_userdata() {
|
||||
skip_action run_userdata && return
|
||||
|
||||
local log="$TINY_CLOUD_LOGS/user-data.log"
|
||||
local exit="$TINY_CLOUD_LOGS/user-data.exit"
|
||||
local userdata="$TINY_CLOUD_VAR/user-data"
|
||||
|
||||
chmod +x "$userdata"
|
||||
{ "$userdata" 2>& 1; echo $? > "$exit"; } | tee "$log"
|
||||
|
||||
return $(cat "$exit")
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
# Tiny Cloud - Main Phase Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR"/tiny-cloud/init-common
|
||||
|
||||
# ensure existence of output directories
|
||||
[ ! -d "$TINY_CLOUD_LOGS" ] && mkdir -p "$TINY_CLOUD_LOGS"
|
||||
[ ! -d "$TINY_CLOUD_VAR" ] && mkdir -p "$TINY_CLOUD_VAR"
|
||||
|
||||
set_hostname() {
|
||||
skip_action set_hostname && return
|
||||
|
||||
local fqdn=$(imds @hostname)
|
||||
local host="${fqdn%%\.*}"
|
||||
|
||||
mkdir -p "$ROOT"/etc
|
||||
echo "$host" > "$ROOT"/etc/hostname
|
||||
$MOCK hostname -F "$ROOT"/etc/hostname
|
||||
echo -e "127.0.1.1\t$fqdn $host" >> "$ROOT"/etc/hosts
|
||||
}
|
||||
|
||||
set_ssh_keys() {
|
||||
skip_action set_ssh_keys && return
|
||||
|
||||
local user="$CLOUD_USER"
|
||||
local pwent="$(getent passwd "$user")"
|
||||
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"
|
||||
imds @ssh-keys > "$keys_file"
|
||||
}
|
||||
|
||||
save_userdata() {
|
||||
skip_action save_userdata && return
|
||||
|
||||
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
|
||||
else
|
||||
cp "$tmpfile" "$userdata"
|
||||
fi
|
||||
rm "$tmpfile"
|
||||
}
|
||||
89
sbin/tiny-cloud
Executable file
89
sbin/tiny-cloud
Executable file
@ -0,0 +1,89 @@
|
||||
#!/bin/sh
|
||||
# vim:set ts=4 et ft=sh:
|
||||
|
||||
# MacOS testing
|
||||
getopt=/opt/homebrew/Cellar/gnu-getopt/2.38.1/bin/getopt
|
||||
|
||||
# Tiny Cloud
|
||||
|
||||
set -e
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR"/tiny-cloud/common
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} [-h | --help] { early | main | final | --bootstrap {complete|incomplete} }
|
||||
EOF
|
||||
}
|
||||
|
||||
bootstrap_complete() {
|
||||
echo "Marking Instance Bootstrap Complete"
|
||||
touch "$TINY_CLOUD_VAR"/.bootstrap-complete
|
||||
}
|
||||
|
||||
bootstrap_incomplete() {
|
||||
echo "Marking Instance Bootstrap Incomplete"
|
||||
rm -f "$TINY_CLOUD_VAR"/.bootstrap-complete
|
||||
}
|
||||
|
||||
args=$($getopt -o hb: --long help,bootstrap: -n ${0##*/} -- "$@")
|
||||
if [ $? -ne 0 ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
eval set -- "$args"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h|--help) usage; exit 0;;
|
||||
-b|--bootstrap) shift
|
||||
case "$1" in
|
||||
complete) # indicate bootstrap is done
|
||||
bootstrap_complete;;
|
||||
incomplete) # indicate bootstrap isn't done
|
||||
bootstrap_incomplete;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
exit 0;;
|
||||
--) shift; break;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
phase="$1"
|
||||
shift
|
||||
|
||||
case "$phase" in
|
||||
early|main|final) ;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
|
||||
# is initial bootstrap already done?
|
||||
if [ -f "$TINY_CLOUD_VAR"/.bootstrap-complete ]; then
|
||||
log -s "Already bootstrapped"
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
### default phase actions
|
||||
|
||||
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
|
||||
|
||||
echo $phase "$@"
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
export PREFIX="$srcdir"
|
||||
export MOCK=echo
|
||||
lib="$srcdir"/lib/tiny-cloud/init
|
||||
|
||||
init_tests \
|
||||
expand_root \
|
||||
@ -17,7 +18,7 @@ PROVIDERS="aws azure gcp nocloud oci"
|
||||
expand_root_body() {
|
||||
fake_bin test-expand-root <<-EOF
|
||||
#!/bin/sh
|
||||
. "$srcdir"/lib/tiny-cloud/init-early
|
||||
. "$lib"
|
||||
expand_root
|
||||
EOF
|
||||
mkdir proc
|
||||
@ -32,7 +33,7 @@ expand_root_body() {
|
||||
expand_root_partition_body() {
|
||||
fake_bin test-expand-root <<-EOF
|
||||
#!/bin/sh
|
||||
. "$srcdir"/lib/tiny-cloud/init-early
|
||||
. "$lib"
|
||||
expand_root
|
||||
EOF
|
||||
mkdir -p proc sys/class/block \
|
||||
@ -56,7 +57,7 @@ expand_root_skip_body() {
|
||||
fake_bin test-expand-root <<-EOF
|
||||
#!/bin/sh
|
||||
SKIP_INIT_ACTIONS=expand_root
|
||||
. "$srcdir"/lib/tiny-cloud/init-early
|
||||
. "$lib"
|
||||
expand_root
|
||||
EOF
|
||||
for provider in $PROVIDERS; do
|
||||
@ -70,7 +71,7 @@ install_hotplugs_skip_body() {
|
||||
fake_bin test-install-hotplugs <<-EOF
|
||||
#!/bin/sh
|
||||
SKIP_INIT_ACTIONS=install_hotplugs
|
||||
. "$srcdir"/lib/tiny-cloud/init-early
|
||||
. "$lib"
|
||||
install_hotplugs
|
||||
EOF
|
||||
for provider in $PROVIDERS; do
|
||||
@ -84,11 +85,10 @@ install_hotplugs_fail_body() {
|
||||
fake_bin test-install-hotplugs <<-EOF
|
||||
#!/bin/sh
|
||||
HOTPLUG_MODULES="vnic_eth_hotplug"
|
||||
. "$srcdir"/lib/tiny-cloud/init-early
|
||||
. "$lib"
|
||||
install_hotplugs
|
||||
EOF
|
||||
CLOUD=aws atf_check -s not-exit:0 \
|
||||
-o match:"^ vnic_eth_hotplug\(!\)$" \
|
||||
test-install-hotplugs
|
||||
}
|
||||
|
||||
|
||||
@ -4,25 +4,31 @@
|
||||
|
||||
export PREFIX="$srcdir"
|
||||
export MOCK=echo
|
||||
lib="$srcdir"/lib/tiny-cloud/init-final
|
||||
init_main="$srcdir"/lib/tiny-cloud/init-main
|
||||
lib="$srcdir"/lib/tiny-cloud/init
|
||||
PROVIDERS="aws azure gcp nocloud oci"
|
||||
|
||||
init_tests \
|
||||
is_userdata_script \
|
||||
userdata_type \
|
||||
run_userdata
|
||||
|
||||
|
||||
is_userdata_script_body() {
|
||||
userdata_type_body() {
|
||||
mkdir -p var/lib/cloud
|
||||
for c in $PROVIDERS; do
|
||||
rm -f var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check \
|
||||
-o match:"missing" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
|
||||
echo "#tiny-cloud-config" > var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check -s not-exit:0 \
|
||||
sh -c ". \"$lib\"; is_userdata_script"
|
||||
|
||||
CLOUD="$c" atf_check \
|
||||
-o match:"unknown" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
|
||||
echo "#!/bin/sh" > var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check -s exit:0 \
|
||||
sh -c ". \"$lib\"; is_userdata_script"
|
||||
-o match:"script" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
done
|
||||
}
|
||||
|
||||
@ -32,11 +38,10 @@ run_userdata_body() {
|
||||
echo "hello from user-data"
|
||||
EOF
|
||||
CLOUD="nocloud" atf_check \
|
||||
sh -c ". \"$init_main\"; save_userdata"
|
||||
sh -c ". \"$lib\"; save_userdata"
|
||||
CLOUD="nocloud" atf_check \
|
||||
-o match:"hello from user-data" \
|
||||
sh -c ". \"$lib\"; run_userdata"
|
||||
grep "hello from user-data" var/log/user-data.log || atf_fail "user-data.log failed"
|
||||
grep -w "0" var/log/user-data.exit || atf_fail "user-data.exit failed"
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
export PREFIX="$srcdir"
|
||||
export MOCK=echo
|
||||
lib="$srcdir"/lib/tiny-cloud/init-main
|
||||
lib="$srcdir"/lib/tiny-cloud/init
|
||||
|
||||
init_tests \
|
||||
set_hostname \
|
||||
@ -95,4 +95,3 @@ save_userdata_compressed_body() {
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user