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

Compresssed User-Data / Initial NoCloud Support

Compressed User-Data
* extends !23 to support more algorithms

NoCloud
* initial support for volume-based meta-data, user-data, and optional vendor-data
* depends on 'yx' tool to extract data from yaml
This commit is contained in:
Jake Buchholz Göktürk 2022-07-05 07:36:23 -07:00
parent ed8bdc8c8b
commit ca264b7387
3 changed files with 96 additions and 7 deletions

View File

@ -35,6 +35,12 @@ unset -f \
CLOUD="${CLOUD:-unknown}"
IMDS_ENDPOINT="169.254.169.254"
_imds() {
wget --quiet --timeout 1 --output-document - \
--header "$(_imds_header)" \
"http://$IMDS_ENDPOINT/$IMDS_URI/$1$IMDS_QUERY"
}
_imds_ssh_keys() { _imds "$IMDS_SSH_KEYS"; }
_imds_userdata() { _imds "$IMDS_USERDATA"; }
@ -48,12 +54,6 @@ source /lib/tiny-cloud/"$CLOUD"/imds
### non-overrideable functions
_imds() {
wget --quiet --timeout 1 --output-document - \
--header "$(_imds_header)" \
"http://$IMDS_ENDPOINT/$IMDS_URI/$1$IMDS_QUERY"
}
imds() {
local cmd args key rv err=1
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then

View File

@ -3,10 +3,40 @@
source /lib/tiny-cloud/init-common
match_header() {
local bytes=$(echo -en "$1")
[ "$bytes" = $(dd bs=1 count=${#bytes} if="$2" 2>/dev/null) ]
}
# TODO: also do this for nocloud meta-data and vendor-data?
save_userdata() {
skip_action save_userdata && return
imds -e @userdata > "$TINY_CLOUD_VAR/$CLOUD_USERDATA"
local userdata="$TINY_CLOUD_VAR/$CLOUD_USERDATA"
local tmpfile=$(mktemp "$userdata.XXXXXX")
local cmd
imds -e @userdata > "$tmpfile"
if match_header '\037\213\010' "$tmpfile"; then
cmd='gzip -dc'
elif match_header 'BZh' "$tmpfile"; then
cmd='bzip2 -dc'
elif match_header '\3757zXZ\000' "$tmpfile"; then
cmd='xz -dc'
elif match_header '\135\0\0\0' "$tmpfile"; then
cmd='lzma -dc'
elif match_header '\211\114\132' "$tmpfile"; then
cmd='lzop -dc'
elif match_header '\002!L\030' "$tmpfile"; then
cmd='lz4 -dc'
elif match_header '(\265/\375' "$tmpfile"; then
cmd='zstd -dc'
else
cmd='cat'
fi
$cmd "$tmpfile" > "$userdata"
rm "$tmpfile"
}
is_userdata_script() {

View File

@ -0,0 +1,59 @@
# NoCloud Instance Metadata
# vim: ts=4 et ft=sh:
IMDS_HOSTNAME=meta-data/hostname
IMDS_SSH_KEYS=meta-data/ssh-keys
IMDS_USERDATA=user-data
# have we loaded the nocloud meta/user/vendor data?
is_nocloud_loaded() { [ -f "$TINY_CLOUD_VAR/.nocloud_loaded" ]; }
# from location specified in kernel cmdline
_load_nocloud_cmdline() {
# TODO
}
# from volume labeled cidata|CIDATA
_load_nocloud_volume() {
local mntdir='/mnt/cidata'
mkdir "$mntdir"
mount -L cidata "$mntdir" || mount -L CIDATA "$mntdir" || return 1
for data in meta user vendor; do
if ! cp "$mntdir/$data-data" "$TINY_CLOUD_VAR/$data-data"; then
[ "$data" = vendor ] && continue
echo "ERROR: Required $data-data not found on CIDATA volume"
umount "$mntdir"
return 1
fi
done
umount "$mntdir"
}
load_nocloud() {
is_nocloud_loaded && return
if grep -qE ' ds=nocloud(-net)?[; ]' /proc/cmdline; then
if ! _load_nocloud_cmdline; then
echo 'ERROR: Unable to load nocloud data specified in kernel cmdline' >&2
return 1
fi
elif ! _load_nocloud_volume; then
echo 'ERROR: Unable to load nocloud data from CIDATA volume' >&2
return 1
fi
touch "$TINY_CLOUD_VAR/.nocloud_loaded"
}
_imds() {
local file="$TINY_CLOUD_VAR"/$(echo "$1" | cut -d/ -f1)
local key=$(echo "$1" | cut -d/ -f2-)
local data value
is_nocloud_loaded || load_nocloud || return 1
# does file exist?
[ -f "$file" ] || return 1
# use 'file/' to get top-level keys
[ "$1" = "$file" ] && cat "$file" || yx -f "$file" "$key"
}