github.com/kata-containers/tests@v0.0.0-20240307153542-772105b56064/integration/kubernetes/vfio.sh (about)

     1  #!/bin/bash
     2  #
     3  # Copyright (c) 2020 Intel Corporation
     4  #
     5  # SPDX-License-Identifier: Apache-2.0
     6  #
     7  
     8  set -x
     9  set -o errexit
    10  set -o nounset
    11  set -o pipefail
    12  set -o errtrace
    13  
    14  SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
    15  source "${SCRIPT_DIR}/../../.ci/lib.sh"
    16  
    17  SYSCONFIG_FILE="/etc/kata-containers/configuration.toml"
    18  
    19  trap cleanup EXIT
    20  cleanup() {
    21  	sudo rm -rf "${SYSCONFIG_FILE}"
    22  	# Don't fail the test if cleanup fails
    23  	# VM will be destroyed anyway.
    24  	${SCRIPT_DIR}/cleanup_env.sh || true
    25  }
    26  
    27  setup_configuration_file() {
    28  	local image_type="$1"
    29  	local machine_type="$2"
    30  	local hypervisor="$3"
    31  	local sandbox_cgroup_only="$4"
    32  
    33  	local default_config_file="/opt/kata/share/defaults/kata-containers/configuration.toml"
    34  	local qemu_config_file="/opt/kata/share/defaults/kata-containers/configuration-qemu.toml"
    35  	local clh_config_file="/opt/kata/share/defaults/kata-containers/configuration-clh.toml"
    36  	local image_file="/opt/kata/share/kata-containers/kata-containers.img"
    37  	local initrd_file="/opt/kata/share/kata-containers/kata-containers-initrd.img"
    38  
    39  	sudo mkdir -p $(dirname "${SYSCONFIG_FILE}")
    40  
    41  	if [ "${hypervisor}" = "qemu" ]; then
    42  		config_file="${qemu_config_file}"
    43  	elif [ "${hypervisor}" = "cloud-hypervisor" ]; then
    44  		config_file="${clh_config_file}"
    45  	fi
    46  
    47  	if [ -f "${config_file}" ]; then
    48  		cp -a "${config_file}" "${SYSCONFIG_FILE}"
    49  	elif [ -f "${default_config_file}" ]; then
    50  		# Check if path contains the hypervisor name
    51  		if ! grep "^path" "${default_config_file}" | grep -q "${hypervisor}"; then
    52  			die "Configuration file for ${hypervisor} hypervisor not found"
    53  		fi
    54  		sudo cp -a "${default_config_file}" "${SYSCONFIG_FILE}"
    55  	else
    56  		die "Error: configuration file for ${hypervisor} doesn't exist"
    57  	fi
    58  
    59  	# machine type applies to configuration.toml and configuration-qemu.toml
    60  	if [ -n "${machine_type}" ]; then
    61  		if [ "${hypervisor}" = "qemu" ]; then
    62  			sudo sed -i 's|^machine_type.*|machine_type = "'${machine_type}'"|g' "${SYSCONFIG_FILE}"
    63  		else
    64  			info "Variable machine_type only applies to qemu. It will be ignored"
    65  		fi
    66  	fi
    67  
    68  	if [ -n "${sandbox_cgroup_only}" ]; then
    69  		sudo sed -i 's|^sandbox_cgroup_only.*|sandbox_cgroup_only='${sandbox_cgroup_only}'|g' "${SYSCONFIG_FILE}"
    70  	fi
    71  
    72  	# Change to initrd or image depending on user input.
    73  	# Non-default configs must be changed to specify either initrd or image, image is default.
    74  	if [ "${image_type}" = "initrd" ]; then
    75  		if $(grep -q "^image.*" "${SYSCONFIG_FILE}"); then
    76  			if $(grep -q "^initrd.*" "${SYSCONFIG_FILE}"); then
    77  				sudo sed -i '/^image.*/d' "${SYSCONFIG_FILE}"
    78  			else
    79  				sudo sed -i 's|^image.*|initrd = "'${initrd_file}'"|g' "${SYSCONFIG_FILE}"
    80  			fi
    81  		fi
    82  	else
    83  		if $(grep -q "^initrd.*" "${SYSCONFIG_FILE}"); then
    84  			if $(grep -q "^image.*" "${SYSCONFIG_FILE}"); then
    85  				sudo sed -i '/^initrd.*/d' "${SYSCONFIG_FILE}"
    86  			else
    87  				sudo sed -i 's|^initrd.*|image = "'${image_file}'"|g' "${SYSCONFIG_FILE}"
    88  			fi
    89  		fi
    90  	fi
    91  
    92  	# enable debug
    93  	sudo sed -i -e 's/^#\(enable_debug\).*=.*$/\1 = true/g' \
    94  		-e 's/^kernel_params = "\(.*\)"/kernel_params = "\1 agent.log=debug"/g' \
    95  		"${SYSCONFIG_FILE}"
    96  
    97  	# Cloud-hypervisor workaround
    98  	# Issue: https://github.com/kata-containers/tests/issues/2963
    99  	if [ "${hypervisor}" = "cloud-hypervisor" ]; then
   100  		sudo sed -i -e 's|^default_memory.*|default_memory = 1024|g' \
   101  		            -e 's|^virtio_fs_cache =.*|virtio_fs_cache = "none"|g' \
   102  		            "${SYSCONFIG_FILE}"
   103  	fi
   104  }
   105  
   106  run_test() {
   107  	local image_type="${1:-}"
   108  	# QEMU machine type
   109  	local machine_type="${2:-}"
   110  	local hypervisor="${3:-}"
   111  	local sandbox_cgroup_only="${4:-}"
   112  
   113  	info "Run test case: hypervisor=${hypervisor}" \
   114  		"${machine_type:+machine=$machine_type}" \
   115  		"image=${image_type} sandbox_cgroup_only=${sandbox_cgroup_only}"
   116  
   117  	if [ -z "$image_type" ]; then
   118  		die "need image type"
   119  	elif [ -z "$hypervisor" ]; then
   120  		die "need hypervisor"
   121  	elif [ -z "$sandbox_cgroup_only" ]; then
   122  		die "need sandbox cgroup only"
   123  	fi
   124  
   125  	setup_configuration_file "$image_type" "$machine_type" "$hypervisor" "$sandbox_cgroup_only"
   126  
   127  	sudo -E kubectl create -f "${SCRIPT_DIR}/runtimeclass_workloads/vfio.yaml"
   128  
   129  	pod_name=vfio
   130  	sudo -E kubectl wait --for=condition=Ready pod "${pod_name}" || \
   131  		{
   132  			sudo -E kubectl describe pod "${pod_name}";
   133  			die "Pod ${pod_name} failed to start";
   134  		}
   135  
   136  	# wait for the container to be ready
   137  	waitForProcess 15 3 "sudo -E kubectl exec ${pod_name} -- ip a"
   138  
   139  	# Expecting 2 network interaces -> 2 mac addresses
   140  	mac_addrs=$(sudo -E kubectl exec "${pod_name}" -- ip a | grep "link/ether" | wc -l)
   141  	if [ ${mac_addrs} -ne 2 ]; then
   142  		die "Error: expecting 2 network interfaces, Got: $(kubectl exec "${pod_name}" -- ip a)"
   143  	else
   144  		info "Success: found 2 network interfaces"
   145  	fi
   146  
   147  	sudo -E kubectl delete -f "${SCRIPT_DIR}/runtimeclass_workloads/vfio.yaml"
   148  }
   149  
   150  main() {
   151  	# Init k8s cluster
   152  	${SCRIPT_DIR}/init.sh
   153  
   154  	sudo modprobe vfio
   155  	sudo modprobe vfio-pci
   156  
   157  	# unbind device from driver
   158  	# PCI address
   159  	local addr="00:03.0"
   160  	echo 0000:${addr} | sudo tee /sys/bus/pci/devices/0000:${addr}/driver/unbind
   161  
   162  	# Create a new VFIO device
   163  	# Ethernet controller: Red Hat, Inc. Virtio network device
   164  	# vendor ID: 1af4
   165  	# device ID: 1041
   166  	local vendor_id="1af4"
   167  	local device_id="1041"
   168  	echo "${vendor_id} ${device_id}" | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
   169  
   170  	# Install network (device) plugin
   171  	sriov_plugin_url=$(get_version "plugins.sriov-network-device.url")
   172  	sriov_plugin_version=$(get_version "plugins.sriov-network-device.version")
   173  	git clone "${sriov_plugin_url}"
   174  	pushd sriov-network-device-plugin
   175  	git checkout "${sriov_plugin_version}"
   176  	sed -i 's|resourceList.*|resourceList": [{"resourceName":"virtio_net","selectors":{"vendors":["'"${vendor_id}"'"],"devices":["'"${device_id}"'"],"drivers":["vfio-pci"],"pfNames":["eth1"]}},{|g' deployments/configMap.yaml
   177  	sudo -E kubectl create -f deployments/configMap.yaml
   178  	sudo -E kubectl create -f deployments/k8s-v1.16/sriovdp-daemonset.yaml
   179  	sleep 5
   180  	popd
   181  	rm -rf sriov-network-device-plugin
   182  
   183  	sriov_pod="$(sudo -E kubectl --namespace=kube-system get pods --output=name | grep sriov-device-plugin | cut -d/ -f2)"
   184  	sudo -E kubectl --namespace=kube-system wait --for=condition=Ready pod "${sriov_pod}"
   185  
   186  	# wait for the virtio_net resource
   187  	for _ in $(seq 1 30); do
   188  		v="$(sudo -E kubectl get node $(hostname | awk '{print tolower($0)}') -o json | jq '.status.allocatable["intel.com/virtio_net"]')"
   189  		[ "${v}" == \"1\" ] && break
   190  		sleep 5
   191  	done
   192  
   193  	# Skip clh/QEMU + initrd:
   194  	# https://github.com/kata-containers/kata-containers/issues/900
   195  	# run_test initrd "" cloud-hypervisor false
   196  	# run_test initrd "" cloud-hypervisor false
   197  	# run_test initrd "q35" qemu false
   198  	# run_test initrd "q35" qemu true
   199  	run_test image "" cloud-hypervisor false
   200  	run_test image "" cloud-hypervisor true
   201  	run_test image "q35" qemu false
   202  	run_test image "q35" qemu true
   203  }
   204  
   205  main $@