1
0
mirror of https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git synced 2026-06-21 00:07:16 +03:00

Tiny cloud autodetect

This commit is contained in:
Natanael Copa 2026-06-07 16:01:36 +00:00 committed by Jake Buchholz Göktürk
parent 4cf9c51317
commit f6046351ca
5 changed files with 100 additions and 25 deletions

View File

@ -6,7 +6,7 @@ tiny-cloud - perform first-boot initialization for cloud instances
# SYNOPSIS # SYNOPSIS
*tiny-cloud* [*-h*|*--help*] { *boot* | *early* | *main* | *final* | *-b*|*--bootstrap* { *complete* | *incomplete* | *status* } | *-E*|*--enable* | *-D*|*--disable* } *tiny-cloud* [*-h*|*--help*] { *boot* | *early* | *main* | *final* | *autodetect* | *-b*|*--bootstrap* { *complete* | *incomplete* | *status* } | *-E*|*--enable* | *-D*|*--disable* }
# DESCRIPTION # DESCRIPTION
@ -61,6 +61,11 @@ been marked complete, later phase invocations exit without doing further work.
Run finalization actions. By default this marks bootstrap complete after any Run finalization actions. By default this marks bootstrap complete after any
additional configured final actions have succeeded. additional configured final actions have succeeded.
*autodetect*
Run provider autodetection probes and print the detected provider name.
This does not use the configured provider, kernel command line hints, or the
cached autodetection result.
# OPERATION # OPERATION
When invoked with a phase argument, *tiny-cloud* first checks whether When invoked with a phase argument, *tiny-cloud* first checks whether

View File

@ -47,31 +47,42 @@ line_kval() {
cat "${2:--}" 2>/dev/null | xargs -n1 | grep "^$1=" | cut -d= -f2- | paste -sd' ' | tr "$3" ' ' cat "${2:--}" 2>/dev/null | xargs -n1 | grep "^$1=" | cut -d= -f2- | paste -sd' ' | tr "$3" ' '
} }
if [ "$CLOUD" = "auto" ]; then cloud_alias() {
case "$1" in
ec2) echo aws;;
gce) echo gcp;;
nocloud-net) echo nocloud;;
oracle) echo oci;;
*) echo "$1";;
esac
}
cloud_hint() {
local F cloud
# 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" ] && {
cloud_alias "$cloud"
return
}
done
}
cloud_autodetect() {
for i in "$LIBDIR"/tiny-cloud/cloud/*/autodetect; do
if [ -x "$i" ]; then
"$i" || :
fi
done | sort -n | cut -d' ' -f2 | head -n 1
}
if [ "$CLOUD" = "auto" ] && [ -z "$TINY_CLOUD_NO_RESOLVE" ]; then
# previously detected? # previously detected?
CLOUD=$(cat "$TINY_CLOUD_VAR"/.autodetect 2>/dev/null) || { CLOUD=$(cat "$TINY_CLOUD_VAR"/.autodetect 2>/dev/null) || {
# try kernel cmdline & DMI product serial CLOUD=$(cloud_hint)
for F in "$PROC/cmdline" "$SYS/class/dmi/id/product_serial"; do [ -z "$CLOUD" ] && CLOUD=$(cloud_autodetect)
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 if [ -z "$CLOUD" ] || [ ! -d "$LIBDIR/tiny-cloud/cloud/$CLOUD" ]; then
log -t autodetect err "unable to determine cloud" log -t autodetect err "unable to determine cloud"
CLOUD=unknown CLOUD=unknown

View File

@ -7,11 +7,12 @@ set -e
: "${PREFIX:=/usr}" : "${PREFIX:=/usr}"
: "${LIBDIR:=$PREFIX/lib}" : "${LIBDIR:=$PREFIX/lib}"
[ "$1" = "autodetect" ] && TINY_CLOUD_NO_RESOLVE=1
. "$LIBDIR/tiny-cloud/common" . "$LIBDIR/tiny-cloud/common"
usage() { usage() {
cat <<-EOF cat <<-EOF
Usage: ${0##*/} [-h | --help] { boot | early | main | final | --bootstrap {complete|incomplete|status} | --enable | --disable } Usage: ${0##*/} [-h | --help] { boot | early | main | final | autodetect | --bootstrap {complete|incomplete|status} | --enable | --disable }
EOF EOF
} }
@ -72,6 +73,14 @@ shift
case "$phase" in case "$phase" in
boot|early|main|final) ;; boot|early|main|final) ;;
autodetect)
CLOUD=$(cloud_autodetect)
if [ -z "$CLOUD" ] || [ ! -d "$LIBDIR/tiny-cloud/cloud/$CLOUD" ]; then
echo unknown
exit 1
fi
echo "$CLOUD"
exit 0;;
*) usage >&2; exit 1;; *) usage >&2; exit 1;;
esac esac

