Skip to content

Commit be7f6f8

Browse files
authored
firecracker: Refactor logic and bump to kernel 6.1.102 (#83)
2 parents 3bc134a + 6ba18f8 commit be7f6f8

File tree

5 files changed

+93
-99
lines changed

5 files changed

+93
-99
lines changed

internal/qubesome/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func runner(in WorkloadInfo, runnerOverride string) error {
176176
if !reflect.DeepEqual(ew.Workload.HostAccess, w.HostAccess) {
177177
msg := diffMessage(w, ew)
178178
if len(msg) > 0 {
179-
err := fmt.Errorf("workload %s tries to access more than profile allows", in.Profile)
179+
err := fmt.Errorf("workload %s tries to access more than profile allows", in.Name)
180180
dbus.NotifyOrLog("qubesome: access denied", err.Error()+":<br/>"+msg)
181181

182182
return err

internal/runners/firecracker/deps.go

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,53 +11,51 @@ import (
1111
"os"
1212
"os/exec"
1313
"path/filepath"
14+
"strconv"
1415

1516
"github.com/qubesome/cli/internal/files"
17+
"github.com/qubesome/cli/internal/util/dbus"
1618
"golang.org/x/sys/execabs"
19+
20+
_ "embed"
1721
)
1822

19-
const (
20-
command = "/usr/bin/firecracker"
21-
runUserDir = "/run/user/%d"
22-
qubesomeDir = "qubesome"
23-
qubesomeFilemode = 0o700
24-
qubesomeCfgFilemode = 0o600
23+
//go:embed firecracker.config
24+
var configTmpl string
2525

26-
kernelURL = "https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.5/x86_64/vmlinux-5.10.186"
26+
const (
27+
// kernelUrl from https://s3.amazonaws.com/spec.ccfc.min/
28+
kernelURL = "https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.11/x86_64/vmlinux-6.1.102"
2729
kernelFile = "vmlinux"
2830

31+
// light-weight image that contains the necessary tools for setting up
32+
// firecracker's network taps.
33+
firecrackerImg = "ghcr.io/qubesome/firecracker:latest"
34+
2935
MB = 1024 * 1024
3036
maxDownloadSize = 100 * MB
3137

3238
networkDevName = "tap1"
3339
)
3440

35-
func ensureDependencies(img string) error {
36-
if _, err := exec.LookPath(command); err != nil {
41+
func ensureDependencies() error {
42+
if _, err := exec.LookPath(files.FireCrackerBinary); err != nil {
3743
return err
3844
}
3945

40-
uid := os.Getuid()
41-
baseDir := fmt.Sprintf(runUserDir, uid)
42-
43-
_, err := os.Stat(baseDir)
44-
if err != nil {
45-
return err
46-
}
47-
48-
d := filepath.Join(baseDir, qubesomeDir)
49-
if err = os.MkdirAll(d, qubesomeFilemode); err != nil {
46+
d := files.QubesomeDir()
47+
if err := os.MkdirAll(d, files.DirMode); err != nil {
5048
return err
5149
}
5250

5351
kfile := filepath.Join(d, kernelFile)
54-
_, err = os.Stat(kfile)
52+
_, err := os.Stat(kfile)
5553
if err != nil {
5654
if !errors.Is(err, fs.ErrNotExist) {
5755
return err
5856
}
5957

60-
slog.Info("cached kernel image not found")
58+
dbus.NotifyOrLog("firecracker", "downloading fresh kernel image")
6159
err = download(kernelURL, kfile)
6260
if err != nil {
6361
return fmt.Errorf("failed to download kernel image: %w", err)
@@ -66,19 +64,44 @@ func ensureDependencies(img string) error {
6664

6765
_, err = net.InterfaceByName(networkDevName)
6866
if err != nil {
69-
return setupTaps(img)
67+
return setupTaps()
7068
}
7169

7270
return nil
7371
}
7472

75-
func setupTaps(img string) error {
73+
func createRootFs(dir, img string) (string, error) {
74+
slog.Info("creating root fs")
75+
rootfs := filepath.Join(dir, "roofs.ext4")
76+
bin := files.ContainerRunnerBinary("docker")
77+
cmd := execabs.Command(bin,
78+
"run", "--rm", "--privileged",
79+
"-v", dir+":"+dir,
80+
img,
81+
"create_rootfs", rootfs, strconv.Itoa(os.Getuid()),
82+
)
83+
84+
cmd.Stderr = os.Stderr
85+
cmd.Stdin = os.Stdin
86+
cmd.Stdout = os.Stdout
87+
88+
if err := cmd.Run(); err != nil {
89+
return "", err
90+
}
91+
92+
return rootfs, nil
93+
}
94+
95+
func setupTaps() error {
7696
slog.Info("setting up taps")
77-
bin := files.ContainerRunnerBinary("")
97+
bin := files.ContainerRunnerBinary("docker")
98+
99+
slog.Debug("setting up taps", "device name", networkDevName)
78100
cmd := execabs.Command(bin,
79101
"run", "--rm", "--privileged",
80102
"--network", "host",
81-
img,
103+
"-e", fmt.Sprintf("TAP_DEV=%s", networkDevName),
104+
firecrackerImg,
82105
"setup_taps",
83106
)
84107

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"boot-source": {
3+
"kernel_image_path": "{{.KernelImagePath}}",
4+
"boot_args": "keep_bootcon console=ttyS0 reboot=k panic=1 pci=off",
5+
"initrd_path": null
6+
},
7+
"drives": [
8+
{
9+
"drive_id": "rootfs",
10+
"path_on_host": "{{.RootFsPath}}",
11+
"is_root_device": true,
12+
"is_read_only": false,
13+
"partuuid": null,
14+
"cache_type": "Unsafe",
15+
"io_engine": "Sync",
16+
"rate_limiter": null
17+
}
18+
],
19+
"machine-config": {
20+
"vcpu_count": 2,
21+
"mem_size_mib": 256,
22+
"smt": false,
23+
"track_dirty_pages": false
24+
},
25+
"cpu-config": null,
26+
"balloon": null,
27+
"network-interfaces": [
28+
{
29+
"iface_id": "eth0",
30+
"guest_mac": "06:00:AC:10:00:02",
31+
"host_dev_name": "{{.HostDeviceName}}"
32+
}
33+
],
34+
"vsock": null,
35+
"logger": null,
36+
"metrics": null,
37+
"mmds-config": null,
38+
"entropy": null
39+
}

internal/runners/firecracker/run.go

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"log/slog"
77
"os"
88
"path/filepath"
9-
"strconv"
109
"text/template"
1110

1211
"github.com/qubesome/cli/internal/files"
@@ -20,28 +19,6 @@ type configParams struct {
2019
HostDeviceName string
2120
}
2221

23-
func createRootFs(dir, img string) (string, error) {
24-
slog.Info("creating root fs")
25-
rootfs := filepath.Join(dir, "roofs.ext4")
26-
bin := files.ContainerRunnerBinary("")
27-
cmd := execabs.Command(bin,
28-
"run", "--rm", "--privileged",
29-
"-v", "/tmp/:/tmp/",
30-
img,
31-
"create_rootfs", rootfs, strconv.Itoa(os.Getuid()),
32-
)
33-
34-
cmd.Stderr = os.Stderr
35-
cmd.Stdin = os.Stdin
36-
cmd.Stdout = os.Stdout
37-
38-
if err := cmd.Run(); err != nil {
39-
return "", err
40-
}
41-
42-
return rootfs, nil
43-
}
44-
4522
func Run(ew types.EffectiveWorkload) error {
4623
slog.Warn("use of firecracker is experimental")
4724

@@ -53,7 +30,7 @@ func Run(ew types.EffectiveWorkload) error {
5330
return fmt.Errorf("firecracker does not support single instance")
5431
}
5532

56-
if err := ensureDependencies(ew.Workload.Image); err != nil {
33+
if err := ensureDependencies(); err != nil {
5734
return err
5835
}
5936

@@ -67,10 +44,7 @@ func Run(ew types.EffectiveWorkload) error {
6744
return err
6845
}
6946

70-
uid := os.Getuid()
71-
baseDir := fmt.Sprintf(runUserDir, uid)
72-
kfile := filepath.Join(baseDir, qubesomeDir, kernelFile)
73-
47+
kfile := filepath.Join(files.QubesomeDir(), kernelFile)
7448
params := configParams{
7549
KernelImagePath: kfile,
7650
RootFsPath: rootfs,
@@ -85,7 +59,7 @@ func Run(ew types.EffectiveWorkload) error {
8559
return err
8660
}
8761

88-
f, err := os.OpenFile(cfgPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, qubesomeCfgFilemode)
62+
f, err := os.OpenFile(cfgPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, files.FileMode)
8963
if err != nil {
9064
return fmt.Errorf("failed to open firecracker config file: %w", err)
9165
}
@@ -105,10 +79,10 @@ func Run(ew types.EffectiveWorkload) error {
10579
}
10680

10781
func run(args []string) error {
108-
slog.Debug(command, "args", args)
82+
slog.Debug(files.FireCrackerBinary, "args", args)
10983

11084
ctx := context.Background()
111-
cmd := execabs.CommandContext(ctx, command, args...)
85+
cmd := execabs.CommandContext(ctx, files.FireCrackerBinary, args...)
11286

11387
cmd.Stdin = os.Stdin
11488
cmd.Stderr = os.Stderr

internal/runners/firecracker/template.go

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)