#!/usr/bin/env atf-sh # vim:set filetype=sh: # shellcheck shell=sh . $(atf_get_srcdir)/test_env.sh export PREFIX="$srcdir" export MOCK=echo lib="$srcdir"/lib/tiny-cloud/init init_tests \ expand_root \ expand_root_partition \ ethernets \ find_first_interface_up \ auto_detect_ethernet_interface \ set_default_interfaces \ enable_sshd \ create_default_user \ save_userdata_plain \ save_userdata_compressed \ set_hostname \ set_ssh_keys \ userdata_type \ run_userdata \ autodetect_aws_cmdline \ autodetect_aws_nitro \ autodetect_aws_xen \ autodetect_azure \ autodetect_digitalocean \ autodetect_gcp \ autodetect_hetzner \ autodetect_incus \ autodetect_nocloud_cmdline \ autodetect_nocloud_dmi \ autodetect_nocloud_volume \ autodetect_oci \ autodetect_scaleway \ autodetect_unknown PROVIDERS="aws azure digitalocean gcp hetzner nocloud oci scaleway" expand_root_body() { mkdir proc echo "/dev/xvda / ext4 rw,noatime 0 0" > proc/mounts for provider in $PROVIDERS; do CLOUD="$provider" atf_check \ -o match:"resize2fs /dev/xvda" \ sh -c ". $lib; init__expand_root" done } expand_root_partition_body() { mkdir -p proc sys/class/block \ sys/devices/pci0000:00/0000:00:1b.0/0000:01:00.0/nvme/nvme0/nvme0n1/nvme0n1p2 \ sys/devices/pci0000:00/0000:00:1b.0/0000:01:00.0/nvme/nvme0/nvme0n1/device ln -s ../../devices/pci0000:00/0000:00:1b.0/0000:01:00.0/nvme/nvme0/nvme0n1 sys/class/block/nvme0n1 ln -s ../../devices/pci0000:00/0000:00:1b.0/0000:01:00.0/nvme/nvme0/nvme0n1/nvme0n1p2 sys/class/block/nvme0n1p2 echo 2 > sys/class/block/nvme0n1p2/partition echo "/dev/nvme0n1p2 / ext4 rw,noatime 0 0" > proc/mounts for provider in $PROVIDERS; do CLOUD="$provider" atf_check \ -o match:"sfdisk .*/dev/nvme0n1" \ -o match:"partx .*/dev/nvme0n1" \ -o match:"resize2fs /dev/nvme0n1p2" \ sh -c ". $lib; init__expand_root" done } ethernets_body() { fake_interfaces lo br0 eth0 eth2 eth11 # check that they are sorted by ifindex, not name # and that br0 and lo are excluded atf_check \ -o match:"eth0 eth2 eth11" \ -o not-match:"br0" \ -o not-match:"lo" \ sh -c ". $lib; ethernets | tr '\n' ' '" } find_first_interface_up_body() { fake_interfaces eth0 eth1 echo up > sys/class/net/eth1/operstate atf_check \ -o match:"eth1" \ sh -c ". $lib; find_first_interface_up eth0 eth1" } auto_detect_ethernet_interface_body() { fake_interfaces eth0 eth1 echo up > sys/class/net/eth1/operstate atf_check \ -o match:"^eth1$" \ sh -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" } set_default_interfaces_body() { fake_interfaces eth0 eth1 echo up > sys/class/net/eth1/operstate atf_check \ sh -c ". $lib; init__set_default_interfaces" atf_check \ -o match:"auto lo" \ -o match:"iface eth1" \ -o match:"use dhcp" \ cat etc/network/interfaces } enable_sshd_body() { for provider in $PROVIDERS; do CLOUD="$provider" atf_check \ -o match:"rc-update.* add sshd default" \ -o match:"rc-update.* --update" \ sh -c ". $lib; init__enable_sshd" done } create_default_user_body() { atf_check \ -o match:"addgroup alpine" \ -o match:"adduser.*alpine" \ -o match:"addgroup alpine wheel" \ -o match:"chpasswd -e" \ sh -c ". $lib; init__create_default_user" } save_userdata_plain_body() { fake_userdata_nocloud <<-EOF #userdata EOF CLOUD="nocloud" atf_check -e match:"NoCloud 'meta-data' is empty" \ sh -c ". \"$lib\"; init__save_userdata" atf_check -o match:"^#userdata" cat var/lib/cloud/user-data } save_userdata_compressed_body() { for comp in gzip bzip2 xz lzma lzop lz4 zstd; do # fake_userdata_nocloud will set PATH so dont run it in a subshell printf "%s\n" "#userdata" | $comp -c > tmpfile fake_userdata_nocloud < tmpfile CLOUD="nocloud" atf_check \ -e 'ignore' \ sh -c ". \"$lib\"; init__save_userdata" if ! grep "^#userdata" var/lib/cloud/user-data; then atf_fail "$comp failed" fi done } set_hostname_body() { fake_metadata_nocloud <<-EOF hostname: myhostname EOF CLOUD="nocloud" atf_check \ -o match:"hostname.*-F $PWD/etc/hostname" \ sh -c ". \"$lib\"; init__set_hostname" atf_check -o match:"^myhostname$" cat etc/hostname } set_ssh_keys_body() { fake_bin getent <<-EOF #!/bin/sh echo "alpine:x:1000:1000:Linux User,,,:/home/alpine:/bin/sh" EOF fake_metadata_nocloud <<-EOF public-keys: - openssh-key: ssh-ed25519 keydata - openssh-key: ssh-rsa foobar EOF CLOUD="nocloud" atf_check \ -o match:"chown.*/\.ssh" \ sh -c ". \"$lib\"; init__set_ssh_keys" atf_check -o match:"^ssh-ed25519 keydata" \ -o match:"^ssh-rsa foobar" \ cat home/alpine/.ssh/authorized_keys } 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" touch var/lib/cloud/user-data CLOUD="$c" atf_check \ -o match:"empty" \ sh -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" echo "no-content-type" > var/lib/cloud/user-data CLOUD="$c" atf_check \ -o match:"unknown" \ sh -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" echo "#!/bin/sh" > var/lib/cloud/user-data CLOUD="$c" atf_check -s exit:0 \ -o match:"script" \ sh -c ". \"$lib\"; userdata_type" done } run_userdata_body() { fake_userdata_nocloud <<-EOF #!/bin/sh echo "hello from user-data" EOF CLOUD="nocloud" atf_check -e match:"NoCloud 'meta-data' is empty" \ sh -c ". \"$lib\"; init__save_userdata" CLOUD="nocloud" atf_check \ -o match:"hello from user-data" \ sh -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" } autodetect_unknown_body() { atf_check \ -o match:"unknown" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_aws_cmdline_body() { mkdir -p proc echo "quiet tinycloud=cloud=aws console=ttyS0" > proc/cmdline atf_check \ -o match:"aws" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_aws_nitro_body() { mkdir -p sys/class/dmi/id cat > sys/class/dmi/id/modalias <<-EOT dmi:bvnAmazonEC2:bvr1.0:bd10/16/2017:br1.0:svnAmazonEC2:pnm6g.metal:pvr1.0:rvnAmazonEC2:rnNotSpecified:rvrNotSpecified:cvnAmazonEC2:ct1:cvrNotSpecified:skuNotSpecified: EOT atf_check \ -o match:"aws" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_aws_xen_body() { mkdir -p sys/class/dmi/id cat > sys/class/dmi/id/modalias <<-EOT dmi:bvnXen:bvr4.11.amazon:bd08/24/2006:svnXen:pnHVMdomU:pvr4.11.amazon:cvnXen:ct1:cvr EOT atf_check \ -o match:"aws" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_azure_body() { mkdir -p sys/class/dmi/id cat > sys/class/dmi/id/modalias <<-EOT dmi:bvnMicrosoftCorporation:bvrHyper-VUEFIReleasev4.1:bd03/08/2024:br4.1:svnMicrosoftCorporation:pnVirtualMachine:pvrHyper-VUEFIReleasev4.1:rvnMicrosoftCorporation:rnVirtualMachine:rvrHyper-VUEFIReleasev4.1:cvnMicrosoftCorporation:ct3:cvrHyper-VUEFIReleasev4.1:skuNone: EOT atf_check \ -o match:"azure" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_digitalocean_body() { mkdir -p sys/class/dmi/id cat > sys/class/dmi/id/modalias <<-EOT dmi:bvnDigitalOcean:bvr20171212:bd12/12/2017:br0.0:svnDigitalOcean:pnDroplet:pvr20171212:rvnDigitalOcean:rnDroplet:rvr20171212:cvnQEMU:ct1:cvrpc-i440fx-6.1:sku: EOT atf_check \ -o match:"digitalocean" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_gcp_body() { mkdir -p sys/class/dmi/id cat > sys/class/dmi/id/modalias <<-EOT dmi:bvnGoogle:bvrGoogle:bd10/22/2024:br1.0:svnGoogle:pnGoogleComputeEngine:pvr:rvnKVM:rnGoogleComputeEngine:rvr:cvnGoogle:ct1:cvr:sku: EOT atf_check \ -o match:"gcp" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_hetzner_body() { mkdir -p sys/class/dmi/id cat > sys/class/dmi/id/modalias <<-EOT dmi:bvnHetzner:bvrHetzner:bd10/22/2024:br1.0:svnHetzner:pnHetzner:pvr:rvnKVM:rnHetzner:rvr:cvnHetzner:ct1:cvr:sku: EOT atf_check \ -o match:"hetzner" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_incus_body() { mkdir -p dev/incus touch dev/incus/sock atf_check \ -o match:"incus" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_nocloud_cmdline_body() { mkdir -p proc echo "quiet ds=nocloud;s=https://10.42.42.42/ console=ttyS0" > proc/cmdline atf_check \ -o match:"nocloud" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_nocloud_dmi_body() { mkdir -p sys/class/dmi/id 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" } autodetect_nocloud_volume_body() { fake_bin findfs <<-EOF #!/bin/sh case "\$1" in LABEL=cidata) echo "/dev/sda1";; LABEL=CIDATA) echo "/dev/sda2";; *) exit 1;; esac EOF atf_check \ -o match:"nocloud" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_oci_body() { mkdir -p sys/class/dmi/id echo OracleCloud.com > sys/class/dmi/id/chassis_asset_tag atf_check \ -o match:"oci" \ sh -c ". \"$lib\"; echo \$CLOUD" } autodetect_scaleway_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 \ -o match:"scaleway" \ sh -c ". \"$lib\"; echo \$CLOUD" }