mirror of
https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git
synced 2026-06-21 00:07:16 +03:00
Compare commits
14 Commits
552f7e1e05
...
64ddf390bc
| Author | SHA1 | Date | |
|---|---|---|---|
| 64ddf390bc | |||
|
|
fbb910acc1 | ||
|
|
6290b1e1bd | ||
|
|
da1e86f4bd | ||
|
|
656aad0896 | ||
|
|
19688765e9 | ||
|
|
263803475e | ||
|
|
dcadf2ad0a | ||
|
|
f6046351ca | ||
|
|
cc2b219f04 | ||
|
|
a365c69683 | ||
|
|
29f40b34c2 | ||
|
|
168bb06699 | ||
|
|
cfe3c2dda5 |
22
CHANGELOG.md
22
CHANGELOG.md
@ -1,5 +1,27 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 2026-06-15 - Tiny Cloud v3.3.3
|
||||
|
||||
* Support IPv6 and multiple endpoints
|
||||
[#68](https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud/-/work_items/68)
|
||||
|
||||
* Check for IP routes to IMDS endpoints before trying them; retry if none are
|
||||
routable. Fixes race condition between `dhcpcd` starting and attempting to
|
||||
reach IMDS before routes are resolved.
|
||||
|
||||
* Currently the most recent IMDS endpoint that worked is cached, but only if
|
||||
**root** is running `imds`. We may consider keeping track of this per user
|
||||
in the future
|
||||
|
||||
## 2026-06-08 - Tiny Cloud v3.3.2
|
||||
|
||||
* Fixes an autodetect regression introduced in v3.3.1
|
||||
|
||||
## 2026-06-07 - Tiny Cloud v3.3.1
|
||||
|
||||
* Adds `tiny-cloud autodetect` subcommand, which outputs what Tiny Cloud's cloud
|
||||
autodetection currently finds, thanks @ncopa!
|
||||
|
||||
## 2026-05-23 - Tiny Cloud v3.3.0
|
||||
|
||||
#### GOOGLE CLOUD BEHAVIOR CHANGE
|
||||
|
||||
13
README.md
13
README.md
@ -131,6 +131,19 @@ The default endpoint is `169.254.169.254` for most cloud providers. This
|
||||
setting allows you to specify a custom IP address and optional port for the
|
||||
metadata service.
|
||||
|
||||
Multiple endpoints can be configured with `IMDS_ENDPOINTS`. The list is tried
|
||||
in order, and the most recently working endpoint is tried first on later
|
||||
queries. `IMDS_ENDPOINTS` defaults to `IMDS_ENDPOINT` when unset. IPv6 endpoints
|
||||
must use URL-style brackets:
|
||||
|
||||
```sh
|
||||
IMDS_ENDPOINTS="169.254.169.254 [fd00:ec2::254]"
|
||||
```
|
||||
|
||||
Tiny Cloud checks for routes to configured IMDS endpoints before trying metadata
|
||||
requests. `IMDS_ENDPOINT_WAIT_ATTEMPTS` controls how many route checks are made
|
||||
before metadata requests are tried anyway.
|
||||
|
||||
### Metadata API Version
|
||||
|
||||
Each provider's API has a built-in default version. You can override the
|
||||
|
||||
88
bin/imds
88
bin/imds
@ -53,6 +53,9 @@ unset -f \
|
||||
# Common to many clouds
|
||||
# Can be overridden in /etc/tiny-cloud.conf
|
||||
: "${IMDS_ENDPOINT:=169.254.169.254}"
|
||||
: "${IMDS_ENDPOINTS:=$IMDS_ENDPOINT}"
|
||||
: "${IMDS_ENDPOINT_CACHE:=$TINY_CLOUD_VAR/.imds-endpoint}"
|
||||
: "${IMDS_ENDPOINT_WAIT_ATTEMPTS:=10}"
|
||||
|
||||
# Common to AWS and NoCloud(ish)
|
||||
IMDS_HOSTNAME="meta-data/hostname"
|
||||
@ -68,10 +71,89 @@ IMDS_IPV6_NET="subnet-ipv6-cidr-blocks"
|
||||
IMDS_IPV4_PREFIX="ipv4-prefix"
|
||||
IMDS_IPV6_PREFIX="ipv6-prefix"
|
||||
|
||||
_imds_endpoints() {
|
||||
local cached e
|
||||
cached="$(cat "$IMDS_ENDPOINT_CACHE" 2>/dev/null)" || :
|
||||
for e in $IMDS_ENDPOINTS; do
|
||||
[ "$e" = "$cached" ] && echo "$e"
|
||||
done
|
||||
for e in $IMDS_ENDPOINTS; do
|
||||
[ "$e" != "$cached" ] && echo "$e"
|
||||
done
|
||||
}
|
||||
|
||||
_imds_host_port() {
|
||||
local host port
|
||||
case "$1" in
|
||||
\[*\]:*)
|
||||
host="${1#\[}"
|
||||
host="${host%%\]*}"
|
||||
port="${1##*\]:}"
|
||||
;;
|
||||
\[*\])
|
||||
host="${1#\[}"
|
||||
host="${host%\]}"
|
||||
port=80
|
||||
;;
|
||||
*:*)
|
||||
host="${1%:*}"
|
||||
port="${1##*:}"
|
||||
;;
|
||||
*)
|
||||
host="$1"
|
||||
port=80
|
||||
;;
|
||||
esac
|
||||
echo "$host"
|
||||
echo "$port"
|
||||
}
|
||||
|
||||
_imds_has_route() {
|
||||
local host
|
||||
set -- $(_imds_host_port "$1")
|
||||
host="$1"
|
||||
case "$host" in
|
||||
*:*) ip -6 route get "$host" >/dev/null 2>&1 ;;
|
||||
[0-9]*.[0-9]*.[0-9]*.[0-9]*) ip route get "$host" >/dev/null 2>&1 ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
_imds() {
|
||||
wget --quiet --timeout 1 --output-document - \
|
||||
--header "$(_imds_header)" \
|
||||
"http://$IMDS_ENDPOINT/$IMDS_URI/$1$IMDS_QUERY"
|
||||
local endpoint endpoints routed attempts=1 cached
|
||||
if [ "$IMDS_ENDPOINT_WAIT_ATTEMPTS" -le 0 ]; then
|
||||
endpoints="$(_imds_endpoints)"
|
||||
fi
|
||||
while :; do
|
||||
[ -n "$endpoints" ] && break
|
||||
endpoints=
|
||||
routed=
|
||||
for endpoint in $(_imds_endpoints); do
|
||||
if _imds_has_route "$endpoint"; then
|
||||
endpoints="$endpoints $endpoint"
|
||||
routed=1
|
||||
fi
|
||||
done
|
||||
[ -n "$routed" ] && break
|
||||
[ "$attempts" -ge "$IMDS_ENDPOINT_WAIT_ATTEMPTS" ] && {
|
||||
endpoints="$(_imds_endpoints)"
|
||||
break
|
||||
}
|
||||
sleep 1
|
||||
attempts=$((attempts + 1))
|
||||
done
|
||||
for endpoint in $endpoints; do
|
||||
IMDS_ENDPOINT="$endpoint"
|
||||
IMDS_CURRENT_ENDPOINT="$endpoint"
|
||||
wget --quiet --timeout 1 --output-document - \
|
||||
--header "$(_imds_header)" \
|
||||
"http://$endpoint/$IMDS_URI/$1$IMDS_QUERY" && {
|
||||
cached="$(cat "$IMDS_ENDPOINT_CACHE" 2>/dev/null)" || :
|
||||
[ "$endpoint" = "$cached" ] || echo "$endpoint" 2>/dev/null > "$IMDS_ENDPOINT_CACHE" || :
|
||||
return 0
|
||||
}
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_imds_userdata() { _imds "$IMDS_USERDATA"; }
|
||||
|
||||
@ -98,6 +98,18 @@ inside *@nic:* queries.
|
||||
*CLOUD*
|
||||
Cloud provider name. When set to *auto*, the autodetected provider is used.
|
||||
|
||||
*IMDS_ENDPOINT*
|
||||
Single provider metadata endpoint. Used as the default value for
|
||||
*IMDS_ENDPOINTS*.
|
||||
|
||||
*IMDS_ENDPOINTS*
|
||||
Whitespace-separated provider metadata endpoint list. IPv6 endpoints must use
|
||||
brackets, for example *[fd00:ec2::254]*.
|
||||
|
||||
*IMDS_ENDPOINT_WAIT_ATTEMPTS*
|
||||
Number of times to check for routes to any IMDS endpoint before trying
|
||||
metadata requests anyway. The default is *10*.
|
||||
|
||||
# EXIT STATUS
|
||||
|
||||
*0*
|
||||
|
||||
@ -6,7 +6,7 @@ tiny-cloud - perform first-boot initialization for cloud instances
|
||||
|
||||
# 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
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
When invoked with a phase argument, *tiny-cloud* first checks whether
|
||||
|
||||
@ -37,10 +37,20 @@ Blank lines and shell comments are ignored.
|
||||
Provider's API version to use. Providers that have versioned APIs have
|
||||
built-in default values.
|
||||
|
||||
*IMDS_ENDPOINT*=<ip_address>
|
||||
*IMDS_ENDPOINT*=<ip_address[:port]>
|
||||
Provider endpoint IP address to use. Defaults to 169.254.169.254 for many
|
||||
providers.
|
||||
|
||||
*IMDS_ENDPOINTS*=<endpoint> ...
|
||||
Whitespace-separated provider endpoint list. Defaults to *IMDS_ENDPOINT*.
|
||||
Endpoints are tried in order, with the most recently working endpoint tried
|
||||
first on later queries. IPv6 endpoints must use brackets, for example
|
||||
*[fd00:ec2::254]* or *[fd00:ec2::254]:80*.
|
||||
|
||||
*IMDS_ENDPOINT_WAIT_ATTEMPTS*=<number>
|
||||
Number of times to check for routes to any IMDS endpoint before trying
|
||||
metadata requests anyway. The default is *10*.
|
||||
|
||||
*IMDS_TOKEN_TTL*=<seconds>
|
||||
Metadata token lifetime in seconds for AWS metadata access. This is only used
|
||||
by the AWS provider. The default is *5*.
|
||||
|
||||
@ -9,14 +9,18 @@ IMDS_TOKEN_TTL_HEADER="X-aws-ec2-metadata-token-ttl-seconds"
|
||||
IMDS_URI="$IMDS_API_VERSION"
|
||||
|
||||
_imds_token() {
|
||||
local host port
|
||||
# Only try to get token if using IMDSv2
|
||||
# IMDSv1: API versions 2009-04-04 and earlier (no token support)
|
||||
# IMDSv2: API versions 2009-04-05 and later, or 'latest' (requires token)
|
||||
expr "$IMDS_API_VERSION" "<=" "2009-04-04" > /dev/null && return
|
||||
set -- $(_imds_host_port "${IMDS_CURRENT_ENDPOINT:-$IMDS_ENDPOINT}")
|
||||
host="$1"
|
||||
port="$2"
|
||||
# IMDSv2 - request token
|
||||
printf "PUT /latest/api/token HTTP/1.0\r\n%s: %s\r\n\r\n" \
|
||||
"$IMDS_TOKEN_TTL_HEADER" "$IMDS_TOKEN_TTL" \
|
||||
| nc -w 1 "$IMDS_ENDPOINT" 80 | tail -n 1
|
||||
| nc -w 1 "$host" "$port" | tail -n 1
|
||||
}
|
||||
|
||||
_imds_header() {
|
||||
|
||||
@ -47,31 +47,43 @@ line_kval() {
|
||||
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
|
||||
return 0
|
||||
}
|
||||
|
||||
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?
|
||||
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
|
||||
CLOUD=$(cloud_hint)
|
||||
[ -z "$CLOUD" ] && CLOUD=$(cloud_autodetect)
|
||||
if [ -z "$CLOUD" ] || [ ! -d "$LIBDIR/tiny-cloud/cloud/$CLOUD" ]; then
|
||||
log -t autodetect err "unable to determine cloud"
|
||||
CLOUD=unknown
|
||||
|
||||
@ -13,6 +13,14 @@
|
||||
# Useful for custom metadata services
|
||||
#IMDS_ENDPOINT=169.254.169.254
|
||||
|
||||
# Ordered IMDS endpoint list. Defaults to IMDS_ENDPOINT.
|
||||
# IPv6 endpoints must use brackets: [fd00:ec2::254] or [fd00:ec2::254]:80
|
||||
#IMDS_ENDPOINTS="169.254.169.254 [fd00:ec2::254]"
|
||||
|
||||
# Number of times to check for routes to any IMDS endpoint before trying
|
||||
# metadata requests anyway.
|
||||
#IMDS_ENDPOINT_WAIT_ATTEMPTS=10
|
||||
|
||||
# IMDS API version
|
||||
# Most providers have a default version, overrideable here if necessary
|
||||
#IMDS_API_VERSION=""
|
||||
|
||||
@ -244,7 +244,7 @@ in_list() {
|
||||
init__userdata_users() {
|
||||
local i users="$(get_userdata users)"
|
||||
for i in $users; do
|
||||
local name="" gecos="" homedir="" shell="" primary_group="" groups=""
|
||||
local name="" gecos="" homedir="" shell="" primary_group="" groups="" passwd="" hashed_passwd=""
|
||||
local system=false no_create_home=false lock_passwd=true
|
||||
local keys="$(get_userdata users/$i)"
|
||||
if [ "$i" = 1 ] && [ "$keys" = "default" ]; then
|
||||
@ -273,6 +273,10 @@ init__userdata_users() {
|
||||
if in_list no_create_home $keys; then
|
||||
no_create_home="$(get_userdata users/$i/no_create_home)"
|
||||
fi
|
||||
if in_list passwd $keys; then
|
||||
passwd="$(get_userdata users/$i/passwd)"
|
||||
echo "${user}:${passwd}" | $MOCK chpasswd -e
|
||||
fi
|
||||
|
||||
if getent passwd "$name" >/dev/null; then
|
||||
log -i -t "$phase" info "$ACTION: user $name already exists"
|
||||
@ -286,12 +290,17 @@ init__userdata_users() {
|
||||
$MOCK adduser -D ${gecos:+-g "$gecos"} ${homedir:+-h "$homedir"} ${shell:+-s "$shell"} ${primary_group:+-G "$primary_group"} ${system:+-S} ${no_create_home:+-H} "$name"
|
||||
fi
|
||||
|
||||
if in_list hashed_passwd $keys; then
|
||||
hashed_passwd="$(get_userdata users/$i/hashed_passwd)"
|
||||
echo "${name}:${hashed_passwd}" | $MOCK chpasswd -e
|
||||
fi
|
||||
|
||||
if in_list lock_passwd $keys; then
|
||||
lock_passwd="$(get_userdata users/$i/lock_passwd)"
|
||||
fi
|
||||
|
||||
if [ "$lock_passwd" != "false" ]; then
|
||||
echo "$name:*" | $MOCK chpasswd -e
|
||||
if [ "$lock_passwd" != "false" ] && [ -z "$hashed_passwd" ]; then
|
||||
echo "${name}:*" | $MOCK chpasswd -e
|
||||
fi
|
||||
|
||||
if in_list ssh_authorized_keys $keys; then
|
||||
|
||||
@ -7,11 +7,12 @@ set -e
|
||||
|
||||
: "${PREFIX:=/usr}"
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
[ "$1" = "autodetect" ] && TINY_CLOUD_NO_RESOLVE=1
|
||||
. "$LIBDIR/tiny-cloud/common"
|
||||
|
||||
usage() {
|
||||
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
|
||||
}
|
||||
|
||||
@ -72,6 +73,14 @@ shift
|
||||
|
||||
case "$phase" in
|
||||
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;;
|
||||
esac
|
||||
|
||||
|
||||
@ -78,11 +78,19 @@ for url; do
|
||||
esac
|
||||
done
|
||||
|
||||
host="${url#http*://}"
|
||||
host="${host%%/*}"
|
||||
path="${url#http*://$host}"
|
||||
url_no_scheme="${url#*://}"
|
||||
case "$url_no_scheme" in
|
||||
*/*) host="${url_no_scheme%%/*}"; path="/${url_no_scheme#*/}";;
|
||||
*) host="$url_no_scheme"; path=/;;
|
||||
esac
|
||||
path="${path#${WGET_STRIP_PREFIX:-/}}"
|
||||
path="${path%\?*}"
|
||||
[ -n "$WGET_HOST_LOG" ] && echo "$host" >> "$WGET_HOST_LOG"
|
||||
case "$host" in
|
||||
\[*\]:*) yaml_host="${host#\[}"; yaml_host="${yaml_host%%\]*}";;
|
||||
\[*\]) yaml_host="${host#\[}"; yaml_host="${yaml_host%\]}";;
|
||||
*) yaml_host="$host";;
|
||||
esac
|
||||
|
||||
|
||||
if [ -z "$WGETCONTENT" ]; then
|
||||
@ -93,7 +101,7 @@ if [ -z "$WGETCONTENT" ]; then
|
||||
(
|
||||
IFS=/
|
||||
set -- ${path#/}
|
||||
yx -f "${WGET_YAML:-$host.yaml}" "$@" 2>/dev/null
|
||||
yx -f "${WGET_YAML:-$yaml_host.yaml}" "$@" 2>/dev/null
|
||||
)
|
||||
fi
|
||||
fi
|
||||
@ -107,4 +115,3 @@ case "$outfile" in
|
||||
echo "$WGETCONTENT" > "$outfile"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
103
tests/imds.test
103
tests/imds.test
@ -10,6 +10,11 @@ PROVIDERS="aws azure digitalocean gcp hetzner incus oci nocloud scaleway"
|
||||
init_tests \
|
||||
imds_help \
|
||||
imds_space \
|
||||
imds_endpoint_fallback \
|
||||
imds_endpoint_cache \
|
||||
imds_endpoint_ipv6 \
|
||||
imds_endpoint_route_skip \
|
||||
imds_endpoint_route_wait \
|
||||
\
|
||||
imds_hostname_aws \
|
||||
imds_hostname_azure \
|
||||
@ -44,6 +49,7 @@ init_tests \
|
||||
imds_aws_api_version_imdsv1 \
|
||||
imds_aws_api_version_imdsv2_explicit \
|
||||
imds_aws_api_version_imdsv2_latest \
|
||||
imds_aws_token_endpoint_port \
|
||||
\
|
||||
imds_nocloud_cmdline_local_hostname \
|
||||
imds_nocloud_smbios_local_hostname \
|
||||
@ -63,6 +69,81 @@ imds_space_body() {
|
||||
done
|
||||
}
|
||||
|
||||
imds_endpoint_fallback_body() {
|
||||
IMDS_API_VERSION=2009-04-04 CLOUD=aws fake_metadata aws <<-EOF
|
||||
hostname: myhostname
|
||||
EOF
|
||||
IMDS_API_VERSION=2009-04-04 IMDS_ENDPOINT_WAIT_ATTEMPTS=0 \
|
||||
IMDS_ENDPOINTS="fail 169.254.169.254" CLOUD=aws atf_check \
|
||||
-o match:"myhostname" \
|
||||
imds @hostname
|
||||
atf_check -o match:"^169.254.169.254$" cat var/lib/cloud/.imds-endpoint
|
||||
}
|
||||
|
||||
imds_endpoint_cache_body() {
|
||||
mkdir -p var/lib/cloud
|
||||
echo "cached.example" > var/lib/cloud/.imds-endpoint
|
||||
cat > cached.example.yaml <<-EOF
|
||||
hostname: cached-hostname
|
||||
EOF
|
||||
cat > first.example.yaml <<-EOF
|
||||
hostname: first-hostname
|
||||
EOF
|
||||
IMDS_API_VERSION=2009-04-04 IMDS_ENDPOINT_WAIT_ATTEMPTS=0 \
|
||||
WGET_STRIP_PREFIX="/2009-04-04/meta-data" \
|
||||
WGET_HOST_LOG="$PWD/hosts.log" \
|
||||
IMDS_ENDPOINTS="first.example cached.example" CLOUD=aws atf_check \
|
||||
-o match:"cached-hostname" \
|
||||
imds @hostname
|
||||
atf_check -o match:"^cached.example$" head -n 1 hosts.log
|
||||
}
|
||||
|
||||
imds_endpoint_ipv6_body() {
|
||||
cat > "fd00:ec2::254.yaml" <<-EOF
|
||||
hostname: ipv6-hostname
|
||||
EOF
|
||||
IMDS_API_VERSION=2009-04-04 IMDS_ENDPOINT_WAIT_ATTEMPTS=0 \
|
||||
WGET_STRIP_PREFIX="/2009-04-04/meta-data" \
|
||||
WGET_HOST_LOG="$PWD/hosts.log" \
|
||||
IMDS_ENDPOINTS="[fd00:ec2::254]" CLOUD=aws atf_check \
|
||||
-o match:"ipv6-hostname" \
|
||||
imds @hostname
|
||||
atf_check -o match:"^\\[fd00:ec2::254\\]$" cat hosts.log
|
||||
}
|
||||
|
||||
imds_endpoint_route_skip_body() {
|
||||
IMDS_API_VERSION=2009-04-04 CLOUD=aws fake_metadata aws <<-EOF
|
||||
hostname: myhostname
|
||||
EOF
|
||||
fake_bin ip <<-'EOF'
|
||||
#!/bin/sh
|
||||
[ "$3" = 169.254.169.254 ]
|
||||
EOF
|
||||
IMDS_API_VERSION=2009-04-04 IMDS_ENDPOINT_WAIT_ATTEMPTS=1 \
|
||||
IMDS_ENDPOINTS="192.0.2.1 169.254.169.254" CLOUD=aws atf_check \
|
||||
-o match:"myhostname" \
|
||||
imds @hostname
|
||||
atf_check -o match:"^169.254.169.254$" cat var/lib/cloud/.imds-endpoint
|
||||
}
|
||||
|
||||
imds_endpoint_route_wait_body() {
|
||||
IMDS_API_VERSION=2009-04-04 CLOUD=aws fake_metadata aws <<-EOF
|
||||
hostname: myhostname
|
||||
EOF
|
||||
fake_bin ip <<-'EOF'
|
||||
#!/bin/sh
|
||||
mkdir -p tmp
|
||||
count=$(cat tmp/route-count 2>/dev/null || echo 0)
|
||||
count=$((count + 1))
|
||||
echo "$count" > tmp/route-count
|
||||
[ "$count" -gt 1 ]
|
||||
EOF
|
||||
IMDS_API_VERSION=2009-04-04 IMDS_ENDPOINT_WAIT_ATTEMPTS=5 CLOUD=aws atf_check \
|
||||
-o match:"myhostname" \
|
||||
imds @hostname
|
||||
atf_check -o match:"^2$" cat tmp/route-count
|
||||
}
|
||||
|
||||
check_hostname() {
|
||||
fake_metadata "$1" <<-EOF
|
||||
# aws, digitalocean, hetzner, nocloud
|
||||
@ -251,6 +332,28 @@ imds_aws_api_version_imdsv2_latest_body() {
|
||||
imds @hostname
|
||||
}
|
||||
|
||||
imds_aws_token_endpoint_port_body() {
|
||||
cat > "fd00:ec2::254.yaml" <<-EOF
|
||||
hostname: test-imdsv2-port
|
||||
EOF
|
||||
fake_bin nc <<-'NCEOF'
|
||||
#!/bin/sh
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
-w) shift 2;;
|
||||
*) echo "$1" >> nc.args; shift;;
|
||||
esac
|
||||
done
|
||||
cat > /dev/null
|
||||
printf "HTTP/1.0 200 OK\r\n\r\nmock-token"
|
||||
NCEOF
|
||||
IMDS_API_VERSION=latest WGET_STRIP_PREFIX="/latest/meta-data" \
|
||||
IMDS_ENDPOINTS="[fd00:ec2::254]:8080" CLOUD=aws atf_check \
|
||||
-o match:"test-imdsv2-port" \
|
||||
imds @hostname
|
||||
atf_check -o match:"^fd00:ec2::254 8080 $" sh -c "tr '\n' ' ' < nc.args"
|
||||
}
|
||||
|
||||
imds_nocloud_cmdline_local_hostname_body() {
|
||||
atf_require_prog yx
|
||||
mkdir proc
|
||||
|
||||
104
tests/init.test
104
tests/init.test
@ -26,6 +26,8 @@ init_tests \
|
||||
set_ssh_keys_gcp \
|
||||
userdata_type \
|
||||
run_userdata \
|
||||
autodetect_config_overrides_cmdline \
|
||||
autodetect_cache_overrides_cmdline \
|
||||
autodetect_aws_cmdline \
|
||||
autodetect_aws_nitro \
|
||||
autodetect_aws_xen \
|
||||
@ -38,6 +40,7 @@ init_tests \
|
||||
autodetect_nocloud_dmi \
|
||||
autodetect_nocloud_volume \
|
||||
autodetect_oci \
|
||||
autodetect_scaleway_cmdline \
|
||||
autodetect_scaleway \
|
||||
autodetect_unknown
|
||||
|
||||
@ -49,7 +52,7 @@ expand_root_body() {
|
||||
for provider in $PROVIDERS; do
|
||||
CLOUD="$provider" atf_check \
|
||||
-o match:"resize2fs /dev/xvda" \
|
||||
sh -c ". $lib; init__expand_root"
|
||||
sh -e -c ". $lib; init__expand_root"
|
||||
done
|
||||
}
|
||||
|
||||
@ -67,7 +70,7 @@ expand_root_partition_body() {
|
||||
-o match:"sfdisk .*/dev/nvme0n1" \
|
||||
-o match:"partx .*/dev/nvme0n1" \
|
||||
-o match:"resize2fs /dev/nvme0n1p2" \
|
||||
sh -c ". $lib; init__expand_root"
|
||||
sh -e -c ". $lib; init__expand_root"
|
||||
done
|
||||
}
|
||||
|
||||
@ -103,7 +106,7 @@ expand_root_lvm_partition_body() {
|
||||
-o match:"pvresize /dev/vda2" \
|
||||
-o match:"lvextend -l \\+85%VG /dev/mapper/vg0-root" \
|
||||
-o match:"resize2fs /dev/mapper/vg0-root" \
|
||||
sh -c ". $lib; init__expand_root"
|
||||
sh -e -c ". $lib; init__expand_root"
|
||||
done
|
||||
}
|
||||
|
||||
@ -136,7 +139,7 @@ expand_root_lvm_whole_disk_body() {
|
||||
-o match:"resize2fs /dev/mapper/vg1-root" \
|
||||
-o not-match:"sfdisk" \
|
||||
-o not-match:"partx" \
|
||||
sh -c ". $lib; init__expand_root"
|
||||
sh -e -c ". $lib; init__expand_root"
|
||||
done
|
||||
}
|
||||
|
||||
@ -149,7 +152,7 @@ ethernets_body() {
|
||||
-o match:"eth0 eth2 eth11" \
|
||||
-o not-match:"br0" \
|
||||
-o not-match:"lo" \
|
||||
sh -c ". $lib; ethernets | tr '\n' ' '"
|
||||
sh -e -c ". $lib; ethernets | tr '\n' ' '"
|
||||
}
|
||||
|
||||
find_first_interface_up_body() {
|
||||
@ -158,7 +161,7 @@ find_first_interface_up_body() {
|
||||
|
||||
atf_check \
|
||||
-o match:"eth1" \
|
||||
sh -c ". $lib; find_first_interface_up eth0 eth1"
|
||||
sh -e -c ". $lib; find_first_interface_up eth0 eth1"
|
||||
}
|
||||
|
||||
auto_detect_ethernet_interface_body() {
|
||||
@ -167,13 +170,13 @@ auto_detect_ethernet_interface_body() {
|
||||
|
||||
atf_check \
|
||||
-o match:"^eth1$" \
|
||||
sh -c ". $lib; auto_detect_ethernet_interface"
|
||||
sh -e -c ". $lib; auto_detect_ethernet_interface"
|
||||
|
||||
# test that we pick first if all are down
|
||||
echo down > sys/class/net/eth1/operstate
|
||||
atf_check \
|
||||
-o match:"^eth0$" \
|
||||
sh -c ". $lib; TINY_CLOUD_LINK_WAIT_MAX=1; auto_detect_ethernet_interface"
|
||||
sh -e -c ". $lib; TINY_CLOUD_LINK_WAIT_MAX=1; auto_detect_ethernet_interface"
|
||||
}
|
||||
|
||||
set_default_interfaces_body() {
|
||||
@ -181,7 +184,7 @@ set_default_interfaces_body() {
|
||||
echo up > sys/class/net/eth1/operstate
|
||||
|
||||
atf_check \
|
||||
sh -c ". $lib; init__set_default_interfaces"
|
||||
sh -e -c ". $lib; init__set_default_interfaces"
|
||||
atf_check \
|
||||
-o match:"auto lo" \
|
||||
-o match:"iface eth1" \
|
||||
@ -194,7 +197,7 @@ enable_sshd_body() {
|
||||
CLOUD="$provider" atf_check \
|
||||
-o match:"rc-update.* add sshd default" \
|
||||
-o match:"rc-update.* --update" \
|
||||
sh -c ". $lib; init__enable_sshd"
|
||||
sh -e -c ". $lib; init__enable_sshd"
|
||||
done
|
||||
}
|
||||
|
||||
@ -204,7 +207,7 @@ create_default_user_body() {
|
||||
-o match:"adduser.*alpine" \
|
||||
-o match:"addgroup alpine wheel" \
|
||||
-o match:"chpasswd -e" \
|
||||
sh -c ". $lib; init__create_default_user"
|
||||
sh -e -c ". $lib; init__create_default_user"
|
||||
}
|
||||
|
||||
save_userdata_plain_body() {
|
||||
@ -212,7 +215,7 @@ save_userdata_plain_body() {
|
||||
#userdata
|
||||
EOF
|
||||
CLOUD="nocloud" atf_check -e match:"NoCloud 'meta-data' is empty" \
|
||||
sh -c ". \"$lib\"; init__save_userdata"
|
||||
sh -e -c ". \"$lib\"; init__save_userdata"
|
||||
atf_check -o match:"^#userdata" cat var/lib/cloud/user-data
|
||||
}
|
||||
|
||||
@ -224,7 +227,7 @@ save_userdata_compressed_body() {
|
||||
|
||||
CLOUD="nocloud" atf_check \
|
||||
-e 'ignore' \
|
||||
sh -c ". \"$lib\"; init__save_userdata"
|
||||
sh -e -c ". \"$lib\"; init__save_userdata"
|
||||
|
||||
if ! grep "^#userdata" var/lib/cloud/user-data; then
|
||||
atf_fail "$comp failed"
|
||||
@ -239,7 +242,7 @@ set_hostname_body() {
|
||||
|
||||
CLOUD="nocloud" atf_check \
|
||||
-o match:"hostname.*-F $PWD/etc/hostname" \
|
||||
sh -c ". \"$lib\"; init__set_hostname"
|
||||
sh -e -c ". \"$lib\"; init__set_hostname"
|
||||
atf_check -o match:"^myhostname$" cat etc/hostname
|
||||
}
|
||||
|
||||
@ -255,7 +258,7 @@ set_ssh_keys_body() {
|
||||
EOF
|
||||
CLOUD="nocloud" atf_check \
|
||||
-o match:"chown.*/\.ssh" \
|
||||
sh -c ". \"$lib\"; init__set_ssh_keys"
|
||||
sh -e -c ". \"$lib\"; init__set_ssh_keys"
|
||||
atf_check -o match:"^ssh-ed25519 keydata" \
|
||||
-o match:"^ssh-rsa foobar" \
|
||||
cat home/alpine/.ssh/authorized_keys
|
||||
@ -286,7 +289,7 @@ set_ssh_keys_gcp_body() {
|
||||
-e ignore \
|
||||
-o match:"chown -R bar:1001 .*\\.ssh" \
|
||||
-o not-match:"no SSH keys found for alpine" \
|
||||
sh -c ". \"$lib\"; init__set_ssh_keys"
|
||||
sh -e -c ". \"$lib\"; init__set_ssh_keys"
|
||||
atf_check -o match:"^ssh-ed25519 foobar1 alpine" \
|
||||
-o match:"^ssh-rsa foobar5 google-ssh" \
|
||||
-o not-match:"foobar4" \
|
||||
@ -302,32 +305,32 @@ userdata_type_body() {
|
||||
rm -f var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check \
|
||||
-o match:"missing" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
sh -e -c ". \"$lib\"; userdata_type"
|
||||
|
||||
touch var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check \
|
||||
-o match:"empty" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
sh -e -c ". \"$lib\"; userdata_type"
|
||||
|
||||
echo "#tiny-cloud-config" > var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check \
|
||||
-o match:"tiny-cloud-config" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
sh -e -c ". \"$lib\"; userdata_type"
|
||||
|
||||
echo "no-content-type" > var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check \
|
||||
-o match:"unknown" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
sh -e -c ". \"$lib\"; userdata_type"
|
||||
|
||||
echo "#alpine-config" > var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check \
|
||||
-o match:"alpine-config" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
sh -e -c ". \"$lib\"; userdata_type"
|
||||
|
||||
echo "#!/bin/sh" > var/lib/cloud/user-data
|
||||
CLOUD="$c" atf_check -s exit:0 \
|
||||
-o match:"script" \
|
||||
sh -c ". \"$lib\"; userdata_type"
|
||||
sh -e -c ". \"$lib\"; userdata_type"
|
||||
done
|
||||
}
|
||||
|
||||
@ -337,10 +340,10 @@ run_userdata_body() {
|
||||
echo "hello from user-data"
|
||||
EOF
|
||||
CLOUD="nocloud" atf_check -e match:"NoCloud 'meta-data' is empty" \
|
||||
sh -c ". \"$lib\"; init__save_userdata"
|
||||
sh -e -c ". \"$lib\"; init__save_userdata"
|
||||
CLOUD="nocloud" atf_check \
|
||||
-o match:"hello from user-data" \
|
||||
sh -c ". \"$lib\"; init__run_userdata"
|
||||
sh -e -c ". \"$lib\"; init__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"
|
||||
}
|
||||
@ -348,7 +351,24 @@ run_userdata_body() {
|
||||
autodetect_unknown_body() {
|
||||
atf_check \
|
||||
-o match:"unknown" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -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 -e -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 -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_aws_cmdline_body() {
|
||||
@ -356,7 +376,7 @@ autodetect_aws_cmdline_body() {
|
||||
echo "quiet tinycloud=cloud=aws console=ttyS0" > proc/cmdline
|
||||
atf_check \
|
||||
-o match:"aws" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_aws_nitro_body() {
|
||||
@ -366,7 +386,7 @@ autodetect_aws_nitro_body() {
|
||||
EOT
|
||||
atf_check \
|
||||
-o match:"aws" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_aws_xen_body() {
|
||||
@ -376,7 +396,7 @@ autodetect_aws_xen_body() {
|
||||
EOT
|
||||
atf_check \
|
||||
-o match:"aws" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_azure_body() {
|
||||
@ -386,7 +406,7 @@ autodetect_azure_body() {
|
||||
EOT
|
||||
atf_check \
|
||||
-o match:"azure" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_digitalocean_body() {
|
||||
@ -396,7 +416,7 @@ autodetect_digitalocean_body() {
|
||||
EOT
|
||||
atf_check \
|
||||
-o match:"digitalocean" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_gcp_body() {
|
||||
@ -406,7 +426,7 @@ autodetect_gcp_body() {
|
||||
EOT
|
||||
atf_check \
|
||||
-o match:"gcp" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_hetzner_body() {
|
||||
@ -416,7 +436,7 @@ autodetect_hetzner_body() {
|
||||
EOT
|
||||
atf_check \
|
||||
-o match:"hetzner" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_incus_body() {
|
||||
@ -424,7 +444,7 @@ autodetect_incus_body() {
|
||||
touch dev/incus/sock
|
||||
atf_check \
|
||||
-o match:"incus" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_nocloud_cmdline_body() {
|
||||
@ -432,7 +452,7 @@ autodetect_nocloud_cmdline_body() {
|
||||
echo "quiet ds=nocloud;s=https://10.42.42.42/ console=ttyS0" > proc/cmdline
|
||||
atf_check \
|
||||
-o match:"nocloud" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_nocloud_dmi_body() {
|
||||
@ -440,7 +460,7 @@ autodetect_nocloud_dmi_body() {
|
||||
echo "ds=nocloud;s=https://10.42.42.42/" > sys/class/dmi/id/product_serial
|
||||
atf_check \
|
||||
-o match:"nocloud" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_nocloud_volume_body() {
|
||||
@ -455,7 +475,7 @@ autodetect_nocloud_volume_body() {
|
||||
|
||||
atf_check \
|
||||
-o match:"nocloud" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_oci_body() {
|
||||
@ -463,7 +483,15 @@ autodetect_oci_body() {
|
||||
echo OracleCloud.com > sys/class/dmi/id/chassis_asset_tag
|
||||
atf_check \
|
||||
-o match:"oci" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -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 -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
autodetect_scaleway_body() {
|
||||
@ -473,5 +501,5 @@ autodetect_scaleway_body() {
|
||||
EOT
|
||||
atf_check \
|
||||
-o match:"scaleway" \
|
||||
sh -c ". \"$lib\"; echo \$CLOUD"
|
||||
sh -e -c ". \"$lib\"; echo \$CLOUD"
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ PATH="$atf_srcdir/bin:$srcdir/bin:$srcdir/sbin:$PATH"
|
||||
|
||||
export TINY_CLOUD_BASEDIR="$srcdir"
|
||||
export ROOT="$PWD"
|
||||
export IMDS_ENDPOINT_WAIT_ATTEMPTS=0
|
||||
|
||||
|
||||
init_tests() {
|
||||
|
||||
@ -30,6 +30,8 @@ init_tests \
|
||||
userdata_users_system \
|
||||
userdata_users_no_create_home \
|
||||
userdata_users_groups \
|
||||
userdata_users_passwd \
|
||||
userdata_users_hashed_passwd \
|
||||
userdata_users_lock_passwd \
|
||||
userdata_users_doas \
|
||||
userdata_users_doas_with_default \
|
||||
@ -385,6 +387,38 @@ userdata_users_groups_body() {
|
||||
tiny-cloud main
|
||||
}
|
||||
|
||||
userdata_users_passwd_body() {
|
||||
# first specified user will replace default user
|
||||
fake_userdata_nocloud <<-EOF
|
||||
#alpine-config
|
||||
users:
|
||||
- none
|
||||
- name: foo
|
||||
passwd: $6$foosalt$QuhZ.r54aqCAn7mTnU4jBh9LPyuVQCa8.H0dZWCMYHVaNzsPX/heqKqI3EtnB6j.YLuaENmnlEHTiwu.iVVcG1
|
||||
EOF
|
||||
atf_check -e ignore -o ignore tiny-cloud early
|
||||
atf_check \
|
||||
-e match:"userdata_users: done" \
|
||||
-o match:"chpasswd -e" \
|
||||
tiny-cloud main
|
||||
}
|
||||
|
||||
userdata_users_hashed_passwd_body() {
|
||||
# first specified user will replace default user
|
||||
fake_userdata_nocloud <<-EOF
|
||||
#alpine-config
|
||||
users:
|
||||
- none
|
||||
- name: foo
|
||||
hashed_passwd: $6$foosalt$QuhZ.r54aqCAn7mTnU4jBh9LPyuVQCa8.H0dZWCMYHVaNzsPX/heqKqI3EtnB6j.YLuaENmnlEHTiwu.iVVcG1
|
||||
EOF
|
||||
atf_check -e ignore -o ignore tiny-cloud early
|
||||
atf_check \
|
||||
-e match:"userdata_users: done" \
|
||||
-o match:"chpasswd -e" \
|
||||
tiny-cloud main
|
||||
}
|
||||
|
||||
userdata_users_lock_passwd_body() {
|
||||
# first specified user will replace default user
|
||||
fake_userdata_nocloud <<-EOF
|
||||
|
||||
@ -10,6 +10,8 @@ PROVIDERS="alpine aws azure digitalocean gcp incus hetzner nocloud oci scaleway"
|
||||
|
||||
init_tests \
|
||||
tiny_cloud_help \
|
||||
tiny_cloud_autodetect \
|
||||
tiny_cloud_autodetect_unknown \
|
||||
tiny_cloud_disabled \
|
||||
no_metadata_boot \
|
||||
no_userdata_early \
|
||||
@ -28,6 +30,26 @@ tiny_cloud_help_body() {
|
||||
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() {
|
||||
mkdir -p etc
|
||||
touch etc/tiny-cloud.disabled
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user