Skip to content

Commit 266ca58

Browse files
committed
Virt for qemu:///session
Simple test to see if the machine would even start properly. Needs more code for qemu:///system, like storage and network. Signed-off-by: Anders F Björklund <[email protected]>
1 parent faa0774 commit 266ca58

File tree

5 files changed

+248
-6
lines changed

5 files changed

+248
-6
lines changed

pkg/virt/disk.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package virt
22

33
import (
44
"errors"
5+
"fmt"
56
"os"
7+
"os/exec"
68
"path/filepath"
9+
"strconv"
710

811
"github.com/docker/go-units"
912
"github.com/lima-vm/lima/pkg/driver"
@@ -43,7 +46,14 @@ func EnsureDisk(driver *driver.BaseDriver) error {
4346
if err != nil {
4447
return err
4548
}
46-
_ = isBaseDiskISO
47-
// TODO
49+
args := []string{"create", "-f", "qcow2"}
50+
if !isBaseDiskISO {
51+
args = append(args, "-b", baseDisk)
52+
}
53+
args = append(args, diffDisk, strconv.Itoa(int(diskSize)))
54+
cmd := exec.Command("qemu-img", args...)
55+
if out, err := cmd.CombinedOutput(); err != nil {
56+
return fmt.Errorf("failed to run %v: %q: %w", cmd.Args, string(out), err)
57+
}
4858
return nil
4959
}

pkg/virt/domain.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package virt
2+
3+
import (
4+
"bytes"
5+
"os"
6+
"path/filepath"
7+
"text/template"
8+
9+
"github.com/lima-vm/lima/pkg/driver"
10+
"github.com/lima-vm/lima/pkg/networks"
11+
"github.com/lima-vm/lima/pkg/store/filenames"
12+
)
13+
14+
type DomainConfig struct {
15+
Name string
16+
Memory int64
17+
CPUs int
18+
CIDataPath string
19+
DiskPath string
20+
Interface string
21+
QemuCommandline string
22+
Network string
23+
SlirpNetwork string
24+
SlirpIPAddress string
25+
SSHLocalPort int
26+
}
27+
28+
const domainXMLTemplate = `<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
29+
<name>{{.Name}}</name><memory unit='B'>{{.Memory}}</memory>
30+
<vcpu>{{.CPUs}}</vcpu>
31+
<features><acpi/><apic/></features>
32+
<cpu mode='host-passthrough'></cpu>
33+
<os firmware='efi'>
34+
<type>hvm</type>
35+
<boot dev='cdrom'/>
36+
<boot dev='hd'/>
37+
<bootmenu enable='no'/>
38+
</os>
39+
<devices>
40+
<console type='pty'>
41+
<target type='serial'/>
42+
</console>
43+
<disk type='file' device='cdrom'>
44+
<driver name='qemu' type='raw'/>
45+
<source file='{{.CIDataPath}}'/>
46+
<target dev='hdd' bus='sata'/>
47+
<readonly/>
48+
</disk>
49+
<disk type='file' device='disk'>
50+
<driver name='qemu' type='qcow2'/>
51+
<source file='{{.DiskPath}}'/>
52+
<target dev='vda' bus='virtio'/>
53+
</disk>
54+
<!--
55+
<graphics type='vnc' autoport='yes' listen='127.0.0.1'>
56+
<listen type='address' address='127.0.0.1'/>
57+
</graphics>
58+
-->
59+
{{.Interface}}
60+
</devices>
61+
{{.QemuCommandline}}
62+
</domain>`
63+
64+
const interfaceXMLTemplate = `
65+
<interface type='user'>
66+
<source network='{{.Network}}'/>
67+
<model type='virtio'/>
68+
</interface>`
69+
70+
const qemuXMLTemplate = `
71+
<qemu:commandline>
72+
<qemu:arg value='-netdev'/>
73+
<qemu:arg value='user,id=net0,net={{.SlirpNetwork}},dhcpstart={{.SlirpIPAddress}},hostfwd=tcp:127.0.0.1:{{.SSHLocalPort}}-:22'/>
74+
<qemu:arg value='-device'/>
75+
<qemu:arg value='virtio-net-pci,netdev=net0'/>
76+
<qemu:arg value='-device'/>
77+
<qemu:arg value='virtio-rng-pci'/>
78+
</qemu:commandline>`
79+
80+
func DomainXML(driver *driver.BaseDriver) (string, error) {
81+
tmpl, err := template.New("domain").Parse(domainXMLTemplate)
82+
if err != nil {
83+
return "", err
84+
}
85+
qemu, err := template.New("qemu").Parse(qemuXMLTemplate)
86+
if err != nil {
87+
return "", err
88+
}
89+
//baseDisk := filepath.Join(driver.Instance.Dir, filenames.BaseDisk)
90+
diffDisk := filepath.Join(driver.Instance.Dir, filenames.DiffDisk)
91+
ciDataPath := filepath.Join(driver.Instance.Dir, filenames.CIDataISO)
92+
cfg := DomainConfig{
93+
Name: "lima-" + driver.Instance.Name,
94+
Memory: driver.Instance.Memory,
95+
CPUs: driver.Instance.CPUs,
96+
CIDataPath: ciDataPath,
97+
DiskPath: diffDisk,
98+
//Network: "lima-" + driver.Instance.Name,
99+
SlirpNetwork: networks.SlirpNetwork,
100+
SlirpIPAddress: networks.SlirpIPAddress,
101+
SSHLocalPort: driver.SSHLocalPort,
102+
}
103+
var buf bytes.Buffer
104+
err = qemu.Execute(&buf, cfg)
105+
if err != nil {
106+
return "", err
107+
}
108+
cfg.QemuCommandline = buf.String()
109+
110+
var xml bytes.Buffer
111+
err = tmpl.Execute(&xml, cfg)
112+
if err != nil {
113+
return "", err
114+
}
115+
domainXML := filepath.Join(driver.Instance.Dir, "domain.xml")
116+
err = os.WriteFile(domainXML, xml.Bytes(), 0o644)
117+
if err != nil {
118+
return "", err
119+
}
120+
return xml.String(), nil
121+
}

pkg/virt/network.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package virt
2+
3+
import (
4+
"bytes"
5+
"os"
6+
"path/filepath"
7+
"text/template"
8+
9+
"github.com/lima-vm/lima/pkg/driver"
10+
)
11+
12+
type NetworkConfig struct {
13+
Name string
14+
Address string
15+
Netmask string
16+
}
17+
18+
const networkXMLTemplate = `<network>
19+
<name>{{.Name}}</name>
20+
<ip address='{{.Address}}' netmask='{{.Netmask}}'>
21+
</ip>
22+
</network>`
23+
24+
func NetworkXML(driver *driver.BaseDriver) (string, error) {
25+
tmpl, err := template.New("network").Parse(networkXMLTemplate)
26+
if err != nil {
27+
return "", err
28+
}
29+
cfg := NetworkConfig{
30+
Name: "lima-" + driver.Instance.Name,
31+
Address: "192.168.55.15",
32+
Netmask: "255.255.255.0",
33+
}
34+
var xml bytes.Buffer
35+
err = tmpl.Execute(&xml, cfg)
36+
if err != nil {
37+
return "", err
38+
}
39+
networkXML := filepath.Join(driver.Instance.Dir, "network.xml")
40+
err = os.WriteFile(networkXML, xml.Bytes(), 0o644)
41+
if err != nil {
42+
return "", err
43+
}
44+
return xml.String(), nil
45+
}

pkg/virt/plugin/main.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,31 @@ import (
77
var VERSION uint32 = libvirt.VERSION_NUMBER
88

99
func Version() (uint32, error) { return libvirt.GetVersion() }
10+
11+
const connectString = "qemu:///session"
12+
13+
func CreateNetwork(xml string) error {
14+
conn, err := libvirt.NewConnect(connectString)
15+
if err != nil {
16+
return err
17+
}
18+
defer conn.Close()
19+
net, err := conn.NetworkDefineXML(xml)
20+
if err != nil {
21+
return err
22+
}
23+
return net.Create()
24+
}
25+
26+
func CreateDomain(xml string) error {
27+
conn, err := libvirt.NewConnect(connectString)
28+
if err != nil {
29+
return err
30+
}
31+
defer conn.Close()
32+
vm, err := conn.DomainDefineXML(xml)
33+
if err != nil {
34+
return err
35+
}
36+
return vm.Create()
37+
}

pkg/virt/virt_driver_unix.go

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package virt
44

55
import (
66
"context"
7-
"errors"
87
"path/filepath"
98
"plugin"
109

@@ -27,7 +26,7 @@ func New(driver *driver.BaseDriver) *LimaVirtDriver {
2726
}
2827
}
2928

30-
func (l *LimaVirtDriver) Validate() error {
29+
func (l *LimaVirtDriver) loadPlugin() error {
3130
dir, err := usrlocalliblima.Dir()
3231
if err != nil {
3332
return err
@@ -36,7 +35,16 @@ func (l *LimaVirtDriver) Validate() error {
3635
if err != nil {
3736
return err
3837
}
38+
l.virtPlugin = p
39+
return nil
40+
}
3941

42+
func (l *LimaVirtDriver) Validate() error {
43+
err := l.loadPlugin()
44+
if err != nil {
45+
return err
46+
}
47+
p := l.virtPlugin
4048
// test variable
4149
v, err := p.Lookup("VERSION")
4250
if err != nil {
@@ -55,7 +63,6 @@ func (l *LimaVirtDriver) Validate() error {
5563
}
5664
logrus.Infof("Version: %d", n)
5765

58-
l.virtPlugin = p
5966
return nil
6067
}
6168

@@ -64,7 +71,38 @@ func (l *LimaVirtDriver) CreateDisk() error {
6471
}
6572

6673
func (l *LimaVirtDriver) Start(_ context.Context) (chan error, error) {
67-
return nil, errors.New("TODO")
74+
err := l.loadPlugin()
75+
if err != nil {
76+
return nil, err
77+
}
78+
79+
/*
80+
net, err := NetworkXML(l.BaseDriver)
81+
if err != nil {
82+
return nil, err
83+
}
84+
cn, err := l.virtPlugin.Lookup("CreateNetwork")
85+
if err != nil {
86+
return nil, err
87+
}
88+
if err := cn.(func(string) error)(net); err != nil {
89+
return nil, err
90+
}
91+
*/
92+
93+
dom, err := DomainXML(l.BaseDriver)
94+
if err != nil {
95+
return nil, err
96+
}
97+
cd, err := l.virtPlugin.Lookup("CreateDomain")
98+
if err != nil {
99+
return nil, err
100+
}
101+
if err := cd.(func(string) error)(dom); err != nil {
102+
return nil, err
103+
}
104+
105+
return nil, err
68106
}
69107

70108
func (l *LimaVirtDriver) Stop(_ context.Context) error {

0 commit comments

Comments
 (0)