diff options
author | Franck Cuny <franck@fcuny.net> | 2021-05-15 13:51:19 -0700 |
---|---|---|
committer | Franck Cuny <franck@fcuny.net> | 2021-05-15 13:51:19 -0700 |
commit | 97e7a59291bf16c1dfa8e48b267116b4c66bc4c0 (patch) | |
tree | 1de0d475a6573b261b88888c7b0ef39f5f8e15ac /cmd | |
parent | hack: firecracker binary and CNI configuration (diff) | |
download | containerd-to-vm-97e7a59291bf16c1dfa8e48b267116b4c66bc4c0.tar.gz |
boot the VM
The binary needs a few more arguments: the path to the firecracker binary, the path to a linux kernel. Using the image that was generated, we can now boot the VM with firecracker. This will rely on a CNI configuration to create the network, and will use the provided kernel to boot.
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/c2vm/main.go | 83 |
1 files changed, 80 insertions, 3 deletions
diff --git a/cmd/c2vm/main.go b/cmd/c2vm/main.go index 3251f96..37a7704 100644 --- a/cmd/c2vm/main.go +++ b/cmd/c2vm/main.go @@ -19,6 +19,8 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/platforms" "github.com/docker/docker/pkg/archive" + "github.com/firecracker-microvm/firecracker-go-sdk" + "github.com/firecracker-microvm/firecracker-go-sdk/client/models" "github.com/google/renameio" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -29,7 +31,8 @@ const ( ) var ( - platform = platforms.Only(ocispec.Platform{ + firecrackerSock = filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "firecracker.sock") + platform = platforms.Only(ocispec.Platform{ OS: "linux", Architecture: "amd64", }) @@ -37,8 +40,10 @@ var ( func main() { var ( - containerName = flag.String("container", "", "Name of the container") - outFile = flag.String("out", "container.img", "firecracker output to create") + containerName = flag.String("container", "", "Name of the container") + outFile = flag.String("out", "container.img", "firecracker output to create") + linuxKernel = flag.String("linux-kernel", "", "path to the linux kernel to use") + firecrackerBinary = flag.String("firecracker-binary", "", "path to the firecracker binary") ) flag.Parse() @@ -47,6 +52,14 @@ func main() { log.Fatal("a container is required") } + if *linuxKernel == "" { + log.Fatalf("a linux kernel is required") + } + + if *firecrackerBinary == "" { + log.Fatalf("the path to the firecracker binary is required") + } + client, err := containerd.New(containerdSock) if err != nil { log.Fatalf("failed to create a client for containerd: %v", err) @@ -100,6 +113,8 @@ func main() { if err := resizeImage(*outFile); err != nil { log.Fatalf("failed to resize the image %s: %s\n", *outFile, err) } + + bootVM(ctx, *outFile, *linuxKernel, *firecrackerBinary) } func extract(ctx context.Context, client *containerd.Client, image containerd.Image, mntDir string) error { @@ -224,3 +239,65 @@ func writeToFile(filepath string, content string) error { } return nil } + +func bootVM(ctx context.Context, rawImage, linuxKernel, firecrackerBinary string) { + vmmCtx, vmmCancel := context.WithCancel(ctx) + defer vmmCancel() + + devices := make([]models.Drive, 1) + devices[0] = models.Drive{ + DriveID: firecracker.String("1"), + PathOnHost: &rawImage, + IsRootDevice: firecracker.Bool(true), + IsReadOnly: firecracker.Bool(false), + } + fcCfg := firecracker.Config{ + LogLevel: "debug", + SocketPath: firecrackerSock, + KernelImagePath: linuxKernel, + KernelArgs: "console=ttyS0 reboot=k panic=1 pci=off init=/init.sh random.trust_cpu=on", + Drives: devices, + MachineCfg: models.MachineConfiguration{ + VcpuCount: firecracker.Int64(1), + CPUTemplate: models.CPUTemplate("C3"), + HtEnabled: firecracker.Bool(true), + MemSizeMib: firecracker.Int64(512), + }, + NetworkInterfaces: []firecracker.NetworkInterface{ + { + CNIConfiguration: &firecracker.CNIConfiguration{ + NetworkName: "c2vm", + IfName: "eth0", + }, + }, + }, + } + + machineOpts := []firecracker.Opt{} + + command := firecracker.VMCommandBuilder{}. + WithBin(firecrackerBinary). + WithSocketPath(fcCfg.SocketPath). + WithStdin(os.Stdin). + WithStdout(os.Stdout). + WithStderr(os.Stderr). + Build(ctx) + machineOpts = append(machineOpts, firecracker.WithProcessRunner(command)) + m, err := firecracker.NewMachine(vmmCtx, fcCfg, machineOpts...) + if err != nil { + fmt.Printf("failed to start the vm: %+v\n", err) + os.Exit(1) + } + + if err := m.Start(vmmCtx); err != nil { + fmt.Printf("failed to start the vm: %+v\n", err) + os.Exit(1) + } + defer m.StopVMM() + + if err := m.Wait(vmmCtx); err != nil { + fmt.Printf("failed to start the vm: %+v\n", err) + os.Exit(1) + } + log.Print("Machine was started") +} |