1
0
mirror of https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git synced 2025-12-14 19:02:45 +03:00

cloud via cmdline / move autodetect

This commit is contained in:
Jake Buchholz Göktürk 2024-11-14 01:22:48 +00:00
parent 0548b418ec
commit 3ea8b15de0
10 changed files with 100 additions and 74 deletions

View File

@ -84,7 +84,7 @@ _imds_ssh_keys() {
done | sort -u
}
_imds_nic_index() { cat "/sys/class/net/$1/address"; }
_imds_nic_index() { cat "$SYS/class/net/$1/address"; }
### load cloud-specific variables and functions

View File

@ -4,8 +4,7 @@
# vim:set filetype=sh:
# shellcheck shell=sh
grep -w 'ds=nocloud' "$ROOT"/proc/cmdline 2>/dev/null \
|| grep -w "^ds=nocloud" "$ROOT"/sys/class/dmi/id/product_serial 2>/dev/null \
|| findfs LABEL=cidata >/dev/null 2>&1 \
# kernel cmdline & DMI product serial are checked in common
findfs LABEL=cidata >/dev/null 2>&1 \
|| findfs LABEL=CIDATA >/dev/null 2>&1 \
&& echo "10 nocloud"

View File

@ -8,8 +8,8 @@ is_nocloud_loaded() { [ -f "$TINY_CLOUD_VAR/.nocloud_loaded" ]; }
_load_nocloud_cmdline() {
local kopt kv k v data
for kopt in $(cat "$ROOT/proc/cmdline" 2>/dev/null) \
$(grep '^ds=nocloud' "$ROOT"/sys/class/dmi/id/product_serial 2>/dev/null) ; do
for kopt in $(cat "$PROC/cmdline" 2>/dev/null) \
$(grep '^ds=nocloud' "$SYS"/class/dmi/id/product_serial 2>/dev/null) ; do
echo "$kopt" | grep -qE '(^|=)ds=nocloud(-net)?;' || continue
for kv in $(echo "${kopt#*;}" | tr \; ' '); do
k=$(echo "$kv" | cut -d= -f1)
@ -88,7 +88,6 @@ load_nocloud() {
}
_imds() {
mkdir -p "$TINY_CLOUD_VAR"
local file="$TINY_CLOUD_VAR/$(echo "$1" | cut -d/ -f1)"
local keypath="$(echo "$1" | cut -d/ -f2- | tr / ' ')"

View File

@ -9,7 +9,7 @@ set_resolv_conf() {
local nameservers="$(imds meta-data/resolv_conf/nameservers)"
for i in $nameservers; do
local server="$(imds meta-data/resolv_conf/nameservers/$i)"
add_once "$ROOT"/etc/resolv.conf "nameserver $server"
add_once "$ETC"/resolv.conf "nameserver $server"
done
}
@ -22,8 +22,8 @@ want_ephemeral_network() {
if has_ipv4_address; then
return 1
fi
for i in $(cat "$ROOT"/proc/cmdline 2>/dev/null) \
$(cat "$ROOT"/sys/class/dmi/id/product_serial 2>/dev/null); do
for i in $(cat "$PROC"/cmdline 2>/dev/null) \
$(cat "$SYS"/class/dmi/id/product_serial 2>/dev/null); do
case "$i" in
"ds=nocloud;"*)
for kv in $(echo "${i#*;}" | tr \; ' '); do
@ -45,13 +45,13 @@ want_ephemeral_network() {
init__set_network_interfaces() {
local interfaces="$(imds meta-data/network-interfaces)"
mkdir -p "$ROOT"/etc/network
mkdir -p "$ETC"/network
if [ -n "$interfaces" ]; then
printf "%s\n" "$interfaces" > "$ROOT"/etc/network/interfaces
elif ! [ -f "$ROOT"/etc/network/interfaces ]; then
printf "%s\n" "$interfaces" > "$ETC"/network/interfaces
elif ! [ -f "$ETC"/network/interfaces ]; then
init__set_default_interfaces
fi
if ! grep -q dhcp "$ROOT"/etc/network/interfaces; then
if ! grep -q dhcp "$ETC"/network/interfaces; then
set_resolv_conf
fi
}

View File

@ -29,7 +29,7 @@ _imds_ssh_keys() { _imds "$IMDS_SSH_KEYS"; }
_imds_nic_index() {
local m n=0
local mac=$(cat "/sys/class/net/$1/mac")
local mac=$(cat "$SYS/class/net/$1/mac")
while m=$(imds "$IMDS_NICS/$n/mac" | tr A-F a-f); do
[ "$m" = "$mac" ] && echo $n; return 0
done

View File

@ -3,11 +3,58 @@
# shellcheck shell=sh
# set defaults
[ -f "$ROOT/etc/tiny-cloud.conf" ] && . "$ROOT/etc/tiny-cloud.conf"
: "${ETC:=$ROOT/etc}"
: "${PROC:=$ROOT/proc}"
: "${SYS:=$ROOT/sys}"
[ -f "$ETC/tiny-cloud.conf" ] && . "$ETC/tiny-cloud.conf"
: "${CLOUD:=auto}"
: "${CLOUD_USER:=alpine}"
: "${TINY_CLOUD_LOGS:=$ROOT/var/log}"
: "${TINY_CLOUD_VAR:=$ROOT/var/lib/cloud}"
mkdir -p "${TINY_CLOUD_LOGS:=$ROOT/var/log}"
mkdir -p "${TINY_CLOUD_VAR:=$ROOT/var/lib/cloud}"
lower() { tr 'A-Z' 'a-z'; }
line_has_k() {
# <key> [<file>] - line(s) in stdin/<file> have <key> defined?
cat "${2:--}" 2>/dev/null | xargs -n1 | cut -d= -f1 | grep -q "^$1$"
}
line_kval() {
# <key> [<file>] [<chars>] - <key> value(s) from stdin/<file> line(s)
# replace output <chars> with spaces (suitable for "sub-kv" situations)
cat "${2:--}" 2>/dev/null | xargs -n1 | grep "^$1=" | cut -d= -f2- | paste -sd' ' | tr "$3" ' '
}
if [ "$CLOUD" = "auto" ]; then
# previously detected?
CLOUD=$(cat "$TINY_CLOUD_VAR"/.autodetect 2>/dev/null) || {
# try kernel cmdline & DMI product serial
for F in "$PROC/cmdline" "$SYS/class/dmi/id/product_serial"; do
CLOUD=$(line_kval tinycloud "$F" : | line_kval cloud)
[ -z "$CLOUD" ] && CLOUD=$(line_kval ds "$F" ';' | cut -d' ' -f1 | lower)
[ -n "$CLOUD" ] && break
done
if [ -n "$CLOUD" ]; then
# convert cloud-init cloud names
case "$CLOUD" in
ec2) CLOUD=aws;;
gce) CLOUD=gcp;;
nocloud-net) CLOUD=nocloud;;
oracle) CLOUD=oci;;
esac
else
# try all the autodetects, sorted by confidence...
CLOUD=$(
for i in "$LIBDIR"/tiny-cloud/cloud/*/autodetect; do
[ -x "$i" ] && "$i"
done | sort -n | cut -d' ' -f2 | head -n 1
)
fi
if [ -z "$CLOUD" ] || [ ! -d "$LIBDIR/tiny-cloud/cloud/$CLOUD" ]; then
CLOUD=unknown
else
printf "%s\n" "$CLOUD" > "$TINY_CLOUD_VAR"/.autodetect
fi
}
fi
log() {
local facility="local7"

View File

@ -32,31 +32,12 @@ DEFAULT_ACTIONS_FINAL=""
: "${INIT_ACTIONS_MAIN=$DEFAULT_ACTIONS_MAIN}"
: "${INIT_ACTIONS_FINAL=$DEFAULT_ACTIONS_FINAL}"
# 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
# autodetect cloud
if [ "$CLOUD" = "auto" ]; then
CLOUD=$(cat "$TINY_CLOUD_VAR"/.autodetect 2>/dev/null) || {
CLOUD=$(
for i in "$LIBDIR"/tiny-cloud/cloud/*/autodetect; do
if [ -f "$i" ]; then
"$i"
fi
done | sort -n | cut -d' ' -f2 | head -n 1
)
: ${CLOUD:=unknown}
printf "%s\n" "$CLOUD" > "$TINY_CLOUD_VAR"/.autodetect
}
fi
### standard boot phase functions...
init__expand_root() {
local dev=$(awk '$2 == "/" {print $1}' "$ROOT"/proc/mounts 2>/dev/null)
local filesystem=$(awk '$2 == "/" {print $3}' "$ROOT"/proc/mounts 2>/dev/null)
local partition=$(cat "$ROOT/sys/class/block/${dev#/dev/}/partition" 2>/dev/null)
local dev=$(awk '$2 == "/" {print $1}' "$PROC"/mounts 2>/dev/null)
local filesystem=$(awk '$2 == "/" {print $3}' "$PROC"/mounts 2>/dev/null)
local partition=$(cat "$SYS/class/block/${dev#/dev/}/partition" 2>/dev/null)
# only support ext2/ext3/ext4 for now
case "$filesystem" in
@ -66,7 +47,7 @@ init__expand_root() {
if [ -n "$partition" ]; then
# it's a partition, resize it
local volume=$(readlink -f "$ROOT/sys/class/block/${dev#/dev/}/..")
local volume=$(readlink -f "$SYS/class/block/${dev#/dev/}/..")
volume="/dev/${volume##*/}"
echo ", +" | $MOCK sfdisk -q --no-reread -N "$partition" "$volume"
$MOCK partx -u "$volume"
@ -79,7 +60,7 @@ init__expand_root() {
# collect ethernet interfaces, sorted by index
ethernets() {
for i in "$ROOT/sys/class/net/"*; do
for i in "$SYS/class/net/"*; do
local iface="${i##*/}"
case "$iface" in
eth*) echo "$(cat "$i/ifindex") $iface";;
@ -93,7 +74,7 @@ find_first_interface_up() {
[ $# -eq 0 ] && return
while [ $n -le ${TINY_CLOUD_LINK_WAIT_MAX:-10} ]; do
for i in "$@"; do
if [ "$(cat "$ROOT/sys/class/net/$i/operstate")" = "up" ]; then
if [ "$(cat "$SYS/class/net/$i/operstate")" = "up" ]; then
echo "$i"
return
fi
@ -148,16 +129,16 @@ init__set_ephemeral_network() {
}
init__set_default_interfaces() {
if [ -f "$ROOT"/etc/network/interfaces ]; then
if [ -f "$ETC"/network/interfaces ]; then
log -i -t "$phase" info "$ACTION: already set up"
return
fi
mkdir -p "$ROOT/etc/network"
mkdir -p "$ETC/network"
printf "%s\n%s\n\n" \
"auto lo" \
"iface lo inet loopback" \
> "$ROOT/etc/network/interfaces"
> "$ETC/network/interfaces"
local iface="$(auto_detect_ethernet_interface)"
if [ -z "$iface" ]; then
@ -167,7 +148,7 @@ init__set_default_interfaces() {
printf "%s\n%s\n\t%s\n\n" \
"auto $iface" \
"iface $iface" \
"use dhcp" >> "$ROOT/etc/network/interfaces"
"use dhcp" >> "$ETC/network/interfaces"
}
init__create_default_user() {
@ -188,12 +169,12 @@ init__create_default_user() {
echo "$user:*" | $MOCK chpasswd -e
# setup sudo and/or doas
if [ -d "$ROOT/etc/sudoers.d" ]; then
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > "$ROOT/etc/sudoers.d/wheel"
if [ -d "$ETC/sudoers.d" ]; then
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > "$ETC/sudoers.d/wheel"
fi
if [ -d "$ROOT/etc/doas.d" ]; then
if [ -d "$ETC/doas.d" ]; then
echo 'permit nopass :wheel' > "$TARGET/etc/doas.d/wheel.conf"
elif [ -f "$ROOT/etc/doas.conf" ]; then
elif [ -f "$ETC/doas.conf" ]; then
add_once "$TARGET/etc/doas.conf" "permit nopass :wheel"
fi
}
@ -247,10 +228,10 @@ init__set_hostname() {
return 1
fi
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
mkdir -p "$ETC"
echo "$host" > "$ETC"/hostname
$MOCK hostname -F "$ETC"/hostname
echo -e "127.0.1.1\t$fqdn $host" >> "$ETC"/hosts
}
init__set_ssh_keys() {

View File

@ -21,24 +21,24 @@ init__userdata_apk_cache() {
case "$cache" in
/*) cache="../..$cache";;
esac
mkdir -p "$ROOT"/etc/apk
ln -sf "$cache" "$ROOT"/etc/apk/cache
mkdir -p "$ETC"/apk
ln -sf "$cache" "$ETC"/apk/cache
}
init__userdata_apk_repositories() {
local apk="$(get_userdata apk)"
if [ -z "$apk" ] && ! [ -e "$ROOT"/etc/apk/repositories ]; then
if [ -z "$apk" ] && ! [ -e "$ETC"/apk/repositories ]; then
$MOCK setup-apkrepos -1 -c
return
fi
local repositories="$(get_userdata apk/repositories)"
mkdir -p "$ROOT"/etc/apk
mkdir -p "$ETC"/apk
for r in $repositories; do
local baseurl="$(get_userdata apk/repositories/$r/base_url)"
local repos="$(get_userdata apk/repositories/$r/repos)"
local version="$(get_userdata apk/repositories/$r/version)"
if [ -z "$version" ]; then
local version_id=$( . "$ROOT"/etc/os-release 2>/dev/null && echo "$VERSION_ID")
local version_id=$( . "$ETC"/os-release 2>/dev/null && echo "$VERSION_ID")
case "$version_id" in
edge*|*_alpha*) version="edge";;
[0-9]*.[0-9]*.[0-9]*) version="v${version_id%.*}";;
@ -49,14 +49,14 @@ init__userdata_apk_repositories() {
fi
for repo in $repos; do
local uri="${baseurl%/}/$(get_userdata apk/repositories/$r/repos/$repo)"
add_once "$ROOT"/etc/apk/repositories "$uri"
add_once "$ETC"/apk/repositories "$uri"
done
done
}
find_biggest_empty_disk() {
local d p
for d in "$ROOT"/sys/class/block/*/device; do
for d in "$SYS"/class/block/*/device; do
p=${d%/device}
if [ -e "$p"/size ] && [ -z "$(blkid /dev/${p##*/})" ]; then
echo "$(cat $p/size) ${p##*/}"
@ -69,7 +69,7 @@ init__userdata_autoinstall() {
if [ "$autoinstall" = "true" ]; then
local disk="$(find_biggest_empty_disk)"
if [ -n "$disk" ]; then
rm -f "$ROOT"/etc/runlevels/*/tiny-cloud*
rm -f "$ETC"/runlevels/*/tiny-cloud*
$MOCK lbu include /root/.ssh /home
$MOCK ERASE_DISKS=/dev/$disk setup-disk -m sys /dev/$disk
# TODO: make reboot configurable

View File

@ -291,17 +291,17 @@ init__userdata_users() {
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"
if [ -d "$ETC/doas.d" ]; then
touch "$ETC/doas.d/$name.conf"
chmod 660 "$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"
if [ -d "$ETC/doas.d" ]; then
echo "$line" >> "$ETC/doas.d/$name.conf"
elif [ -f "$ETC/doas.conf" ]; then
add_once "$ETC/doas.conf" "$line"
fi
done
fi

View File

@ -49,15 +49,15 @@ while true; do
-[ED]|--enable|--disable) # just openrc for now
: "${ROOT:=}" # for mounted volumes
# always start with a clean slate
rm -f "$ROOT"/etc/runlevels/*/tiny-cloud*
rm -f "$ETC"/runlevels/*/tiny-cloud*
log -i info "- tiny-cloud* services removed from all runlevels"
if [ "$1" = '-D' ] || [ "$1" = '--disable' ]; then
exit 0
fi
ln -s /etc/init.d/tiny-cloud-boot "$ROOT"/etc/runlevels/boot
ln -s /etc/init.d/tiny-cloud-boot "$ETC"/runlevels/boot
log -i info "+ tiny-cloud-boot service added to boot runlevel"
for p in early main final; do
ln -s "/etc/init.d/tiny-cloud-$p" "$ROOT"/etc/runlevels/default
ln -s "/etc/init.d/tiny-cloud-$p" "$ETC"/runlevels/default
log -i info "+ tiny-cloud-$p service added to default runlevel"
done
exit 0;;
@ -75,7 +75,7 @@ case "$phase" in
*) usage >&2; exit 1;;
esac
if [ -e "$ROOT"/etc/tiny-cloud.disabled ]; then
if [ -e "$ETC"/tiny-cloud.disabled ]; then
log -i -t "$phase" info "tiny-cloud disabled"
exit 0
fi