Replace Bash qvm scripts with Go CLI implementation

This commit is contained in:
Joshua Bell 2026-01-26 20:48:32 -06:00
parent ffb456707f
commit 2a6a333721
27 changed files with 2551 additions and 1702 deletions

75
internal/qmp/client.go Normal file
View file

@ -0,0 +1,75 @@
package qmp
import (
"encoding/json"
"fmt"
"time"
"github.com/digitalocean/go-qemu/qmp"
"github.com/samber/mo"
)
type Client struct {
monitor qmp.Monitor
}
type VMStatus struct {
Running bool
Singlestep bool
Status string
}
func Connect(socketPath string) mo.Result[*Client] {
monitor, err := qmp.NewSocketMonitor("unix", socketPath, 2*time.Second)
if err != nil {
return mo.Err[*Client](fmt.Errorf("failed to create socket monitor: %w", err))
}
if err := monitor.Connect(); err != nil {
return mo.Err[*Client](fmt.Errorf("failed to connect to QMP socket: %w", err))
}
return mo.Ok(&Client{monitor: monitor})
}
func (c *Client) Status() mo.Result[VMStatus] {
type statusResult struct {
ID string `json:"id"`
Return struct {
Running bool `json:"running"`
Singlestep bool `json:"singlestep"`
Status string `json:"status"`
} `json:"return"`
}
cmd := []byte(`{"execute":"query-status"}`)
raw, err := c.monitor.Run(cmd)
if err != nil {
return mo.Err[VMStatus](fmt.Errorf("failed to execute query-status: %w", err))
}
var result statusResult
if err := json.Unmarshal(raw, &result); err != nil {
return mo.Err[VMStatus](fmt.Errorf("failed to parse status response: %w", err))
}
return mo.Ok(VMStatus{
Running: result.Return.Running,
Singlestep: result.Return.Singlestep,
Status: result.Return.Status,
})
}
func (c *Client) Shutdown() mo.Result[struct{}] {
cmd := []byte(`{"execute":"system_powerdown"}`)
_, err := c.monitor.Run(cmd)
if err != nil {
return mo.Err[struct{}](fmt.Errorf("failed to execute system_powerdown: %w", err))
}
return mo.Ok(struct{}{})
}
func (c *Client) Close() error {
return c.monitor.Disconnect()
}