108 lines
2.9 KiB
Go
108 lines
2.9 KiB
Go
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{
|
|
{
|
|
Model: &libvirtxml.DomainInterfaceModel{Type: "virtio"},
|
|
Source: &nicSource,
|
|
},
|
|
}
|
|
|
|
// 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
|
|
}
|