Hot swapping physical disks passed through to a qemu VM

I have been somewhat around the houses on this one, and indeed did get to the point where I was able to send QMP commands to a guest via a UNIX socket. This is supported by the default Proxmox config using a socket at /var/run/qemu-server/<server-id>.qmp. I can then interactively send QMP JSON messages using

rlwrap -C qmp socat - UNIX:/var/run/qemu-server/101.qmp

(rlwrap is not installed by default, but can be installed using "apt install rlwrap")

However, the QMP message format was as opaque as I thought it was going to be and has no direct equivalent to "drive_add" for reasons of ideological purity (which are perhaps understandable but nonetheless hugely unhelpful in the context of my present difficulty). There is a "blockdev_add" command that may well have done what I wanted assuming I could work out the correct syntax.

I therefore took a step back and came to the conclusion that "qm monitor" probably wasn't accepting input from stdin because of readline support. This lead me to think of "expect". A quick "apt install expect" later, and I was able to create scripts to attach and detach drives as follows:

qemu-drive-attach <vm-id> <device-name> <path-to-block-device>

with qemu-drive-attach script (device-name is arbitrary - I use "virtio8" for consistency with the Proxmox naming scheme)

!/usr/bin/expect
set vm_id               [lindex $argv 0];
set device_name         [lindex $argv 1];
set device_file         [lindex $argv 2];

spawn qm monitor $vm_id
expect "qm> "
send "drive_add 0 file=$device_file,if=none,id=drive-$device_name,cache=none,detect-zeroes=on\r"

expect "OK" {
    expect "qm> "
    send "device_add virtio-blk-pci,drive=drive-$device_name,id=$device_name\r"
}

expect "qm> "
send "quit\r"

send_user "\n"

And for detaching

qemu-drive-detach <vm-id> <device-name>

with qemu-drive-detach script

#!/usr/bin/expect
set vm_id               [lindex $argv 0];
set device_name         [lindex $argv 1];

spawn qm monitor $vm_id
expect "qm> "
send "device_del $device_name\r"

expect "qm> "
send "quit\r"

send_user "\n"

Error checking with these scripts leaves something to be desired, particularly as device_add and device_del are silent on success, but this will enable external block device drives to be hotswapped into the VM from a script.