Skip to content

Commit e0f4b15

Browse files
committed
vm: create installation VM
The installation VM is a temporary VM used for running privleged command using rootless podman. This VM uses the vm image build with make image. It has already pre configured the local podman, the proxy and the required directories for bootc. Signed-off-by: Alice Frosi <[email protected]>
1 parent 3c17a53 commit e0f4b15

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

pkg/vm/installvm.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package vm
2+
3+
import (
4+
"fmt"
5+
6+
"math/rand"
7+
8+
"github.com/containers/podman-bootc/pkg/vm/domain"
9+
"github.com/google/uuid"
10+
"github.com/sirupsen/logrus"
11+
"libvirt.org/go/libvirt"
12+
"libvirt.org/go/libvirtxml"
13+
)
14+
15+
const (
16+
CIDInstallVM = 3
17+
VSOCKPort = 1234
18+
)
19+
const (
20+
mac = "52:54:00:0b:dd:1e"
21+
imodel = "e1000"
22+
)
23+
24+
const (
25+
StorageVirtiofsTarget = "storage"
26+
ConfigVirtiofsTarget = "config"
27+
OutputVirtiofsTarget = "output"
28+
)
29+
30+
type InstallOptions struct {
31+
DiskImage string
32+
OutputImage string
33+
InputFormat domain.DiskDriverType
34+
OutputFormat domain.DiskDriverType
35+
ContainerStoragePath string
36+
ConfigPath string
37+
OutputPath string
38+
Root bool
39+
}
40+
41+
type InstallVM struct {
42+
libvirtURI string
43+
domain string
44+
opts InstallOptions
45+
}
46+
47+
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOQRSTUVWXYZ0123456789"
48+
49+
func RandomString(n int) string {
50+
b := make([]byte, n)
51+
for i := range b {
52+
b[i] = letterBytes[rand.Intn(len(letterBytes))]
53+
}
54+
return string(b)
55+
}
56+
57+
func NewInstallVM(opts InstallOptions) *InstallVM {
58+
uri := "qemu:///session"
59+
if opts.Root {
60+
uri = "qemu:///system"
61+
}
62+
name := "bootc-" + RandomString(5)
63+
return &InstallVM{
64+
domain: name,
65+
libvirtURI: uri,
66+
opts: opts,
67+
}
68+
}
69+
70+
func (vm *InstallVM) newDomain() *libvirtxml.Domain {
71+
return domain.NewDomain(
72+
domain.WithName(vm.domain),
73+
domain.WithUUID(uuid.New().String()),
74+
domain.WithKVM(),
75+
domain.WithOS(),
76+
domain.WithMemory(2048),
77+
domain.WithMemoryBackingForVirtiofs(),
78+
domain.WithCPUHostModel(),
79+
domain.WithVCPUs(2),
80+
domain.WithSerialConsole(),
81+
domain.WithVSOCK(CIDInstallVM),
82+
domain.WithInterface(mac, imodel),
83+
domain.WithDisk(vm.opts.DiskImage, "input", "vda", vm.opts.InputFormat, domain.DiskBusVirtio),
84+
domain.WithDisk(vm.opts.OutputImage, "output", "vdb", vm.opts.OutputFormat, domain.DiskBusVirtio),
85+
domain.WithFilesystem(vm.opts.ContainerStoragePath, StorageVirtiofsTarget),
86+
domain.WithFilesystem(vm.opts.ConfigPath, ConfigVirtiofsTarget),
87+
domain.WithFilesystem(vm.opts.OutputPath, OutputVirtiofsTarget),
88+
)
89+
}
90+
91+
func (vm *InstallVM) Run() error {
92+
domainXML, err := vm.newDomain().Marshal()
93+
if err != nil {
94+
return err
95+
}
96+
conn, err := libvirt.NewConnect(vm.libvirtURI)
97+
if err != nil {
98+
return err
99+
}
100+
_, err = conn.DomainDefineXMLFlags(domainXML, libvirt.DOMAIN_DEFINE_VALIDATE)
101+
if err != nil {
102+
return fmt.Errorf("unable to define virtual machine domain: %w", err)
103+
}
104+
dom, err := conn.LookupDomainByName(vm.domain)
105+
if err != nil {
106+
return err
107+
}
108+
defer dom.Free()
109+
err = dom.Create()
110+
if err != nil {
111+
return fmt.Errorf("Failed to start domain: %v", err)
112+
}
113+
logrus.Debugf("Domain %s started successfully.", vm.domain)
114+
115+
return nil
116+
}
117+
118+
func (vm *InstallVM) Stop() error {
119+
conn, err := libvirt.NewConnect(vm.libvirtURI)
120+
if err != nil {
121+
return err
122+
}
123+
dom, err := conn.LookupDomainByName(vm.domain)
124+
if err != nil {
125+
return err
126+
}
127+
defer dom.Free()
128+
if err := dom.Destroy(); err != nil {
129+
logrus.Warning("Failed to destroy the domain %s, maybe already stopped: %v", vm.domain, err)
130+
}
131+
if err := dom.Undefine(); err != nil {
132+
return fmt.Errorf("Undefine failed: %v", err)
133+
}
134+
logrus.Debugf("Domain %s stopped and deleted successfully", vm.domain)
135+
136+
return nil
137+
}

0 commit comments

Comments
 (0)