From 9ebadddf962ca080de77ef2fc5da1e06665ee949 Mon Sep 17 00:00:00 2001 From: Ashwin Gopalan Date: Fri, 28 Jul 2023 10:43:58 -0700 Subject: [PATCH] Add qemu-system-aarch64 capabilities and include project-machine/qcli as dep Included a new default config for aarch64 platforms and obtained appropriate paths. Changed dependency from raharper/qcli to project-machine/qcli wherever applicable. --- go.mod | 2 +- go.sum | 6 +-- pkg/api/qconfig.go | 95 ++++++++++++++++++++++++++++++++++++++++++---- pkg/api/vm.go | 2 +- 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 58058eb..de69d63 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/lxc/lxd v0.0.0-20221130220346-2c77027b7a5e github.com/mitchellh/go-homedir v1.1.0 github.com/msoap/byline v1.1.1 - github.com/raharper/qcli v0.0.9 + github.com/project-machine/qcli v0.2.1 github.com/rodaine/table v1.1.0 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 diff --git a/go.sum b/go.sum index 30c04de..56193aa 100644 --- a/go.sum +++ b/go.sum @@ -210,11 +210,9 @@ github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE= github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/project-machine/qcli v0.2.1 h1:rIRItjdkeBbD4NIxYyTkxCeJIolGHdniJ51Phfg2Ols= +github.com/project-machine/qcli v0.2.1/go.mod h1:N7+8pGJWD/PvJOmzY6dmor4DYnG18bW/Mwa5Ful0GEs= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/raharper/qcli v0.0.8 h1:9kxYqNPUte3rjlBW6D/R3t22gZfZvb0RQPdDygB+1AA= -github.com/raharper/qcli v0.0.8/go.mod h1:2V3cMEpdXCSWz5cqXnbBFsnLM8j81PfklKKVF1aE0RE= -github.com/raharper/qcli v0.0.9 h1:s11hQHgRJJX4mz/ydeMGdosLjoUTlgDK+fiXx/k5XzE= -github.com/raharper/qcli v0.0.9/go.mod h1:2V3cMEpdXCSWz5cqXnbBFsnLM8j81PfklKKVF1aE0RE= github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= diff --git a/pkg/api/qconfig.go b/pkg/api/qconfig.go index e77332d..c955e0c 100644 --- a/pkg/api/qconfig.go +++ b/pkg/api/qconfig.go @@ -2,22 +2,28 @@ package api import ( "fmt" + "github.com/project-machine/qcli" "os" "path" "path/filepath" + "runtime" "strconv" "strings" - "github.com/raharper/qcli" - log "github.com/sirupsen/logrus" ) func GetKvmPath() (string, error) { - // perfer qemu-kvm, qemu-system-x86_64, kvm - emulators := []string{"qemu-kvm", "qemu-system-x86_64", "kvm"} + // prefer qemu-kvm, qemu-system-x86_64, kvm for x86 platform, + // qemu-system-aarch64 when on arm64 platform + var emulators []string paths := []string{"/usr/libexec", "/usr/bin"} - + switch runtime.GOARCH { + case "amd64", "x86_64": + emulators = []string{"qemu-kvm", "qemu-system-x86_64", "kvm"} + case "aarch64", "arm64": + emulators = []string{"qemu-system-aarch64"} + } for _, emulator := range emulators { for _, prefix := range paths { kvmPath := path.Join(prefix, emulator) @@ -29,7 +35,7 @@ func GetKvmPath() (string, error) { return "", fmt.Errorf("Failed to find QEMU/KVM binary [%s] in paths [%s]\n", emulators, paths) } -func NewDefaultConfig(name string, numCpus, numMemMB uint32, sockDir string) (*qcli.Config, error) { +func NewDefaultX86Config(name string, numCpus, numMemMB uint32, sockDir string) (*qcli.Config, error) { smp := qcli.SMP{CPUs: numCpus} if numCpus < 1 { smp.CPUs = 4 @@ -139,6 +145,73 @@ func NewDefaultConfig(name string, numCpus, numMemMB uint32, sockDir string) (*q return c, nil } +func NewDefaultAarch64Config(name string, numCpus uint32, numMemMB uint32, sockDir string) (*qcli.Config, error) { + smp := qcli.SMP{CPUs: numCpus} + if numCpus < 1 { + smp.CPUs = 4 + } + + mem := qcli.Memory{ + Size: fmt.Sprintf("%dm", numMemMB), + } + if numMemMB < 1 { + mem.Size = "1G" + } + path, err := GetKvmPath() + if err != nil { + return &qcli.Config{}, fmt.Errorf("Failed creating new default config: %s", err) + } + c := &qcli.Config{ + Name: name, + Path: path, + Machine: qcli.Machine{ + Type: qcli.MachineTypeVirt, + Acceleration: qcli.MachineAccelerationKVM, + }, + CPUModel: "host", + Memory: mem, + CharDevices: []qcli.CharDevice{ + qcli.CharDevice{ + Driver: qcli.PCISerialDevice, + Backend: qcli.Socket, + ID: "serial0", + Path: "/tmp/console.sock", + }, + qcli.CharDevice{ + Driver: qcli.LegacySerial, + Backend: qcli.Socket, + ID: "monitor0", + Path: filepath.Join(sockDir, "monitor.sock"), + }, + }, + SerialDevices: []qcli.SerialDevice{ + qcli.SerialDevice{ + Driver: qcli.PCISerialDevice, + ID: "pciser0", + ChardevIDs: []string{"serial0"}, + MaxPorts: 1, + }, + }, + MonitorDevices: []qcli.MonitorDevice{ + qcli.MonitorDevice{ + ChardevID: "monitor0", + }, + }, + QMPSockets: []qcli.QMPSocket{ + qcli.QMPSocket{ + Type: "unix", + Server: true, + NoWait: true, + Name: filepath.Join(sockDir, "qmp.sock"), + }, + }, + Knobs: qcli.Knobs{ + NoGraphic: true, + }, + } + return c, nil +} + // FIXME: what to do with remote client/server ? push to zot and use zot URLs? // ImportDiskImage will copy/create a source image to server image func (qd *QemuDisk) ImportDiskImage(imageDir string) error { @@ -310,7 +383,15 @@ func ConfigureUEFIVars(c *qcli.Config, srcVars, runDir string, secureBoot bool) } func GenerateQConfig(runDir, sockDir string, v VMDef) (*qcli.Config, error) { - c, err := NewDefaultConfig(v.Name, v.Cpus, v.Memory, sockDir) + var c *qcli.Config + var err error + switch runtime.GOARCH { + case "amd64", "x86_64": + c, err = NewDefaultX86Config(v.Name, v.Cpus, v.Memory, sockDir) + case "aarch64", "arm64": + c, err = NewDefaultAarch64Config(v.Name, v.Cpus, v.Memory, sockDir) + } + if err != nil { return c, err } diff --git a/pkg/api/vm.go b/pkg/api/vm.go index de317c9..5b4008c 100644 --- a/pkg/api/vm.go +++ b/pkg/api/vm.go @@ -26,7 +26,7 @@ import ( "sync" "time" - "github.com/raharper/qcli" + "github.com/project-machine/qcli" log "github.com/sirupsen/logrus" )