From 60ac429c240d0019a2dbc326ee9d43aa934ab3df Mon Sep 17 00:00:00 2001 From: Alexander Noskov Date: Mon, 24 Feb 2020 16:29:09 -0600 Subject: [PATCH] Extend VM's configuration with NUMA/CPU/Memory/NIC changes Add abbility to extend VM's configuration via JSON to configure: * NUMA nodes / cpu cells * CPU mode, sockets, threads * Memory backend * NIC model Change-Id: I1640fd250427827b6800be60ca559a058c7cf989 --- tools/deployment/seaworthy-virt/README.rst | 21 ++++++- .../seaworthy-virt/airship_gate/lib/config.sh | 58 ++++++++++++++++++- .../seaworthy-virt/airship_gate/lib/virsh.sh | 7 ++- 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/tools/deployment/seaworthy-virt/README.rst b/tools/deployment/seaworthy-virt/README.rst index 1d84b38ac..77348e4a1 100644 --- a/tools/deployment/seaworthy-virt/README.rst +++ b/tools/deployment/seaworthy-virt/README.rst @@ -174,10 +174,14 @@ via Airship. Each key is the name of a VM and value is a JSON object: { "memory": integer, "vcpus": integer, + "sockets": integer, + "threads": integer, "disk_layout": "simple", + "cpu_mode": "host-passthrough", "networking": { "ens3": { "mac": "52:54:00:00:be:31", + "model": "e1000", "pci": { "slot": 3, "port": 0 @@ -193,18 +197,33 @@ via Airship. Each key is the name of a VM and value is a JSON object: } }, "bootstrap": true, + "cpu_cells": { + "cell0": { + "cpus": "0-11", + "memory": "25165824" + }, + "cell1": { + "cpus": "12-23", + "memory": "25165824" + } + }, "userdata": "packages: [docker.io]" } * memory - VM RAM in megabytes * vcpus - Number of VM CPUs + * sockets - Number of sockets. (Optional) + * threads - Number of threads. (Optional) * disk_layout - A disk profile for the VM matching one defined under ``.disk_layouts`` * bootstrap - True/False for whether the framework should bootstrap the VM's OS + * cpu_cells - Parameter to setup NUMA nodes and allocate RAM memory. (Optional) + * cpu_mode - CPU mode for the VM. (if not specified, default: host) * userdata - Cloud-init userdata to feed the VM when bootstrapped for further customization - * networking - Network attachment and addressing configuration. Every key but ``addresses`` + * networking - Network attachment and addressing configuration. Every key but ``addresses`` is assumed to be a desired NIC on the VM. For each NIC stanza, the following fields are respected: * mac - A MAC address for the NIC + * model - A model for the NIC (if not specified, default: virtio) * pci - A JSON object specifying ``slot`` and ``port`` specifying the PCI address for the NIC * attachment - What network from ``.networking`` is attached to this NIC diff --git a/tools/deployment/seaworthy-virt/airship_gate/lib/config.sh b/tools/deployment/seaworthy-virt/airship_gate/lib/config.sh index 6e5b8d161..0317794a3 100644 --- a/tools/deployment/seaworthy-virt/airship_gate/lib/config.sh +++ b/tools/deployment/seaworthy-virt/airship_gate/lib/config.sh @@ -43,7 +43,15 @@ export AIRSHIP_KEYSTONE_URL=${AIRSHIP_KEYSTONE_URL:-'http://keystone.gate.local: config_vm_memory() { nodename=${1} - jq -cr ".vm.${nodename}.memory" < "${GATE_MANIFEST}" + mem=$(jq -cr ".vm.${nodename}.memory" < "${GATE_MANIFEST}") + mem_backing=$(jq -cr ".vm.${nodename}.memorybacking" < "${GATE_MANIFEST}") + + if [[ "${mem_backing}" != "null" ]] + then + echo "memory=${mem},${mem_backing}=yes" + else + echo "${mem}" + fi } config_vm_names() { @@ -55,6 +63,19 @@ config_vm_iface_list() { jq -cr ".vm.${nodename}.networking | del(.addresses) | keys | .[]" < "${GATE_MANIFEST}" } +config_vm_iface_model() { + nodename="$1" + interface="$2" + iface_model=$(jq -cr ".vm.${nodename}.networking.${interface}.model" < "${GATE_MANIFEST}") + + if [[ "${iface_model}" != "null" ]] + then + echo "${iface_model}" + else + echo "virtio" + fi +} + config_vm_iface_mac() { nodename="$1" interface="$2" @@ -112,9 +133,42 @@ config_vm_net_ip() { jq -cr "$query" < "${GATE_MANIFEST}" } +config_vm_cpu() { + nodename=${1} + cpu_mode=$(jq -cr ".vm.${nodename}.cpu_mode" < "${GATE_MANIFEST}") + cpu_cells=$(jq -cr ".vm.${nodename}.cpu_cells" < "${GATE_MANIFEST}") + + if [[ "${cpu_mode}" != "null" ]] + then + config_string="mode=${cpu_mode}" + if [[ "${cpu_cells}" != "null" ]] + then + cpu_cells_to_s=$(echo "${cpu_cells}" | jq -cr "[to_entries[] | [.key + \".cpus=\" + .value.cpus, .key + \".memory=\" + .value.memory]] | add | join (\",\")") + config_string="${config_string},${cpu_cells_to_s}" + fi + else + config_string=${VIRSH_CPU_OPTS} + fi + echo -n "$config_string" +} + config_vm_vcpus() { nodename=${1} - jq -cr ".vm.${nodename}.vcpus" < "${GATE_MANIFEST}" + vcpus=$(jq -cr ".vm.${nodename}.vcpus" < "${GATE_MANIFEST}") + sockets=$(jq -cr ".vm.${nodename}.sockets" < "${GATE_MANIFEST}") + threads=$(jq -cr ".vm.${nodename}.threads" < "${GATE_MANIFEST}") + + if [[ "${sockets}" != "null" ]] + then + config_string="vcpus=${vcpus},sockets=${sockets}" + if [[ "${threads}" != "null" ]] + then + config_string="${config_string},threads=${threads}" + fi + echo -n "$config_string" + else + echo "${vcpus}" + fi } config_vm_bootstrap() { diff --git a/tools/deployment/seaworthy-virt/airship_gate/lib/virsh.sh b/tools/deployment/seaworthy-virt/airship_gate/lib/virsh.sh index a26e1969a..f5371046b 100644 --- a/tools/deployment/seaworthy-virt/airship_gate/lib/virsh.sh +++ b/tools/deployment/seaworthy-virt/airship_gate/lib/virsh.sh @@ -378,12 +378,13 @@ vm_render_interface() { namekey="$(get_namekey)" mac="$(config_vm_iface_mac "$vm" "$iface")" + model="$(config_vm_iface_model "$vm" "$iface")" network="$(config_vm_iface_network "$vm" "$iface")" network="${namekey}_${network}" slot="$(config_vm_iface_slot "$vm" "$iface")" port="$(config_vm_iface_port "$vm" "$iface")" - config_string="model=virtio,network=${network}" + config_string="model=${model},network=${network}" if [[ ! -z "$mac" ]] then @@ -498,7 +499,7 @@ vm_create() { --name "${NAME}" \ --os-variant ubuntu16.04 \ --virt-type kvm \ - --cpu "${VIRSH_CPU_OPTS}" \ + --cpu "$(config_vm_cpu "${NAME}")" \ --serial "file,path=${TEMP_DIR}/console/${NAME}.log" \ --graphics vnc,listen=0.0.0.0 \ --noautoconsole \ @@ -520,7 +521,7 @@ vm_create() { --name "${NAME}" \ --os-variant ubuntu16.04 \ --virt-type kvm \ - --cpu "${VIRSH_CPU_OPTS}" \ + --cpu "$(config_vm_cpu "${NAME}")" \ --graphics vnc,listen=0.0.0.0 \ --serial file,path="${TEMP_DIR}/console/${NAME}.log" \ --noautoconsole \