diff --git a/lib/tiny-cloud/user-data/alpine-config b/lib/tiny-cloud/user-data/alpine-config index 63e10ca..50363c8 100644 --- a/lib/tiny-cloud/user-data/alpine-config +++ b/lib/tiny-cloud/user-data/alpine-config @@ -64,18 +64,64 @@ find_biggest_empty_disk() { done | sort -n | tail -n 1 | cut -d' ' -f2 } +is_number() { + case "$1" in + ''|*[!0-9]*) return 1 ;; + esac + return 0 +} + init__userdata_autoinstall() { local autoinstall="$(get_userdata autoinstall)" + local disk reboot swapsize uselvm if [ "$autoinstall" = "true" ]; then - local disk="$(find_biggest_empty_disk)" - if [ -n "$disk" ]; then - rm -f "$ETC"/runlevels/*/tiny-cloud* - $MOCK lbu include /root/.ssh /home - ERASE_DISKS=/dev/$disk $MOCK setup-disk -m sys /dev/$disk - # TODO: make reboot configurable - $MOCK reboot - else - log err "no empty disk found" + disk=auto + reboot=true + else + disk="$(get_userdata autoinstall/disk)" + if [ -z "$disk" ]; then + log err "no disk specified" + return + fi + reboot="$(get_userdata autoinstall/reboot)" + : ${reboot:=true} + + swapsize="$(get_userdata autoinstall/swapsize)" + uselvm="$(get_userdata autoinstall/lvm)" + if [ "$uselvm" != "true" ]; then + unset uselvm fi fi + + if [ "$disk" = "auto" ]; then + disk="$(find_biggest_empty_disk)" + if [ -z "$disk" ]; then + log err "no empty disk found" + return + fi + disk="/dev/$disk" + fi + + if ! [ -b "$disk" ] && [ -z "$MOCK" ]; then + log err "$disk is not a block device" + return + fi + + if [ -n "$swapsize" ] && ! is_number ${swapsize%[MG]}; then + log err "swapsize is not valid: $swapsize" + return + fi + + case "$swapsize" in + *M) swapsize=${swapsize%M};; + *G) swapsize=$(( ${swapsize%G} * 1000));; + esac + + rm -f "$ETC"/runlevels/*/tiny-cloud* + $MOCK lbu include /root/.ssh /home + ERASE_DISKS=/dev/$disk $MOCK setup-disk -m sys ${uselvm+-L} ${swapsize+-s ${swapsize}} $disk + + if [ "$reboot" = "true" ]; then + $MOCK reboot + fi } diff --git a/tests/tiny-cloud-alpine.test b/tests/tiny-cloud-alpine.test index 43dab1d..cef4a67 100755 --- a/tests/tiny-cloud-alpine.test +++ b/tests/tiny-cloud-alpine.test @@ -49,7 +49,14 @@ init_tests \ userdata_package_upgrade \ userdata_packages \ userdata_runcmd \ - userdata_autoinstall + userdata_autoinstall \ + userdata_no_autoinstall \ + userdata_autoinstall_no_reboot \ + userdata_autoinstall_select_disk \ + userdata_autoinstall_disable_swap \ + userdata_autoinstall_swapsize \ + userdata_autoinstall_swapsize_invalid \ + userdata_autoinstall_lvm set_ephemeral_network_cmdline_body() { fake_interfaces eth0 eth1 eth2 @@ -760,6 +767,160 @@ userdata_autoinstall_body() { atf_check \ -e match:"userdata_autoinstall: done" \ -o match:"setup-disk" \ + -o match:"reboot" \ + tiny-cloud final +} + +userdata_no_autoinstall_body() { + fake_userdata_nocloud <<-EOF + #alpine-config + EOF + fake_bin blkid <<-EOF + #!/bin/sh + true + EOF + fake_disk nvme0n8 10000 + fake_disk vda 20000 + + # run net phase to extract the user data + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -e match:"userdata_autoinstall: done" \ + -o not-match:"setup-disk" \ + -o not-match:"reboot" \ + tiny-cloud final +} + +userdata_autoinstall_no_reboot_body() { + fake_userdata_nocloud <<-EOF + #alpine-config + autoinstall: + disk: auto + reboot: false + EOF + fake_bin blkid <<-EOF + #!/bin/sh + true + EOF + fake_disk nvme0n8 10000 + fake_disk vda 20000 + + # run net phase to extract the user data + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -e match:"userdata_autoinstall: done" \ + -o match:"setup-disk.*vda" \ + -o not-match:"reboot" \ + tiny-cloud final +} + +userdata_autoinstall_select_disk_body() { + fake_userdata_nocloud <<-EOF + #alpine-config + autoinstall: + disk: /dev/nvme0n8 + EOF + fake_bin blkid <<-EOF + #!/bin/sh + true + EOF + fake_disk nvme0n8 10000 + fake_disk vda 20000 + + # run net phase to extract the user data + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -e match:"userdata_autoinstall: done" \ + -o match:"setup-disk.*nvme0n8" \ + -o match:"reboot" \ + tiny-cloud final +} + +userdata_autoinstall_disable_swap_body() { + fake_userdata_nocloud <<-EOF + #alpine-config + autoinstall: + disk: auto + swapsize: 0 + EOF + fake_bin blkid <<-EOF + #!/bin/sh + true + EOF + fake_disk vda 20000 + + # run net phase to extract the user data + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -e match:"userdata_autoinstall: done" \ + -o match:"setup-disk.*-s 0.*vda" \ + -o match:"reboot" \ + tiny-cloud final +} + +userdata_autoinstall_swapsize_body() { + fake_userdata_nocloud <<-EOF + #alpine-config + autoinstall: + disk: auto + swapsize: 4G + EOF + fake_bin blkid <<-EOF + #!/bin/sh + true + EOF + fake_disk vda 20000 + + # run net phase to extract the user data + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -e match:"userdata_autoinstall: done" \ + -o match:"setup-disk.*-s 4000 .*vda" \ + -o match:"reboot" \ + tiny-cloud final +} + +userdata_autoinstall_swapsize_invalid_body() { + fake_userdata_nocloud <<-EOF + #alpine-config + autoinstall: + disk: auto + swapsize: invalidG + EOF + fake_bin blkid <<-EOF + #!/bin/sh + true + EOF + fake_disk vda 20000 + + # run net phase to extract the user data + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -e match:"userdata_autoinstall: done" \ + -o not-match:"setup-disk.*-s 4000 .*vda" \ + -o not-match:"reboot" \ + tiny-cloud final +} + +userdata_autoinstall_lvm_body() { + fake_userdata_nocloud <<-EOF + #alpine-config + autoinstall: + disk: auto + lvm: true + EOF + fake_bin blkid <<-EOF + #!/bin/sh + true + EOF + fake_disk vda 20000 + + # run net phase to extract the user data + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -e match:"userdata_autoinstall: done" \ + -o match:"setup-disk.*-L.*vda" \ + -o match:"reboot" \ tiny-cloud final }