qga #
QEMU Guest Agent Protocol client for V
qga is full featured QGA client for interacting with guest operating systems in QEMU-powered virtual machine from virtualisation host.
See also:
- Guest Agent in QEMU Wiki: https://wiki.qemu.org/Features/GuestAgent
- QEMU Guest Agent Protocol Reference: https://qemu-project.gitlab.io/qemu/interop/qemu-ga-ref.html
Usage
Run the virtual machine. In this example disk.qcow2 contains Debian 12 Bookworm with qemu-guest-agent package installed.
/usr/bin/qemu-system-x86_64 \
-name testvm \
-accel kvm \
-cpu host \
-smp 1 \
-m 1024M \
-drive file=disk.qcow2,media=disk,if=virtio \
-chardev socket,path=/tmp/qga.sock,server=on,wait=off,id=qga0 \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
Then connect to a guest agent server socket /tmp/gqa.sock:
import qga
fn main() {
mut ga := qga.Client.new('/tmp/qga.sock')!
agent_version := ga.info()!.version
println('everything is fine! guest agent version is ${agent_version}')
}
Error handling
GuestAgentError contains extended error information. See the description of the structure fields.
The error can be returned either directly by the guest agent or when trying to communicating it. GuestAgentError has an explicit flag to distinguish such errors. If for some reason the guest agent could not be reached, is_unreachable will be true. The error information will be in the underlying error stored in the err field and in the error text itself.
module main
import qga
fn main() {
mut ga := qga.Client.new('/tmp/qga.sock')!
ga.get_devices() or {
if err is qga.GuestAgentError {
if err.is_unreachable {
println('agent is unreachable')
return
} else {
println('error info from guest agent: class=${err.class} desc=${err.desc}')
return
}
}
}
}
Prints this (so guest-get-devices is disabled on Debian):
error info from guest agent: class=CommandNotFound desc=Command guest-get-devices has been disabled
In addition, qga module provides a small set of specific error codes. They can be checked in this way without err smartcasting:
ga.ping() or {
match err.code() {
qga.err_no_connect { panic('socket connection error') }
qga.err_timed_out { panic('timeout reached') }
qga.err_from_agent { panic('error ocurred in guest agent') }
else { panic(err) }
}
}
License
LGPL-3.0-or-later
See COPYING and COPYING.LESSER for information.
Constants #
const err_no_connect = 1000
Connection to socket failed.
const err_cannot_read = 1001
Cannot read data from socket.
const err_cannot_write = 1002
Cannot write to socket.
const err_timed_out = 1003
Read or write timeout reached. This may cause if guest agent daemon is shut off in guest.
const err_from_agent = 1004
Guest agent returned an error. See details in class and desc fields of GuestAgentError.
fn Client.from_handle #
fn Client.from_handle(handle int, params ClientParams) !Client
Client.from_handle creates new Client instance connected to socket handle.
fn Client.new #
fn Client.new(addr string, params ClientParams) !Client
Client.new creates new Client instance connected to provided UNIX domain socket address.
Example
mut ga := qga.Client.new('/tmp/qga0.sock')!
ga.ping()!
fn (Client) close #
fn (mut c Client) close() !
close closes connection to stream socket.
fn (Client) exec #
fn (mut c Client) exec(path string, params GuestExecParams) !int
exec executes guest-exec command.
fn (Client) exec_status #
fn (mut c Client) exec_status(pid int) !GuestExecStatus
exec_status executes guest-exec-status command.
fn (Client) file_close #
fn (mut c Client) file_close(handle int) !
file_close executes guest-file-close command.
fn (Client) file_flush #
fn (mut c Client) file_flush(handle int) !
file_flush executes guest-file-flush command.
fn (Client) file_open #
fn (mut c Client) file_open(path string, mode string) !int
file_open executes guest-file-open command.
fn (Client) file_read #
fn (mut c Client) file_read(handle int, count int) !GuestFileRead
file_read executes guest-file-read command.
fn (Client) file_seek #
fn (mut c Client) file_seek(handle int, offset int, whence GuestAgentWhence) !GuestFileSeek
file_seek executes guest-file-seek command.
fn (Client) file_write #
fn (mut c Client) file_write(handle int, buf string, params GuestFileWriteParams) !GuestFileWrite
file_write executes guest-file-write command.
fn (Client) fsfreeze_freeze #
fn (mut c Client) fsfreeze_freeze() !int
fsfreeze_freeze executes guest-fsfreeze-freeze command.
fn (Client) fsfreeze_freeze_list #
fn (mut c Client) fsfreeze_freeze_list(mountpoints []string) !int
fsfreeze_freeze_list executes guest-fsfreeze-freeze-list command. An empty mountpoints array will freeze all filesystems.
fn (Client) fsfreeze_status #
fn (mut c Client) fsfreeze_status() !GuestFsfreezeStatus
fsfreeze_status executes guest-fsfreeze-status command.
fn (Client) fsfreeze_thaw #
fn (mut c Client) fsfreeze_thaw() !int
fsfreeze_thaw executes guest-fsfreeze-thaw command.
fn (Client) fstrim #
fn (mut c Client) fstrim(minimum u64) !GuestFilesystemTrimResponse
fstrim executes guest-fstrim command. Set minimum to zero to discard every free block.
fn (Client) get_cpustats #
fn (mut c Client) get_cpustats() ![]GuestCpuStats
get_cpustats executes guest-get-cpustats command.
fn (Client) get_devices #
fn (mut c Client) get_devices() ![]GuestDeviceInfo
get_devices executes guest-get-devices command.
fn (Client) get_disks #
fn (mut c Client) get_disks() ![]GuestDiskInfo
get_disks executes guest-get-disks command.
fn (Client) get_diskstats #
fn (mut c Client) get_diskstats() ![]GuestDiskStatsInfo
get_diskstats executes guest-get-diskstats command.
fn (Client) get_fsinfo #
fn (mut c Client) get_fsinfo() ![]GuestFilesystemInfo
get_fsinfo executes guest-get-fsinfo command.
fn (Client) get_host_name #
fn (mut c Client) get_host_name() !string
get_host_name executes guest-get-host-name command.
fn (Client) get_load #
fn (mut c Client) get_load() !GuestLoadAverage
get_load executes guest-get-load command.
fn (Client) get_memory_block_info #
fn (mut c Client) get_memory_block_info() !GuestMemoryBlockInfo
get_memory_block_info executes guest-get-memory-block-info command.
fn (Client) get_memory_blocks #
fn (mut c Client) get_memory_blocks() ![]GuestMemoryBlock
get_memory_blocks executes guest-get-memory-blocks command.
fn (Client) get_osinfo #
fn (mut c Client) get_osinfo() !GuestOSInfo
get_osinfo executes guest-get-osinfo command.
fn (Client) get_time #
fn (mut c Client) get_time() !i64
get_time executes guest-get-time command.
fn (Client) get_timezone #
fn (mut c Client) get_timezone() !GuestTimezone
get_timezone executes guest-get-timezone command.
fn (Client) get_users #
fn (mut c Client) get_users() ![]GuestUser
get_users executes guest-get-users command.
fn (Client) get_vcpus #
fn (mut c Client) get_vcpus() ![]GuestLogicalProcessor
get_vcpus executes guest-get-vcpus command.
fn (Client) info #
fn (mut c Client) info() !GuestAgentInfo
info executes guest-info command.
fn (Client) network_get_interfaces #
fn (mut c Client) network_get_interfaces() ![]GuestNetworkInterface
network_get_interfaces executes guest-network-get-interfaces command.
fn (Client) network_get_route #
fn (mut c Client) network_get_route() ![]GuestNetworkRoute
network_get_route executes guest-network-get-route command.
fn (Client) ping #
fn (mut c Client) ping() !
ping executes guest-ping command, a non-error return implies success.
fn (Client) set_memory_blocks #
fn (mut c Client) set_memory_blocks(blocks []GuestMemoryBlock) ![]GuestMemoryBlockResponse
set_memory_blocks executes guest-set-memory-blocks command.
fn (Client) set_time #
fn (mut c Client) set_time(epoch i64) !
set_time executes guest-set-time command.
fn (Client) set_user_password #
fn (mut c Client) set_user_password(username string, password string, crypted bool) !
set_user_password executes guest-set-user-password command.
fn (Client) set_vcpus #
fn (mut c Client) set_vcpus(vcpus []GuestLogicalProcessor) !int
set_vcpus executes guest-set-vcpus command.
fn (Client) shutdown #
fn (mut c Client) shutdown(mode GuestShutdownMode) !
shutdown executes guest-shutdown command.
fn (Client) suspend_disk #
fn (mut c Client) suspend_disk() !
suspend_disk executes guest-suspend-disk command.
fn (Client) suspend_hybrid #
fn (mut c Client) suspend_hybrid() !
suspend_hybrid executes guest-suspend-hybrid command.
fn (Client) suspend_ram #
fn (mut c Client) suspend_ram() !
suspend_ram executes guest-suspend-ram command.
fn (Client) sync #
fn (mut c Client) sync(id u64) !u64
sync executes the guest-sync command.
fn (Client) sync_delimited #
fn (mut c Client) sync_delimited(id u64) !u64
sync_delimited executes guest-sync-delimited command.
enum GuestCpuStatsType #
enum GuestCpuStatsType {
linux
}
enum GuestDeviceType #
enum GuestDeviceType {
pci
}
enum GuestDiskBusType #
enum GuestDiskBusType {
ide
fdc
scsi
virtio
xen
usb
uml
sata
sd
unknown
ieee1394
ssa
fibre
raid
iscsi
sas
mmc
virtual
file_backed_virtual @[json: 'file-backed-virtual']
nvme
}
enum GuestFsfreezeStatus #
enum GuestFsfreezeStatus {
thawed
frozen
}
enum GuestIpAddressType #
enum GuestIpAddressType {
ipv4
ipv6
}
enum GuestMemoryBlockResponseType #
enum GuestMemoryBlockResponseType {
success
not_found @[json: 'not-found']
operation_not_supported @[json: 'operation-not-supported']
operation_failed @[json: 'operation-failed']
}
enum GuestShutdownMode #
enum GuestShutdownMode {
halt
powerdown
reboot
}
enum QGASeek #
enum QGASeek {
set
cur
end
}
struct ClientParams #
struct ClientParams {
timeout time.Duration = 5 * time.second // socket write and read timeout
read_buffer_size int = 4096 // read buffer size in bytes
}
struct GuestAgentCommandInfo #
struct GuestAgentCommandInfo {
pub:
name string
enabled bool
success_response bool @[json: 'success-response']
}
struct GuestAgentError #
struct GuestAgentError {
pub:
msg string // human-readable error message
code int // error code (see err_* constants in this module)
class string // error class provided by QEMU Guest Agent Protocol
desc string // error desc provided by QEMU Guest Agent Protocol
is_unreachable bool // true if the error means the guest agent could not be reached
err ?IError // the underlying error if available
}
fn (GuestAgentError) msg #
fn (e GuestAgentError) msg() string
fn (GuestAgentError) code #
fn (e GuestAgentError) code() int
struct GuestAgentInfo #
struct GuestAgentInfo {
pub:
version string
supported_commands []GuestAgentCommandInfo
}
struct GuestAgentWhence #
struct GuestAgentWhence {
pub:
value int
name QGASeek
}
struct GuestCCWAddress #
struct GuestCCWAddress {
pub:
cssid int
ssid int
subchno int
devno int
}
struct GuestCpuStats #
struct GuestCpuStats {
GuestLinuxCpuStats
pub:
type GuestCpuStatsType
}
struct GuestDeviceId #
struct GuestDeviceId {
pub:
type GuestDeviceType
vendor_id int @[json: 'vendor-id']
device_id int @[json: 'device-id']
}
struct GuestDeviceInfo #
struct GuestDeviceInfo {
driver_name string @[json: 'driver-name']
driver_data ?string @[json: 'driver-data']
driver_version ?string @[json: 'driver-version']
id ?GuestDeviceId
}
struct GuestDiskAddress #
struct GuestDiskAddress {
pub:
pci_controller GuestPCIAddress @[json: 'pci-controller']
bus_type GuestDiskBusType @[json: 'bus-type']
bus int
target int
unit int
serial ?string
dev ?string
ccw_address ?GuestCCWAddress @[json: 'ccw-address']
}
struct GuestDiskInfo #
struct GuestDiskInfo {
pub:
name string
partition bool
dependencies ?[]string
address ?GuestDiskAddress
alias ?string
smart ?GuestDiskSmart
}
struct GuestDiskSmart #
struct GuestDiskSmart {
pub:
critical_warning int @[json: 'critical-warning']
temperature int @[json: 'temperature']
available_spare int @[json: 'available-spare']
available_spare_threshold int @[json: 'available-spare-threshold']
percentage_used int @[json: 'percentage-used']
data_units_read_lo int @[json: 'data-units-read-lo']
data_units_read_hi int @[json: 'data-units-read-hi']
data_units_written_lo int @[json: 'data-units-written-lo']
data_units_written_hi int @[json: 'data-units-written-hi']
host_read_commands_lo int @[json: 'host-read-commands-lo']
host_read_commands_hi int @[json: 'host-read-commands-hi']
host_write_commands_lo int @[json: 'host-write-commands-lo']
host_write_commands_hi int @[json: 'host-write-commands-hi']
controller_busy_time_lo int @[json: 'controller-busy-time-lo']
controller_busy_time_hi int @[json: 'controller-busy-time-hi']
power_cycles_lo int @[json: 'power-cycles-lo']
power_cycles_hi int @[json: 'power-cycles-hi']
power_on_hours_lo int @[json: 'power-on-hours-lo']
power_on_hours_hi int @[json: 'power-on-hours-hi']
unsafe_shutdowns_lo int @[json: 'unsafe-shutdowns-lo']
unsafe_shutdowns_hi int @[json: 'unsafe-shutdowns-hi']
media_errors_lo int @[json: 'media-errors-lo']
media_errors_hi int @[json: 'media-errors-hi']
number_of_error_log_entries_lo int @[json: 'number-of-error-log-entries-lo']
number_of_error_log_entries_hi int @[json: 'number-of-error-log-entries-hi']
}
struct GuestDiskStats #
struct GuestDiskStats {
read_sectors ?int @[json: 'read-sectors']
read_ios ?int @[json: 'read-ios']
read_merges ?int @[json: 'read-merges']
write_sectors ?int @[json: 'write-sectors']
write_ios ?int @[json: 'write-ios']
write_merges ?int @[json: 'write-merges']
discard_sectors ?int @[json: 'discard-sectors']
discard_ios ?int @[json: 'discard-ios']
discard_merges ?int @[json: 'discard-merges']
flush_ios ?int @[json: 'flush-ios']
read_ticks ?int @[json: 'read-ticks']
write_ticks ?int @[json: 'write-ticks']
discard_ticks ?int @[json: 'discard-ticks']
flush_ticks ?int @[json: 'flush-ticks']
ios_pgr ?int @[json: 'ios-pgr']
total_ticks ?int @[json: 'total-ticks']
weight_ticks ?int @[json: 'weight-ticks']
}
struct GuestDiskStatsInfo #
struct GuestDiskStatsInfo {
pub:
name string
major int
minor int
stats GuestDiskStats
}
struct GuestExecParams #
struct GuestExecParams {
pub:
args ?[]string
env ?[]string
input_data ?string
capture_output ?bool
}
struct GuestExecStatus #
struct GuestExecStatus {
pub:
exited bool
exitcode ?int
signal ?int
out_data ?string @[json: 'out-data']
err_data ?string @[json: 'err-data']
out_truncated ?bool @[json: 'out-truncated']
err_truncated ?bool @[json: 'err-truncated']
}
struct GuestFileRead #
struct GuestFileRead {
pub:
count int
buf_b64 string @[json: 'buf-b64']
eof bool
}
struct GuestFileSeek #
struct GuestFileSeek {
pub:
position int
eof bool
}
struct GuestFileWrite #
struct GuestFileWrite {
pub:
count int
eof bool
}
struct GuestFileWriteParams #
struct GuestFileWriteParams {
pub:
is_encoded bool
count ?int
}
struct GuestFilesystemInfo #
struct GuestFilesystemInfo {
pub:
name string
mountpoint string
type string
used_bytes ?u64 @[json: 'used-bytes']
total_bytes ?u64 @[json: 'total-bytes']
total_bytes_privileged ?u64 @[json: 'total-bytes-privileged']
disk []GuestDiskAddress
}
struct GuestFilesystemTrimResponse #
struct GuestFilesystemTrimResponse {
pub:
paths []GuestFilesystemTrimResult
}
struct GuestFilesystemTrimResult #
struct GuestFilesystemTrimResult {
path string
error ?string
trimmed ?u64
minimum ?u64
}
struct GuestIpAddress #
struct GuestIpAddress {
pub:
ip_address string @[json: 'ip-address']
ip_address_type GuestIpAddressType @[json: 'ip-address-type']
prefix int
}
struct GuestLinuxCpuStats #
struct GuestLinuxCpuStats {
pub:
cpu int
user int
nice int
system int
idle int
iowait ?int
irq ?int
sofirq ?int
steal ?int
guest ?int
guestnice ?int
}
struct GuestLoadAverage #
struct GuestLoadAverage {
load1m f64
load5m f64
load15m f64
}
struct GuestLogicalProcessor #
struct GuestLogicalProcessor {
pub:
logical_id int @[json: 'logical-id']
online bool
can_offline ?bool @[json: 'can-offline']
}
struct GuestMemoryBlock #
struct GuestMemoryBlock {
pub:
phys_index int @[json: 'phys-index']
online bool
can_offline ?bool @[json: 'can-offline']
}
struct GuestMemoryBlockInfo #
struct GuestMemoryBlockInfo {
size int
}
struct GuestMemoryBlockResponse #
struct GuestMemoryBlockResponse {
pub:
phys_index int @[json: 'phys-index']
response GuestMemoryBlockResponseType
error_code ?int @[json: 'error-code']
}
struct GuestNetworkInterface #
struct GuestNetworkInterface {
pub:
name string
hardware_address ?string @[json: 'hardware-address']
ip_addresses ?[]GuestIpAddress @[json: 'ip-addresses']
statistics ?GuestNetworkInterfaceStat
}
struct GuestNetworkInterfaceStat #
struct GuestNetworkInterfaceStat {
pub:
rx_bytes int @[json: 'rx-bytes']
rx_packets int @[json: 'rx-packets']
rx_errs int @[json: 'rx-errs']
rx_dropped int @[json: 'rx-dropped']
tx_bytes int @[json: 'tx-bytes']
tx_packets int @[json: 'tx-packets']
tx_errs int @[json: 'tx-errs']
tx_dropped int @[json: 'tx-dropped']
}
struct GuestNetworkRoute #
struct GuestNetworkRoute {
pub:
iface string
destination string
metric int
gateway ?string
mask ?string
irtt ?int
flags ?int
refcnt ?int
use ?int
window ?int
mtu ?int
desprefixlen ?string
source ?string
srcprefixlen ?string
nexthop ?string
version int
}
struct GuestOSInfo #
struct GuestOSInfo {
pub:
kernel_release ?string @[json: 'kernel-release']
kernel_version ?string @[json: 'kernel-version']
machine ?string
id ?string
name ?string
pretty_name ?string @[json: 'pretty-name']
version ?string
version_id ?string @[json: 'version-id']
variant ?string
variant_id ?string @[json: 'variant-id']
}
struct GuestPCIAddress #
struct GuestPCIAddress {
pub:
domain int
bus int
slot int
function int
}
struct GuestTimezone #
struct GuestTimezone {
zone ?string
offset int
}
struct GuestUser #
struct GuestUser {
pub:
user string
domain string
login_time f64 @[json: 'login-time']
}
- README
- Constants
- fn Client.from_handle
- fn Client.new
- type Client
- fn close
- fn exec
- fn exec_status
- fn file_close
- fn file_flush
- fn file_open
- fn file_read
- fn file_seek
- fn file_write
- fn fsfreeze_freeze
- fn fsfreeze_freeze_list
- fn fsfreeze_status
- fn fsfreeze_thaw
- fn fstrim
- fn get_cpustats
- fn get_devices
- fn get_disks
- fn get_diskstats
- fn get_fsinfo
- fn get_host_name
- fn get_load
- fn get_memory_block_info
- fn get_memory_blocks
- fn get_osinfo
- fn get_time
- fn get_timezone
- fn get_users
- fn get_vcpus
- fn info
- fn network_get_interfaces
- fn network_get_route
- fn ping
- fn set_memory_blocks
- fn set_time
- fn set_user_password
- fn set_vcpus
- fn shutdown
- fn ssh_add_authorized_keys
- fn ssh_get_authorized_keys
- fn ssh_remove_authorized_keys
- fn suspend_disk
- fn suspend_hybrid
- fn suspend_ram
- fn sync
- fn sync_delimited
- enum GuestCpuStatsType
- enum GuestDeviceType
- enum GuestDiskBusType
- enum GuestFsfreezeStatus
- enum GuestIpAddressType
- enum GuestMemoryBlockResponseType
- enum GuestShutdownMode
- enum QGASeek
- struct ClientParams
- struct GuestAgentCommandInfo
- struct GuestAgentError
- struct GuestAgentInfo
- struct GuestAgentWhence
- struct GuestCCWAddress
- struct GuestCpuStats
- struct GuestDeviceId
- struct GuestDeviceInfo
- struct GuestDiskAddress
- struct GuestDiskInfo
- struct GuestDiskSmart
- struct GuestDiskStats
- struct GuestDiskStatsInfo
- struct GuestExecParams
- struct GuestExecStatus
- struct GuestFileRead
- struct GuestFileSeek
- struct GuestFileWrite
- struct GuestFileWriteParams
- struct GuestFilesystemInfo
- struct GuestFilesystemTrimResponse
- struct GuestFilesystemTrimResult
- struct GuestIpAddress
- struct GuestLinuxCpuStats
- struct GuestLoadAverage
- struct GuestLogicalProcessor
- struct GuestMemoryBlock
- struct GuestMemoryBlockInfo
- struct GuestMemoryBlockResponse
- struct GuestNetworkInterface
- struct GuestNetworkInterfaceStat
- struct GuestNetworkRoute
- struct GuestOSInfo
- struct GuestPCIAddress
- struct GuestTimezone
- struct GuestUser