mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-21 07:08:12 +00:00
Merge pull request #7922 from VersatusHPC/fix/xcattest-vmothersetting-restore
fix(xcat-test): the installation cases corrupt a versioned machine type in vmothersetting
This commit is contained in:
+145
@@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
# vm_machine_type.sh - set and clear the KVM machine type in vmothersetting of a node.
|
||||
#
|
||||
# Usage:
|
||||
# vm_machine_type.sh invalid <node> save vmothersetting, then add machine:invalid
|
||||
# vm_machine_type.sh apply <node> <arch> write the saved value with a valid machine type
|
||||
# vm_machine_type.sh restore <node> [<arch>] write the saved value back and delete it
|
||||
#
|
||||
# The saved value is in $VM_MACHINE_TYPE_STATE_DIR, one file per node. The
|
||||
# default directory is /tmp/xcattest-vmothersetting.<uid>.
|
||||
|
||||
vm_machine_type_dir()
|
||||
{
|
||||
printf '%s\n' "${VM_MACHINE_TYPE_STATE_DIR:-/tmp/xcattest-vmothersetting.$(id -u)}"
|
||||
}
|
||||
|
||||
vm_machine_type_state()
|
||||
{
|
||||
printf '%s/xcattest-%s-vmothersetting\n' "$(vm_machine_type_dir)" "$1"
|
||||
}
|
||||
|
||||
# private_dir -- create the state directory, or accept it only when it is a
|
||||
# directory that the current user owns and nobody else can open.
|
||||
vm_machine_type_private_dir()
|
||||
{
|
||||
local dir
|
||||
dir="$(vm_machine_type_dir)"
|
||||
[ -e "$dir" ] || [ -L "$dir" ] || mkdir -m 0700 "$dir" 2>/dev/null
|
||||
if [ -L "$dir" ] || [ ! -d "$dir" ] || [ ! -O "$dir" ] ||
|
||||
[ -n "$(find "$dir" -maxdepth 0 -perm /077)" ]; then
|
||||
echo "vm_machine_type.sh: $dir is not a private directory of $(id -un)" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vm_machine_type_for_arch()
|
||||
{
|
||||
case "$1" in
|
||||
ppc64*) echo 'machine:pseries-rhel7.6.0' ;;
|
||||
x86_64) echo 'machine:pc' ;;
|
||||
riscv64) echo 'machine:virt' ;;
|
||||
aarch64) echo 'machine:virt' ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
vm_machine_type_get()
|
||||
{
|
||||
local out
|
||||
if ! out="$(lsdef "$1" -i vmothersetting)"; then
|
||||
echo "vm_machine_type.sh: cannot read vmothersetting of $1" >&2
|
||||
return 1
|
||||
fi
|
||||
printf '%s\n' "$out" | sed -n 's/^[[:space:]]*vmothersetting=//p'
|
||||
}
|
||||
|
||||
vm_machine_type_saved()
|
||||
{
|
||||
local state
|
||||
vm_machine_type_private_dir || return 1
|
||||
state="$(vm_machine_type_state "$1")"
|
||||
if [ ! -e "$state" ] && [ ! -L "$state" ]; then
|
||||
echo "vm_machine_type.sh: no saved vmothersetting for $1 in $state" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ -L "$state" ] || [ ! -f "$state" ] || [ ! -O "$state" ]; then
|
||||
echo "vm_machine_type.sh: $state is not a regular file of $(id -un)" >&2
|
||||
return 1
|
||||
fi
|
||||
cat "$state"
|
||||
}
|
||||
|
||||
# join <first> <second> -- join two vmothersetting values with ";".
|
||||
vm_machine_type_join()
|
||||
{
|
||||
if [ -z "$1" ]; then
|
||||
printf '%s\n' "$2"
|
||||
else
|
||||
printf '%s;%s\n' "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
vm_machine_type_invalid()
|
||||
{
|
||||
local node="$1" state original
|
||||
vm_machine_type_private_dir || return 1
|
||||
state="$(vm_machine_type_state "$node")"
|
||||
# A second invalid would save machine:invalid as the original value.
|
||||
if [ -e "$state" ] || [ -L "$state" ]; then
|
||||
echo "vm_machine_type.sh: a saved vmothersetting for $node already exists in $state" >&2
|
||||
return 1
|
||||
fi
|
||||
original="$(vm_machine_type_get "$node")" || return 1
|
||||
# noclobber makes bash create the file with O_EXCL.
|
||||
(set -o noclobber && printf '%s' "$original" >"$state") || return 1
|
||||
# kvm.pm uses the last machine: setting.
|
||||
if ! chdef "$node" "vmothersetting=$(vm_machine_type_join "$original" 'machine:invalid')"; then
|
||||
rm -f "$state"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vm_machine_type_apply()
|
||||
{
|
||||
local node="$1" arch="$2" original machine
|
||||
original="$(vm_machine_type_saved "$node")" || return 1
|
||||
# A machine type the node already names stays in place.
|
||||
if [[ ";$original" == *";machine:"* ]]; then
|
||||
chdef "$node" "vmothersetting=$original"
|
||||
return
|
||||
fi
|
||||
if ! machine="$(vm_machine_type_for_arch "$arch")"; then
|
||||
echo "vm_machine_type.sh: no machine type for arch '$arch'" >&2
|
||||
return 1
|
||||
fi
|
||||
chdef "$node" "vmothersetting=$(vm_machine_type_join "$original" "$machine")"
|
||||
}
|
||||
|
||||
vm_machine_type_restore()
|
||||
{
|
||||
local node="$1" original
|
||||
original="$(vm_machine_type_saved "$node")" || return 1
|
||||
# An empty value makes chdef delete the attribute.
|
||||
chdef "$node" "vmothersetting=$original" || return 1
|
||||
rm -f "$(vm_machine_type_state "$node")"
|
||||
}
|
||||
|
||||
vm_machine_type_main()
|
||||
{
|
||||
local action="$1"
|
||||
shift
|
||||
case "$action" in
|
||||
invalid) vm_machine_type_invalid "$@" ;;
|
||||
apply) vm_machine_type_apply "$@" ;;
|
||||
restore) vm_machine_type_restore "$@" ;;
|
||||
*)
|
||||
echo "usage: vm_machine_type.sh {invalid <node>|apply <node> <arch>|restore <node> [<arch>]}" >&2
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
||||
vm_machine_type_main "$@"
|
||||
fi
|
||||
@@ -46,7 +46,7 @@ cmd:rm -rf /tmp/mountoutput
|
||||
cmd:packimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute
|
||||
check:rc==0
|
||||
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then str1=`lsdef $$CN | grep vmothersetting | cut -d '=' -f 2`;str2=";"; str3="machine:invalid"; if [ -z $str1 ]; then str4=$str3; else str4=$str1$str2$str3;fi; chdef $$CN vmothersetting=$str4; fi
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then /opt/xcat/share/xcat/tools/autotest/testcase/commoncmd/vm_machine_type.sh invalid $$CN; fi
|
||||
check:rc==0
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then str=`lsdef $$CN | grep vmothersetting`; if [[ $str =~ "invalid" ]]; then exit 0; else exit 1; fi; fi
|
||||
check:rc==0
|
||||
@@ -57,7 +57,7 @@ check:rc==0
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then str=`/opt/xcat/share/xcat/tools/autotest/testcase/commoncmd/retry_install.sh $$CN __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute 1`; if [[ $str =~ "failed" ]]; then exit 0; else exit 1; fi; fi
|
||||
check:rc==0
|
||||
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then str1=`lsdef $$CN | grep vmothersetting | cut -d '=' -f 2`;str2="machine:invalid"; if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64" ]]; then str3="machine:pseries-rhel7.6.0"; elif [[ "__GETNODEATTR($$CN,arch)__" =~ "x86_64" ]]; then str3="machine:pc"; elif [[ "__GETNODEATTR($$CN,arch)__" =~ "riscv64" ]]; then str3="machine:virt"; elif [[ "__GETNODEATTR($$CN,arch)__" =~ "aarch64" ]]; then str3="machine:virt";fi; if [ "$str1" == "$str2" ]; then str5=$str3; else str4=`echo $str1 | sed -e "s/$str2//"`;str5=$str4$str3;fi; chdef $$CN vmothersetting=$str5; fi
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then /opt/xcat/share/xcat/tools/autotest/testcase/commoncmd/vm_machine_type.sh apply $$CN __GETNODEATTR($$CN,arch)__; fi
|
||||
check:rc==0
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then str=`lsdef $$CN | grep vmothersetting`; if [[ $str =~ "machine" ]]; then exit 0; else exit 1; fi; fi
|
||||
check:rc==0
|
||||
@@ -68,7 +68,7 @@ check:rc==0
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then str=`/opt/xcat/share/xcat/tools/autotest/testcase/commoncmd/retry_install.sh $$CN __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute`; echo $str; if [[ $str =~ "The provision succeeded" ]]; then exit 0; else exit 1; fi; fi
|
||||
check:rc==0
|
||||
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then str1=`lsdef $$CN | grep vmothersetting | cut -d '=' -f 2`;str2=";"; if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64" ]]; then str3="machine:pseries-rhel7.6.0"; elif [[ "__GETNODEATTR($$CN,arch)__" =~ "x86_64" ]]; then str3="machine:pc"; elif [[ "__GETNODEATTR($$CN,arch)__" =~ "riscv64" ]]; then str3="machine:virt"; elif [[ "__GETNODEATTR($$CN,arch)__" =~ "aarch64" ]]; then str3="machine:virt";fi; if [ "$str1" == "$str3" ]; then chdef $$CN vmothersetting=; else str4=`echo $str1 | sed -e "s/$str2$str3//"`; chdef $$CN vmothersetting=$str4;fi; fi
|
||||
cmd:if [ "__GETNODEATTR($$CN,mgt)__" == "kvm" ]; then /opt/xcat/share/xcat/tools/autotest/testcase/commoncmd/vm_machine_type.sh restore $$CN __GETNODEATTR($$CN,arch)__; fi
|
||||
check:rc==0
|
||||
cmd:if [ "__GETNODEATTR($$CN,arch)__" != "ppc64" -a "__GETNODEATTR($$CN,mgt)__" != "ipmi" -a "__GETNODEATTR($$CN,mgt)__" != "openbmc" ];then echo "CN node $$CN is a VM, mgt is __GETNODEATTR($$CN,mgt)__, starting to recreate the vm"; echo "rpower $$CN off"; rpower $$CN off; sleep 3; echo "rpower $$CN stat"; rpower $$CN stat; var=`expr substr "__GETNODEATTR($$CN,vmstorage)__" 1 3`; echo "The disk type of $$CN is $var"; if [ "$var" = "phy" ]; then echo "mkvm $$CN"; mkvm $$CN; echo "rmvm $$CN -f -p"; rmvm $$CN -f -p; echo "mkvm $$CN"; mkvm $$CN; exit $?; elif [ "$var" = "dir" ]; then echo "mkvm $$CN -s 30G -f"; mkvm $$CN -s 30G -f; echo "rmvm $$CN -f -p"; rmvm $$CN -f -p; echo "mkvm $$CN -s 30G -f"; mkvm $$CN -s 30G -f; exit $?; elif ["$var" = "nfs" -o "$var" = "lvm" ];then echo "Need to fix disk type $var"; exit 2; else echo "Unsupported disk type $var"; exit 3;fi;else echo "CN node $$CN is not a VM; do not need to recreate it";fi
|
||||
check:rc==0
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
#
|
||||
# reg_linux_diskless_installation_flat corrupts the KVM machine type of the compute node, checks
|
||||
# that the node fails to boot, and then restores it. The restore reads a machine type from a
|
||||
# ladder that names ppc64 and x86_64 only, so on any other architecture it writes an empty
|
||||
# vmothersetting and the check after it fails.
|
||||
#
|
||||
# The two commands are lifted out of the case file and RUN, with lsdef and chdef shadowed, so
|
||||
# the assertions read the value the case would write. The extraction fails the test when it
|
||||
# stops matching, so a rewrite fails loudly instead of covering nothing.
|
||||
|
||||
load 'helpers/shell_source'
|
||||
|
||||
setup()
|
||||
{
|
||||
CASE="$(repo_path 'xCAT-test/autotest/testcase/installation/reg_linux_diskless_installation_flat')"
|
||||
[ -r "$CASE" ] || skip "$CASE is required"
|
||||
export CASE
|
||||
}
|
||||
|
||||
# The command that restores the machine type, and the one that removes it again afterwards.
|
||||
restore_command()
|
||||
{
|
||||
extract_first_matching_line "$CASE" \
|
||||
'^cmd:.*str2="machine:invalid".*chdef [$][$]CN vmothersetting=[$]str5'
|
||||
}
|
||||
|
||||
remove_command()
|
||||
{
|
||||
extract_first_matching_line "$CASE" \
|
||||
'^cmd:.*str2=";".*~ "ppc64".*chdef [$][$]CN vmothersetting='
|
||||
}
|
||||
|
||||
# Render one command the way xcattest does, then run it with lsdef and chdef shadowed. bash
|
||||
# resolves a function ahead of PATH, so the case's own backticks read the stub.
|
||||
#
|
||||
# Sets OUT to everything the command printed and WRITTEN to the value it gave chdef.
|
||||
run_case_command()
|
||||
{
|
||||
local cmd="$1" arch="$2" lsdef_value="$3"
|
||||
|
||||
cmd="${cmd#cmd:}"
|
||||
cmd="${cmd//__GETNODEATTR(\$\$CN,arch)__/$arch}"
|
||||
cmd="${cmd//__GETNODEATTR(\$\$CN,mgt)__/kvm}"
|
||||
cmd="${cmd//\$\$CN/cn1}"
|
||||
|
||||
OUT="$(bash -c "lsdef() { echo ' vmothersetting=$lsdef_value'; }
|
||||
chdef() { echo \"CHDEF:[\$*]\"; }
|
||||
$cmd" 2>&1)" || true
|
||||
# The brackets keep an empty value apart from no call at all: the cleanup is meant to write
|
||||
# an empty vmothersetting, and a command that never reaches chdef must not read as that.
|
||||
CHDEF_CALLS="$(grep -c '^CHDEF:' <<<"$OUT" || true)"
|
||||
WRITTEN="$(sed -n 's/^CHDEF:\[cn1 vmothersetting=\(.*\)\]$/\1/p' <<<"$OUT")"
|
||||
}
|
||||
|
||||
# The machine type each architecture must end up with. riscv64 guests run the qemu "virt"
|
||||
# machine; kvm.pm sets it in guest_arch_profile.
|
||||
#
|
||||
# The restore writes the machine type; the cleanup after it takes the same machine type away
|
||||
# again and leaves every other setting. Both read the same ladder, so both are checked against
|
||||
# the same value.
|
||||
assert_arch()
|
||||
{
|
||||
local arch="$1" machine="$2" restore remove
|
||||
|
||||
restore="$(restore_command)"
|
||||
remove="$(remove_command)"
|
||||
|
||||
# The node carries the corrupt value only.
|
||||
run_case_command "$restore" "$arch" 'machine:invalid'
|
||||
[ "$CHDEF_CALLS" -eq 1 ]
|
||||
[ "$WRITTEN" = "machine:$machine" ]
|
||||
|
||||
# The node carries a setting of its own beside the corrupt value.
|
||||
run_case_command "$restore" "$arch" 'cpumode:host-passthrough;machine:invalid'
|
||||
[ "$CHDEF_CALLS" -eq 1 ]
|
||||
[ "$WRITTEN" = "cpumode:host-passthrough;machine:$machine" ]
|
||||
|
||||
# The cleanup, with nothing but the machine type to remove.
|
||||
run_case_command "$remove" "$arch" "machine:$machine"
|
||||
[ "$(grep -c 'unary operator expected' <<<"$OUT")" -eq 0 ]
|
||||
[ "$CHDEF_CALLS" -eq 1 ]
|
||||
[ "$WRITTEN" = "" ]
|
||||
|
||||
# The cleanup, with a setting of its own that must survive it.
|
||||
run_case_command "$remove" "$arch" "cpumode:host-passthrough;machine:$machine"
|
||||
[ "$(grep -c 'unary operator expected' <<<"$OUT")" -eq 0 ]
|
||||
[ "$CHDEF_CALLS" -eq 1 ]
|
||||
[ "$WRITTEN" = "cpumode:host-passthrough" ]
|
||||
}
|
||||
|
||||
@test "ppc64le: the restore writes the machine type and the cleanup takes it away" {
|
||||
assert_arch ppc64le pseries-rhel7.6.0
|
||||
}
|
||||
|
||||
@test "x86_64: the restore writes the machine type and the cleanup takes it away" {
|
||||
assert_arch x86_64 pc
|
||||
}
|
||||
|
||||
@test "riscv64: the restore writes the machine type and the cleanup takes it away" {
|
||||
assert_arch riscv64 virt
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env bats
|
||||
# vm_machine_type.sh sets machine:invalid, then a valid machine type, then clears it again.
|
||||
# lsdef and chdef are shell functions that read and write vmothersetting of node cn1 in a file.
|
||||
|
||||
load 'helpers/shell_source'
|
||||
|
||||
setup()
|
||||
{
|
||||
source "$(require_repo_file 'xCAT-test/autotest/testcase/commoncmd/vm_machine_type.sh')"
|
||||
VMOTHER="${BATS_TEST_TMPDIR}/vmothersetting"
|
||||
export VM_MACHINE_TYPE_STATE_DIR="${BATS_TEST_TMPDIR}/state"
|
||||
mkdir -m 0700 "$VM_MACHINE_TYPE_STATE_DIR"
|
||||
STATE="${VM_MACHINE_TYPE_STATE_DIR}/xcattest-cn1-vmothersetting"
|
||||
LSDEF_FAIL=0
|
||||
CHDEF_FAIL=0
|
||||
CHDEF_CALLS=0
|
||||
}
|
||||
|
||||
# lsdef prints no line for an attribute without a value.
|
||||
lsdef()
|
||||
{
|
||||
if [ "$LSDEF_FAIL" -ne 0 ]; then
|
||||
echo "Error: [mn]: Could not find an object named '$1' of type 'node'." >&2
|
||||
return 1
|
||||
fi
|
||||
printf 'Object name: %s\n' "$1"
|
||||
if [ -s "$VMOTHER" ]; then
|
||||
printf ' vmothersetting=%s\n' "$(cat "$VMOTHER")"
|
||||
fi
|
||||
}
|
||||
|
||||
chdef()
|
||||
{
|
||||
[ "$1" = cn1 ] || return 1
|
||||
[ "$CHDEF_FAIL" -eq 0 ] || return 1
|
||||
case "$2" in
|
||||
vmothersetting=*) printf '%s' "${2#vmothersetting=}" >"$VMOTHER" ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
CHDEF_CALLS=$((CHDEF_CALLS + 1))
|
||||
}
|
||||
|
||||
set_vmother()
|
||||
{
|
||||
printf '%s' "$1" >"$VMOTHER"
|
||||
}
|
||||
|
||||
vmother()
|
||||
{
|
||||
cat "$VMOTHER"
|
||||
}
|
||||
|
||||
# assert_arch <arch> <machine> <original> -- the value after each step of the case.
|
||||
assert_arch()
|
||||
{
|
||||
local arch="$1" machine="$2" original="$3" sep=''
|
||||
[ -z "$original" ] || sep=';'
|
||||
CHDEF_CALLS=0
|
||||
|
||||
set_vmother "$original"
|
||||
vm_machine_type_main invalid cn1
|
||||
[ "$(vmother)" = "${original}${sep}machine:invalid" ]
|
||||
|
||||
vm_machine_type_main apply cn1 "$arch"
|
||||
[ "$(vmother)" = "${original}${sep}machine:$machine" ]
|
||||
|
||||
vm_machine_type_main restore cn1 "$arch"
|
||||
[ "$(vmother)" = "$original" ]
|
||||
[ "$CHDEF_CALLS" -eq 3 ]
|
||||
}
|
||||
|
||||
@test "ppc64le: the case sets and clears pseries-rhel7.6.0" {
|
||||
assert_arch ppc64le pseries-rhel7.6.0 ''
|
||||
assert_arch ppc64le pseries-rhel7.6.0 'cpumode:host-passthrough'
|
||||
}
|
||||
|
||||
@test "x86_64: the case sets and clears pc" {
|
||||
assert_arch x86_64 pc ''
|
||||
assert_arch x86_64 pc 'cpumode:host-passthrough'
|
||||
}
|
||||
|
||||
@test "riscv64: the case sets and clears virt" {
|
||||
assert_arch riscv64 virt ''
|
||||
assert_arch riscv64 virt 'cpumode:host-passthrough'
|
||||
}
|
||||
|
||||
@test "aarch64: the case sets and clears virt" {
|
||||
assert_arch aarch64 virt ''
|
||||
assert_arch aarch64 virt 'cpumode:host-passthrough'
|
||||
}
|
||||
|
||||
# assert_round_trip <arch> <original> -- the case ends with the exact value it started with.
|
||||
assert_round_trip()
|
||||
{
|
||||
local arch="$1" original="$2" machine
|
||||
|
||||
set_vmother "$original"
|
||||
vm_machine_type_main invalid cn1
|
||||
# kvm.pm uses the last machine: field of vmothersetting.
|
||||
machine="$(vmother | tr ';' '\n' | grep '^machine:' | tail -n 1)"
|
||||
[ "$machine" = "machine:invalid" ]
|
||||
|
||||
vm_machine_type_main apply cn1 "$arch"
|
||||
vm_machine_type_main restore cn1 "$arch"
|
||||
[ "$(vmother)" = "$original" ]
|
||||
[ -z "$(ls -A "$VM_MACHINE_TYPE_STATE_DIR")" ]
|
||||
}
|
||||
|
||||
@test "round trip: no vmothersetting" {
|
||||
assert_round_trip x86_64 ''
|
||||
}
|
||||
|
||||
@test "round trip: machine:invalid" {
|
||||
assert_round_trip x86_64 'machine:invalid'
|
||||
}
|
||||
|
||||
@test "round trip: cpumode:host-passthrough" {
|
||||
assert_round_trip x86_64 'cpumode:host-passthrough'
|
||||
}
|
||||
|
||||
@test "round trip: x86_64 with a versioned machine type" {
|
||||
assert_round_trip x86_64 'cpumode:host-passthrough;machine:pc-q35-9.2'
|
||||
}
|
||||
|
||||
@test "round trip: riscv64 with a versioned machine type" {
|
||||
assert_round_trip riscv64 'machine:virt-9.2'
|
||||
}
|
||||
|
||||
@test "round trip: riscv64 with a versioned machine type after another setting" {
|
||||
assert_round_trip riscv64 'cpumode:host-passthrough;machine:virt-9.2'
|
||||
}
|
||||
|
||||
@test "round trip: several settings" {
|
||||
assert_round_trip ppc64le 'vcpupin:0-3;membind:0;devpassthrough:pci_0000_01_00_0,pci_0000_02_00_0;cpumode:host-model'
|
||||
}
|
||||
|
||||
@test "apply keeps a machine type the node already names" {
|
||||
set_vmother 'cpumode:host-passthrough;machine:pc-q35-9.2'
|
||||
vm_machine_type_main invalid cn1
|
||||
vm_machine_type_main apply cn1 x86_64
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough;machine:pc-q35-9.2' ]
|
||||
}
|
||||
|
||||
@test "restore without a saved value fails and leaves vmothersetting alone" {
|
||||
set_vmother 'cpumode:host-passthrough;machine:pc'
|
||||
run vm_machine_type_main restore cn1 x86_64
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"no saved vmothersetting for cn1"* ]]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough;machine:pc' ]
|
||||
}
|
||||
|
||||
@test "apply fails for an architecture without a machine type" {
|
||||
set_vmother ''
|
||||
vm_machine_type_main invalid cn1
|
||||
run vm_machine_type_main apply cn1 s390x
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"no machine type for arch 's390x'"* ]]
|
||||
[ "$(vmother)" = 'machine:invalid' ]
|
||||
}
|
||||
|
||||
@test "invalid saves an empty vmothersetting that lsdef read" {
|
||||
set_vmother ''
|
||||
vm_machine_type_main invalid cn1
|
||||
[ -f "$STATE" ]
|
||||
[ ! -s "$STATE" ]
|
||||
[ "$(vmother)" = 'machine:invalid' ]
|
||||
}
|
||||
|
||||
@test "invalid creates a private state directory" {
|
||||
rmdir "$VM_MACHINE_TYPE_STATE_DIR"
|
||||
vm_machine_type_main invalid cn1
|
||||
[ -d "$VM_MACHINE_TYPE_STATE_DIR" ]
|
||||
[ -z "$(find "$VM_MACHINE_TYPE_STATE_DIR" -maxdepth 0 -perm /077)" ]
|
||||
}
|
||||
|
||||
@test "invalid fails without a snapshot or chdef when lsdef fails" {
|
||||
set_vmother 'cpumode:host-passthrough'
|
||||
LSDEF_FAIL=1
|
||||
run vm_machine_type_main invalid cn1
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"cannot read vmothersetting of cn1"* ]]
|
||||
[ ! -e "$STATE" ]
|
||||
[ "$CHDEF_CALLS" -eq 0 ]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough' ]
|
||||
}
|
||||
|
||||
@test "a second invalid is refused and keeps the first snapshot" {
|
||||
set_vmother 'cpumode:host-passthrough'
|
||||
vm_machine_type_main invalid cn1
|
||||
run vm_machine_type_main invalid cn1
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"saved vmothersetting for cn1 already exists"* ]]
|
||||
[ "$(cat "$STATE")" = 'cpumode:host-passthrough' ]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough;machine:invalid' ]
|
||||
[ "$CHDEF_CALLS" -eq 1 ]
|
||||
|
||||
vm_machine_type_main apply cn1 x86_64
|
||||
vm_machine_type_main restore cn1 x86_64
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough' ]
|
||||
}
|
||||
|
||||
@test "invalid refuses a snapshot left by an earlier run" {
|
||||
set_vmother 'cpumode:host-passthrough'
|
||||
printf '%s' 'machine:stale' >"$STATE"
|
||||
run vm_machine_type_main invalid cn1
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"saved vmothersetting for cn1 already exists"* ]]
|
||||
[ "$(cat "$STATE")" = 'machine:stale' ]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough' ]
|
||||
[ "$CHDEF_CALLS" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "invalid refuses a symbolic link as the state file" {
|
||||
set_vmother 'cpumode:host-passthrough'
|
||||
ln -s "${BATS_TEST_TMPDIR}/target" "$STATE"
|
||||
run vm_machine_type_main invalid cn1
|
||||
[ "$status" -ne 0 ]
|
||||
[ ! -e "${BATS_TEST_TMPDIR}/target" ]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough' ]
|
||||
[ "$CHDEF_CALLS" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "restore refuses a symbolic link as the state file" {
|
||||
set_vmother 'cpumode:host-passthrough;machine:pc'
|
||||
printf '%s' 'machine:other' >"${BATS_TEST_TMPDIR}/target"
|
||||
ln -s "${BATS_TEST_TMPDIR}/target" "$STATE"
|
||||
run vm_machine_type_main restore cn1 x86_64
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"is not a regular file"* ]]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough;machine:pc' ]
|
||||
[ "$CHDEF_CALLS" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "invalid refuses a symbolic link as the state directory" {
|
||||
set_vmother 'cpumode:host-passthrough'
|
||||
rmdir "$VM_MACHINE_TYPE_STATE_DIR"
|
||||
mkdir -m 0700 "${BATS_TEST_TMPDIR}/real"
|
||||
ln -s "${BATS_TEST_TMPDIR}/real" "$VM_MACHINE_TYPE_STATE_DIR"
|
||||
run vm_machine_type_main invalid cn1
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"is not a private directory"* ]]
|
||||
[ -z "$(ls -A "${BATS_TEST_TMPDIR}/real")" ]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough' ]
|
||||
[ "$CHDEF_CALLS" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "invalid refuses a state directory that other users can write" {
|
||||
set_vmother 'cpumode:host-passthrough'
|
||||
chmod 0777 "$VM_MACHINE_TYPE_STATE_DIR"
|
||||
run vm_machine_type_main invalid cn1
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"is not a private directory"* ]]
|
||||
[ -z "$(ls -A "$VM_MACHINE_TYPE_STATE_DIR")" ]
|
||||
[ "$CHDEF_CALLS" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "restore keeps the snapshot when chdef fails" {
|
||||
set_vmother 'cpumode:host-passthrough'
|
||||
vm_machine_type_main invalid cn1
|
||||
CHDEF_FAIL=1
|
||||
run vm_machine_type_main restore cn1 x86_64
|
||||
[ "$status" -ne 0 ]
|
||||
[ "$(cat "$STATE")" = 'cpumode:host-passthrough' ]
|
||||
[ "$(vmother)" = 'cpumode:host-passthrough;machine:invalid' ]
|
||||
}
|
||||
Reference in New Issue
Block a user