View File

@ -26,6 +26,8 @@ init_tests \
set_ssh_keys_gcp \ set_ssh_keys_gcp \
userdata_type \ userdata_type \
run_userdata \ run_userdata \
autodetect_config_overrides_cmdline \
autodetect_cache_overrides_cmdline \
autodetect_aws_cmdline \ autodetect_aws_cmdline \
autodetect_aws_nitro \ autodetect_aws_nitro \
autodetect_aws_xen \ autodetect_aws_xen \
@ -38,6 +40,7 @@ init_tests \
autodetect_nocloud_dmi \ autodetect_nocloud_dmi \
autodetect_nocloud_volume \ autodetect_nocloud_volume \
autodetect_oci \ autodetect_oci \
autodetect_scaleway_cmdline \
autodetect_scaleway \ autodetect_scaleway \
autodetect_unknown autodetect_unknown
@ -351,6 +354,23 @@ autodetect_unknown_body() {
sh -c ". \"$lib\"; echo \$CLOUD" sh -c ". \"$lib\"; echo \$CLOUD"
} }
autodetect_config_overrides_cmdline_body() {
mkdir -p proc
echo "quiet ds=scaleway console=ttyS0" > proc/cmdline
CLOUD=aws atf_check \
-o match:"aws" \
sh -c ". \"$lib\"; echo \$CLOUD"
}
autodetect_cache_overrides_cmdline_body() {
mkdir -p proc var/lib/cloud
echo aws > var/lib/cloud/.autodetect
echo "quiet ds=scaleway console=ttyS0" > proc/cmdline
atf_check \
-o match:"aws" \
sh -c ". \"$lib\"; echo \$CLOUD"
}
autodetect_aws_cmdline_body() { autodetect_aws_cmdline_body() {
mkdir -p proc mkdir -p proc
echo "quiet tinycloud=cloud=aws console=ttyS0" > proc/cmdline echo "quiet tinycloud=cloud=aws console=ttyS0" > proc/cmdline
@ -466,6 +486,14 @@ autodetect_oci_body() {
sh -c ". \"$lib\"; echo \$CLOUD" sh -c ". \"$lib\"; echo \$CLOUD"
} }
autodetect_scaleway_cmdline_body() {
mkdir -p proc
echo "quiet ds=scaleway console=ttyS0" > proc/cmdline
atf_check \
-o match:"scaleway" \
sh -c ". \"$lib\"; echo \$CLOUD"
}
autodetect_scaleway_body() { autodetect_scaleway_body() {
mkdir -p sys/class/dmi/id mkdir -p sys/class/dmi/id
cat > sys/class/dmi/id/modalias <<-EOT cat > sys/class/dmi/id/modalias <<-EOT

View File

@ -10,6 +10,8 @@ PROVIDERS="alpine aws azure digitalocean gcp incus hetzner nocloud oci scaleway"
init_tests \ init_tests \
tiny_cloud_help \ tiny_cloud_help \
tiny_cloud_autodetect \
tiny_cloud_autodetect_unknown \
tiny_cloud_disabled \ tiny_cloud_disabled \
no_metadata_boot \ no_metadata_boot \
no_userdata_early \ no_userdata_early \
@ -28,6 +30,26 @@ tiny_cloud_help_body() {
done done
} }
tiny_cloud_autodetect_body() {
mkdir -p sys/class/dmi/id
cat > sys/class/dmi/id/modalias <<-EOT
dmi:bvnScaleway:bvrScaleway:bd10/22/2024:br1.0:svnScaleway:pnScaleway:pvr:rvnKVM:rnScaleway:rvr:cvnScaleway:ct1:cvr:sku:
EOT
atf_check -s exit:0 \
-o match:"^scaleway$" \
tiny-cloud autodetect
}
tiny_cloud_autodetect_unknown_body() {
mkdir -p etc proc var/lib/cloud
echo "CLOUD=auto" > etc/tiny-cloud.conf
echo scaleway > var/lib/cloud/.autodetect
echo "quiet ds=scaleway console=ttyS0" > proc/cmdline
atf_check -s exit:1 \
-o match:"^unknown$" \
tiny-cloud autodetect
}
tiny_cloud_disabled_body() { tiny_cloud_disabled_body() {
mkdir -p etc mkdir -p etc
touch etc/tiny-cloud.disabled touch etc/tiny-cloud.disabled