From d55a501ab1113e518bceb1ceeff3bc47fa7fcacd Mon Sep 17 00:00:00 2001 From: Richard Case Date: Mon, 30 Dec 2024 09:53:42 +0000 Subject: [PATCH] feat: add ability to specify additional volumes Signed-off-by: Richard Case --- .env | 1 + .envrc | 11 +++++++ devbox.json | 18 ++++++++++++ devbox.lock | 53 ++++++++++++++++++++++++++++++++++ internal/cmd/microvm/create.go | 7 +++++ pkg/app/create.go | 29 +++++++++++++++---- pkg/app/types.go | 1 + 7 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 .env create mode 100644 .envrc create mode 100644 devbox.json create mode 100644 devbox.lock diff --git a/.env b/.env new file mode 100644 index 0000000..44684a4 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +NIX_HARDENING_ENABLE="" \ No newline at end of file diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..5ba2536 --- /dev/null +++ b/.envrc @@ -0,0 +1,11 @@ +#!/bin/bash + +# Automatically sets up your devbox environment whenever you cd into this +# directory via our direnv integration: + +eval "$(devbox generate direnv --print-envrc --env-file .env)" + +# check out https://www.jetpack.io/devbox/docs/ide_configuration/direnv/ +# for more details + +export NIX_HARDENING_ENABLE="" diff --git a/devbox.json b/devbox.json new file mode 100644 index 0000000..e193dfd --- /dev/null +++ b/devbox.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.6/.schema/devbox.schema.json", + "packages": [ + "go@1.22.9" + ], + "shell": { + "env": { + "GOPATH": "$HOME/go/", + "PATH": "$PATH:$HOME/go/bin" + }, + "init_hook": [ + "export \"GOROOT=$(go env GOROOT)\"" + ], + "scripts": { + "run_test": "go run main.go" + } + } +} \ No newline at end of file diff --git a/devbox.lock b/devbox.lock new file mode 100644 index 0000000..ef25046 --- /dev/null +++ b/devbox.lock @@ -0,0 +1,53 @@ +{ + "lockfile_version": "1", + "packages": { + "go@1.22.9": { + "last_modified": "2024-11-28T07:51:56Z", + "resolved": "github:NixOS/nixpkgs/226216574ada4c3ecefcbbec41f39ce4655f78ef#go_1_22", + "source": "devbox-search", + "version": "1.22.9", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/4nf51i4ah186y2jy3fad2fyvpa49qx6q-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/4nf51i4ah186y2jy3fad2fyvpa49qx6q-go-1.22.9" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8w8vzwgp55yl8j1ljgm4wzdgjkvkv5v3-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/8w8vzwgp55yl8j1ljgm4wzdgjkvkv5v3-go-1.22.9" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/vlih7j78ki05i8nvzdsxvws7a7ksq04m-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/vlih7j78ki05i8nvzdsxvws7a7ksq04m-go-1.22.9" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/frc5188kgv3ws0n999c7cy5vi2f8k4jp-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/frc5188kgv3ws0n999c7cy5vi2f8k4jp-go-1.22.9" + } + } + } + } +} diff --git a/internal/cmd/microvm/create.go b/internal/cmd/microvm/create.go index 093ca49..6bfbd2c 100644 --- a/internal/cmd/microvm/create.go +++ b/internal/cmd/microvm/create.go @@ -23,6 +23,7 @@ func newCreateCommand() *cli.Command { createInput := &app.CreateInput{} networkInterfaces := &cli.StringSlice{} metadataFromFile := &cli.StringSlice{} + volumes := &cli.StringSlice{} cmd := &cli.Command{ Name: "create", @@ -43,6 +44,7 @@ func newCreateCommand() *cli.Command { createInput.NetworkInterfaces = networkInterfaces.Value() createInput.MetadataFromFile = metadataFromFile.Value() + createInput.Volumes = volumes.Value() if err := a.Create(ctx.Context, createInput); err != nil { return fmt.Errorf("creating microvm: %s", err) @@ -151,6 +153,11 @@ func newCreateCommand() *cli.Command { Usage: "set the cloud-init final message", Destination: &createInput.Metadata.Message, }, + &cli.StringSliceFlag{ + Name: "volume", + Usage: "attach an additional volume, The following format: name=containerimage=mountpoint", + Destination: volumes, + }, }, } diff --git a/pkg/app/create.go b/pkg/app/create.go index 3d6f553..9788ca7 100644 --- a/pkg/app/create.go +++ b/pkg/app/create.go @@ -63,7 +63,7 @@ func (a *app) addUserdata(spec *flintlocktypes.MicroVMSpec, input *CreateInput) return nil } -//TODO: this whole thing needs rewriting +// TODO: this whole thing needs rewriting func (a *app) convertCreateInputToReq(input *CreateInput) (*flintlocktypes.MicroVMSpec, error) { req := &flintlocktypes.MicroVMSpec{ Id: input.Name, @@ -77,7 +77,7 @@ func (a *app) convertCreateInputToReq(input *CreateInput) (*flintlocktypes.Micro Image: input.KernelImage, AddNetworkConfig: input.KernelAddNetConf, Filename: &input.KernelFileName, - //TODO: additional args + // TODO: additional args }, RootVolume: &flintlocktypes.Volume{ Id: "root", @@ -103,7 +103,7 @@ func (a *app) convertCreateInputToReq(input *CreateInput) (*flintlocktypes.Micro metaFromFile := input.MetadataFromFile[i] metaparts := strings.Split(metaFromFile, "=") if len(metaparts) != 2 { - //TODO: proper error + // TODO: proper error return nil, fmt.Errorf("metadata not in name=pathtofile format") } content, err := os.ReadFile(metaparts[1]) @@ -117,14 +117,14 @@ func (a *app) convertCreateInputToReq(input *CreateInput) (*flintlocktypes.Micro netInt := input.NetworkInterfaces[i] netParts := strings.Split(netInt, ":") if len(netParts) < 1 || len(netParts) > 4 { - //TODO: proper error + // TODO: proper error return nil, fmt.Errorf("network interfaces not in correct format, expect name:type:[macaddress]:[ipaddress]") } macAddress := "" ipAddress := "" name := netParts[0] - intType := netParts[1] //TODO: validate the types + intType := netParts[1] // TODO: validate the types if name == "eth0" { return nil, fmt.Errorf("you cannot use eth0 as the name of the interface as this is reserved") @@ -165,6 +165,25 @@ func (a *app) convertCreateInputToReq(input *CreateInput) (*flintlocktypes.Micro req.Interfaces = append(req.Interfaces, apiIface) } + for i := range input.Volumes { + volume := input.Volumes[i] + volParts := strings.Split(volume, "=") + if len(volParts) != 3 { + // TODO: proper error + return nil, fmt.Errorf("volume not in correct format, expect name=containerimage=mountpoint") + } + + apiVolume := &flintlocktypes.Volume{ + Id: volParts[0], + IsReadOnly: false, + MountPoint: volParts[2], + Source: &flintlocktypes.VolumeSource{ + ContainerSource: &volParts[1], + }, + } + req.AdditionalVolumes = append(req.AdditionalVolumes, apiVolume) + } + return req, nil } diff --git a/pkg/app/types.go b/pkg/app/types.go index 81802f5..55a64ec 100644 --- a/pkg/app/types.go +++ b/pkg/app/types.go @@ -16,6 +16,7 @@ type CreateInput struct { NetworkInterfaces []string MetadataFromFile []string Metadata Metadata + Volumes []string } type Metadata struct {