#!/bin/sh # vim: set sw=4 ts=4 sts=4 et : cordon() { printf 'Cordoning node %s ... ' "$1" >&2 if kubectl cordon "$1"; then : else r=$? echo FAILED >&2 return $r fi } drain() { printf 'Draining node %s ... ' "$1" kubectl drain \ --ignore-daemonsets \ --pod-selector 'app!=csi-attacher,app!=csi-provisioner' \ --delete-emptydir-data \ "$1" } migrate() { printf 'Migrating %s to %s ... \n' "$1" "$2" >&2 virsh migrate "$1" "$2" --live --persistent --undefinesource --verbose } shutdown() { if [ "$(virsh domstate "$1")" = 'shut off' ]; then printf 'VM %s is already shut off\n' "$1" >&2 return 0 fi virsh shutdown "$1" || return printf 'Waiting for %s to shut down ... ' "$1" >&2 if virsh event --event lifecycle "$1"; then echo OK >&2 else r=$? echo FAILED >&2 return $r fi } host="$1" export LIBVIRT_DEFAULT_URI=qemu+ssh://${host}/system case "${host}" in vmhost0.pyrocufflink.blue) dest=qemu+ssh://vmhost1.pyrocufflink.blue/system ;; vmhost1.pyrocufflink.blue) dest=qemu+ssh://vmhost0.pyrocufflink.blue/system ;; *) printf 'Unknown VM host: %s\n' "${host}" >&2 exit 1 ;; esac printf 'Checking libvirt connection ... ' virsh uri || exit set -- nodes=$( kubectl get node -o name -l '!node-role.kubernetes.io/control-plane' \ | sed s@node/@@ ) for node in ${nodes}; do if virsh domuuid "${node%%.*}" >/dev/null 2>&1; then set -- "$@" "${node}" cordon "${node}" || exit fi done for node; do drain "${node}" || exit done for node; do shutdown "${node%%.*}" || exit done virsh list --name | while read -r vm_name; do [ -n "${vm_name}" ] || continue if [ "$(virsh domstate "${vm_name}")" = running ]; then migrate "${vm_name}" "${dest}" || exit fi done