LibVirt Net Core wrapper test on production QEMU/KVM server.
What is https://libvirt.org/? This is public library related to QEMU/KVM. This additional opportunity to control QEMU/KVM server, main opportunity is VIRSH command. Look to this page please - Microservice with report of QEMU-KVM server (VirtualMachines, Storage, Network). Also demo of Linq, Lambda, Inheritance model. - this is way to control QEMU/KVM server programmatically by own code.
libvirt library installed as separate Linux package:
# sudo apt install libvirt-daemon-system
This library allow create external connection from VM Manager to QEMU/KVM server.
Also this library used for SPICE/VNC VirtViewer.
Main future of this library is:
- Read common QEMU-KVM information, read list of VM, read VM config (XML file like this).
- Create screenshot of VM console.
Read VM CPU utilization.
Raise event of each VM.
This library has .NET CORE wrapper https://github.com/IDNT/AppBasics-Virtualization-Libvirt and can be use in any .NET CORE API.
Below you can see my test of this library with real production QEMU-KVM server.
1: Imports System
2: Imports Libvirt
3: 'https://github.com/IDNT/AppBasics-Virtualization-Libvirt
4: Module Program
5: Sub Main(args As String())
6:
7: Dim KvmHost As LibvirtConnection
8:
9: Console.Write("Get password string" & vbCrLf & ">")
10: Dim TmpPass = ReadPassword()
11: Console.WriteLine()
12: Dim LibVirtAU As LibvirtAuthentication = New OpenAuthPasswordAuth With {.Username = "root", .Password = DecryptString(My.Resources.Pass, TmpPass)}
13: Try
14: KvmHost = LibvirtConnection.Create.WithCredentials(LibVirtAU).Connect(My.Resources.Url, LibVirtAU)
15: Catch ex As Exception
16: Console.WriteLine(ex.Message)
17: End Try
18:
19: Console.WriteLine()
20: Console.WriteLine($"Connected to node {KvmHost.Node.Hostname}")
21: Console.WriteLine(Environment.NewLine + "[Node]")
22: Console.WriteLine($" Total Memory ..........: {KvmHost.Node.MemoryKBytes / 1024 / 1024} GB")
23: Console.WriteLine($" Free Memory ...........: {KvmHost.Node.MemFreeBytes / 1024 / 1024 / 1024} GB")
24: Console.WriteLine($" CPU Model .............: {KvmHost.Node.CpuModelName}")
25: Console.WriteLine($" CPU Frequency .........: {KvmHost.Node.CpuFrequencyMhz} MHz")
26: Console.WriteLine($" CPU NUMA Nodes ........: {KvmHost.Node.CpuNumaNodes}")
27: Console.WriteLine($" CPU Sockets per Node ..: {KvmHost.Node.CpuSocketsPerNode}")
28: Console.WriteLine($" CPU Cores per Socket ..: {KvmHost.Node.CpuCoresPerSocket}")
29: Console.WriteLine($" CPU Threads per Core ..: {KvmHost.Node.CpuThreadsPerCore}")
30:
31: Console.WriteLine("[VMS]")
32: For Each VM In KvmHost.Domains
33: 'full VM.XmlDescription working!
34: Console.WriteLine($" {VM.Name} ({VM.UniqueId}) {VM.State} osInfo={VM.OsInfoId} Up={TimeSpan.FromSeconds(VM.UptimeSeconds).ToString()}")
35: Console.WriteLine($" memory={VM.MemoryMaxKbyte / 1024} MB")
36:
37: Dim FS1 = New IO.FileStream($"{VM.Name}.jpg", IO.FileMode.Create)
38: VM.GetScreenshot(FS1, System.Drawing.Imaging.ImageFormat.Jpeg)
39: FS1.Close()
40: IO.File.WriteAllText($"{VM.Name}.xml", VM.XmlDescription.OuterXml)
41:
42: Console.WriteLine(" [Nic]")
43: Try
44: For Each Nic In VM.NetworkInterfaces
45: Console.WriteLine($" {Nic.Address.ToString()} bridge={Nic.Source.Network}, mac={Nic.MAC.Address}")
46: Next
47: Catch ex As Exception
48: Console.WriteLine(ex.Message)
49: End Try
50:
51: GoTo SkipError1
52: Console.WriteLine(" [Disks]")
53: 'VM.DiskDevices dont working => InvalidOperationException: Instance validation error: 'block' is not a valid value for VirXmlDomainDiskType.
54: Try
55: For Each dev In VM.DiskDevices.ToList
56: Console.WriteLine($" {dev.Address.ToString()} {dev.Device} (driver={dev.Driver}) target={dev.Target.ToString()} source={dev.Source?.GetPath()}")
57: Console.WriteLine()
58: Next
59: Catch ex As Exception
60: Console.WriteLine(ex.Message)
61: End Try
62: SkipError1:
63: Next
64:
65: GoTo SkipError2
66: 'dont working => Can't determine path of storage pool $dsk-c with driver disk.
67: Console.WriteLine()
68: Console.WriteLine("[KvmHost Pools]")
69: Try
70: For Each Pool In KvmHost.StoragePools.ToList
71: Console.WriteLine($" {Pool.Name} (state={Pool.State} driver={Pool.DriverType} path={Pool.GetPath()}) {Pool.CapacityInByte / 1024 / 1024 / 1024} GB ({Pool.ByteAvailable / 1024 / 1024 / 1024} GB free)")
72: Next
73: Catch ex As Exception
74: Console.WriteLine(ex.Message)
75: End Try
76: SkipError2:
77:
78: Console.WriteLine()
79: Console.WriteLine("[KvmHost Volumes]")
80: Try
81: For Each Volume In KvmHost.StorageVolumes
82: Console.WriteLine($" Volume {Volume.Name} (type={Volume.VolumeType}, path={Volume.Path}) {Volume.CapacityInByte / 1024 / 1024 / 1024} GB ({Volume.ByteAllocated / 1024 / 1024 / 1024} GB allocated)")
83: Next
84: Catch ex As Exception
85: Console.WriteLine(ex.Message)
86: End Try
87:
88: Console.WriteLine("press [ENTER] to exit CPU Utilization")
89: Dim VM1 = KvmHost.Domains.Where(Function(X) X.Name = "D82-site").FirstOrDefault
90: While Not Console.KeyAvailable
91: Console.WriteLine($"{VM1.Name}'s CPU Utilization = {VM1.CpuUtilization.LastSecond}%")
92: Threading.Thread.Sleep(1000)
93: End While
94:
95:
96: Console.WriteLine()
97: Console.WriteLine("Waiting for VM lifecycle events...")
98: AddHandler KvmHost.DomainEventReceived, AddressOf KvmHost_DomainEventReceived
99: Console.WriteLine()
100: Console.WriteLine("[ENTER] to exit")
101: Console.ReadLine()
102: KvmHost.Close()
103:
104: End Sub
105: Private Sub KvmHost_DomainEventReceived(ByVal sender As Object, ByVal e As VirDomainEventArgs)
106: Dim VM = CType(sender, LibvirtDomain)
107: Console.WriteLine($"EVENT: {e.UniqueId} {VM?.Name} {e.EventType}")
108: End Sub
109:
110: ...
111:
112:
Full code of this test I uploaded to Github https://github.com/Alex-1347/LibvirtNetCoreWrapper.
<SITEMAP> <MVC> <ASP> <NET> <DATA> <KIOSK> <FLEX> <SQL> <NOTES> <LINUX> <MONO> <FREEWARE> <DOCS> <ENG> <CHAT ME> <ABOUT ME> < THANKS ME> |