mkvm/mkvm.go

109 lines
2.9 KiB
Go
Raw Normal View History

2024-12-03 04:22:30 +00:00
package main
import (
"fmt"
"github.com/sirupsen/logrus"
"libvirt.org/go/libvirt"
"libvirt.org/go/libvirtxml"
"mkvm/volumes"
"mkvm/volumes/pools"
)
func mkvm(conn *libvirt.Connect, metadataURL string, name string) error {
logger := logrus.WithField("vm", name)
logger.Debug("creating vm")
pool, err := pools.GetPool(conn)
if err != nil {
return err
}
err = volumes.Create(conn, pool, argDiskSizeGB, argImage, name)
if err != nil {
return err
}
disks := []libvirtxml.DomainDisk{pool.GetDomainDiskXML(name)}
smbios := map[int]map[string]string{
1: {"serial": fmt.Sprintf("ds=nocloud-net;s=%s/", metadataURL)},
}
qemuArgs := []libvirtxml.DomainQEMUCommandlineArg{}
for smbiosType, values := range smbios {
arg := libvirtxml.DomainQEMUCommandlineArg{
Value: fmt.Sprintf("type=%d", smbiosType),
}
for key, value := range values {
arg.Value = fmt.Sprintf("%s,%s=%s", arg.Value, key, value)
}
qemuArgs = append(qemuArgs, libvirtxml.DomainQEMUCommandlineArg{Value: "-smbios"}, arg)
}
interfaces := []libvirtxml.DomainInterface{
{
2024-12-03 06:57:21 +00:00
Model: &libvirtxml.DomainInterfaceModel{Type: "virtio"},
Source: &nicSource,
2024-12-03 04:22:30 +00:00
},
}
// Create the domain
domainXML := &libvirtxml.Domain{
Type: "kvm",
Name: name,
Memory: &libvirtxml.DomainMemory{Value: uint(argMemoryMB), Unit: "MiB"},
VCPU: &libvirtxml.DomainVCPU{Value: uint(argCPUs)},
OS: &libvirtxml.DomainOS{
Type: &libvirtxml.DomainOSType{Arch: "x86_64", Type: "hvm"},
BootDevices: []libvirtxml.DomainBootDevice{{Dev: "hd"}},
},
Features: &libvirtxml.DomainFeatureList{
ACPI: &libvirtxml.DomainFeature{},
APIC: &libvirtxml.DomainFeatureAPIC{},
VMPort: &libvirtxml.DomainFeatureState{State: "off"},
},
CPU: &libvirtxml.DomainCPU{Mode: "host-model"},
Devices: &libvirtxml.DomainDeviceList{
Emulator: "/usr/bin/kvm",
Disks: disks,
Channels: []libvirtxml.DomainChannel{
{
Source: &libvirtxml.DomainChardevSource{
UNIX: &libvirtxml.DomainChardevSourceUNIX{Path: "/var/lib/libvirt/qemu/f16x86_64.agent", Mode: "bind"},
},
Target: &libvirtxml.DomainChannelTarget{
VirtIO: &libvirtxml.DomainChannelTargetVirtIO{Name: "org.qemu.guest_agent.0"},
},
},
},
Consoles: []libvirtxml.DomainConsole{{Target: &libvirtxml.DomainConsoleTarget{}}},
Serials: []libvirtxml.DomainSerial{{}},
Interfaces: interfaces,
},
QEMUCommandline: &libvirtxml.DomainQEMUCommandline{Args: qemuArgs},
}
domainXMLString, err := domainXML.Marshal()
if err != nil {
return err
}
logger.Debug("defining domain from xml")
domain, err := conn.DomainDefineXML(domainXMLString)
if err != nil {
return fmt.Errorf("error defining domain from xml description: %v", err)
}
logger.Debug("booting domain")
err = domain.Create()
if err != nil {
return fmt.Errorf("error creating domain: %v", err)
}
logger.Debug("domain booted")
return nil
}