Skip to content

Commit 9ceb32f

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 e06bdc5 commit 9ceb32f

File tree

5 files changed

+214
-3
lines changed

5 files changed

+214
-3
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: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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+
_ = interfaceXMLTemplate
86+
qemu, err := template.New("qemu").Parse(qemuXMLTemplate)
87+
if err != nil {
88+
return "", err
89+
}
90+
// baseDisk := filepath.Join(driver.Instance.Dir, filenames.BaseDisk)
91+
diffDisk := filepath.Join(driver.Instance.Dir, filenames.DiffDisk)
92+
ciDataPath := filepath.Join(driver.Instance.Dir, filenames.CIDataISO)
93+
cfg := DomainConfig{
94+
Name: "lima-" + driver.Instance.Name,
95+
Memory: driver.Instance.Memory,
96+
CPUs: driver.Instance.CPUs,
97+
CIDataPath: ciDataPath,
98+
DiskPath: diffDisk,
99+
// Network: "lima-" + driver.Instance.Name,
100+
SlirpNetwork: networks.SlirpNetwork,
101+
SlirpIPAddress: networks.SlirpIPAddress,
102+
SSHLocalPort: driver.SSHLocalPort,
103+
}
104+
var buf bytes.Buffer
105+
err = qemu.Execute(&buf, cfg)
106+
if err != nil {
107+
return "", err
108+
}
109+
cfg.QemuCommandline = buf.String()
110+
111+
var xml bytes.Buffer
112+
err = tmpl.Execute(&xml, cfg)
113+
if err != nil {
114+
return "", err
115+
}
116+
domainXML := filepath.Join(driver.Instance.Dir, "domain.xml")
117+
err = os.WriteFile(domainXML, xml.Bytes(), 0o644)
118+
if err != nil {
119+
return "", err
120+
}
121+
return domainXML, nil
122+
}

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 networkXML, nil
45+
}

pkg/virt/virt.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,19 @@ func Version() (string, error) {
1818
}
1919
return m[1], nil
2020
}
21+
22+
const connectString = "qemu:///session"
23+
24+
func virsh(args ...string) error {
25+
connect := []string{"--connect", connectString}
26+
args = append(connect, args...)
27+
return exec.Command("virsh", args...).Run()
28+
}
29+
30+
func CreateNetwork(xml string) error {
31+
return virsh("net-create", xml)
32+
}
33+
34+
func CreateDomain(xml string) error {
35+
return virsh("create", xml)
36+
}

pkg/virt/virt_driver.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,25 @@ func (l *LimaVirtDriver) CreateDisk() error {
3939
}
4040

4141
func (l *LimaVirtDriver) Start(_ context.Context) (chan error, error) {
42-
return nil, errors.New("TODO")
42+
/*
43+
net, err := NetworkXML(l.BaseDriver)
44+
if err != nil {
45+
return nil, err
46+
}
47+
if err := CreateNetwork(net); err != nil {
48+
return nil, err
49+
}
50+
*/
51+
52+
dom, err := DomainXML(l.BaseDriver)
53+
if err != nil {
54+
return nil, err
55+
}
56+
if err := CreateDomain(dom); err != nil {
57+
return nil, err
58+
}
59+
60+
return nil, err
4361
}
4462

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

0 commit comments

Comments
 (0)