lib.sh 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #!/bin/sh
  2. # Source the main regression test library if present
  3. [ -f "${RT_LIB}" ] && . "${RT_LIB}"
  4. # Temporary directory for tests to use.
  5. AYA_TMPDIR="${RT_PROJECT_ROOT}/_tmp"
  6. # Directory for VM images
  7. AYA_IMGDIR="${RT_PROJECT_ROOT}/_images"
  8. # Test Architecture
  9. if [ -z "${AYA_TEST_ARCH}" ]; then
  10. AYA_TEST_ARCH="$(uname -m)"
  11. fi
  12. # Test Image
  13. if [ -z "${AYA_TEST_IMAGE}" ]; then
  14. AYA_TEST_IMAGE="fedora35"
  15. fi
  16. case "${AYA_TEST_IMAGE}" in
  17. fedora*) AYA_SSH_USER="fedora";;
  18. centos*) AYA_SSH_USER="centos";;
  19. esac
  20. # compiles the ebpf program by using rust-script to create a temporary
  21. # cargo project in $(pwd)/ebpf. caller must add rm -rf ebpf to the clean_up
  22. # functionAYA_TEST_ARCH
  23. compile_ebpf() {
  24. file=$(basename "$1")
  25. dir=$(dirname "$1")
  26. base=$(echo "${file}" | cut -f1 -d '.')
  27. rm -rf "${dir}/ebpf"
  28. rust-script --pkg-path "${dir}/ebpf" --gen-pkg-only "$1"
  29. artifact=$(sed -n 's/^name = \"\(.*\)\"/\1/p' "${dir}/ebpf/Cargo.toml" | head -n1)
  30. mkdir -p "${dir}/.cargo"
  31. cat > "${dir}/.cargo/config.toml" << EOF
  32. [build]
  33. target = "bpfel-unknown-none"
  34. [unstable]
  35. build-std = ["core"]
  36. EOF
  37. cat >> "${dir}/ebpf/Cargo.toml" << EOF
  38. [workspace]
  39. members = []
  40. EOF
  41. # overwrite the rs file as rust-script adds a main fn
  42. cp "$1" "${dir}/ebpf/${file}"
  43. cargo build -q --manifest-path "${dir}/ebpf/Cargo.toml"
  44. mv "${dir}/ebpf/target/bpfel-unknown-none/debug/${artifact}" "${dir}/${base}.o"
  45. rm -rf "${dir}/.cargo"
  46. rm -rf "${dir}/ebpf"
  47. }
  48. # compile a C BPF file
  49. compile_c_ebpf() {
  50. file=$(basename "$1")
  51. dir=$(dirname "$1")
  52. base=$(echo "${file}" | cut -f1 -d '.')
  53. rust-script "${RT_PROJECT_ROOT}/_lib/compile-ebpf.ers" "${1}" "${dir}/${base}.o"
  54. rm -rf "${dir}/include"
  55. }
  56. # compiles the userspace program by using rust-script to create a temporary
  57. # cargo project in $(pwd)/user. caller must add rm -rf ebpf to the clean_up
  58. # function. this is required since the binary produced has to be run with
  59. # sudo to load an eBPF program
  60. compile_user() {
  61. file=$(basename "$1")
  62. dir=$(dirname "$1")
  63. base=$(echo "${file}" | cut -f1 -d '.')
  64. rm -rf "${dir}/user"
  65. rust-script --pkg-path "${dir}/user" --gen-pkg-only "$1"
  66. artifact=$(sed -n 's/^name = \"\(.*\)\"/\1/p' "${dir}/user/Cargo.toml" | head -n1)
  67. cat >> "${dir}/user/Cargo.toml" << EOF
  68. [workspace]
  69. members = []
  70. EOF
  71. cargo build -q --release --manifest-path "${dir}/user/Cargo.toml" --target=x86_64-unknown-linux-musl
  72. mv "${dir}/user/target/x86_64-unknown-linux-musl/release/${artifact}" "${dir}/${base}"
  73. rm -rf "${dir}/user"
  74. }
  75. download_images() {
  76. mkdir -p "${AYA_IMGDIR}"
  77. case $1 in
  78. fedora35)
  79. if [ ! -f "${AYA_IMGDIR}/fedora35.${AYA_TEST_ARCH}.qcow2" ]; then
  80. IMAGE="Fedora-Cloud-Base-35-1.2.${AYA_TEST_ARCH}.qcow2"
  81. IMAGE_URL="https://download.fedoraproject.org/pub/fedora/linux/releases/35/Cloud/${AYA_TEST_ARCH}/images"
  82. echo "Downloading: ${IMAGE}, this may take a while..."
  83. curl -o "${AYA_IMGDIR}/fedora35.${AYA_TEST_ARCH}.qcow2" -sSL "${IMAGE_URL}/${IMAGE}"
  84. fi
  85. ;;
  86. centos8)
  87. if [ ! -f "${AYA_IMGDIR}/centos8.${AYA_TEST_ARCH}.qcow2" ]; then
  88. IMAGE="CentOS-8-GenericCloud-8.4.2105-20210603.0.${AYA_TEST_ARCH}.qcow2"
  89. IMAGE_URL="https://cloud.centos.org/centos/8/${AYA_TEST_ARCH}/images"
  90. echo "Downloading: ${IMAGE}, this may take a while..."
  91. curl -o "${AYA_IMGDIR}/centos8.${AYA_TEST_ARCH}.qcow2" -sSL "${IMAGE_URL}/${IMAGE}"
  92. fi
  93. ;;
  94. *)
  95. echo "$1 is not a recognized image name"
  96. return 1
  97. ;;
  98. esac
  99. }
  100. start_vm() {
  101. download_images "${AYA_TEST_IMAGE}"
  102. # prepare config
  103. cat > "${AYA_TMPDIR}/metadata.yaml" <<EOF
  104. instance-id: iid-local01
  105. local-hostname: test
  106. EOF
  107. if [ ! -f "${AYA_TMPDIR}/test_rsa" ]; then
  108. ssh-keygen -t rsa -b 4096 -f "${AYA_TMPDIR}/test_rsa" -N "" -C "" -q
  109. pub_key=$(cat "${AYA_TMPDIR}/test_rsa.pub")
  110. cat > "${AYA_TMPDIR}/user-data.yaml" <<EOF
  111. #cloud-config
  112. ssh_authorized_keys:
  113. - ${pub_key}
  114. EOF
  115. fi
  116. if [ ! -f "${AYA_TMPDIR}/ssh_config" ]; then
  117. cat > "${AYA_TMPDIR}/ssh_config" <<EOF
  118. StrictHostKeyChecking=no
  119. UserKnownHostsFile=/dev/null
  120. GlobalKnownHostsFile=/dev/null
  121. EOF
  122. fi
  123. cloud-localds "${AYA_TMPDIR}/seed.img" "${AYA_TMPDIR}/user-data.yaml" "${AYA_TMPDIR}/metadata.yaml"
  124. case "${AYA_TEST_ARCH}" in
  125. x86_64)
  126. QEMU=qemu-system-x86_64
  127. machine="q35"
  128. cpu="qemu64"
  129. if [ "$(uname -m)" = "${AYA_TEST_ARCH}" ]; then
  130. if [ -c /dev/kvm ]; then
  131. machine="${machine},accel=kvm"
  132. cpu="host"
  133. elif [ "$(uname -s)" = "Darwin" ]; then
  134. machine="${machine},accel=hvf"
  135. cpu="host"
  136. fi
  137. fi
  138. ;;
  139. aarch64)
  140. QEMU=qemu-system-aarch64
  141. machine="virt"
  142. cpu="cortex-a57"
  143. if [ "$(uname -m)" = "${AYA_TEST_ARCH}" ]; then
  144. if [ -c /dev/kvm ]; then
  145. machine="${machine},accel=kvm"
  146. cpu="host"
  147. elif [ "$(uname -s)" = "Darwin" ]; then
  148. machine="${machine},accel=hvf"
  149. cpu="host"
  150. fi
  151. fi
  152. ;;
  153. *)
  154. echo "${AYA_TEST_ARCH} is not supported"
  155. return 1
  156. ;;
  157. esac
  158. qemu-img create -F qcow2 -f qcow2 -o backing_file="${AYA_IMGDIR}/${AYA_TEST_IMAGE}.${AYA_TEST_ARCH}.qcow2" "${AYA_TMPDIR}/vm.qcow2" || return 1
  159. $QEMU \
  160. -machine "${machine}" \
  161. -cpu "${cpu}" \
  162. -m 2G \
  163. -display none \
  164. -monitor none \
  165. -daemonize \
  166. -pidfile "${AYA_TMPDIR}/vm.pid" \
  167. -device virtio-net-pci,netdev=net0 \
  168. -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  169. -drive if=virtio,format=qcow2,file="${AYA_TMPDIR}/vm.qcow2" \
  170. -drive if=virtio,format=raw,file="${AYA_TMPDIR}/seed.img" || return 1
  171. trap cleanup_vm EXIT
  172. echo "Waiting for SSH on port 2222..."
  173. retry=0
  174. max_retries=300
  175. 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
  176. retry=$((retry+1))
  177. if [ ${retry} -gt ${max_retries} ]; then
  178. echo "Unable to connect to VM"
  179. return 1
  180. fi
  181. sleep 1
  182. done
  183. echo "VM launched, installing dependencies"
  184. exec_vm sudo dnf install -qy bpftool
  185. }
  186. scp_vm() {
  187. local=$1
  188. scp -q -F "${AYA_TMPDIR}/ssh_config" \
  189. -i "${AYA_TMPDIR}/test_rsa" \
  190. -P 2222 "${local}" \
  191. "${AYA_SSH_USER}@localhost:${local}"
  192. }
  193. exec_vm() {
  194. ssh -q -F "${AYA_TMPDIR}/ssh_config" \
  195. -i "${AYA_TMPDIR}/test_rsa" \
  196. -p 2222 \
  197. ${AYA_SSH_USER}@localhost \
  198. "$@"
  199. }
  200. stop_vm() {
  201. if [ -f "${AYA_TMPDIR}/vm.pid" ]; then
  202. echo "Stopping VM forcefully"
  203. kill -9 "$(cat "${AYA_TMPDIR}/vm.pid")"
  204. rm "${AYA_TMPDIR}/vm.pid"
  205. fi
  206. rm -f "${AYA_TMPDIR}/vm.qcow2"
  207. }
  208. cleanup_vm() {
  209. if [ "$?" != "0" ]; then
  210. stop_vm
  211. fi
  212. }