run.sh 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #!/usr/bin/env bash
  2. set -ex
  3. if [ "$(uname -s)" = "Darwin" ]; then
  4. PATH="$(dirname "$(brew list gnu-getopt | grep "bin/getopt$")"):$PATH"
  5. export PATH
  6. fi
  7. AYA_SOURCE_DIR="$(realpath "$(dirname "$0")"/..)"
  8. # Temporary directory for tests to use.
  9. AYA_TMPDIR="${AYA_SOURCE_DIR}/.tmp"
  10. # Directory for VM images
  11. AYA_IMGDIR=${AYA_TMPDIR}
  12. if [ -z "${AYA_BUILD_TARGET}" ]; then
  13. AYA_BUILD_TARGET=$(rustc -vV | sed -n 's|host: ||p')
  14. fi
  15. AYA_HOST_ARCH=$(uname -m)
  16. if [ "${AYA_HOST_ARCH}" = "arm64" ]; then
  17. AYA_HOST_ARCH="aarch64"
  18. fi
  19. if [ -z "${AYA_GUEST_ARCH}" ]; then
  20. AYA_GUEST_ARCH="${AYA_HOST_ARCH}"
  21. fi
  22. if [ "${AYA_GUEST_ARCH}" = "aarch64" ]; then
  23. if [ -z "${AARCH64_UEFI}" ]; then
  24. AARCH64_UEFI="$(brew list qemu -1 -v | grep edk2-aarch64-code.fd)"
  25. fi
  26. fi
  27. if [ -z "$AYA_MUSL_TARGET" ]; then
  28. AYA_MUSL_TARGET=${AYA_GUEST_ARCH}-unknown-linux-musl
  29. fi
  30. # Test Image
  31. if [ -z "${AYA_TEST_IMAGE}" ]; then
  32. AYA_TEST_IMAGE="fedora38"
  33. fi
  34. case "${AYA_TEST_IMAGE}" in
  35. fedora*) AYA_SSH_USER="fedora";;
  36. centos*) AYA_SSH_USER="centos";;
  37. esac
  38. download_images() {
  39. mkdir -p "${AYA_IMGDIR}"
  40. case $1 in
  41. fedora37)
  42. if [ ! -f "${AYA_IMGDIR}/fedora37.${AYA_GUEST_ARCH}.qcow2" ]; then
  43. IMAGE="Fedora-Cloud-Base-37-1.7.${AYA_GUEST_ARCH}.qcow2"
  44. IMAGE_URL="https://download.fedoraproject.org/pub/fedora/linux/releases/37/Cloud/${AYA_GUEST_ARCH}/images"
  45. echo "Downloading: ${IMAGE}, this may take a while..."
  46. curl -o "${AYA_IMGDIR}/fedora37.${AYA_GUEST_ARCH}.qcow2" -sSL "${IMAGE_URL}/${IMAGE}"
  47. fi
  48. ;;
  49. fedora38)
  50. if [ ! -f "${AYA_IMGDIR}/fedora38.${AYA_GUEST_ARCH}.qcow2" ]; then
  51. IMAGE="Fedora-Cloud-Base-38_Beta-1.3.${AYA_GUEST_ARCH}.qcow2"
  52. IMAGE_URL="https://fr2.rpmfind.net/linux/fedora/linux/releases/test/38_Beta/Cloud/${AYA_GUEST_ARCH}/images"
  53. echo "Downloading: ${IMAGE}, this may take a while..."
  54. curl -o "${AYA_IMGDIR}/fedora38.${AYA_GUEST_ARCH}.qcow2" -sSL "${IMAGE_URL}/${IMAGE}"
  55. fi
  56. ;;
  57. centos8)
  58. if [ ! -f "${AYA_IMGDIR}/centos8.${AYA_GUEST_ARCH}.qcow2" ]; then
  59. IMAGE="CentOS-8-GenericCloud-8.4.2105-20210603.0.${AYA_GUEST_ARCH}.qcow2"
  60. IMAGE_URL="https://cloud.centos.org/centos/8/${AYA_GUEST_ARCH}/images"
  61. echo "Downloading: ${IMAGE}, this may take a while..."
  62. curl -o "${AYA_IMGDIR}/centos8.${AYA_GUEST_ARCH}.qcow2" -sSL "${IMAGE_URL}/${IMAGE}"
  63. fi
  64. ;;
  65. *)
  66. echo "$1 is not a recognized image name"
  67. return 1
  68. ;;
  69. esac
  70. }
  71. start_vm() {
  72. download_images "${AYA_TEST_IMAGE}"
  73. # prepare config
  74. cat > "${AYA_TMPDIR}/metadata.yaml" <<EOF
  75. instance-id: iid-local01
  76. local-hostname: test
  77. EOF
  78. if [ ! -f "${AYA_TMPDIR}/test_rsa" ]; then
  79. ssh-keygen -t rsa -b 4096 -f "${AYA_TMPDIR}/test_rsa" -N "" -C "" -q
  80. pub_key=$(cat "${AYA_TMPDIR}/test_rsa.pub")
  81. fi
  82. if [ ! -f "${AYA_TMPDIR}/ssh_config" ]; then
  83. cat > "${AYA_TMPDIR}/ssh_config" <<EOF
  84. StrictHostKeyChecking=no
  85. UserKnownHostsFile=/dev/null
  86. GlobalKnownHostsFile=/dev/null
  87. EOF
  88. fi
  89. cat > "${AYA_TMPDIR}/user-data.yaml" <<EOF
  90. #cloud-config
  91. ssh_authorized_keys:
  92. - ${pub_key}
  93. EOF
  94. "$AYA_SOURCE_DIR"/test/cloud-localds "${AYA_TMPDIR}/seed.img" "${AYA_TMPDIR}/user-data.yaml" "${AYA_TMPDIR}/metadata.yaml"
  95. case "${AYA_GUEST_ARCH}" in
  96. x86_64)
  97. QEMU=qemu-system-x86_64
  98. machine="q35"
  99. cpu="qemu64"
  100. nr_cpus="$(nproc --all)"
  101. if [ "${AYA_HOST_ARCH}" = "${AYA_GUEST_ARCH}" ]; then
  102. if [ -c /dev/kvm ]; then
  103. machine="${machine},accel=kvm"
  104. cpu="host"
  105. elif [ "$(uname -s)" = "Darwin" ]; then
  106. machine="${machine},accel=hvf"
  107. cpu="host"
  108. fi
  109. fi
  110. ;;
  111. aarch64)
  112. QEMU=qemu-system-aarch64
  113. machine="virt"
  114. cpu="cortex-a57"
  115. uefi=("-drive" "file=${AARCH64_UEFI},if=pflash,format=raw,readonly=on")
  116. if [ "${AYA_HOST_ARCH}" = "${AYA_GUEST_ARCH}" ]; then
  117. if [ -c /dev/kvm ]; then
  118. machine="${machine},accel=kvm"
  119. cpu="host"
  120. nr_cpus="$(nproc --all)"
  121. elif [ "$(uname -s)" = "Darwin" ]; then
  122. machine="${machine},accel=hvf,highmem=off"
  123. cpu="cortex-a72"
  124. # nrpoc --all on apple silicon returns the two extra fancy
  125. # cores and then qemu complains that nr_cpus > actual_cores
  126. nr_cpus=8
  127. fi
  128. fi
  129. ;;
  130. *)
  131. echo "${AYA_GUEST_ARCH} is not supported"
  132. return 1
  133. ;;
  134. esac
  135. if [ ! -f "${AYA_IMGDIR}/vm.qcow2" ]; then
  136. echo "Creating VM image"
  137. qemu-img create -F qcow2 -f qcow2 -o backing_file="${AYA_IMGDIR}/${AYA_TEST_IMAGE}.${AYA_GUEST_ARCH}.qcow2" "${AYA_IMGDIR}/vm.qcow2" || return 1
  138. else
  139. echo "Reusing existing VM image"
  140. fi
  141. $QEMU \
  142. -machine "${machine}" \
  143. -cpu "${cpu}" \
  144. -m 3G \
  145. -smp "${nr_cpus}" \
  146. -display none \
  147. -monitor none \
  148. -daemonize \
  149. -pidfile "${AYA_TMPDIR}/vm.pid" \
  150. -device virtio-net-pci,netdev=net0 \
  151. -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  152. "${uefi[@]}" \
  153. -drive if=virtio,format=qcow2,file="${AYA_IMGDIR}/vm.qcow2" \
  154. -drive if=virtio,format=raw,file="${AYA_TMPDIR}/seed.img" || return 1
  155. trap cleanup_vm EXIT
  156. echo "Waiting for SSH on port 2222..."
  157. retry=0
  158. max_retries=300
  159. while ! ssh -q -F "${AYA_TMPDIR}/ssh_config" -o ConnectTimeout=1 -i "${AYA_TMPDIR}/test_rsa" "${AYA_SSH_USER}"@localhost -p 2222 echo "Hello VM"; do
  160. retry=$((retry+1))
  161. if [ ${retry} -gt ${max_retries} ]; then
  162. echo "Unable to connect to VM"
  163. return 1
  164. fi
  165. sleep 1
  166. done
  167. echo "VM launched"
  168. exec_vm uname -a
  169. echo "Enabling testing repositories"
  170. exec_vm sudo dnf config-manager --set-enabled updates-testing
  171. exec_vm sudo dnf config-manager --set-enabled updates-testing-modular
  172. }
  173. scp_vm() {
  174. local=$1
  175. remote=$(basename "$1")
  176. scp -q -F "${AYA_TMPDIR}/ssh_config" \
  177. -i "${AYA_TMPDIR}/test_rsa" \
  178. -P 2222 "${local}" \
  179. "${AYA_SSH_USER}@localhost:${remote}"
  180. }
  181. rsync_vm() {
  182. rsync -a -e "ssh -p 2222 -F ${AYA_TMPDIR}/ssh_config -i ${AYA_TMPDIR}/test_rsa" "$1" "$AYA_SSH_USER"@localhost:
  183. }
  184. exec_vm() {
  185. ssh -q -F "${AYA_TMPDIR}/ssh_config" \
  186. -i "${AYA_TMPDIR}/test_rsa" \
  187. -p 2222 \
  188. "${AYA_SSH_USER}"@localhost \
  189. "$@"
  190. }
  191. stop_vm() {
  192. if [ -f "${AYA_TMPDIR}/vm.pid" ]; then
  193. echo "Stopping VM forcefully"
  194. kill -9 "$(cat "${AYA_TMPDIR}/vm.pid")"
  195. rm "${AYA_TMPDIR}/vm.pid"
  196. fi
  197. }
  198. cleanup_vm() {
  199. if ! stop_vm; then
  200. rm -f "${AYA_IMGDIR}/vm.qcow2"
  201. fi
  202. }
  203. start_vm
  204. trap cleanup_vm EXIT
  205. # make sure we always use fresh sources (also see comment at the end)
  206. rsync_vm "$*"
  207. exec_vm "find $* -type f -executable -print0 | xargs -0 -I {} sudo {} --test-threads=1"
  208. # we rm and sync but it doesn't seem to work reliably - I guess we could sleep a
  209. # few seconds after but ain't nobody got time for that. Instead we also rm
  210. # before rsyncing.
  211. exec_vm "rm -rf $*; sync"