Add virtual machines list

This commit is contained in:
josh committed 2026-04-14 09:12:30 -04:00
1 parent 23008b4997
commit 5773347bda
3 files changed
+177 -5

No files matched your search

+93
View File
@@ -115,6 +115,98 @@ def read_filesystems
result
end
def parse_mem(s)
return 0 unless s
n, unit = s.split
mult = case unit
when "KiB" then 1024
when "MiB" then 1024 ** 2
when "GiB" then 1024 ** 3
when "TiB" then 1024 ** 4
else 1
end
n.to_i * mult
end
def read_vm_dominfo(name)
out = `virsh --connect qemu:///system dominfo #{Shellwords.escape(name)} 2>/dev/null`
info = {}
out.each_line do |line|
key, value = line.split(":", 2).map { |s| s&.strip }
next unless key && value
case key
when "State" then info["state"] = value
when "CPU(s)" then info["vcpus"] = value.to_i
when "Max memory" then info["memory"] = parse_mem(value)
when "Used memory" then info["used_memory"] = parse_mem(value)
when "Autostart" then info["autostart"] = (value == "enable")
end
end
info
end
def read_vm_disks(name)
out = `virsh --connect qemu:///system domblklist #{Shellwords.escape(name)} --details 2>/dev/null`
targets = []
out.each_line do |line|
parts = line.strip.split(/\s+/)
next if parts.size < 3
next if parts[0] == "Type" || parts[0].start_with?("-")
next unless parts[1] == "disk"
targets << parts[2]
end
total_cap = 0
total_alloc = 0
targets.each do |tgt|
blk = `virsh --connect qemu:///system domblkinfo #{Shellwords.escape(name)} #{Shellwords.escape(tgt)} --bytes 2>/dev/null`
blk.each_line do |l|
k, v = l.split(":", 2).map { |s| s&.strip }
next unless k && v
total_cap += v.to_i if k == "Capacity"
total_alloc += v.to_i if k == "Allocation"
end
end
{ "disk_total" => total_cap, "disk_used" => total_alloc }
end
def read_vm_os(name)
xml = `virsh --connect qemu:///system dumpxml #{Shellwords.escape(name)} 2>/dev/null`
return nil if xml.empty?
if xml =~ %r{<libosinfo:os\s+id="([^"]+)"}
path = $1.sub(%r{^https?://[^/]+/}, "")
parts = path.split("/").reject(&:empty?)
return parts.map { |p| p.sub(/^\w/, &:upcase) }.join(" ") unless parts.empty?
end
if xml =~ %r{<title>([^<]+)</title>}
return $1.strip
end
nil
end
def read_virtual_machines
list_out = `virsh --connect qemu:///system list --all --name 2>/dev/null`
return [] unless $?.success?
names = list_out.split("\n").map(&:strip).reject(&:empty?)
return [] if names.empty?
names.map do |name|
dom = read_vm_dominfo(name)
disk = read_vm_disks(name)
{
"type" => "vm",
"name" => name,
"state" => dom["state"],
"vcpus" => dom["vcpus"],
"memory" => dom["memory"],
"used_memory" => dom["used_memory"],
"autostart" => dom["autostart"],
"os" => read_vm_os(name),
"disk_total" => disk["disk_total"],
"disk_used" => disk["disk_used"]
}
end
end
def handle_info(conn)
info = []
@@ -142,6 +234,7 @@ def handle_info(conn)
end
info.concat(read_filesystems)
info.concat(read_virtual_machines)
if conn
conn.puts JSON.generate(info)