From 7c40b67aa9af0df3949d4a5531121eb057481fe8 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 10 Oct 2024 17:29:39 -0400 Subject: [PATCH 01/35] initial virtiofs support testing --- .../microvm/cloudhypervisor/create.go | 34 ++++++++++++++++--- .../microvm/cloudhypervisor/state.go | 19 +++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index b7fc0d31..4485a40b 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -54,12 +54,38 @@ func (p *provider) startCloudHypervisor(_ context.Context, detached bool, logger *logrus.Entry, ) (*os.Process, error) { + + logger.Debugf("creating virtiofsd") + + cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", + "--socket-path="+state.VirtioFSPath(), + "-o", "source=/mnt/user/appdata,cache=always,sandbox=chroot,xattr") + stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) + } + + stdErrFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening sterr file %s: %w", state.VirtioFSStderrPath(), err) + } + + cmdVirtioFS.Stderr = stdErrFileVirtioFS + cmdVirtioFS.Stdout = stdOutFileVirtioFS + cmdVirtioFS.Stdin = &bytes.Buffer{} + + var startErr error + startErr = cmdVirtioFS.Start() + if startErr != nil { + return nil, fmt.Errorf("starting virtiofsd process: %w", err) + } + args, err := p.buildArgs(vm, state, logger) if err != nil { return nil, err } - cmd := exec.Command(p.config.CloudHypervisorBin, args...) //nolint: gosec // TODO: need to validate the args + cmd := exec.Command(p.config.CloudHypervisorBin, args...) stdOutFile, err := p.fs.OpenFile(state.StdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { @@ -74,8 +100,6 @@ func (p *provider) startCloudHypervisor(_ context.Context, cmd.Stderr = stdErrFile cmd.Stdout = stdOutFile cmd.Stdin = &bytes.Buffer{} - - var startErr error if detached { startErr = process.DetachedStart(cmd) } else { @@ -110,7 +134,7 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( // CPU and memory args = append(args, "--cpus", fmt.Sprintf("boot=%d", vm.Spec.VCPU)) - args = append(args, "--memory", fmt.Sprintf("size=%dM", vm.Spec.MemoryInMb)) + args = append(args, "--memory", fmt.Sprintf("size=%dM,shared=on", vm.Spec.MemoryInMb)) // Volumes (root, additional, metadata) rootVolumeStatus, volumeStatusFound := vm.Status.Volumes[vm.Spec.RootVolume.ID] @@ -119,6 +143,8 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( } args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) + // --fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512 + args = append(args, "--fs", fmt.Sprintf("tag=appdata,socket=%s,num_queues=1,queue_size=512", state.VirtioFSPath())) for _, vol := range vm.Spec.AdditionalVolumes { status, ok := vm.Status.Volumes[vol.ID] diff --git a/infrastructure/microvm/cloudhypervisor/state.go b/infrastructure/microvm/cloudhypervisor/state.go index 88d5b62a..ccb5f7f0 100644 --- a/infrastructure/microvm/cloudhypervisor/state.go +++ b/infrastructure/microvm/cloudhypervisor/state.go @@ -14,6 +14,9 @@ const ( logFileName = "cloudhypervisor.log" stdOutFileName = "cloudhypervisor.stdout" stdErrFileName = "cloudhypervisor.stderr" + stdErrVirtioFSFileName = "virtiofs.stderr" + stdOutVirtioFSFileName = "virtiofs.stdout" + socketVirtiofsFileName = "virtiofs.sock" socketFileName = "cloudhypervisor.sock" cloudInitFileName = "cloud-init.img" ) @@ -30,6 +33,10 @@ type State interface { StderrPath() string SockPath() string + VirtioFSPath() string + VirtioFSStdoutPath() string + VirtioFSStderrPath() string + CloudInitImage() string } @@ -80,3 +87,15 @@ func (s *fsState) CloudInitImage() string { func (s *fsState) SetPid(pid int) error { return shared.PIDWriteToFile(pid, s.PIDPath(), s.fs) } + +func (s *fsState) VirtioFSPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, socketVirtiofsFileName) +} + +func (s *fsState) VirtioFSStdoutPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, stdOutVirtioFSFileName) +} + +func (s *fsState) VirtioFSStderrPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, stdErrVirtioFSFileName) +} \ No newline at end of file From fcb85af4fdf778a0b873ff378dcccb9564da95a4 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 10 Oct 2024 18:10:57 -0400 Subject: [PATCH 02/35] increase queue size --- infrastructure/microvm/cloudhypervisor/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 4485a40b..2bc87e96 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -144,7 +144,7 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) // --fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512 - args = append(args, "--fs", fmt.Sprintf("tag=appdata,socket=%s,num_queues=1,queue_size=512", state.VirtioFSPath())) + args = append(args, "--fs", fmt.Sprintf("tag=appdata,socket=%s,num_queues=1,queue_size=1024", state.VirtioFSPath())) for _, vol := range vm.Spec.AdditionalVolumes { status, ok := vm.Status.Volumes[vol.ID] From 23e2bb16d0eebb94760097b8fe4180f5535be162 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Fri, 11 Oct 2024 11:14:59 -0400 Subject: [PATCH 03/35] update path and tag --- infrastructure/microvm/cloudhypervisor/create.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 2bc87e96..51dc35fe 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -59,7 +59,7 @@ func (p *provider) startCloudHypervisor(_ context.Context, cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", "--socket-path="+state.VirtioFSPath(), - "-o", "source=/mnt/user/appdata,cache=always,sandbox=chroot,xattr") + "-o", "source=/mnt/user,cache=always,sandbox=chroot,xattr") stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) @@ -144,7 +144,7 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) // --fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512 - args = append(args, "--fs", fmt.Sprintf("tag=appdata,socket=%s,num_queues=1,queue_size=1024", state.VirtioFSPath())) + args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024", state.VirtioFSPath())) for _, vol := range vm.Spec.AdditionalVolumes { status, ok := vm.Status.Volumes[vol.ID] From 1189f9a07e87bf56563c0a6e9d70dd1d01850135 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Tue, 15 Oct 2024 21:22:55 -0400 Subject: [PATCH 04/35] change cache mode to none --- infrastructure/microvm/cloudhypervisor/create.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 51dc35fe..caceb304 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -57,9 +57,9 @@ func (p *provider) startCloudHypervisor(_ context.Context, logger.Debugf("creating virtiofsd") - cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", + cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", "--socket-path="+state.VirtioFSPath(), - "-o", "source=/mnt/user,cache=always,sandbox=chroot,xattr") + "-o", "source=/mnt/user,cache=none,sandbox=chroot,xattr") stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) From 020eb5f6ae5061e4b5eb809cf17981233f6a44dc Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Tue, 15 Oct 2024 22:04:39 -0400 Subject: [PATCH 05/35] adding announce sub mounts --- infrastructure/microvm/cloudhypervisor/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index caceb304..9e4f0d9d 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -144,7 +144,7 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) // --fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512 - args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024", state.VirtioFSPath())) + args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024,announce_submounts", state.VirtioFSPath())) for _, vol := range vm.Spec.AdditionalVolumes { status, ok := vm.Status.Volumes[vol.ID] From 7b983a3de4e0f9ee2a256890c1f67a7c5519cc45 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Tue, 15 Oct 2024 22:05:56 -0400 Subject: [PATCH 06/35] set more params to hopfully fix --- infrastructure/microvm/cloudhypervisor/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 9e4f0d9d..707c2edf 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -144,7 +144,7 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) // --fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512 - args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024,announce_submounts", state.VirtioFSPath())) + args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024,announce_submounts,allow_root", state.VirtioFSPath())) for _, vol := range vm.Spec.AdditionalVolumes { status, ok := vm.Status.Volumes[vol.ID] From 70a942cad4c4cb5f0631fd75548f6532465f7870 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Tue, 15 Oct 2024 22:58:11 -0400 Subject: [PATCH 07/35] remove xattr and adding announce --- infrastructure/microvm/cloudhypervisor/create.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 707c2edf..81a15338 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -59,7 +59,7 @@ func (p *provider) startCloudHypervisor(_ context.Context, cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", "--socket-path="+state.VirtioFSPath(), - "-o", "source=/mnt/user,cache=none,sandbox=chroot,xattr") + "-o", "source=/mnt/user,cache=always,sandbox=chroot,announce_submounts") stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) @@ -144,7 +144,8 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) // --fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512 - args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024,announce_submounts,allow_root", state.VirtioFSPath())) + args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024", state.VirtioFSPath())) + for _, vol := range vm.Spec.AdditionalVolumes { status, ok := vm.Status.Volumes[vol.ID] From b2d6f3f0c8d68db237d3148092d6f2bbaa4b8aef Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Mon, 23 Dec 2024 13:49:50 -0500 Subject: [PATCH 08/35] adding deletion --- .../microvm/cloudhypervisor/create.go | 49 ++++++++++++++++++- .../microvm/cloudhypervisor/delete.go | 18 ++++++- .../microvm/cloudhypervisor/state.go | 17 +++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 81a15338..815763f1 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -36,6 +36,14 @@ func (p *provider) Create(ctx context.Context, vm *models.MicroVM) error { return fmt.Errorf("creating metadata image: %w", err) } + procVFS, err := p.startVirtioFS(ctx, vm, vmState, logger) + if err != nil { + return fmt.Errorf("starting virtiofs process: %w", err) + } + if err = vmState.SetVirtioFSPid(procVFS.Pid); err != nil { + return fmt.Errorf("saving pid %d to file: %w", procVFS.Pid, err) + } + proc, err := p.startCloudHypervisor(ctx, vm, vmState, p.config.RunDetached, logger) if err != nil { return fmt.Errorf("starting cloudhypervisor process: %w", err) @@ -48,6 +56,44 @@ func (p *provider) Create(ctx context.Context, vm *models.MicroVM) error { return nil } +func (p *provider) startVirtioFS(_ context.Context, + vm *models.MicroVM, + state State, + logger *logrus.Entry, +) (*os.Process, error) { + + logger.Debugf("creating virtiofsd") + + cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", + "--socket-path="+state.VirtioFSPath(), + "--thread-pool-size=32", + "-o", "source=/mnt/user,cache=none,sandbox=chroot,announce_submounts,allow_direct_io") + stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) + } + + stdErrFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening sterr file %s: %w", state.VirtioFSStderrPath(), err) + } + + cmdVirtioFS.Stderr = stdErrFileVirtioFS + cmdVirtioFS.Stdout = stdOutFileVirtioFS + cmdVirtioFS.Stdin = &bytes.Buffer{} + + var startErr error + process.DetachedStart(cmdVirtioFS) + + if startErr != nil { + return nil, fmt.Errorf("starting virtiofsd process: %w", err) + } + return cmdVirtioFS.Process, nil +} + + + + func (p *provider) startCloudHypervisor(_ context.Context, vm *models.MicroVM, state State, @@ -59,7 +105,8 @@ func (p *provider) startCloudHypervisor(_ context.Context, cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", "--socket-path="+state.VirtioFSPath(), - "-o", "source=/mnt/user,cache=always,sandbox=chroot,announce_submounts") + "--thread-pool-size=32", + "-o", "source=/mnt/user,cache=none,sandbox=chroot,announce_submounts,allow_direct_io") stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) diff --git a/infrastructure/microvm/cloudhypervisor/delete.go b/infrastructure/microvm/cloudhypervisor/delete.go index 0f10a7c5..c76b2c3e 100644 --- a/infrastructure/microvm/cloudhypervisor/delete.go +++ b/infrastructure/microvm/cloudhypervisor/delete.go @@ -87,7 +87,23 @@ func (p *provider) Delete(ctx context.Context, id string) error { return fmt.Errorf("failed to wait for pid %d: %w", pid, err) } - logger.Info("deleted microvm") + pidVirtiofs, pidVirtiofsErr := vmState.PID() + if pidVirtiofsErr != nil { + return fmt.Errorf("unable to get VirtioFS PID: %w", pidVirtiofsErr) + } + processVirtioFSExists, err := process.Exists(pidVirtiofs) + if err != nil { + return fmt.Errorf("checking if VirtioFS process is running: %w", err) + } + if !processVirtioFSExists { + logger.Debugf("virtiofsd is not used") + logger.Info("deleted microvm") + return nil + } + logger.Debugf("sending SIGTERM to %d virtiofsd", pid) + if sigErr := process.SendSignal(pid, syscall.SIGTERM); sigErr != nil { + return fmt.Errorf("failed to terminate with SIGTERM: %w", sigErr) + } return nil } diff --git a/infrastructure/microvm/cloudhypervisor/state.go b/infrastructure/microvm/cloudhypervisor/state.go index ccb5f7f0..2dcfa37e 100644 --- a/infrastructure/microvm/cloudhypervisor/state.go +++ b/infrastructure/microvm/cloudhypervisor/state.go @@ -14,6 +14,7 @@ const ( logFileName = "cloudhypervisor.log" stdOutFileName = "cloudhypervisor.stdout" stdErrFileName = "cloudhypervisor.stderr" + pidVirtioFSFileName = "virtiofs.pid" stdErrVirtioFSFileName = "virtiofs.stderr" stdOutVirtioFSFileName = "virtiofs.stdout" socketVirtiofsFileName = "virtiofs.sock" @@ -33,6 +34,10 @@ type State interface { StderrPath() string SockPath() string + VirtioPID() (int, error) + VirtioFSPIDPath() string + SetVirtioFSPid(pid int) error + VirtioFSPath() string VirtioFSStdoutPath() string VirtioFSStderrPath() string @@ -98,4 +103,16 @@ func (s *fsState) VirtioFSStdoutPath() string { func (s *fsState) VirtioFSStderrPath() string { return fmt.Sprintf("%s/%s", s.stateRoot, stdErrVirtioFSFileName) +} + +func (s *fsState) VirtioFSPIDPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, pidVirtioFSFileName) +} + +func (s *fsState) VirtioPID() (int, error) { + return shared.PIDReadFromFile(s.VirtioFSPIDPath(), s.fs) +} + +func (s *fsState) SetVirtioFSPid(pid int) error { + return shared.PIDWriteToFile(pid, s.VirtioFSPIDPath(), s.fs) } \ No newline at end of file From ccc011da03742c40172de435177ae031d5999ad0 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Mon, 23 Dec 2024 13:57:41 -0500 Subject: [PATCH 09/35] remove virtiofs exit condition --- .../microvm/cloudhypervisor/delete.go | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/delete.go b/infrastructure/microvm/cloudhypervisor/delete.go index c76b2c3e..710fadc7 100644 --- a/infrastructure/microvm/cloudhypervisor/delete.go +++ b/infrastructure/microvm/cloudhypervisor/delete.go @@ -86,24 +86,8 @@ func (p *provider) Delete(ctx context.Context, id string) error { if err := process.WaitWithContext(ctxTimeout, pid); err != nil { return fmt.Errorf("failed to wait for pid %d: %w", pid, err) } - - pidVirtiofs, pidVirtiofsErr := vmState.PID() - if pidVirtiofsErr != nil { - return fmt.Errorf("unable to get VirtioFS PID: %w", pidVirtiofsErr) - } - processVirtioFSExists, err := process.Exists(pidVirtiofs) - if err != nil { - return fmt.Errorf("checking if VirtioFS process is running: %w", err) - } - if !processVirtioFSExists { - logger.Debugf("virtiofsd is not used") - logger.Info("deleted microvm") - return nil - } - logger.Debugf("sending SIGTERM to %d virtiofsd", pid) - if sigErr := process.SendSignal(pid, syscall.SIGTERM); sigErr != nil { - return fmt.Errorf("failed to terminate with SIGTERM: %w", sigErr) - } + + logger.Info("deleted microvm") return nil } From 5296f93ef32b52905169e59127fa430d558d7a22 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Mon, 23 Dec 2024 14:42:31 -0500 Subject: [PATCH 10/35] adding virtiofsd bin arg --- .../microvm/cloudhypervisor/create.go | 27 +------------------ .../microvm/cloudhypervisor/provider.go | 2 ++ infrastructure/microvm/providers.go | 1 + internal/command/flags/flags.go | 5 ++++ internal/config/config.go | 2 ++ pkg/defaults/defaults.go | 3 +++ 6 files changed, 14 insertions(+), 26 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 815763f1..994ae879 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -64,7 +64,7 @@ func (p *provider) startVirtioFS(_ context.Context, logger.Debugf("creating virtiofsd") - cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", + cmdVirtioFS := exec.Command(p.config.VirtioFSBin, "--socket-path="+state.VirtioFSPath(), "--thread-pool-size=32", "-o", "source=/mnt/user,cache=none,sandbox=chroot,announce_submounts,allow_direct_io") @@ -101,31 +101,7 @@ func (p *provider) startCloudHypervisor(_ context.Context, logger *logrus.Entry, ) (*os.Process, error) { - logger.Debugf("creating virtiofsd") - - cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", - "--socket-path="+state.VirtioFSPath(), - "--thread-pool-size=32", - "-o", "source=/mnt/user,cache=none,sandbox=chroot,announce_submounts,allow_direct_io") - stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) - if err != nil { - return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) - } - - stdErrFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) - if err != nil { - return nil, fmt.Errorf("opening sterr file %s: %w", state.VirtioFSStderrPath(), err) - } - - cmdVirtioFS.Stderr = stdErrFileVirtioFS - cmdVirtioFS.Stdout = stdOutFileVirtioFS - cmdVirtioFS.Stdin = &bytes.Buffer{} - var startErr error - startErr = cmdVirtioFS.Start() - if startErr != nil { - return nil, fmt.Errorf("starting virtiofsd process: %w", err) - } args, err := p.buildArgs(vm, state, logger) if err != nil { @@ -190,7 +166,6 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( } args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) - // --fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512 args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024", state.VirtioFSPath())) diff --git a/infrastructure/microvm/cloudhypervisor/provider.go b/infrastructure/microvm/cloudhypervisor/provider.go index 95abe7c4..dc8e5959 100644 --- a/infrastructure/microvm/cloudhypervisor/provider.go +++ b/infrastructure/microvm/cloudhypervisor/provider.go @@ -26,6 +26,8 @@ const ( type Config struct { // CloudHypervisorBin is the Cloud Hypervisor binary to use. CloudHypervisorBin string + // VirtioFSBin is the virtiofs binary to use. + VirtioFSBin string // StateRoot is the folder to store any required state (i.e. socks, pid, log files). StateRoot string // RunDetached indicates that the cloud hypervisor processes diff --git a/infrastructure/microvm/providers.go b/infrastructure/microvm/providers.go index 0f7d3af0..4d69c447 100644 --- a/infrastructure/microvm/providers.go +++ b/infrastructure/microvm/providers.go @@ -70,6 +70,7 @@ func firecrackerConfig(cfg *config.Config) *firecracker.Config { func cloudHypervisorConfig(cfg *config.Config) *cloudhypervisor.Config { return &cloudhypervisor.Config{ CloudHypervisorBin: cfg.CloudHypervisorBin, + VirtioFSBin: cfg.VirtioFSBin, RunDetached: cfg.CloudHypervisorDetatch, StateRoot: cfg.StateRootDir + "/vm", } diff --git a/internal/command/flags/flags.go b/internal/command/flags/flags.go index 8e56e6f2..80da8153 100644 --- a/internal/command/flags/flags.go +++ b/internal/command/flags/flags.go @@ -31,6 +31,7 @@ const ( tlsClientCAFlag = "tls-client-ca" debugEndpointFlag = "debug-endpoint" cloudHypervisorBinFlag = "cloudhypervisor-bin" + virtioFSBinFlag = "virtiofs-bin" cloudHypervisorDetachFlag = "cloudhypervisor-detach" ) @@ -203,6 +204,10 @@ func addCloudHypervisorFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { cloudHypervisorBinFlag, defaults.CloudHypervisorBin, "The path to the cloud hypervisor binary to use.") + cmd.Flags().StringVar(&cfg.VirtioFSBin, + virtioFSBinFlag, + defaults.VirtioFSBin, + "The path to the virtiofs binary to use.") cmd.Flags().BoolVar(&cfg.CloudHypervisorDetatch, cloudHypervisorDetachFlag, defaults.CloudHypervisorDetach, diff --git a/internal/config/config.go b/internal/config/config.go index 5d281b3d..9cdcc8e8 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -24,6 +24,8 @@ type Config struct { FirecrackerDetatch bool // CloudHypervisorBin is the Cloud Hypervisor binary to use. CloudHypervisorBin string + // VirtioFSBin is the VirtioFS binary to use. + VirtioFSBin string // CloudHypervisorDetatch indicates if the child cloud hypervisor processes should be detached from their parent. CloudHypervisorDetatch bool // StateRootDir is the directory to act as the root for the runtime state of flintlock. diff --git a/pkg/defaults/defaults.go b/pkg/defaults/defaults.go index 834e68b3..d779ade1 100644 --- a/pkg/defaults/defaults.go +++ b/pkg/defaults/defaults.go @@ -29,6 +29,9 @@ const ( // CloudHypervisorBin is the name of the Cloud Hypervisor binary. CloudHypervisorBin = "cloud-hypervisor-static" + + // VirtioFSBin is the name of the virtiofsd binary. + VirtioFSBin = "/usr/libexec/virtiofsd" // CloudHypervisorDetach is the default for the flag to indicates with the child cloud-hypervisor // processes should be run detached. From 7afe90eac478fa33f5c450aedbdf83a27510c35d Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 07:38:02 -0500 Subject: [PATCH 11/35] adding proto --- api/types/microvm.proto | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/types/microvm.proto b/api/types/microvm.proto index ab13ec4d..df13fe0a 100644 --- a/api/types/microvm.proto +++ b/api/types/microvm.proto @@ -151,9 +151,19 @@ message Volume { message VolumeSource { // Container is used to specify a source of a volume as a OCI container. optional string container_source = 1; + + optional string virtiofs_source = 2; + //TODO: add CSI } +// VirtioFSVolumeSource represents the details of a volume coming from a OCI image. +message VirtioFSVolumeSource { + // Path on the host machine to pass through. + string path = 1; +} + + // ContainerVolumeSource represents the details of a volume coming from a OCI image. message ContainerVolumeSource { // Image specifies the conatiner image to use for the volume. From d46a0499b426a850edfb8064e793ead8aceeed1c Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 07:50:40 -0500 Subject: [PATCH 12/35] updating go version for gen --- api/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/go.mod b/api/go.mod index 0e187c05..9b63073c 100644 --- a/api/go.mod +++ b/api/go.mod @@ -1,6 +1,6 @@ module github.com/liquidmetal-dev/flintlock/api -go 1.17 +go 1.18 require ( github.com/containerd/typeurl/v2 v2.1.0 From 02a66889766f7033ae09faeb0c7571e9a128f2bd Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 09:00:48 -0500 Subject: [PATCH 13/35] adding generation and vol convertion --- api/services/microvm/v1alpha1/microvms.pb.go | 184 +---- .../microvm/v1alpha1/microvms.pb.gw.go | 3 +- .../microvm/v1alpha1/microvms.swagger.json | 5 +- .../microvm/v1alpha1/microvms_grpc.pb.go | 106 +-- api/types/microvm.pb.go | 633 +++++++----------- buf.lock | 4 +- core/models/volumes.go | 9 + infrastructure/grpc/convert.go | 5 + infrastructure/mock/containerd.go | 2 +- infrastructure/mock/ext_containerd.go | 2 +- internal/inject/wire_gen.go | 3 +- .../grpc/services/microvm/v1alpha1/proto.md | 68 +- userdocs/docs/grpc/types/proto.md | 165 ++--- 13 files changed, 490 insertions(+), 699 deletions(-) diff --git a/api/services/microvm/v1alpha1/microvms.pb.go b/api/services/microvm/v1alpha1/microvms.pb.go index dabb1f78..3f210c3b 100644 --- a/api/services/microvm/v1alpha1/microvms.pb.go +++ b/api/services/microvm/v1alpha1/microvms.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.35.1 // protoc (unknown) // source: services/microvm/v1alpha1/microvms.proto @@ -37,11 +37,9 @@ type CreateMicroVMRequest struct { func (x *CreateMicroVMRequest) Reset() { *x = CreateMicroVMRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateMicroVMRequest) String() string { @@ -52,7 +50,7 @@ func (*CreateMicroVMRequest) ProtoMessage() {} func (x *CreateMicroVMRequest) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -91,11 +89,9 @@ type CreateMicroVMResponse struct { func (x *CreateMicroVMResponse) Reset() { *x = CreateMicroVMResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateMicroVMResponse) String() string { @@ -106,7 +102,7 @@ func (*CreateMicroVMResponse) ProtoMessage() {} func (x *CreateMicroVMResponse) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -138,11 +134,9 @@ type DeleteMicroVMRequest struct { func (x *DeleteMicroVMRequest) Reset() { *x = DeleteMicroVMRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeleteMicroVMRequest) String() string { @@ -153,7 +147,7 @@ func (*DeleteMicroVMRequest) ProtoMessage() {} func (x *DeleteMicroVMRequest) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -185,11 +179,9 @@ type GetMicroVMRequest struct { func (x *GetMicroVMRequest) Reset() { *x = GetMicroVMRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GetMicroVMRequest) String() string { @@ -200,7 +192,7 @@ func (*GetMicroVMRequest) ProtoMessage() {} func (x *GetMicroVMRequest) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -232,11 +224,9 @@ type GetMicroVMResponse struct { func (x *GetMicroVMResponse) Reset() { *x = GetMicroVMResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GetMicroVMResponse) String() string { @@ -247,7 +237,7 @@ func (*GetMicroVMResponse) ProtoMessage() {} func (x *GetMicroVMResponse) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -280,11 +270,9 @@ type ListMicroVMsRequest struct { func (x *ListMicroVMsRequest) Reset() { *x = ListMicroVMsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListMicroVMsRequest) String() string { @@ -295,7 +283,7 @@ func (*ListMicroVMsRequest) ProtoMessage() {} func (x *ListMicroVMsRequest) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -334,11 +322,9 @@ type ListMicroVMsResponse struct { func (x *ListMicroVMsResponse) Reset() { *x = ListMicroVMsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListMicroVMsResponse) String() string { @@ -349,7 +335,7 @@ func (*ListMicroVMsResponse) ProtoMessage() {} func (x *ListMicroVMsResponse) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -381,11 +367,9 @@ type ListMessage struct { func (x *ListMessage) Reset() { *x = ListMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListMessage) String() string { @@ -396,7 +380,7 @@ func (*ListMessage) ProtoMessage() {} func (x *ListMessage) ProtoReflect() protoreflect.Message { mi := &file_services_microvm_v1alpha1_microvms_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -558,7 +542,7 @@ func file_services_microvm_v1alpha1_microvms_proto_rawDescGZIP() []byte { } var file_services_microvm_v1alpha1_microvms_proto_msgTypes = make([]protoimpl.MessageInfo, 9) -var file_services_microvm_v1alpha1_microvms_proto_goTypes = []interface{}{ +var file_services_microvm_v1alpha1_microvms_proto_goTypes = []any{ (*CreateMicroVMRequest)(nil), // 0: microvm.services.api.v1alpha1.CreateMicroVMRequest (*CreateMicroVMResponse)(nil), // 1: microvm.services.api.v1alpha1.CreateMicroVMResponse (*DeleteMicroVMRequest)(nil), // 2: microvm.services.api.v1alpha1.DeleteMicroVMRequest @@ -603,105 +587,7 @@ func file_services_microvm_v1alpha1_microvms_proto_init() { if File_services_microvm_v1alpha1_microvms_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_services_microvm_v1alpha1_microvms_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMicroVMRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMicroVMResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteMicroVMRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetMicroVMRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetMicroVMResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMicroVMsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMicroVMsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_services_microvm_v1alpha1_microvms_proto_msgTypes[5].OneofWrappers = []interface{}{} + file_services_microvm_v1alpha1_microvms_proto_msgTypes[5].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/services/microvm/v1alpha1/microvms.pb.gw.go b/api/services/microvm/v1alpha1/microvms.pb.gw.go index d513b279..5065ea54 100644 --- a/api/services/microvm/v1alpha1/microvms.pb.gw.go +++ b/api/services/microvm/v1alpha1/microvms.pb.gw.go @@ -274,6 +274,7 @@ func request_MicroVM_ListMicroVMsStream_0(ctx context.Context, marshaler runtime // UnaryRPC :call MicroVMServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMicroVMHandlerFromEndpoint instead. +// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterMicroVMHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MicroVMServer) error { mux.Handle("POST", pattern_MicroVM_CreateMicroVM_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { @@ -421,7 +422,7 @@ func RegisterMicroVMHandler(ctx context.Context, mux *runtime.ServeMux, conn *gr // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MicroVMClient". // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MicroVMClient" // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "MicroVMClient" to call the correct interceptors. +// "MicroVMClient" to call the correct interceptors. This client ignores the HTTP middlewares. func RegisterMicroVMHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MicroVMClient) error { mux.Handle("POST", pattern_MicroVM_CreateMicroVM_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { diff --git a/api/services/microvm/v1alpha1/microvms.swagger.json b/api/services/microvm/v1alpha1/microvms.swagger.json index 5e1d45c4..8190675f 100644 --- a/api/services/microvm/v1alpha1/microvms.swagger.json +++ b/api/services/microvm/v1alpha1/microvms.swagger.json @@ -516,7 +516,10 @@ "properties": { "containerSource": { "type": "string", - "description": "Container is used to specify a source of a volume as a OCI container.\n\nTODO: add CSI" + "description": "Container is used to specify a source of a volume as a OCI container." + }, + "virtiofsSource": { + "type": "string" } }, "description": "VolumeSource is the source of a volume. Based loosely on the volumes in Kubernetes Pod specs." diff --git a/api/services/microvm/v1alpha1/microvms_grpc.pb.go b/api/services/microvm/v1alpha1/microvms_grpc.pb.go index bb7e8697..cc3378dc 100644 --- a/api/services/microvm/v1alpha1/microvms_grpc.pb.go +++ b/api/services/microvm/v1alpha1/microvms_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: services/microvm/v1alpha1/microvms.proto package v1alpha1 @@ -12,18 +16,28 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + MicroVM_CreateMicroVM_FullMethodName = "/microvm.services.api.v1alpha1.MicroVM/CreateMicroVM" + MicroVM_DeleteMicroVM_FullMethodName = "/microvm.services.api.v1alpha1.MicroVM/DeleteMicroVM" + MicroVM_GetMicroVM_FullMethodName = "/microvm.services.api.v1alpha1.MicroVM/GetMicroVM" + MicroVM_ListMicroVMs_FullMethodName = "/microvm.services.api.v1alpha1.MicroVM/ListMicroVMs" + MicroVM_ListMicroVMsStream_FullMethodName = "/microvm.services.api.v1alpha1.MicroVM/ListMicroVMsStream" +) // MicroVMClient is the client API for MicroVM service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// MicroVM providers a service to create and manage the lifecycle of microvms. type MicroVMClient interface { CreateMicroVM(ctx context.Context, in *CreateMicroVMRequest, opts ...grpc.CallOption) (*CreateMicroVMResponse, error) DeleteMicroVM(ctx context.Context, in *DeleteMicroVMRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) GetMicroVM(ctx context.Context, in *GetMicroVMRequest, opts ...grpc.CallOption) (*GetMicroVMResponse, error) ListMicroVMs(ctx context.Context, in *ListMicroVMsRequest, opts ...grpc.CallOption) (*ListMicroVMsResponse, error) - ListMicroVMsStream(ctx context.Context, in *ListMicroVMsRequest, opts ...grpc.CallOption) (MicroVM_ListMicroVMsStreamClient, error) + ListMicroVMsStream(ctx context.Context, in *ListMicroVMsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ListMessage], error) } type microVMClient struct { @@ -35,8 +49,9 @@ func NewMicroVMClient(cc grpc.ClientConnInterface) MicroVMClient { } func (c *microVMClient) CreateMicroVM(ctx context.Context, in *CreateMicroVMRequest, opts ...grpc.CallOption) (*CreateMicroVMResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateMicroVMResponse) - err := c.cc.Invoke(ctx, "/microvm.services.api.v1alpha1.MicroVM/CreateMicroVM", in, out, opts...) + err := c.cc.Invoke(ctx, MicroVM_CreateMicroVM_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -44,8 +59,9 @@ func (c *microVMClient) CreateMicroVM(ctx context.Context, in *CreateMicroVMRequ } func (c *microVMClient) DeleteMicroVM(ctx context.Context, in *DeleteMicroVMRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/microvm.services.api.v1alpha1.MicroVM/DeleteMicroVM", in, out, opts...) + err := c.cc.Invoke(ctx, MicroVM_DeleteMicroVM_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -53,8 +69,9 @@ func (c *microVMClient) DeleteMicroVM(ctx context.Context, in *DeleteMicroVMRequ } func (c *microVMClient) GetMicroVM(ctx context.Context, in *GetMicroVMRequest, opts ...grpc.CallOption) (*GetMicroVMResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(GetMicroVMResponse) - err := c.cc.Invoke(ctx, "/microvm.services.api.v1alpha1.MicroVM/GetMicroVM", in, out, opts...) + err := c.cc.Invoke(ctx, MicroVM_GetMicroVM_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -62,20 +79,22 @@ func (c *microVMClient) GetMicroVM(ctx context.Context, in *GetMicroVMRequest, o } func (c *microVMClient) ListMicroVMs(ctx context.Context, in *ListMicroVMsRequest, opts ...grpc.CallOption) (*ListMicroVMsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListMicroVMsResponse) - err := c.cc.Invoke(ctx, "/microvm.services.api.v1alpha1.MicroVM/ListMicroVMs", in, out, opts...) + err := c.cc.Invoke(ctx, MicroVM_ListMicroVMs_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *microVMClient) ListMicroVMsStream(ctx context.Context, in *ListMicroVMsRequest, opts ...grpc.CallOption) (MicroVM_ListMicroVMsStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &MicroVM_ServiceDesc.Streams[0], "/microvm.services.api.v1alpha1.MicroVM/ListMicroVMsStream", opts...) +func (c *microVMClient) ListMicroVMsStream(ctx context.Context, in *ListMicroVMsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ListMessage], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &MicroVM_ServiceDesc.Streams[0], MicroVM_ListMicroVMsStream_FullMethodName, cOpts...) if err != nil { return nil, err } - x := µVMListMicroVMsStreamClient{stream} + x := &grpc.GenericClientStream[ListMicroVMsRequest, ListMessage]{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -85,37 +104,28 @@ func (c *microVMClient) ListMicroVMsStream(ctx context.Context, in *ListMicroVMs return x, nil } -type MicroVM_ListMicroVMsStreamClient interface { - Recv() (*ListMessage, error) - grpc.ClientStream -} - -type microVMListMicroVMsStreamClient struct { - grpc.ClientStream -} - -func (x *microVMListMicroVMsStreamClient) Recv() (*ListMessage, error) { - m := new(ListMessage) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type MicroVM_ListMicroVMsStreamClient = grpc.ServerStreamingClient[ListMessage] // MicroVMServer is the server API for MicroVM service. // All implementations should embed UnimplementedMicroVMServer -// for forward compatibility +// for forward compatibility. +// +// MicroVM providers a service to create and manage the lifecycle of microvms. type MicroVMServer interface { CreateMicroVM(context.Context, *CreateMicroVMRequest) (*CreateMicroVMResponse, error) DeleteMicroVM(context.Context, *DeleteMicroVMRequest) (*emptypb.Empty, error) GetMicroVM(context.Context, *GetMicroVMRequest) (*GetMicroVMResponse, error) ListMicroVMs(context.Context, *ListMicroVMsRequest) (*ListMicroVMsResponse, error) - ListMicroVMsStream(*ListMicroVMsRequest, MicroVM_ListMicroVMsStreamServer) error + ListMicroVMsStream(*ListMicroVMsRequest, grpc.ServerStreamingServer[ListMessage]) error } -// UnimplementedMicroVMServer should be embedded to have forward compatible implementations. -type UnimplementedMicroVMServer struct { -} +// UnimplementedMicroVMServer should be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedMicroVMServer struct{} func (UnimplementedMicroVMServer) CreateMicroVM(context.Context, *CreateMicroVMRequest) (*CreateMicroVMResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateMicroVM not implemented") @@ -129,9 +139,10 @@ func (UnimplementedMicroVMServer) GetMicroVM(context.Context, *GetMicroVMRequest func (UnimplementedMicroVMServer) ListMicroVMs(context.Context, *ListMicroVMsRequest) (*ListMicroVMsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListMicroVMs not implemented") } -func (UnimplementedMicroVMServer) ListMicroVMsStream(*ListMicroVMsRequest, MicroVM_ListMicroVMsStreamServer) error { +func (UnimplementedMicroVMServer) ListMicroVMsStream(*ListMicroVMsRequest, grpc.ServerStreamingServer[ListMessage]) error { return status.Errorf(codes.Unimplemented, "method ListMicroVMsStream not implemented") } +func (UnimplementedMicroVMServer) testEmbeddedByValue() {} // UnsafeMicroVMServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to MicroVMServer will @@ -141,6 +152,13 @@ type UnsafeMicroVMServer interface { } func RegisterMicroVMServer(s grpc.ServiceRegistrar, srv MicroVMServer) { + // If the following call pancis, it indicates UnimplementedMicroVMServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&MicroVM_ServiceDesc, srv) } @@ -154,7 +172,7 @@ func _MicroVM_CreateMicroVM_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/microvm.services.api.v1alpha1.MicroVM/CreateMicroVM", + FullMethod: MicroVM_CreateMicroVM_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MicroVMServer).CreateMicroVM(ctx, req.(*CreateMicroVMRequest)) @@ -172,7 +190,7 @@ func _MicroVM_DeleteMicroVM_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/microvm.services.api.v1alpha1.MicroVM/DeleteMicroVM", + FullMethod: MicroVM_DeleteMicroVM_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MicroVMServer).DeleteMicroVM(ctx, req.(*DeleteMicroVMRequest)) @@ -190,7 +208,7 @@ func _MicroVM_GetMicroVM_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/microvm.services.api.v1alpha1.MicroVM/GetMicroVM", + FullMethod: MicroVM_GetMicroVM_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MicroVMServer).GetMicroVM(ctx, req.(*GetMicroVMRequest)) @@ -208,7 +226,7 @@ func _MicroVM_ListMicroVMs_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/microvm.services.api.v1alpha1.MicroVM/ListMicroVMs", + FullMethod: MicroVM_ListMicroVMs_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MicroVMServer).ListMicroVMs(ctx, req.(*ListMicroVMsRequest)) @@ -221,21 +239,11 @@ func _MicroVM_ListMicroVMsStream_Handler(srv interface{}, stream grpc.ServerStre if err := stream.RecvMsg(m); err != nil { return err } - return srv.(MicroVMServer).ListMicroVMsStream(m, µVMListMicroVMsStreamServer{stream}) + return srv.(MicroVMServer).ListMicroVMsStream(m, &grpc.GenericServerStream[ListMicroVMsRequest, ListMessage]{ServerStream: stream}) } -type MicroVM_ListMicroVMsStreamServer interface { - Send(*ListMessage) error - grpc.ServerStream -} - -type microVMListMicroVMsStreamServer struct { - grpc.ServerStream -} - -func (x *microVMListMicroVMsStreamServer) Send(m *ListMessage) error { - return x.ServerStream.SendMsg(m) -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type MicroVM_ListMicroVMsStreamServer = grpc.ServerStreamingServer[ListMessage] // MicroVM_ServiceDesc is the grpc.ServiceDesc for MicroVM service. // It's only intended for direct use with grpc.RegisterService, diff --git a/api/types/microvm.pb.go b/api/types/microvm.pb.go index 7a3210db..bed809af 100644 --- a/api/types/microvm.pb.go +++ b/api/types/microvm.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.35.1 // protoc (unknown) // source: types/microvm.proto @@ -118,7 +118,7 @@ func (x MicroVMStatus_MicroVMState) Number() protoreflect.EnumNumber { // Deprecated: Use MicroVMStatus_MicroVMState.Descriptor instead. func (MicroVMStatus_MicroVMState) EnumDescriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{9, 0} + return file_types_microvm_proto_rawDescGZIP(), []int{10, 0} } type Mount_MountType int32 @@ -164,7 +164,7 @@ func (x Mount_MountType) Number() protoreflect.EnumNumber { // Deprecated: Use Mount_MountType.Descriptor instead. func (Mount_MountType) EnumDescriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{11, 0} + return file_types_microvm_proto_rawDescGZIP(), []int{12, 0} } // MicroVM represents a microvm machine that is created via a provider. @@ -182,11 +182,9 @@ type MicroVM struct { func (x *MicroVM) Reset() { *x = MicroVM{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MicroVM) String() string { @@ -197,7 +195,7 @@ func (*MicroVM) ProtoMessage() {} func (x *MicroVM) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -280,11 +278,9 @@ type MicroVMSpec struct { func (x *MicroVMSpec) Reset() { *x = MicroVMSpec{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MicroVMSpec) String() string { @@ -295,7 +291,7 @@ func (*MicroVMSpec) ProtoMessage() {} func (x *MicroVMSpec) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -443,11 +439,9 @@ type Kernel struct { func (x *Kernel) Reset() { *x = Kernel{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Kernel) String() string { @@ -458,7 +452,7 @@ func (*Kernel) ProtoMessage() {} func (x *Kernel) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -516,11 +510,9 @@ type Initrd struct { func (x *Initrd) Reset() { *x = Initrd{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Initrd) String() string { @@ -531,7 +523,7 @@ func (*Initrd) ProtoMessage() {} func (x *Initrd) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -582,11 +574,9 @@ type NetworkInterface struct { func (x *NetworkInterface) Reset() { *x = NetworkInterface{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NetworkInterface) String() string { @@ -597,7 +587,7 @@ func (*NetworkInterface) ProtoMessage() {} func (x *NetworkInterface) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -664,11 +654,9 @@ type StaticAddress struct { func (x *StaticAddress) Reset() { *x = StaticAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StaticAddress) String() string { @@ -679,7 +667,7 @@ func (*StaticAddress) ProtoMessage() {} func (x *StaticAddress) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -738,11 +726,9 @@ type Volume struct { func (x *Volume) Reset() { *x = Volume{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Volume) String() string { @@ -753,7 +739,7 @@ func (*Volume) ProtoMessage() {} func (x *Volume) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -817,16 +803,15 @@ type VolumeSource struct { unknownFields protoimpl.UnknownFields // Container is used to specify a source of a volume as a OCI container. - ContainerSource *string `protobuf:"bytes,1,opt,name=container_source,json=containerSource,proto3,oneof" json:"container_source,omitempty"` //TODO: add CSI + ContainerSource *string `protobuf:"bytes,1,opt,name=container_source,json=containerSource,proto3,oneof" json:"container_source,omitempty"` + VirtiofsSource *string `protobuf:"bytes,2,opt,name=virtiofs_source,json=virtiofsSource,proto3,oneof" json:"virtiofs_source,omitempty"` } func (x *VolumeSource) Reset() { *x = VolumeSource{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VolumeSource) String() string { @@ -837,7 +822,7 @@ func (*VolumeSource) ProtoMessage() {} func (x *VolumeSource) ProtoReflect() protoreflect.Message { mi := &file_types_microvm_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -859,6 +844,60 @@ func (x *VolumeSource) GetContainerSource() string { return "" } +func (x *VolumeSource) GetVirtiofsSource() string { + if x != nil && x.VirtiofsSource != nil { + return *x.VirtiofsSource + } + return "" +} + +// VirtioFSVolumeSource represents the details of a volume coming from a OCI image. +type VirtioFSVolumeSource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path on the host machine to pass through. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *VirtioFSVolumeSource) Reset() { + *x = VirtioFSVolumeSource{} + mi := &file_types_microvm_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VirtioFSVolumeSource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VirtioFSVolumeSource) ProtoMessage() {} + +func (x *VirtioFSVolumeSource) ProtoReflect() protoreflect.Message { + mi := &file_types_microvm_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VirtioFSVolumeSource.ProtoReflect.Descriptor instead. +func (*VirtioFSVolumeSource) Descriptor() ([]byte, []int) { + return file_types_microvm_proto_rawDescGZIP(), []int{8} +} + +func (x *VirtioFSVolumeSource) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + // ContainerVolumeSource represents the details of a volume coming from a OCI image. type ContainerVolumeSource struct { state protoimpl.MessageState @@ -871,11 +910,9 @@ type ContainerVolumeSource struct { func (x *ContainerVolumeSource) Reset() { *x = ContainerVolumeSource{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ContainerVolumeSource) String() string { @@ -885,8 +922,8 @@ func (x *ContainerVolumeSource) String() string { func (*ContainerVolumeSource) ProtoMessage() {} func (x *ContainerVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_types_microvm_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_types_microvm_proto_msgTypes[9] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -898,7 +935,7 @@ func (x *ContainerVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerVolumeSource.ProtoReflect.Descriptor instead. func (*ContainerVolumeSource) Descriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{8} + return file_types_microvm_proto_rawDescGZIP(), []int{9} } func (x *ContainerVolumeSource) GetImage() string { @@ -930,11 +967,9 @@ type MicroVMStatus struct { func (x *MicroVMStatus) Reset() { *x = MicroVMStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MicroVMStatus) String() string { @@ -944,8 +979,8 @@ func (x *MicroVMStatus) String() string { func (*MicroVMStatus) ProtoMessage() {} func (x *MicroVMStatus) ProtoReflect() protoreflect.Message { - mi := &file_types_microvm_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_types_microvm_proto_msgTypes[10] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -957,7 +992,7 @@ func (x *MicroVMStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use MicroVMStatus.ProtoReflect.Descriptor instead. func (*MicroVMStatus) Descriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{9} + return file_types_microvm_proto_rawDescGZIP(), []int{10} } func (x *MicroVMStatus) GetState() MicroVMStatus_MicroVMState { @@ -1013,11 +1048,9 @@ type VolumeStatus struct { func (x *VolumeStatus) Reset() { *x = VolumeStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VolumeStatus) String() string { @@ -1027,8 +1060,8 @@ func (x *VolumeStatus) String() string { func (*VolumeStatus) ProtoMessage() {} func (x *VolumeStatus) ProtoReflect() protoreflect.Message { - mi := &file_types_microvm_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_types_microvm_proto_msgTypes[11] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1040,7 +1073,7 @@ func (x *VolumeStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeStatus.ProtoReflect.Descriptor instead. func (*VolumeStatus) Descriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{10} + return file_types_microvm_proto_rawDescGZIP(), []int{11} } func (x *VolumeStatus) GetMount() *Mount { @@ -1064,11 +1097,9 @@ type Mount struct { func (x *Mount) Reset() { *x = Mount{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Mount) String() string { @@ -1078,8 +1109,8 @@ func (x *Mount) String() string { func (*Mount) ProtoMessage() {} func (x *Mount) ProtoReflect() protoreflect.Message { - mi := &file_types_microvm_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_types_microvm_proto_msgTypes[12] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1091,7 +1122,7 @@ func (x *Mount) ProtoReflect() protoreflect.Message { // Deprecated: Use Mount.ProtoReflect.Descriptor instead. func (*Mount) Descriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{11} + return file_types_microvm_proto_rawDescGZIP(), []int{12} } func (x *Mount) GetType() Mount_MountType { @@ -1124,11 +1155,9 @@ type NetworkInterfaceStatus struct { func (x *NetworkInterfaceStatus) Reset() { *x = NetworkInterfaceStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NetworkInterfaceStatus) String() string { @@ -1138,8 +1167,8 @@ func (x *NetworkInterfaceStatus) String() string { func (*NetworkInterfaceStatus) ProtoMessage() {} func (x *NetworkInterfaceStatus) ProtoReflect() protoreflect.Message { - mi := &file_types_microvm_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_types_microvm_proto_msgTypes[13] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1151,7 +1180,7 @@ func (x *NetworkInterfaceStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkInterfaceStatus.ProtoReflect.Descriptor instead. func (*NetworkInterfaceStatus) Descriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{12} + return file_types_microvm_proto_rawDescGZIP(), []int{13} } func (x *NetworkInterfaceStatus) GetHostDeviceName() string { @@ -1188,11 +1217,9 @@ type NetworkOverrides struct { func (x *NetworkOverrides) Reset() { *x = NetworkOverrides{} - if protoimpl.UnsafeEnabled { - mi := &file_types_microvm_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_types_microvm_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NetworkOverrides) String() string { @@ -1202,8 +1229,8 @@ func (x *NetworkOverrides) String() string { func (*NetworkOverrides) ProtoMessage() {} func (x *NetworkOverrides) ProtoReflect() protoreflect.Message { - mi := &file_types_microvm_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_types_microvm_proto_msgTypes[14] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1215,7 +1242,7 @@ func (x *NetworkOverrides) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkOverrides.ProtoReflect.Descriptor instead. func (*NetworkOverrides) Descriptor() ([]byte, []int) { - return file_types_microvm_proto_rawDescGZIP(), []int{13} + return file_types_microvm_proto_rawDescGZIP(), []int{14} } func (x *NetworkOverrides) GetBridgeName() string { @@ -1367,85 +1394,92 @@ var file_types_microvm_proto_rawDesc = []byte{ 0x73, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x4d, 0x62, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x42, 0x0d, 0x0a, 0x0b, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x6d, 0x62, 0x22, 0x53, 0x0a, 0x0c, 0x56, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x10, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x88, 0x01, 0x01, 0x42, 0x13, 0x0a, 0x11, 0x5f, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x6d, 0x62, 0x22, 0x95, 0x01, 0x0a, 0x0c, + 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x2d, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x56, 0x6f, 0x6c, - 0x75, 0x6d, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, - 0x99, 0x05, 0x0a, 0x0d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2b, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x2e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0c, 0x6b, - 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x0b, 0x6b, 0x65, 0x72, 0x6e, 0x65, - 0x6c, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0c, 0x69, 0x6e, 0x69, 0x74, 0x72, 0x64, - 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x0f, + 0x76, 0x69, 0x72, 0x74, 0x69, 0x6f, 0x66, 0x73, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x69, 0x6f, 0x66, + 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x88, 0x01, 0x01, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, + 0x12, 0x0a, 0x10, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x69, 0x6f, 0x66, 0x73, 0x5f, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x56, 0x69, 0x72, 0x74, 0x69, 0x6f, 0x46, 0x53, 0x56, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, + 0x2d, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x56, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x99, + 0x05, 0x0a, 0x0d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x2b, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0c, 0x6b, 0x65, + 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x0b, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, + 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0c, 0x69, 0x6e, 0x69, 0x74, 0x72, 0x64, 0x5f, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x6c, + 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x72, 0x64, 0x4d, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x64, 0x0a, 0x12, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x72, 0x64, 0x4d, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x64, 0x0a, 0x12, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, + 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x11, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x65, 0x74, 0x72, 0x79, 0x1a, 0x59, 0x0a, 0x0c, + 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x4e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x74, 0x72, 0x79, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x65, 0x74, 0x72, 0x79, 0x1a, 0x59, 0x0a, - 0x0c, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, - 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6d, 0x0a, 0x16, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x42, 0x0a, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, - 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, - 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0c, 0x0a, - 0x08, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x22, 0x3c, 0x0a, 0x0c, 0x56, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x6c, 0x69, - 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x6f, 0x75, - 0x6e, 0x74, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x79, 0x0a, 0x05, 0x4d, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x22, 0x0a, 0x09, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, - 0x03, 0x44, 0x45, 0x56, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x48, 0x4f, 0x53, 0x54, 0x50, 0x41, - 0x54, 0x48, 0x10, 0x01, 0x22, 0x79, 0x0a, 0x16, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, - 0x0a, 0x10, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x68, 0x6f, 0x73, 0x74, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1f, - 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, - 0x48, 0x0a, 0x10, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, - 0x64, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0b, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x62, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x6d, 0x65, - 0x74, 0x61, 0x6c, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, - 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6d, 0x0a, 0x16, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x42, 0x0a, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x56, + 0x4d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, + 0x47, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, + 0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x22, 0x3c, 0x0a, 0x0c, 0x56, 0x6f, + 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x6c, 0x69, 0x6e, + 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x79, 0x0a, 0x05, 0x4d, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x20, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, + 0x22, 0x0a, 0x09, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, + 0x44, 0x45, 0x56, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x48, 0x4f, 0x53, 0x54, 0x50, 0x41, 0x54, + 0x48, 0x10, 0x01, 0x22, 0x79, 0x0a, 0x16, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, + 0x10, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x68, 0x6f, 0x73, 0x74, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1f, 0x0a, + 0x0b, 0x6d, 0x61, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x48, + 0x0a, 0x10, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, + 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0b, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x62, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x6d, 0x65, 0x74, + 0x61, 0x6c, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1461,8 +1495,8 @@ func file_types_microvm_proto_rawDescGZIP() []byte { } var file_types_microvm_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_types_microvm_proto_msgTypes = make([]protoimpl.MessageInfo, 19) -var file_types_microvm_proto_goTypes = []interface{}{ +var file_types_microvm_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_types_microvm_proto_goTypes = []any{ (NetworkInterface_IfaceType)(0), // 0: flintlock.types.NetworkInterface.IfaceType (MicroVMStatus_MicroVMState)(0), // 1: flintlock.types.MicroVMStatus.MicroVMState (Mount_MountType)(0), // 2: flintlock.types.Mount.MountType @@ -1474,46 +1508,47 @@ var file_types_microvm_proto_goTypes = []interface{}{ (*StaticAddress)(nil), // 8: flintlock.types.StaticAddress (*Volume)(nil), // 9: flintlock.types.Volume (*VolumeSource)(nil), // 10: flintlock.types.VolumeSource - (*ContainerVolumeSource)(nil), // 11: flintlock.types.ContainerVolumeSource - (*MicroVMStatus)(nil), // 12: flintlock.types.MicroVMStatus - (*VolumeStatus)(nil), // 13: flintlock.types.VolumeStatus - (*Mount)(nil), // 14: flintlock.types.Mount - (*NetworkInterfaceStatus)(nil), // 15: flintlock.types.NetworkInterfaceStatus - (*NetworkOverrides)(nil), // 16: flintlock.types.NetworkOverrides - nil, // 17: flintlock.types.MicroVMSpec.LabelsEntry - nil, // 18: flintlock.types.MicroVMSpec.MetadataEntry - nil, // 19: flintlock.types.Kernel.CmdlineEntry - nil, // 20: flintlock.types.MicroVMStatus.VolumesEntry - nil, // 21: flintlock.types.MicroVMStatus.NetworkInterfacesEntry - (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp + (*VirtioFSVolumeSource)(nil), // 11: flintlock.types.VirtioFSVolumeSource + (*ContainerVolumeSource)(nil), // 12: flintlock.types.ContainerVolumeSource + (*MicroVMStatus)(nil), // 13: flintlock.types.MicroVMStatus + (*VolumeStatus)(nil), // 14: flintlock.types.VolumeStatus + (*Mount)(nil), // 15: flintlock.types.Mount + (*NetworkInterfaceStatus)(nil), // 16: flintlock.types.NetworkInterfaceStatus + (*NetworkOverrides)(nil), // 17: flintlock.types.NetworkOverrides + nil, // 18: flintlock.types.MicroVMSpec.LabelsEntry + nil, // 19: flintlock.types.MicroVMSpec.MetadataEntry + nil, // 20: flintlock.types.Kernel.CmdlineEntry + nil, // 21: flintlock.types.MicroVMStatus.VolumesEntry + nil, // 22: flintlock.types.MicroVMStatus.NetworkInterfacesEntry + (*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp } var file_types_microvm_proto_depIdxs = []int32{ 4, // 0: flintlock.types.MicroVM.spec:type_name -> flintlock.types.MicroVMSpec - 12, // 1: flintlock.types.MicroVM.status:type_name -> flintlock.types.MicroVMStatus - 17, // 2: flintlock.types.MicroVMSpec.labels:type_name -> flintlock.types.MicroVMSpec.LabelsEntry + 13, // 1: flintlock.types.MicroVM.status:type_name -> flintlock.types.MicroVMStatus + 18, // 2: flintlock.types.MicroVMSpec.labels:type_name -> flintlock.types.MicroVMSpec.LabelsEntry 5, // 3: flintlock.types.MicroVMSpec.kernel:type_name -> flintlock.types.Kernel 6, // 4: flintlock.types.MicroVMSpec.initrd:type_name -> flintlock.types.Initrd 9, // 5: flintlock.types.MicroVMSpec.root_volume:type_name -> flintlock.types.Volume 9, // 6: flintlock.types.MicroVMSpec.additional_volumes:type_name -> flintlock.types.Volume 7, // 7: flintlock.types.MicroVMSpec.interfaces:type_name -> flintlock.types.NetworkInterface - 18, // 8: flintlock.types.MicroVMSpec.metadata:type_name -> flintlock.types.MicroVMSpec.MetadataEntry - 22, // 9: flintlock.types.MicroVMSpec.created_at:type_name -> google.protobuf.Timestamp - 22, // 10: flintlock.types.MicroVMSpec.updated_at:type_name -> google.protobuf.Timestamp - 22, // 11: flintlock.types.MicroVMSpec.deleted_at:type_name -> google.protobuf.Timestamp - 19, // 12: flintlock.types.Kernel.cmdline:type_name -> flintlock.types.Kernel.CmdlineEntry + 19, // 8: flintlock.types.MicroVMSpec.metadata:type_name -> flintlock.types.MicroVMSpec.MetadataEntry + 23, // 9: flintlock.types.MicroVMSpec.created_at:type_name -> google.protobuf.Timestamp + 23, // 10: flintlock.types.MicroVMSpec.updated_at:type_name -> google.protobuf.Timestamp + 23, // 11: flintlock.types.MicroVMSpec.deleted_at:type_name -> google.protobuf.Timestamp + 20, // 12: flintlock.types.Kernel.cmdline:type_name -> flintlock.types.Kernel.CmdlineEntry 0, // 13: flintlock.types.NetworkInterface.type:type_name -> flintlock.types.NetworkInterface.IfaceType 8, // 14: flintlock.types.NetworkInterface.address:type_name -> flintlock.types.StaticAddress - 16, // 15: flintlock.types.NetworkInterface.overrides:type_name -> flintlock.types.NetworkOverrides + 17, // 15: flintlock.types.NetworkInterface.overrides:type_name -> flintlock.types.NetworkOverrides 10, // 16: flintlock.types.Volume.source:type_name -> flintlock.types.VolumeSource 1, // 17: flintlock.types.MicroVMStatus.state:type_name -> flintlock.types.MicroVMStatus.MicroVMState - 20, // 18: flintlock.types.MicroVMStatus.volumes:type_name -> flintlock.types.MicroVMStatus.VolumesEntry - 14, // 19: flintlock.types.MicroVMStatus.kernel_mount:type_name -> flintlock.types.Mount - 14, // 20: flintlock.types.MicroVMStatus.initrd_mount:type_name -> flintlock.types.Mount - 21, // 21: flintlock.types.MicroVMStatus.network_interfaces:type_name -> flintlock.types.MicroVMStatus.NetworkInterfacesEntry - 14, // 22: flintlock.types.VolumeStatus.mount:type_name -> flintlock.types.Mount + 21, // 18: flintlock.types.MicroVMStatus.volumes:type_name -> flintlock.types.MicroVMStatus.VolumesEntry + 15, // 19: flintlock.types.MicroVMStatus.kernel_mount:type_name -> flintlock.types.Mount + 15, // 20: flintlock.types.MicroVMStatus.initrd_mount:type_name -> flintlock.types.Mount + 22, // 21: flintlock.types.MicroVMStatus.network_interfaces:type_name -> flintlock.types.MicroVMStatus.NetworkInterfacesEntry + 15, // 22: flintlock.types.VolumeStatus.mount:type_name -> flintlock.types.Mount 2, // 23: flintlock.types.Mount.type:type_name -> flintlock.types.Mount.MountType - 13, // 24: flintlock.types.MicroVMStatus.VolumesEntry.value:type_name -> flintlock.types.VolumeStatus - 15, // 25: flintlock.types.MicroVMStatus.NetworkInterfacesEntry.value:type_name -> flintlock.types.NetworkInterfaceStatus + 14, // 24: flintlock.types.MicroVMStatus.VolumesEntry.value:type_name -> flintlock.types.VolumeStatus + 16, // 25: flintlock.types.MicroVMStatus.NetworkInterfacesEntry.value:type_name -> flintlock.types.NetworkInterfaceStatus 26, // [26:26] is the sub-list for method output_type 26, // [26:26] is the sub-list for method input_type 26, // [26:26] is the sub-list for extension type_name @@ -1526,191 +1561,21 @@ func file_types_microvm_proto_init() { if File_types_microvm_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_types_microvm_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MicroVM); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MicroVMSpec); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Kernel); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Initrd); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NetworkInterface); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StaticAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Volume); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VolumeSource); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerVolumeSource); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MicroVMStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VolumeStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Mount); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NetworkInterfaceStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_types_microvm_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NetworkOverrides); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_types_microvm_proto_msgTypes[1].OneofWrappers = []interface{}{} - file_types_microvm_proto_msgTypes[2].OneofWrappers = []interface{}{} - file_types_microvm_proto_msgTypes[3].OneofWrappers = []interface{}{} - file_types_microvm_proto_msgTypes[4].OneofWrappers = []interface{}{} - file_types_microvm_proto_msgTypes[5].OneofWrappers = []interface{}{} - file_types_microvm_proto_msgTypes[6].OneofWrappers = []interface{}{} - file_types_microvm_proto_msgTypes[7].OneofWrappers = []interface{}{} - file_types_microvm_proto_msgTypes[13].OneofWrappers = []interface{}{} + file_types_microvm_proto_msgTypes[1].OneofWrappers = []any{} + file_types_microvm_proto_msgTypes[2].OneofWrappers = []any{} + file_types_microvm_proto_msgTypes[3].OneofWrappers = []any{} + file_types_microvm_proto_msgTypes[4].OneofWrappers = []any{} + file_types_microvm_proto_msgTypes[5].OneofWrappers = []any{} + file_types_microvm_proto_msgTypes[6].OneofWrappers = []any{} + file_types_microvm_proto_msgTypes[7].OneofWrappers = []any{} + file_types_microvm_proto_msgTypes[14].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_types_microvm_proto_rawDesc, NumEnums: 3, - NumMessages: 19, + NumMessages: 20, NumExtensions: 0, NumServices: 0, }, diff --git a/buf.lock b/buf.lock index e9889ad9..4524691e 100644 --- a/buf.lock +++ b/buf.lock @@ -4,8 +4,8 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: f0e53af8f2fc4556b94f482688b57223 + commit: e93e34f48be043dab55be31b4b47f458 - remote: buf.build owner: grpc-ecosystem repository: grpc-gateway - commit: a48fcebcf8f140dd9d09359b9bb185a4 + commit: 4c5ba75caaf84e928b7137ae5c18c26a diff --git a/core/models/volumes.go b/core/models/volumes.go index 33dbc32c..1f4b747d 100644 --- a/core/models/volumes.go +++ b/core/models/volumes.go @@ -47,6 +47,8 @@ func (v Volumes) HasMountableVolumes() bool { type VolumeSource struct { // Container is used to specify a source of a volume as a OCI container. Container *ContainerVolumeSource `json:"container,omitempty"` + + VirtioFS *VirtioFSVolumeSource `json:"virtiofs,omitempty"` } // ContainerDriveSource represents the details of a volume coming from a OCI image. @@ -55,6 +57,13 @@ type ContainerVolumeSource struct { Image ContainerImage `json:"image"` } +// VirtioFSSource represents the details of the VirtioFS volume. +type VirtioFSVolumeSource struct { + // Image is the OCI image to use. + Path string `json:"path"` +} + + // Mount represents a volume mount point. type Mount struct { // Type specifies the type of the mount (e.g. device or directory). diff --git a/infrastructure/grpc/convert.go b/infrastructure/grpc/convert.go index 1e135764..987d3a18 100644 --- a/infrastructure/grpc/convert.go +++ b/infrastructure/grpc/convert.go @@ -139,6 +139,11 @@ func convertVolumeToModel(volume *types.Volume) *models.Volume { Image: models.ContainerImage(*volume.Source.ContainerSource), } } + if volume.Source.VirtiofsSource != nil { + convertedVol.Source.VirtioFS = &models.VirtioFSVolumeSource{ + Path: *volume.Source.VirtiofsSource, + } + } } if volume.MountPoint != nil { diff --git a/infrastructure/mock/containerd.go b/infrastructure/mock/containerd.go index 8ff9f347..5993bc9c 100644 --- a/infrastructure/mock/containerd.go +++ b/infrastructure/mock/containerd.go @@ -17,9 +17,9 @@ import ( images "github.com/containerd/containerd/images" leases "github.com/containerd/containerd/leases" namespaces "github.com/containerd/containerd/namespaces" - platforms "github.com/containerd/containerd/platforms" introspection "github.com/containerd/containerd/services/introspection" snapshots "github.com/containerd/containerd/snapshots" + platforms "github.com/containerd/platforms" gomock "github.com/golang/mock/gomock" v1 "github.com/opencontainers/image-spec/specs-go/v1" grpc "google.golang.org/grpc" diff --git a/infrastructure/mock/ext_containerd.go b/infrastructure/mock/ext_containerd.go index 6ee0e567..c034b30d 100644 --- a/infrastructure/mock/ext_containerd.go +++ b/infrastructure/mock/ext_containerd.go @@ -11,7 +11,7 @@ import ( containerd "github.com/containerd/containerd" content "github.com/containerd/containerd/content" images "github.com/containerd/containerd/images" - platforms "github.com/containerd/containerd/platforms" + platforms "github.com/containerd/platforms" gomock "github.com/golang/mock/gomock" digest "github.com/opencontainers/go-digest" v1 "github.com/opencontainers/image-spec/specs-go/v1" diff --git a/internal/inject/wire_gen.go b/internal/inject/wire_gen.go index 90602e41..1395b718 100644 --- a/internal/inject/wire_gen.go +++ b/internal/inject/wire_gen.go @@ -7,8 +7,6 @@ package inject import ( - "time" - "github.com/liquidmetal-dev/flintlock/core/application" "github.com/liquidmetal-dev/flintlock/core/ports" "github.com/liquidmetal-dev/flintlock/infrastructure/containerd" @@ -21,6 +19,7 @@ import ( "github.com/liquidmetal-dev/flintlock/internal/config" "github.com/liquidmetal-dev/flintlock/pkg/defaults" "github.com/spf13/afero" + "time" ) // Injectors from wire.go: diff --git a/userdocs/docs/grpc/services/microvm/v1alpha1/proto.md b/userdocs/docs/grpc/services/microvm/v1alpha1/proto.md index 4d6dcb11..0a27748f 100644 --- a/userdocs/docs/grpc/services/microvm/v1alpha1/proto.md +++ b/userdocs/docs/grpc/services/microvm/v1alpha1/proto.md @@ -3,31 +3,31 @@ ## Table of Contents -- [services/microvm/v1alpha1/microvms.proto](#services/microvm/v1alpha1/microvms.proto) - - [CreateMicroVMRequest](#microvm.services.api.v1alpha1.CreateMicroVMRequest) - - [CreateMicroVMRequest.MetadataEntry](#microvm.services.api.v1alpha1.CreateMicroVMRequest.MetadataEntry) - - [CreateMicroVMResponse](#microvm.services.api.v1alpha1.CreateMicroVMResponse) - - [DeleteMicroVMRequest](#microvm.services.api.v1alpha1.DeleteMicroVMRequest) - - [GetMicroVMRequest](#microvm.services.api.v1alpha1.GetMicroVMRequest) - - [GetMicroVMResponse](#microvm.services.api.v1alpha1.GetMicroVMResponse) - - [ListMessage](#microvm.services.api.v1alpha1.ListMessage) - - [ListMicroVMsRequest](#microvm.services.api.v1alpha1.ListMicroVMsRequest) - - [ListMicroVMsResponse](#microvm.services.api.v1alpha1.ListMicroVMsResponse) +- [services/microvm/v1alpha1/microvms.proto](#services_microvm_v1alpha1_microvms-proto) + - [CreateMicroVMRequest](#microvm-services-api-v1alpha1-CreateMicroVMRequest) + - [CreateMicroVMRequest.MetadataEntry](#microvm-services-api-v1alpha1-CreateMicroVMRequest-MetadataEntry) + - [CreateMicroVMResponse](#microvm-services-api-v1alpha1-CreateMicroVMResponse) + - [DeleteMicroVMRequest](#microvm-services-api-v1alpha1-DeleteMicroVMRequest) + - [GetMicroVMRequest](#microvm-services-api-v1alpha1-GetMicroVMRequest) + - [GetMicroVMResponse](#microvm-services-api-v1alpha1-GetMicroVMResponse) + - [ListMessage](#microvm-services-api-v1alpha1-ListMessage) + - [ListMicroVMsRequest](#microvm-services-api-v1alpha1-ListMicroVMsRequest) + - [ListMicroVMsResponse](#microvm-services-api-v1alpha1-ListMicroVMsResponse) - - [MicroVM](#microvm.services.api.v1alpha1.MicroVM) + - [MicroVM](#microvm-services-api-v1alpha1-MicroVM) - [Scalar Value Types](#scalar-value-types) - +

Top

## services/microvm/v1alpha1/microvms.proto - + ### CreateMicroVMRequest @@ -35,15 +35,15 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| microvm | [flintlock.types.MicroVMSpec](#flintlock.types.MicroVMSpec) | | | -| metadata | [CreateMicroVMRequest.MetadataEntry](#microvm.services.api.v1alpha1.CreateMicroVMRequest.MetadataEntry) | repeated | | +| microvm | [flintlock.types.MicroVMSpec](#flintlock-types-MicroVMSpec) | | | +| metadata | [CreateMicroVMRequest.MetadataEntry](#microvm-services-api-v1alpha1-CreateMicroVMRequest-MetadataEntry) | repeated | | - + ### CreateMicroVMRequest.MetadataEntry @@ -52,14 +52,14 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| value | [google.protobuf.Any](#google.protobuf.Any) | | | +| value | [google.protobuf.Any](#google-protobuf-Any) | | | - + ### CreateMicroVMResponse @@ -67,14 +67,14 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | | | +| microvm | [flintlock.types.MicroVM](#flintlock-types-MicroVM) | | | - + ### DeleteMicroVMRequest @@ -89,7 +89,7 @@ - + ### GetMicroVMRequest @@ -104,7 +104,7 @@ - + ### GetMicroVMResponse @@ -112,14 +112,14 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | | | +| microvm | [flintlock.types.MicroVM](#flintlock-types-MicroVM) | | | - + ### ListMessage @@ -127,14 +127,14 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | | | +| microvm | [flintlock.types.MicroVM](#flintlock-types-MicroVM) | | | - + ### ListMicroVMsRequest @@ -150,7 +150,7 @@ - + ### ListMicroVMsResponse @@ -158,7 +158,7 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | repeated | | +| microvm | [flintlock.types.MicroVM](#flintlock-types-MicroVM) | repeated | | @@ -171,18 +171,18 @@ - + ### MicroVM MicroVM providers a service to create and manage the lifecycle of microvms. | Method Name | Request Type | Response Type | Description | | ----------- | ------------ | ------------- | ------------| -| CreateMicroVM | [CreateMicroVMRequest](#microvm.services.api.v1alpha1.CreateMicroVMRequest) | [CreateMicroVMResponse](#microvm.services.api.v1alpha1.CreateMicroVMResponse) | | -| DeleteMicroVM | [DeleteMicroVMRequest](#microvm.services.api.v1alpha1.DeleteMicroVMRequest) | [.google.protobuf.Empty](#google.protobuf.Empty) | | -| GetMicroVM | [GetMicroVMRequest](#microvm.services.api.v1alpha1.GetMicroVMRequest) | [GetMicroVMResponse](#microvm.services.api.v1alpha1.GetMicroVMResponse) | | -| ListMicroVMs | [ListMicroVMsRequest](#microvm.services.api.v1alpha1.ListMicroVMsRequest) | [ListMicroVMsResponse](#microvm.services.api.v1alpha1.ListMicroVMsResponse) | | -| ListMicroVMsStream | [ListMicroVMsRequest](#microvm.services.api.v1alpha1.ListMicroVMsRequest) | [ListMessage](#microvm.services.api.v1alpha1.ListMessage) stream | | +| CreateMicroVM | [CreateMicroVMRequest](#microvm-services-api-v1alpha1-CreateMicroVMRequest) | [CreateMicroVMResponse](#microvm-services-api-v1alpha1-CreateMicroVMResponse) | | +| DeleteMicroVM | [DeleteMicroVMRequest](#microvm-services-api-v1alpha1-DeleteMicroVMRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | | +| GetMicroVM | [GetMicroVMRequest](#microvm-services-api-v1alpha1-GetMicroVMRequest) | [GetMicroVMResponse](#microvm-services-api-v1alpha1-GetMicroVMResponse) | | +| ListMicroVMs | [ListMicroVMsRequest](#microvm-services-api-v1alpha1-ListMicroVMsRequest) | [ListMicroVMsResponse](#microvm-services-api-v1alpha1-ListMicroVMsResponse) | | +| ListMicroVMsStream | [ListMicroVMsRequest](#microvm-services-api-v1alpha1-ListMicroVMsRequest) | [ListMessage](#microvm-services-api-v1alpha1-ListMessage) stream | | diff --git a/userdocs/docs/grpc/types/proto.md b/userdocs/docs/grpc/types/proto.md index a66e5a12..567fe305 100644 --- a/userdocs/docs/grpc/types/proto.md +++ b/userdocs/docs/grpc/types/proto.md @@ -3,43 +3,44 @@ ## Table of Contents -- [types/microvm.proto](#types/microvm.proto) - - [ContainerVolumeSource](#flintlock.types.ContainerVolumeSource) - - [Initrd](#flintlock.types.Initrd) - - [Kernel](#flintlock.types.Kernel) - - [Kernel.CmdlineEntry](#flintlock.types.Kernel.CmdlineEntry) - - [MicroVM](#flintlock.types.MicroVM) - - [MicroVMSpec](#flintlock.types.MicroVMSpec) - - [MicroVMSpec.LabelsEntry](#flintlock.types.MicroVMSpec.LabelsEntry) - - [MicroVMSpec.MetadataEntry](#flintlock.types.MicroVMSpec.MetadataEntry) - - [MicroVMStatus](#flintlock.types.MicroVMStatus) - - [MicroVMStatus.NetworkInterfacesEntry](#flintlock.types.MicroVMStatus.NetworkInterfacesEntry) - - [MicroVMStatus.VolumesEntry](#flintlock.types.MicroVMStatus.VolumesEntry) - - [Mount](#flintlock.types.Mount) - - [NetworkInterface](#flintlock.types.NetworkInterface) - - [NetworkInterfaceStatus](#flintlock.types.NetworkInterfaceStatus) - - [NetworkOverrides](#flintlock.types.NetworkOverrides) - - [StaticAddress](#flintlock.types.StaticAddress) - - [Volume](#flintlock.types.Volume) - - [VolumeSource](#flintlock.types.VolumeSource) - - [VolumeStatus](#flintlock.types.VolumeStatus) +- [types/microvm.proto](#types_microvm-proto) + - [ContainerVolumeSource](#flintlock-types-ContainerVolumeSource) + - [Initrd](#flintlock-types-Initrd) + - [Kernel](#flintlock-types-Kernel) + - [Kernel.CmdlineEntry](#flintlock-types-Kernel-CmdlineEntry) + - [MicroVM](#flintlock-types-MicroVM) + - [MicroVMSpec](#flintlock-types-MicroVMSpec) + - [MicroVMSpec.LabelsEntry](#flintlock-types-MicroVMSpec-LabelsEntry) + - [MicroVMSpec.MetadataEntry](#flintlock-types-MicroVMSpec-MetadataEntry) + - [MicroVMStatus](#flintlock-types-MicroVMStatus) + - [MicroVMStatus.NetworkInterfacesEntry](#flintlock-types-MicroVMStatus-NetworkInterfacesEntry) + - [MicroVMStatus.VolumesEntry](#flintlock-types-MicroVMStatus-VolumesEntry) + - [Mount](#flintlock-types-Mount) + - [NetworkInterface](#flintlock-types-NetworkInterface) + - [NetworkInterfaceStatus](#flintlock-types-NetworkInterfaceStatus) + - [NetworkOverrides](#flintlock-types-NetworkOverrides) + - [StaticAddress](#flintlock-types-StaticAddress) + - [VirtioFSVolumeSource](#flintlock-types-VirtioFSVolumeSource) + - [Volume](#flintlock-types-Volume) + - [VolumeSource](#flintlock-types-VolumeSource) + - [VolumeStatus](#flintlock-types-VolumeStatus) - - [MicroVMStatus.MicroVMState](#flintlock.types.MicroVMStatus.MicroVMState) - - [Mount.MountType](#flintlock.types.Mount.MountType) - - [NetworkInterface.IfaceType](#flintlock.types.NetworkInterface.IfaceType) + - [MicroVMStatus.MicroVMState](#flintlock-types-MicroVMStatus-MicroVMState) + - [Mount.MountType](#flintlock-types-Mount-MountType) + - [NetworkInterface.IfaceType](#flintlock-types-NetworkInterface-IfaceType) - [Scalar Value Types](#scalar-value-types) - +

Top

## types/microvm.proto - + ### ContainerVolumeSource ContainerVolumeSource represents the details of a volume coming from a OCI image. @@ -54,7 +55,7 @@ ContainerVolumeSource represents the details of a volume coming from a OCI image - + ### Initrd Initrd represents the configuration for the initial ramdisk. @@ -70,7 +71,7 @@ Initrd represents the configuration for the initial ramdisk. - + ### Kernel Kernel represents the configuration for a kernel. @@ -79,7 +80,7 @@ Kernel represents the configuration for a kernel. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | image | [string](#string) | | Image is the container image to use. | -| cmdline | [Kernel.CmdlineEntry](#flintlock.types.Kernel.CmdlineEntry) | repeated | Cmdline is the additional kernel command line args. Each provider has its own recommended list, they will be used automatically. This field is for additional values. | +| cmdline | [Kernel.CmdlineEntry](#flintlock-types-Kernel-CmdlineEntry) | repeated | Cmdline is the additional kernel command line args. Each provider has its own recommended list, they will be used automatically. This field is for additional values. | | filename | [string](#string) | optional | Filename is used to specify the name of the kernel file in the Image. | | add_network_config | [bool](#bool) | | AddNetworkConfig if set to true indicates that the network-config kernel argument should be generated. | @@ -88,7 +89,7 @@ Kernel represents the configuration for a kernel. - + ### Kernel.CmdlineEntry @@ -104,7 +105,7 @@ Kernel represents the configuration for a kernel. - + ### MicroVM MicroVM represents a microvm machine that is created via a provider. @@ -113,15 +114,15 @@ MicroVM represents a microvm machine that is created via a provider. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | version | [int32](#int32) | | | -| spec | [MicroVMSpec](#flintlock.types.MicroVMSpec) | | Spec is the specification of the microvm. | -| status | [MicroVMStatus](#flintlock.types.MicroVMStatus) | | Status is the runtime status of the microvm. | +| spec | [MicroVMSpec](#flintlock-types-MicroVMSpec) | | Spec is the specification of the microvm. | +| status | [MicroVMStatus](#flintlock-types-MicroVMStatus) | | Status is the runtime status of the microvm. | - + ### MicroVMSpec MicroVMSpec represents the specification for a microvm. @@ -131,18 +132,18 @@ MicroVMSpec represents the specification for a microvm. | ----- | ---- | ----- | ----------- | | id | [string](#string) | | ID is the identifier of the microvm. If this empty at creation time a ID will be automatically generated. | | namespace | [string](#string) | | Namespace is the name of the namespace the microvm belongs to. | -| labels | [MicroVMSpec.LabelsEntry](#flintlock.types.MicroVMSpec.LabelsEntry) | repeated | Labels allows you to include extra data for the microvms. | +| labels | [MicroVMSpec.LabelsEntry](#flintlock-types-MicroVMSpec-LabelsEntry) | repeated | Labels allows you to include extra data for the microvms. | | vcpu | [int32](#int32) | | VCPU specifies how many vcpu the machine will be allocated. | | memory_in_mb | [int32](#int32) | | MemoryInMb is the amount of memory in megabytes that the machine will be allocated. | -| kernel | [Kernel](#flintlock.types.Kernel) | | Kernel is the details of the kernel to use . | -| initrd | [Initrd](#flintlock.types.Initrd) | optional | Initrd is the optional details of the initial ramdisk. | -| root_volume | [Volume](#flintlock.types.Volume) | | RootVolume specifies the root volume mount for the MicroVM. | -| additional_volumes | [Volume](#flintlock.types.Volume) | repeated | AdditionalVolumes specifies the volumes to be attached to the microvm. | -| interfaces | [NetworkInterface](#flintlock.types.NetworkInterface) | repeated | Interfaces specifies the network interfaces to be attached to the microvm. Device names on the guest machine are determined by the order defined in the list starting from eth1, eth2, ..., ethN. | -| metadata | [MicroVMSpec.MetadataEntry](#flintlock.types.MicroVMSpec.MetadataEntry) | repeated | Metadata allows you to specify data to be added to the metadata service. The key is the name of the metadata item and the value is the base64 encoded contents of the metadata. | -| created_at | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | CreatedAt indicates the time the microvm was created at. | -| updated_at | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | UpdatedAt indicates the time the microvm was last updated. | -| deleted_at | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | DeletedAt indicates the time the microvm was marked as deleted. | +| kernel | [Kernel](#flintlock-types-Kernel) | | Kernel is the details of the kernel to use . | +| initrd | [Initrd](#flintlock-types-Initrd) | optional | Initrd is the optional details of the initial ramdisk. | +| root_volume | [Volume](#flintlock-types-Volume) | | RootVolume specifies the root volume mount for the MicroVM. | +| additional_volumes | [Volume](#flintlock-types-Volume) | repeated | AdditionalVolumes specifies the volumes to be attached to the microvm. | +| interfaces | [NetworkInterface](#flintlock-types-NetworkInterface) | repeated | Interfaces specifies the network interfaces to be attached to the microvm. Device names on the guest machine are determined by the order defined in the list starting from eth1, eth2, ..., ethN. | +| metadata | [MicroVMSpec.MetadataEntry](#flintlock-types-MicroVMSpec-MetadataEntry) | repeated | Metadata allows you to specify data to be added to the metadata service. The key is the name of the metadata item and the value is the base64 encoded contents of the metadata. | +| created_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | CreatedAt indicates the time the microvm was created at. | +| updated_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | UpdatedAt indicates the time the microvm was last updated. | +| deleted_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | DeletedAt indicates the time the microvm was marked as deleted. | | uid | [string](#string) | optional | UID is a globally unique identifier of the microvm. | | provider | [string](#string) | optional | Provider allows you to specify the name of the microvm provider to use. If this isn't supplied then the default provider will be used. | @@ -151,7 +152,7 @@ MicroVMSpec represents the specification for a microvm. - + ### MicroVMSpec.LabelsEntry @@ -167,7 +168,7 @@ MicroVMSpec represents the specification for a microvm. - + ### MicroVMSpec.MetadataEntry @@ -183,7 +184,7 @@ MicroVMSpec represents the specification for a microvm. - + ### MicroVMStatus MicroVMStatus contains the runtime status of the microvm. @@ -191,11 +192,11 @@ MicroVMStatus contains the runtime status of the microvm. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| state | [MicroVMStatus.MicroVMState](#flintlock.types.MicroVMStatus.MicroVMState) | | State stores information about the last known state of the vm and the spec. | -| volumes | [MicroVMStatus.VolumesEntry](#flintlock.types.MicroVMStatus.VolumesEntry) | repeated | Volumes holds the status of the volumes. | -| kernel_mount | [Mount](#flintlock.types.Mount) | | KernelMount holds the status of the kernel mount point. | -| initrd_mount | [Mount](#flintlock.types.Mount) | | InitrdMount holds the status of the initrd mount point. | -| network_interfaces | [MicroVMStatus.NetworkInterfacesEntry](#flintlock.types.MicroVMStatus.NetworkInterfacesEntry) | repeated | NetworkInterfaces holds the status of the network interfaces. | +| state | [MicroVMStatus.MicroVMState](#flintlock-types-MicroVMStatus-MicroVMState) | | State stores information about the last known state of the vm and the spec. | +| volumes | [MicroVMStatus.VolumesEntry](#flintlock-types-MicroVMStatus-VolumesEntry) | repeated | Volumes holds the status of the volumes. | +| kernel_mount | [Mount](#flintlock-types-Mount) | | KernelMount holds the status of the kernel mount point. | +| initrd_mount | [Mount](#flintlock-types-Mount) | | InitrdMount holds the status of the initrd mount point. | +| network_interfaces | [MicroVMStatus.NetworkInterfacesEntry](#flintlock-types-MicroVMStatus-NetworkInterfacesEntry) | repeated | NetworkInterfaces holds the status of the network interfaces. | | retry | [int32](#int32) | | Retry is a counter about how many times we retried to reconcile. | @@ -203,7 +204,7 @@ MicroVMStatus contains the runtime status of the microvm. - + ### MicroVMStatus.NetworkInterfacesEntry @@ -212,14 +213,14 @@ MicroVMStatus contains the runtime status of the microvm. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| value | [NetworkInterfaceStatus](#flintlock.types.NetworkInterfaceStatus) | | | +| value | [NetworkInterfaceStatus](#flintlock-types-NetworkInterfaceStatus) | | | - + ### MicroVMStatus.VolumesEntry @@ -228,14 +229,14 @@ MicroVMStatus contains the runtime status of the microvm. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| value | [VolumeStatus](#flintlock.types.VolumeStatus) | | | +| value | [VolumeStatus](#flintlock-types-VolumeStatus) | | | - + ### Mount Mount represents a volume mount point. @@ -243,7 +244,7 @@ Mount represents a volume mount point. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| type | [Mount.MountType](#flintlock.types.Mount.MountType) | | Type specifies the type of the mount (e.g. device or directory). | +| type | [Mount.MountType](#flintlock-types-Mount-MountType) | | Type specifies the type of the mount (e.g. device or directory). | | source | [string](#string) | | Source is the location of the mounted volume. | @@ -251,7 +252,7 @@ Mount represents a volume mount point. - + ### NetworkInterface @@ -260,17 +261,17 @@ Mount represents a volume mount point. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | device_id | [string](#string) | | DeviceID is the ID of the interface. There is no relation between the ID and the name of the interface device on the quest machine. | -| type | [NetworkInterface.IfaceType](#flintlock.types.NetworkInterface.IfaceType) | | IfaceType specifies the type of network interface to create for use by the guest. | +| type | [NetworkInterface.IfaceType](#flintlock-types-NetworkInterface-IfaceType) | | IfaceType specifies the type of network interface to create for use by the guest. | | guest_mac | [string](#string) | optional | GuestMAC allows the specifying of a specifi MAC address to use for the interface. If not supplied a autogenerated MAC address will be used. | -| address | [StaticAddress](#flintlock.types.StaticAddress) | optional | Address is an optional static IP address to manually assign to this interface. If not supplied then DHCP will be used. | -| overrides | [NetworkOverrides](#flintlock.types.NetworkOverrides) | optional | Overrides is optional overrides applicable for network configuration. | +| address | [StaticAddress](#flintlock-types-StaticAddress) | optional | Address is an optional static IP address to manually assign to this interface. If not supplied then DHCP will be used. | +| overrides | [NetworkOverrides](#flintlock-types-NetworkOverrides) | optional | Overrides is optional overrides applicable for network configuration. | - + ### NetworkInterfaceStatus @@ -287,7 +288,7 @@ Mount represents a volume mount point. - + ### NetworkOverrides NetworkOverrides represents override values for a network interface. @@ -302,7 +303,7 @@ NetworkOverrides represents override values for a network interface. - + ### StaticAddress StaticAddress represents a static IPv4 or IPv6 address. @@ -319,7 +320,22 @@ StaticAddress represents a static IPv4 or IPv6 address. - + + +### VirtioFSVolumeSource +VirtioFSVolumeSource represents the details of a volume coming from a OCI image. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| path | [string](#string) | | Path on the host machine to pass through. | + + + + + + + ### Volume Volume represents the configuration for a volume to be attached to a microvm. @@ -330,7 +346,7 @@ Volume represents the configuration for a volume to be attached to a microvm. | id | [string](#string) | | ID is the uinique identifier of the volume. | | is_read_only | [bool](#bool) | | IsReadOnly specifies that the volume is to be mounted readonly. | | mount_point | [string](#string) | optional | MountPoint allows you to optionally specify a mount point for the volume. This only applied to additional volumes and it will use cloud-init to mount the volumes. | -| source | [VolumeSource](#flintlock.types.VolumeSource) | | Source is where the volume will be sourced from. | +| source | [VolumeSource](#flintlock-types-VolumeSource) | | Source is where the volume will be sourced from. | | partition_id | [string](#string) | optional | PartitionID is the uuid of the boot partition. | | size_in_mb | [int32](#int32) | optional | Size is the size to resize this volume to. @@ -341,7 +357,7 @@ TODO: add rate limiting | - + ### VolumeSource VolumeSource is the source of a volume. Based loosely on the volumes in Kubernetes Pod specs. @@ -349,16 +365,15 @@ VolumeSource is the source of a volume. Based loosely on the volumes in Kubernet | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| container_source | [string](#string) | optional | Container is used to specify a source of a volume as a OCI container. - -TODO: add CSI | +| container_source | [string](#string) | optional | Container is used to specify a source of a volume as a OCI container. | +| virtiofs_source | [string](#string) | optional | | - + ### VolumeStatus @@ -366,7 +381,7 @@ TODO: add CSI | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| mount | [Mount](#flintlock.types.Mount) | | Mount represents a volume mount point. | +| mount | [Mount](#flintlock-types-Mount) | | Mount represents a volume mount point. | @@ -375,7 +390,7 @@ TODO: add CSI | - + ### MicroVMStatus.MicroVMState @@ -389,7 +404,7 @@ TODO: add CSI | - + ### Mount.MountType @@ -401,7 +416,7 @@ TODO: add CSI | - + ### NetworkInterface.IfaceType From 317c0314b342cb69b813e6f2aa605eaf00a172d1 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 11:44:48 -0500 Subject: [PATCH 14/35] adding virtiofs to capabilities and convert --- .../microvm/v1alpha1/microvms.swagger.json | 3 +- api/types/microvm.pb.go | 3 +- api/types/microvm.proto | 1 + core/models/capability.go | 2 + core/plans/microvm_create_update.go | 26 +++++++ core/steps/runtime/virtiofs.go | 68 +++++++++++++++++++ infrastructure/grpc/convert.go | 6 +- infrastructure/grpc/server.go | 2 +- .../microvm/cloudhypervisor/provider.go | 2 +- userdocs/docs/grpc/types/proto.md | 2 +- 10 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 core/steps/runtime/virtiofs.go diff --git a/api/services/microvm/v1alpha1/microvms.swagger.json b/api/services/microvm/v1alpha1/microvms.swagger.json index 8190675f..5b14ab32 100644 --- a/api/services/microvm/v1alpha1/microvms.swagger.json +++ b/api/services/microvm/v1alpha1/microvms.swagger.json @@ -519,7 +519,8 @@ "description": "Container is used to specify a source of a volume as a OCI container." }, "virtiofsSource": { - "type": "string" + "type": "string", + "title": "Used for the virtiofs source path" } }, "description": "VolumeSource is the source of a volume. Based loosely on the volumes in Kubernetes Pod specs." diff --git a/api/types/microvm.pb.go b/api/types/microvm.pb.go index bed809af..fb608d37 100644 --- a/api/types/microvm.pb.go +++ b/api/types/microvm.pb.go @@ -804,7 +804,8 @@ type VolumeSource struct { // Container is used to specify a source of a volume as a OCI container. ContainerSource *string `protobuf:"bytes,1,opt,name=container_source,json=containerSource,proto3,oneof" json:"container_source,omitempty"` - VirtiofsSource *string `protobuf:"bytes,2,opt,name=virtiofs_source,json=virtiofsSource,proto3,oneof" json:"virtiofs_source,omitempty"` + // Used for the virtiofs source path + VirtiofsSource *string `protobuf:"bytes,2,opt,name=virtiofs_source,json=virtiofsSource,proto3,oneof" json:"virtiofs_source,omitempty"` } func (x *VolumeSource) Reset() { diff --git a/api/types/microvm.proto b/api/types/microvm.proto index df13fe0a..d869d498 100644 --- a/api/types/microvm.proto +++ b/api/types/microvm.proto @@ -152,6 +152,7 @@ message VolumeSource { // Container is used to specify a source of a volume as a OCI container. optional string container_source = 1; + // Used for the virtiofs source path optional string virtiofs_source = 2; //TODO: add CSI diff --git a/core/models/capability.go b/core/models/capability.go index 9883eda1..c6efe1ef 100644 --- a/core/models/capability.go +++ b/core/models/capability.go @@ -16,6 +16,8 @@ const ( // MacvtapCapability is a capability that indocates the microvm provider // has support for macvtap network interfaces. MacvtapCapability Capability = "macvtap" + + VirtioFSCapability Capability = "virtiofs" ) // Capabilities represents a list of capabilities. diff --git a/core/plans/microvm_create_update.go b/core/plans/microvm_create_update.go index 8910b7a8..4ec741a5 100644 --- a/core/plans/microvm_create_update.go +++ b/core/plans/microvm_create_update.go @@ -66,6 +66,13 @@ func (p *microvmCreateOrUpdatePlan) Create(ctx context.Context) ([]planner.Proce return nil, fmt.Errorf("adding root dir step: %w", err) } + // MicroVM provider doesn't auto-start + if provider.Capabilities().Has(models.VirtioFSCapability) { + if err := p.addVirtioFSSteps(ctx, p.vm); err != nil { + return nil, fmt.Errorf("adding virtiofs steps: %w", err) + } + } + // Images if err := p.addImageSteps(ctx, p.vm, ports.ImageService); err != nil { return nil, fmt.Errorf("adding image steps: %w", err) @@ -121,6 +128,25 @@ func (p *microvmCreateOrUpdatePlan) addStep(ctx context.Context, step planner.Pr return nil } +func (p *microvmCreateOrUpdatePlan) addVirtioFSSteps(ctx context.Context, + vm *models.MicroVM, +) error { + rootStatus, ok := vm.Status.Volumes[vm.Spec.RootVolume.ID] + if !ok { + rootStatus = &models.VolumeStatus{} + vm.Status.Volumes[vm.Spec.RootVolume.ID] = rootStatus + } + if vm.Spec.RootVolume.Source.VirtioFS != nil { + if err := p.addStep(ctx, runtime.NewVirtioFSMount(&vm.ID, &vm.Spec.RootVolume, rootStatus)); err != nil { + return fmt.Errorf("adding virtiofs root mount step: %w", err) + } + } + + return nil +} + + + func (p *microvmCreateOrUpdatePlan) addImageSteps(ctx context.Context, vm *models.MicroVM, imageSvc ports.ImageService, diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs.go new file mode 100644 index 00000000..9248ed6c --- /dev/null +++ b/core/steps/runtime/virtiofs.go @@ -0,0 +1,68 @@ +package runtime + +import ( + "context" + // "fmt" + + "github.com/sirupsen/logrus" + + cerrs "github.com/liquidmetal-dev/flintlock/core/errors" + "github.com/liquidmetal-dev/flintlock/core/models" + "github.com/liquidmetal-dev/flintlock/pkg/log" + "github.com/liquidmetal-dev/flintlock/pkg/planner" +) + +func NewVirtioFSMount(vmid *models.VMID, + volume *models.Volume, + status *models.VolumeStatus, +) planner.Procedure { + return &volumeVirtioFSMount{ + vmid: vmid, + volume: volume, + status: status, + } +} + +type volumeVirtioFSMount struct { + vmid *models.VMID + volume *models.Volume + status *models.VolumeStatus +} + +// Name is the name of the procedure/operation. +func (s *volumeVirtioFSMount) Name() string { + return "runtime_virtiofs" +} + +func (s *volumeVirtioFSMount) ShouldDo(ctx context.Context) (bool, error) { + logger := log.GetLogger(ctx).WithFields(logrus.Fields{ + "step": s.Name(), + "id": s.volume.ID, + }) + logger.Debug("checking if procedure should be run") + + if s.status == nil || s.status.Mount.Source == "" { + return true, nil + } + + return true,nil +} + +// Do will perform the operation/procedure. +func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, error) { + if s.status == nil { + return nil, cerrs.ErrMissingStatusInfo + } + + logger := log.GetLogger(ctx).WithFields(logrus.Fields{ + "step": s.Name(), + "id": s.volume.ID, + }) + logger.Debug("running step for virtiofs volume") + + return nil,nil +} + +func (s *volumeVirtioFSMount) Verify(_ context.Context) error { + return nil +} diff --git a/infrastructure/grpc/convert.go b/infrastructure/grpc/convert.go index 987d3a18..2b3870b5 100644 --- a/infrastructure/grpc/convert.go +++ b/infrastructure/grpc/convert.go @@ -212,7 +212,11 @@ func convertModelToVolumne(modelVolume *models.Volume) *types.Volume { ContainerSource: (*string)(&modelVolume.Source.Container.Image), } } - + if modelVolume.Source.VirtioFS != nil { + convertedVol.Source = &types.VolumeSource{ + VirtiofsSource: (*string)(&modelVolume.Source.VirtioFS.Path), + } + } return convertedVol } diff --git a/infrastructure/grpc/server.go b/infrastructure/grpc/server.go index d9134817..5ff2f298 100644 --- a/infrastructure/grpc/server.go +++ b/infrastructure/grpc/server.go @@ -41,7 +41,7 @@ func (s *server) CreateMicroVM( //nolint:wrapcheck // don't wrap grpc errors when using the status package return nil, status.Error(codes.InvalidArgument, "invalid create microvm request: MicroVMSpec required") } - + logger.Infof("DEBUG VM: %s", req.Microvm) modelSpec, err := convertMicroVMToModel(req.Microvm) if err != nil { return nil, fmt.Errorf("converting request: %w", err) diff --git a/infrastructure/microvm/cloudhypervisor/provider.go b/infrastructure/microvm/cloudhypervisor/provider.go index dc8e5959..74cce667 100644 --- a/infrastructure/microvm/cloudhypervisor/provider.go +++ b/infrastructure/microvm/cloudhypervisor/provider.go @@ -58,7 +58,7 @@ type provider struct { // Capabilities returns a list of the capabilities the provider supports. func (p *provider) Capabilities() models.Capabilities { - return []models.Capability{models.AutoStartCapability, models.MacvtapCapability} + return []models.Capability{models.AutoStartCapability, models.MacvtapCapability, models.VirtioFSCapability} } // Start will start a created microvm. diff --git a/userdocs/docs/grpc/types/proto.md b/userdocs/docs/grpc/types/proto.md index 567fe305..76be9dc6 100644 --- a/userdocs/docs/grpc/types/proto.md +++ b/userdocs/docs/grpc/types/proto.md @@ -366,7 +366,7 @@ VolumeSource is the source of a volume. Based loosely on the volumes in Kubernet | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | container_source | [string](#string) | optional | Container is used to specify a source of a volume as a OCI container. | -| virtiofs_source | [string](#string) | optional | | +| virtiofs_source | [string](#string) | optional | Used for the virtiofs source path | From 05913feded2771993e7e1e7f40154e9aa6af1b12 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 15:28:51 -0500 Subject: [PATCH 15/35] fix convert --- core/models/volumes.go | 3 ++- core/plans/microvm_create_update.go | 2 +- infrastructure/grpc/convert.go | 22 +++++++++++----------- infrastructure/grpc/server.go | 5 +---- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/core/models/volumes.go b/core/models/volumes.go index 1f4b747d..24d29073 100644 --- a/core/models/volumes.go +++ b/core/models/volumes.go @@ -48,7 +48,8 @@ type VolumeSource struct { // Container is used to specify a source of a volume as a OCI container. Container *ContainerVolumeSource `json:"container,omitempty"` - VirtioFS *VirtioFSVolumeSource `json:"virtiofs,omitempty"` + // Used to specify path for virtiofsd + VirtioFS *VirtioFSVolumeSource `json:"virtiofs_source,omitempty"` } // ContainerDriveSource represents the details of a volume coming from a OCI image. diff --git a/core/plans/microvm_create_update.go b/core/plans/microvm_create_update.go index 4ec741a5..db6b3c99 100644 --- a/core/plans/microvm_create_update.go +++ b/core/plans/microvm_create_update.go @@ -66,7 +66,7 @@ func (p *microvmCreateOrUpdatePlan) Create(ctx context.Context) ([]planner.Proce return nil, fmt.Errorf("adding root dir step: %w", err) } - // MicroVM provider doesn't auto-start + // MicroVM provider doesn't have virtiofs if provider.Capabilities().Has(models.VirtioFSCapability) { if err := p.addVirtioFSSteps(ctx, p.vm); err != nil { return nil, fmt.Errorf("adding virtiofs steps: %w", err) diff --git a/infrastructure/grpc/convert.go b/infrastructure/grpc/convert.go index 2b3870b5..3a792e6b 100644 --- a/infrastructure/grpc/convert.go +++ b/infrastructure/grpc/convert.go @@ -57,7 +57,7 @@ func convertMicroVMToModel(spec *types.MicroVMSpec) (*models.MicroVM, error) { convertedModel.Spec.Initrd.Filename = *spec.Initrd.Filename } } - + if spec.RootVolume != nil { convertedModel.Spec.RootVolume = *convertVolumeToModel(spec.RootVolume) } @@ -132,7 +132,6 @@ func convertVolumeToModel(volume *types.Volume) *models.Volume { if volume.SizeInMb != nil { convertedVol.Size = *volume.SizeInMb } - if volume.Source != nil { if volume.Source.ContainerSource != nil { convertedVol.Source.Container = &models.ContainerVolumeSource{ @@ -142,14 +141,13 @@ func convertVolumeToModel(volume *types.Volume) *models.Volume { if volume.Source.VirtiofsSource != nil { convertedVol.Source.VirtioFS = &models.VirtioFSVolumeSource{ Path: *volume.Source.VirtiofsSource, - } + } } } - + if volume.MountPoint != nil { convertedVol.MountPoint = *volume.MountPoint } - return convertedVol } @@ -207,16 +205,18 @@ func convertModelToVolumne(modelVolume *models.Volume) *types.Volume { SizeInMb: &modelVolume.Size, } + volumeSource := &types.VolumeSource{} + if modelVolume.Source.Container != nil { - convertedVol.Source = &types.VolumeSource{ - ContainerSource: (*string)(&modelVolume.Source.Container.Image), - } + volumeSource.ContainerSource = (*string)(&modelVolume.Source.Container.Image) } if modelVolume.Source.VirtioFS != nil { - convertedVol.Source = &types.VolumeSource{ - VirtiofsSource: (*string)(&modelVolume.Source.VirtioFS.Path), - } + volumeSource.VirtiofsSource = (*string)(&modelVolume.Source.VirtioFS.Path) } + + // Assign the populated VolumeSource to the converted Volume + convertedVol.Source = volumeSource + return convertedVol } diff --git a/infrastructure/grpc/server.go b/infrastructure/grpc/server.go index 5ff2f298..e92c46f6 100644 --- a/infrastructure/grpc/server.go +++ b/infrastructure/grpc/server.go @@ -34,14 +34,13 @@ func (s *server) CreateMicroVM( ) (*mvmv1.CreateMicroVMResponse, error) { logger := log.GetLogger(ctx) logger.Trace("converting request to model") - + if req == nil || req.Microvm == nil { logger.Error("invalid create microvm request: MicroVMSpec required") //nolint:wrapcheck // don't wrap grpc errors when using the status package return nil, status.Error(codes.InvalidArgument, "invalid create microvm request: MicroVMSpec required") } - logger.Infof("DEBUG VM: %s", req.Microvm) modelSpec, err := convertMicroVMToModel(req.Microvm) if err != nil { return nil, fmt.Errorf("converting request: %w", err) @@ -56,8 +55,6 @@ func (s *server) CreateMicroVM( return nil, fmt.Errorf("creating microvm: %w", err) } - logger.Trace("converting model to response") - resp := &mvmv1.CreateMicroVMResponse{ Microvm: &types.MicroVM{ Version: int32(createdModel.Version), From d2065f7aaf598f218db42c6b792a6670449741bb Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 15:40:42 -0500 Subject: [PATCH 16/35] adding check for rootfs --- core/application/commands.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/application/commands.go b/core/application/commands.go index 01ae1fb0..a023e4fe 100644 --- a/core/application/commands.go +++ b/core/application/commands.go @@ -37,6 +37,10 @@ func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M return nil, fmt.Errorf("an error occurred when attempting to validate microvm spec: %w", validErr) } + if mvm.Spec.RootVolume.Source.VirtioFS != nil { + return nil, fmt.Errorf("VirtioFS is not available yet for RootVolume") + } + if mvm.ID.IsEmpty() { name, err := a.ports.IdentifierService.GenerateRandom() if err != nil { From 6ccb30e0c06cd3b547d3dcd9701777f4190eaa09 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 15:57:18 -0500 Subject: [PATCH 17/35] adding validation for virtiofs --- core/application/commands.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/application/commands.go b/core/application/commands.go index a023e4fe..3c98cf95 100644 --- a/core/application/commands.go +++ b/core/application/commands.go @@ -40,6 +40,25 @@ func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M if mvm.Spec.RootVolume.Source.VirtioFS != nil { return nil, fmt.Errorf("VirtioFS is not available yet for RootVolume") } + if len(mvm.Spec.AdditionalVolumes) > 0 { + virtioFSCount := 0 // Counter for VirtioFS volumes + + for _, volume := range mvm.Spec.AdditionalVolumes { + if volume.Source.Container != nil && volume.Source.VirtioFS != nil { + return nil, fmt.Errorf("Cannot have both ContainerSource and VirtioFS on the same volume") + } + + // Check if this volume has VirtioFS + if volume.Source.VirtioFS != nil { + virtioFSCount++ + } + } + + // Ensure only one volume contains VirtioFS + if virtioFSCount > 1 { + return nil, fmt.Errorf("Only one volume can have VirtioFS") + } + } if mvm.ID.IsEmpty() { name, err := a.ports.IdentifierService.GenerateRandom() From 408afb94d4c90b7aec8c3e1e67d0133e004d4546 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 19:56:55 -0500 Subject: [PATCH 18/35] finish initial --- core/plans/microvm_create_update.go | 37 ++++++------ core/steps/runtime/virtiofs.go | 59 ++++++++++++++++--- .../microvm/cloudhypervisor/create.go | 47 --------------- .../microvm/cloudhypervisor/provider.go | 3 +- infrastructure/microvm/providers.go | 1 - infrastructure/virtiofs/virtiofs.go | 45 ++++++++++++++ internal/command/flags/flags.go | 5 -- 7 files changed, 116 insertions(+), 81 deletions(-) create mode 100644 infrastructure/virtiofs/virtiofs.go diff --git a/core/plans/microvm_create_update.go b/core/plans/microvm_create_update.go index db6b3c99..861ab3f9 100644 --- a/core/plans/microvm_create_update.go +++ b/core/plans/microvm_create_update.go @@ -131,26 +131,29 @@ func (p *microvmCreateOrUpdatePlan) addStep(ctx context.Context, step planner.Pr func (p *microvmCreateOrUpdatePlan) addVirtioFSSteps(ctx context.Context, vm *models.MicroVM, ) error { - rootStatus, ok := vm.Status.Volumes[vm.Spec.RootVolume.ID] - if !ok { - rootStatus = &models.VolumeStatus{} - vm.Status.Volumes[vm.Spec.RootVolume.ID] = rootStatus - } - if vm.Spec.RootVolume.Source.VirtioFS != nil { - if err := p.addStep(ctx, runtime.NewVirtioFSMount(&vm.ID, &vm.Spec.RootVolume, rootStatus)); err != nil { - return fmt.Errorf("adding virtiofs root mount step: %w", err) + + for i := range vm.Spec.AdditionalVolumes { + vol := vm.Spec.AdditionalVolumes[i] + if vol.Source.VirtioFS != nil { + status, ok := vm.Status.Volumes[vol.ID] + if !ok { + status = &models.VolumeStatus{} + vm.Status.Volumes[vol.ID] = status + } + if err := p.addStep(ctx, runtime.NewVirtioFSMount(&vm.ID, &vol, status, p.stateDir)); err != nil { + return fmt.Errorf("adding volume mount step: %w", err) + } } } - + return nil } - - func (p *microvmCreateOrUpdatePlan) addImageSteps(ctx context.Context, vm *models.MicroVM, imageSvc ports.ImageService, ) error { + //TODO: Refactory for VirtioFS RootVol Support rootStatus, ok := vm.Status.Volumes[vm.Spec.RootVolume.ID] if !ok { rootStatus = &models.VolumeStatus{} @@ -165,14 +168,12 @@ func (p *microvmCreateOrUpdatePlan) addImageSteps(ctx context.Context, for i := range vm.Spec.AdditionalVolumes { vol := vm.Spec.AdditionalVolumes[i] - - status, ok := vm.Status.Volumes[vol.ID] - if !ok { - status = &models.VolumeStatus{} - vm.Status.Volumes[vol.ID] = status - } - if vol.Source.Container != nil { + status, ok := vm.Status.Volumes[vol.ID] + if !ok { + status = &models.VolumeStatus{} + vm.Status.Volumes[vol.ID] = status + } if err := p.addStep(ctx, runtime.NewVolumeMount(&vm.ID, &vol, status, imageSvc)); err != nil { return fmt.Errorf("adding volume mount step: %w", err) } diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs.go index 9248ed6c..4e64eaa2 100644 --- a/core/steps/runtime/virtiofs.go +++ b/core/steps/runtime/virtiofs.go @@ -1,25 +1,33 @@ package runtime import ( + "bytes" "context" - // "fmt" - - "github.com/sirupsen/logrus" + "fmt" + "os" + "os/exec" cerrs "github.com/liquidmetal-dev/flintlock/core/errors" "github.com/liquidmetal-dev/flintlock/core/models" + "github.com/liquidmetal-dev/flintlock/infrastructure/virtiofs" + "github.com/liquidmetal-dev/flintlock/pkg/defaults" "github.com/liquidmetal-dev/flintlock/pkg/log" "github.com/liquidmetal-dev/flintlock/pkg/planner" + "github.com/liquidmetal-dev/flintlock/pkg/process" + "github.com/sirupsen/logrus" + "github.com/spf13/afero" ) func NewVirtioFSMount(vmid *models.VMID, volume *models.Volume, status *models.VolumeStatus, + stateDir string, ) planner.Procedure { return &volumeVirtioFSMount{ - vmid: vmid, - volume: volume, - status: status, + vmid: vmid, + volume: volume, + status: status, + stateDir: stateDir, } } @@ -27,6 +35,7 @@ type volumeVirtioFSMount struct { vmid *models.VMID volume *models.Volume status *models.VolumeStatus + stateDir string } // Name is the name of the procedure/operation. @@ -44,8 +53,10 @@ func (s *volumeVirtioFSMount) ShouldDo(ctx context.Context) (bool, error) { if s.status == nil || s.status.Mount.Source == "" { return true, nil } + //TODO: MAKE THIS A VALID CHECK IF IT's MOUNTED + mounted := false - return true,nil + return !mounted,nil } // Do will perform the operation/procedure. @@ -58,7 +69,8 @@ func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, erro "step": s.Name(), "id": s.volume.ID, }) - logger.Debug("running step for virtiofs volume") + virtiofsState := virtiofs.NewVirtioFSState(*s.vmid, s.stateDir) + logger.Debug("running step for virtiofs volume: ", virtiofsState.VirtioFSPath()) return nil,nil } @@ -66,3 +78,34 @@ func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, erro func (s *volumeVirtioFSMount) Verify(_ context.Context) error { return nil } + + +func startVirtioFS(ctx context.Context, virtiofsState virtiofs.VirtioFSState, s *volumeVirtioFSMount) (*os.Process, error) { + fs := afero.NewOsFs() + + cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", + "--socket-path="+virtiofsState.VirtioFSPath(), + "--thread-pool-size=32", + "-o", "source=/mnt/user,cache=none,sandbox=chroot,announce_submounts,allow_direct_io") + stdOutFileVirtioFS, err := fs.OpenFile(virtiofsState.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening stdout file %s: %w", virtiofsState.VirtioFSStdoutPath(), err) + } + + stdErrFileVirtioFS, err := fs.OpenFile(virtiofsState.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening sterr file %s: %w", virtiofsState.VirtioFSStderrPath(), err) + } + + cmdVirtioFS.Stderr = stdErrFileVirtioFS + cmdVirtioFS.Stdout = stdOutFileVirtioFS + cmdVirtioFS.Stdin = &bytes.Buffer{} + + var startErr error + process.DetachedStart(cmdVirtioFS) + + if startErr != nil { + return nil, fmt.Errorf("starting virtiofsd process: %w", err) + } + return cmdVirtioFS.Process, nil +} \ No newline at end of file diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index 994ae879..b306534f 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -27,7 +27,6 @@ func (p *provider) Create(ctx context.Context, vm *models.MicroVM) error { logger.Debugf("creating microvm") vmState := NewState(vm.ID, p.config.StateRoot, p.fs) - if err := p.ensureState(vmState); err != nil { return fmt.Errorf("ensuring state dir: %w", err) } @@ -36,14 +35,6 @@ func (p *provider) Create(ctx context.Context, vm *models.MicroVM) error { return fmt.Errorf("creating metadata image: %w", err) } - procVFS, err := p.startVirtioFS(ctx, vm, vmState, logger) - if err != nil { - return fmt.Errorf("starting virtiofs process: %w", err) - } - if err = vmState.SetVirtioFSPid(procVFS.Pid); err != nil { - return fmt.Errorf("saving pid %d to file: %w", procVFS.Pid, err) - } - proc, err := p.startCloudHypervisor(ctx, vm, vmState, p.config.RunDetached, logger) if err != nil { return fmt.Errorf("starting cloudhypervisor process: %w", err) @@ -56,44 +47,6 @@ func (p *provider) Create(ctx context.Context, vm *models.MicroVM) error { return nil } -func (p *provider) startVirtioFS(_ context.Context, - vm *models.MicroVM, - state State, - logger *logrus.Entry, -) (*os.Process, error) { - - logger.Debugf("creating virtiofsd") - - cmdVirtioFS := exec.Command(p.config.VirtioFSBin, - "--socket-path="+state.VirtioFSPath(), - "--thread-pool-size=32", - "-o", "source=/mnt/user,cache=none,sandbox=chroot,announce_submounts,allow_direct_io") - stdOutFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) - if err != nil { - return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) - } - - stdErrFileVirtioFS, err := p.fs.OpenFile(state.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) - if err != nil { - return nil, fmt.Errorf("opening sterr file %s: %w", state.VirtioFSStderrPath(), err) - } - - cmdVirtioFS.Stderr = stdErrFileVirtioFS - cmdVirtioFS.Stdout = stdOutFileVirtioFS - cmdVirtioFS.Stdin = &bytes.Buffer{} - - var startErr error - process.DetachedStart(cmdVirtioFS) - - if startErr != nil { - return nil, fmt.Errorf("starting virtiofsd process: %w", err) - } - return cmdVirtioFS.Process, nil -} - - - - func (p *provider) startCloudHypervisor(_ context.Context, vm *models.MicroVM, state State, diff --git a/infrastructure/microvm/cloudhypervisor/provider.go b/infrastructure/microvm/cloudhypervisor/provider.go index 74cce667..c846450f 100644 --- a/infrastructure/microvm/cloudhypervisor/provider.go +++ b/infrastructure/microvm/cloudhypervisor/provider.go @@ -26,8 +26,7 @@ const ( type Config struct { // CloudHypervisorBin is the Cloud Hypervisor binary to use. CloudHypervisorBin string - // VirtioFSBin is the virtiofs binary to use. - VirtioFSBin string + // StateRoot is the folder to store any required state (i.e. socks, pid, log files). StateRoot string // RunDetached indicates that the cloud hypervisor processes diff --git a/infrastructure/microvm/providers.go b/infrastructure/microvm/providers.go index 4d69c447..0f7d3af0 100644 --- a/infrastructure/microvm/providers.go +++ b/infrastructure/microvm/providers.go @@ -70,7 +70,6 @@ func firecrackerConfig(cfg *config.Config) *firecracker.Config { func cloudHypervisorConfig(cfg *config.Config) *cloudhypervisor.Config { return &cloudhypervisor.Config{ CloudHypervisorBin: cfg.CloudHypervisorBin, - VirtioFSBin: cfg.VirtioFSBin, RunDetached: cfg.CloudHypervisorDetatch, StateRoot: cfg.StateRootDir + "/vm", } diff --git a/infrastructure/virtiofs/virtiofs.go b/infrastructure/virtiofs/virtiofs.go new file mode 100644 index 00000000..7eba72eb --- /dev/null +++ b/infrastructure/virtiofs/virtiofs.go @@ -0,0 +1,45 @@ +package virtiofs + +import ( + "fmt" + + "github.com/liquidmetal-dev/flintlock/core/models" +) + + +type VirtioFSState interface { + + // VirtioPID() (int, error) + VirtioFSPIDPath() string + // SetVirtioFSPid(pid int) error + + VirtioFSPath() string + VirtioFSStdoutPath() string + VirtioFSStderrPath() string +} + +func NewVirtioFSState(vmid models.VMID, stateDir string) VirtioFSState { + return &vFSState{ + stateRoot: fmt.Sprintf("%s/%s", stateDir, vmid.String()), + } +} + +type vFSState struct { + stateRoot string +} + +func (s *vFSState) VirtioFSPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.sock") +} + +func (s *vFSState) VirtioFSStdoutPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.stdout") +} + +func (s *vFSState) VirtioFSStderrPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.pid") +} + +func (s *vFSState) VirtioFSPIDPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.pid") +} \ No newline at end of file diff --git a/internal/command/flags/flags.go b/internal/command/flags/flags.go index 80da8153..8e56e6f2 100644 --- a/internal/command/flags/flags.go +++ b/internal/command/flags/flags.go @@ -31,7 +31,6 @@ const ( tlsClientCAFlag = "tls-client-ca" debugEndpointFlag = "debug-endpoint" cloudHypervisorBinFlag = "cloudhypervisor-bin" - virtioFSBinFlag = "virtiofs-bin" cloudHypervisorDetachFlag = "cloudhypervisor-detach" ) @@ -204,10 +203,6 @@ func addCloudHypervisorFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { cloudHypervisorBinFlag, defaults.CloudHypervisorBin, "The path to the cloud hypervisor binary to use.") - cmd.Flags().StringVar(&cfg.VirtioFSBin, - virtioFSBinFlag, - defaults.VirtioFSBin, - "The path to the virtiofs binary to use.") cmd.Flags().BoolVar(&cfg.CloudHypervisorDetatch, cloudHypervisorDetachFlag, defaults.CloudHypervisorDetach, From 87e2388ca2d3bbddb74367f995a421ae54f591b0 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Thu, 26 Dec 2024 20:16:32 -0500 Subject: [PATCH 19/35] testing --- core/steps/runtime/virtiofs.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs.go index 4e64eaa2..d8f5c677 100644 --- a/core/steps/runtime/virtiofs.go +++ b/core/steps/runtime/virtiofs.go @@ -70,8 +70,11 @@ func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, erro "id": s.volume.ID, }) virtiofsState := virtiofs.NewVirtioFSState(*s.vmid, s.stateDir) + err := startVirtioFS(ctx, virtiofsState, s) logger.Debug("running step for virtiofs volume: ", virtiofsState.VirtioFSPath()) - + if err != nil { + return nil,fmt.Errorf("starting cloudhypervisor process: %w", err) + } return nil,nil } @@ -80,21 +83,21 @@ func (s *volumeVirtioFSMount) Verify(_ context.Context) error { } -func startVirtioFS(ctx context.Context, virtiofsState virtiofs.VirtioFSState, s *volumeVirtioFSMount) (*os.Process, error) { +func startVirtioFS(ctx context.Context, virtiofsState virtiofs.VirtioFSState, s *volumeVirtioFSMount) (error) { fs := afero.NewOsFs() - + options := fmt.Sprintf("source=%s,cache=none,sandbox=chroot,announce_submounts,allow_direct_io", s.volume.Source.VirtioFS.Path) cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", "--socket-path="+virtiofsState.VirtioFSPath(), "--thread-pool-size=32", - "-o", "source=/mnt/user,cache=none,sandbox=chroot,announce_submounts,allow_direct_io") + "-o", options) stdOutFileVirtioFS, err := fs.OpenFile(virtiofsState.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { - return nil, fmt.Errorf("opening stdout file %s: %w", virtiofsState.VirtioFSStdoutPath(), err) + return fmt.Errorf("opening stdout file %s: %w", virtiofsState.VirtioFSStdoutPath(), err) } stdErrFileVirtioFS, err := fs.OpenFile(virtiofsState.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { - return nil, fmt.Errorf("opening sterr file %s: %w", virtiofsState.VirtioFSStderrPath(), err) + return fmt.Errorf("opening sterr file %s: %w", virtiofsState.VirtioFSStderrPath(), err) } cmdVirtioFS.Stderr = stdErrFileVirtioFS @@ -105,7 +108,7 @@ func startVirtioFS(ctx context.Context, virtiofsState virtiofs.VirtioFSState, s process.DetachedStart(cmdVirtioFS) if startErr != nil { - return nil, fmt.Errorf("starting virtiofsd process: %w", err) + return fmt.Errorf("starting virtiofsd process: %w", err) } - return cmdVirtioFS.Process, nil + return nil } \ No newline at end of file From f165fdd4e7d37aa9a2cc466722afaacc186680a9 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 15:32:50 -0500 Subject: [PATCH 20/35] reimplement framework --- core/plans/microvm_create_update.go | 6 +-- core/ports/collection.go | 1 + core/ports/services.go | 14 +++++++ core/steps/runtime/virtiofs.go | 57 ++++++----------------------- infrastructure/virtiofs/virtiofs.go | 51 +++++++++----------------- internal/inject/wire.go | 7 +++- internal/inject/wire_gen.go | 7 +++- 7 files changed, 56 insertions(+), 87 deletions(-) diff --git a/core/plans/microvm_create_update.go b/core/plans/microvm_create_update.go index 861ab3f9..6381dbec 100644 --- a/core/plans/microvm_create_update.go +++ b/core/plans/microvm_create_update.go @@ -140,9 +140,9 @@ func (p *microvmCreateOrUpdatePlan) addVirtioFSSteps(ctx context.Context, status = &models.VolumeStatus{} vm.Status.Volumes[vol.ID] = status } - if err := p.addStep(ctx, runtime.NewVirtioFSMount(&vm.ID, &vol, status, p.stateDir)); err != nil { - return fmt.Errorf("adding volume mount step: %w", err) - } + // if err := p.addStep(ctx, runtime.NewVirtioFSMount(&vm.ID, &vol, status, p.stateDir)); err != nil { + // return fmt.Errorf("adding volume mount step: %w", err) + // } } } diff --git a/core/ports/collection.go b/core/ports/collection.go index e881cd48..73522ee9 100644 --- a/core/ports/collection.go +++ b/core/ports/collection.go @@ -16,4 +16,5 @@ type Collection struct { DiskService DiskService FileSystem afero.Fs Clock func() time.Time + VirtioFSService VirtioFSService } diff --git a/core/ports/services.go b/core/ports/services.go index f5cb4b97..25f4d4cc 100644 --- a/core/ports/services.go +++ b/core/ports/services.go @@ -187,3 +187,17 @@ type DiskFile struct { // ContentBase64 is the content of the file encoded as base64. ContentBase64 string } + + + +// Create VirtioFSInput are the input options for creating a disk. +type VirtioFSCreateInput struct { + Path string +} + + +// MicroVMService is the port definition for a microvm service. +type VirtioFSService interface { + // Create will create a new microvm. + Create(ctx context.Context, inout VirtioFSCreateInput) error +} \ No newline at end of file diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs.go index d8f5c677..d838d447 100644 --- a/core/steps/runtime/virtiofs.go +++ b/core/steps/runtime/virtiofs.go @@ -1,33 +1,27 @@ package runtime import ( - "bytes" "context" "fmt" - "os" - "os/exec" cerrs "github.com/liquidmetal-dev/flintlock/core/errors" "github.com/liquidmetal-dev/flintlock/core/models" - "github.com/liquidmetal-dev/flintlock/infrastructure/virtiofs" - "github.com/liquidmetal-dev/flintlock/pkg/defaults" "github.com/liquidmetal-dev/flintlock/pkg/log" "github.com/liquidmetal-dev/flintlock/pkg/planner" - "github.com/liquidmetal-dev/flintlock/pkg/process" "github.com/sirupsen/logrus" - "github.com/spf13/afero" + "github.com/liquidmetal-dev/flintlock/core/ports" ) func NewVirtioFSMount(vmid *models.VMID, volume *models.Volume, status *models.VolumeStatus, - stateDir string, + vfsSvc ports.VirtioFSService, ) planner.Procedure { return &volumeVirtioFSMount{ vmid: vmid, volume: volume, status: status, - stateDir: stateDir, + vFSService: vfsSvc, } } @@ -35,7 +29,7 @@ type volumeVirtioFSMount struct { vmid *models.VMID volume *models.Volume status *models.VolumeStatus - stateDir string + vFSService ports.VirtioFSService } // Name is the name of the procedure/operation. @@ -69,46 +63,17 @@ func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, erro "step": s.Name(), "id": s.volume.ID, }) - virtiofsState := virtiofs.NewVirtioFSState(*s.vmid, s.stateDir) - err := startVirtioFS(ctx, virtiofsState, s) - logger.Debug("running step for virtiofs volume: ", virtiofsState.VirtioFSPath()) - if err != nil { - return nil,fmt.Errorf("starting cloudhypervisor process: %w", err) + logger.Trace("Creating VirtioFS") + vol := &ports.VirtioFSCreateInput{ + Path: s.volume.Source.VirtioFS.Path, + } + + if err := s.vFSService.Create(ctx, *vol); err != nil { + return nil, fmt.Errorf("creating microvm: %w", err) } return nil,nil } func (s *volumeVirtioFSMount) Verify(_ context.Context) error { return nil -} - - -func startVirtioFS(ctx context.Context, virtiofsState virtiofs.VirtioFSState, s *volumeVirtioFSMount) (error) { - fs := afero.NewOsFs() - options := fmt.Sprintf("source=%s,cache=none,sandbox=chroot,announce_submounts,allow_direct_io", s.volume.Source.VirtioFS.Path) - cmdVirtioFS := exec.Command("/usr/libexec/virtiofsd", - "--socket-path="+virtiofsState.VirtioFSPath(), - "--thread-pool-size=32", - "-o", options) - stdOutFileVirtioFS, err := fs.OpenFile(virtiofsState.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) - if err != nil { - return fmt.Errorf("opening stdout file %s: %w", virtiofsState.VirtioFSStdoutPath(), err) - } - - stdErrFileVirtioFS, err := fs.OpenFile(virtiofsState.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) - if err != nil { - return fmt.Errorf("opening sterr file %s: %w", virtiofsState.VirtioFSStderrPath(), err) - } - - cmdVirtioFS.Stderr = stdErrFileVirtioFS - cmdVirtioFS.Stdout = stdOutFileVirtioFS - cmdVirtioFS.Stdin = &bytes.Buffer{} - - var startErr error - process.DetachedStart(cmdVirtioFS) - - if startErr != nil { - return fmt.Errorf("starting virtiofsd process: %w", err) - } - return nil } \ No newline at end of file diff --git a/infrastructure/virtiofs/virtiofs.go b/infrastructure/virtiofs/virtiofs.go index 7eba72eb..bf832456 100644 --- a/infrastructure/virtiofs/virtiofs.go +++ b/infrastructure/virtiofs/virtiofs.go @@ -1,45 +1,28 @@ package virtiofs import ( - "fmt" - - "github.com/liquidmetal-dev/flintlock/core/models" + "context" + "github.com/spf13/afero" + "github.com/liquidmetal-dev/flintlock/core/ports" + "github.com/liquidmetal-dev/flintlock/internal/config" ) - -type VirtioFSState interface { - - // VirtioPID() (int, error) - VirtioFSPIDPath() string - // SetVirtioFSPid(pid int) error - - VirtioFSPath() string - VirtioFSStdoutPath() string - VirtioFSStderrPath() string -} - -func NewVirtioFSState(vmid models.VMID, stateDir string) VirtioFSState { - return &vFSState{ - stateRoot: fmt.Sprintf("%s/%s", stateDir, vmid.String()), +// New will create a new instance of the VirtioFS. +func New(cfg *config.Config, + fs afero.Fs, +) (ports.VirtioFSService) { + return &vFSService{ + config: cfg, + fs: fs, } } -type vFSState struct { - stateRoot string -} - -func (s *vFSState) VirtioFSPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.sock") -} - -func (s *vFSState) VirtioFSStdoutPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.stdout") -} - -func (s *vFSState) VirtioFSStderrPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.pid") +type vFSService struct { + config *config.Config + fs afero.Fs } -func (s *vFSState) VirtioFSPIDPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, "/virtiofs.pid") +// Create will create a new disk. +func (s *vFSService) Create(_ context.Context, input ports.VirtioFSCreateInput) error { + return nil } \ No newline at end of file diff --git a/internal/inject/wire.go b/internal/inject/wire.go index 8b28bb79..67b6b4d4 100644 --- a/internal/inject/wire.go +++ b/internal/inject/wire.go @@ -16,6 +16,7 @@ import ( "github.com/liquidmetal-dev/flintlock/infrastructure/godisk" microvmgrpc "github.com/liquidmetal-dev/flintlock/infrastructure/grpc" "github.com/liquidmetal-dev/flintlock/infrastructure/microvm" + "github.com/liquidmetal-dev/flintlock/infrastructure/virtiofs" "github.com/liquidmetal-dev/flintlock/infrastructure/network" "github.com/liquidmetal-dev/flintlock/infrastructure/ulid" "github.com/liquidmetal-dev/flintlock/internal/config" @@ -33,7 +34,8 @@ func InitializePorts(cfg *config.Config) (*ports.Collection, error) { appPorts, containerdConfig, networkConfig, - afero.NewOsFs) + afero.NewOsFs, + virtiofs.New) return nil, nil } @@ -80,7 +82,7 @@ func appConfig(cfg *config.Config) *application.Config { } } -func appPorts(repo ports.MicroVMRepository, providers map[string]ports.MicroVMService, es ports.EventService, is ports.IDService, ns ports.NetworkService, ims ports.ImageService, fs afero.Fs, ds ports.DiskService) *ports.Collection { +func appPorts(repo ports.MicroVMRepository, providers map[string]ports.MicroVMService, es ports.EventService, is ports.IDService, ns ports.NetworkService, ims ports.ImageService, fs afero.Fs, ds ports.DiskService, vfs ports.VirtioFSService) *ports.Collection { return &ports.Collection{ Repo: repo, MicrovmProviders: providers, @@ -91,6 +93,7 @@ func appPorts(repo ports.MicroVMRepository, providers map[string]ports.MicroVMSe FileSystem: fs, Clock: time.Now, DiskService: ds, + VirtioFSService: vfs, } } diff --git a/internal/inject/wire_gen.go b/internal/inject/wire_gen.go index 1395b718..a0ce9303 100644 --- a/internal/inject/wire_gen.go +++ b/internal/inject/wire_gen.go @@ -16,6 +16,7 @@ import ( "github.com/liquidmetal-dev/flintlock/infrastructure/microvm" "github.com/liquidmetal-dev/flintlock/infrastructure/network" "github.com/liquidmetal-dev/flintlock/infrastructure/ulid" + "github.com/liquidmetal-dev/flintlock/infrastructure/virtiofs" "github.com/liquidmetal-dev/flintlock/internal/config" "github.com/liquidmetal-dev/flintlock/pkg/defaults" "github.com/spf13/afero" @@ -47,7 +48,8 @@ func InitializePorts(cfg *config.Config) (*ports.Collection, error) { if err != nil { return nil, err } - collection := appPorts(microVMRepository, v, eventService, idService, networkService, imageService, fs, diskService) + virtioFSService := virtiofs.New(cfg, fs) + collection := appPorts(microVMRepository, v, eventService, idService, networkService, imageService, fs, diskService, virtioFSService) return collection, nil } @@ -98,7 +100,7 @@ func appConfig(cfg *config.Config) *application.Config { } } -func appPorts(repo ports.MicroVMRepository, providers map[string]ports.MicroVMService, es ports.EventService, is ports.IDService, ns ports.NetworkService, ims ports.ImageService, fs afero.Fs, ds ports.DiskService) *ports.Collection { +func appPorts(repo ports.MicroVMRepository, providers map[string]ports.MicroVMService, es ports.EventService, is ports.IDService, ns ports.NetworkService, ims ports.ImageService, fs afero.Fs, ds ports.DiskService, vfs ports.VirtioFSService) *ports.Collection { return &ports.Collection{ Repo: repo, MicrovmProviders: providers, @@ -109,6 +111,7 @@ func appPorts(repo ports.MicroVMRepository, providers map[string]ports.MicroVMSe FileSystem: fs, Clock: time.Now, DiskService: ds, + VirtioFSService: vfs, } } From c1ce99b0c4fc4024eb7ef6052253dc15e4337864 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 15:55:18 -0500 Subject: [PATCH 21/35] changing var --- core/steps/runtime/virtiofs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs.go index d838d447..c4e04b6e 100644 --- a/core/steps/runtime/virtiofs.go +++ b/core/steps/runtime/virtiofs.go @@ -64,11 +64,11 @@ func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, erro "id": s.volume.ID, }) logger.Trace("Creating VirtioFS") - vol := &ports.VirtioFSCreateInput{ + vol := ports.VirtioFSCreateInput{ Path: s.volume.Source.VirtioFS.Path, } - if err := s.vFSService.Create(ctx, *vol); err != nil { + if err := s.vFSService.Create(ctx, vol); err != nil { return nil, fmt.Errorf("creating microvm: %w", err) } return nil,nil From dc8d46888777cce87bc96245f16150558cf30701 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 18:13:02 -0500 Subject: [PATCH 22/35] move to custom validator for no rootfs virtiofs --- core/models/microvm.go | 2 +- pkg/validation/validate.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/models/microvm.go b/core/models/microvm.go index 442a250a..16d7f338 100644 --- a/core/models/microvm.go +++ b/core/models/microvm.go @@ -38,7 +38,7 @@ type MicroVMSpec struct { // NetworkInterfaces specifies the network interfaces attached to the machine. NetworkInterfaces []NetworkInterface `json:"network_interfaces" validate:"required,dive,required"` // RootVolume specified the root volume to be attached to the machine. - RootVolume Volume `json:"root_volume" validate:"required"` + RootVolume Volume `json:"root_volume" validate:"required,novirtiofs"` // AdditionalVolumes specifies the volumes to be attached to the machine. AdditionalVolumes Volumes `json:"additional_volumes"` // Metadata allows you to specify data to be added to the metadata service. The key is the name diff --git a/pkg/validation/validate.go b/pkg/validation/validate.go index 66b894a4..04e971d7 100644 --- a/pkg/validation/validate.go +++ b/pkg/validation/validate.go @@ -26,6 +26,7 @@ func NewValidator() Validator { _ = validator.RegisterValidation("imageURI", customImageURIValidator, false) _ = validator.RegisterValidation("datetimeInPast", customTimestampValidator, false) _ = validator.RegisterValidation("guestDeviceName", customNetworkGuestDeviceNameValidator, false) + _ = validator.RegisterValidation("novirtiofs", customNoVirtioFSValidator, false) validator.RegisterStructValidation(customMicroVMSpecStructLevelValidation, models.MicroVMSpec{}) return &validate{ @@ -78,3 +79,8 @@ func customMicroVMSpecStructLevelValidation(structLevel playgroundValidator.Stru return } } + +func customNoVirtioFSValidator(fieldLevel playgroundValidator.FieldLevel) bool { + field, _ := fieldLevel.Field().Interface().(models.Volume) + return field.Source.VirtioFS != nil +} \ No newline at end of file From aa2f3b4d8a6e330f45fe677d8fcb5ebbb5d7f05a Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 18:34:28 -0500 Subject: [PATCH 23/35] moving the rest of the validation to field level --- core/application/commands.go | 23 ----------------------- core/models/microvm.go | 2 +- pkg/validation/validate.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/core/application/commands.go b/core/application/commands.go index 3c98cf95..da8ed02c 100644 --- a/core/application/commands.go +++ b/core/application/commands.go @@ -36,30 +36,7 @@ func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M if validErr := validator.ValidateStruct(mvm); validErr != nil { return nil, fmt.Errorf("an error occurred when attempting to validate microvm spec: %w", validErr) } - - if mvm.Spec.RootVolume.Source.VirtioFS != nil { - return nil, fmt.Errorf("VirtioFS is not available yet for RootVolume") - } - if len(mvm.Spec.AdditionalVolumes) > 0 { - virtioFSCount := 0 // Counter for VirtioFS volumes - - for _, volume := range mvm.Spec.AdditionalVolumes { - if volume.Source.Container != nil && volume.Source.VirtioFS != nil { - return nil, fmt.Errorf("Cannot have both ContainerSource and VirtioFS on the same volume") - } - - // Check if this volume has VirtioFS - if volume.Source.VirtioFS != nil { - virtioFSCount++ - } - } - // Ensure only one volume contains VirtioFS - if virtioFSCount > 1 { - return nil, fmt.Errorf("Only one volume can have VirtioFS") - } - } - if mvm.ID.IsEmpty() { name, err := a.ports.IdentifierService.GenerateRandom() if err != nil { diff --git a/core/models/microvm.go b/core/models/microvm.go index 16d7f338..cd9d2d81 100644 --- a/core/models/microvm.go +++ b/core/models/microvm.go @@ -40,7 +40,7 @@ type MicroVMSpec struct { // RootVolume specified the root volume to be attached to the machine. RootVolume Volume `json:"root_volume" validate:"required,novirtiofs"` // AdditionalVolumes specifies the volumes to be attached to the machine. - AdditionalVolumes Volumes `json:"additional_volumes"` + AdditionalVolumes Volumes `json:"additional_volumes" validate:"onlyOneVirtioFS,multipleVolSources"` // Metadata allows you to specify data to be added to the metadata service. The key is the name // of the metadata item and the value is the base64 encoded contents of the metadata. Metadata map[string]string `json:"metadata"` diff --git a/pkg/validation/validate.go b/pkg/validation/validate.go index 04e971d7..7b89626f 100644 --- a/pkg/validation/validate.go +++ b/pkg/validation/validate.go @@ -27,6 +27,8 @@ func NewValidator() Validator { _ = validator.RegisterValidation("datetimeInPast", customTimestampValidator, false) _ = validator.RegisterValidation("guestDeviceName", customNetworkGuestDeviceNameValidator, false) _ = validator.RegisterValidation("novirtiofs", customNoVirtioFSValidator, false) + _ = validator.RegisterValidation("onlyOneVirtioFS", customOnlyOneVirtioFSValidator, false) + _ = validator.RegisterValidation("multipleVolSources", customMultipleVolSources, false) validator.RegisterStructValidation(customMicroVMSpecStructLevelValidation, models.MicroVMSpec{}) return &validate{ @@ -83,4 +85,33 @@ func customMicroVMSpecStructLevelValidation(structLevel playgroundValidator.Stru func customNoVirtioFSValidator(fieldLevel playgroundValidator.FieldLevel) bool { field, _ := fieldLevel.Field().Interface().(models.Volume) return field.Source.VirtioFS != nil +} + +func customOnlyOneVirtioFSValidator(fieldLevel playgroundValidator.FieldLevel) bool { + field, _ := fieldLevel.Field().Interface().(models.Volumes) + virtioFSCount := 0 // Counter for VirtioFS volumes + if len(field) > 0 { + for _, volume := range field { + // Check if this volume has VirtioFS + if volume.Source.VirtioFS != nil { + virtioFSCount++ + } + } + } + return virtioFSCount > 1 +} + +func customMultipleVolSources(fieldLevel playgroundValidator.FieldLevel) bool { + field, _ := fieldLevel.Field().Interface().(models.Volumes) + if len(field) > 0 { + for _, volume := range field { + // Check if this volume has VirtioFS + if volume.Source.VirtioFS != nil { + } + if volume.Source.Container != nil && volume.Source.VirtioFS != nil { + return true + } + } + } + return false } \ No newline at end of file From 8f8e04e168570655b50ac30943d36f9f692e9278 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 18:35:32 -0500 Subject: [PATCH 24/35] remove extra if statement --- pkg/validation/validate.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/validation/validate.go b/pkg/validation/validate.go index 7b89626f..aa3c802b 100644 --- a/pkg/validation/validate.go +++ b/pkg/validation/validate.go @@ -105,9 +105,6 @@ func customMultipleVolSources(fieldLevel playgroundValidator.FieldLevel) bool { field, _ := fieldLevel.Field().Interface().(models.Volumes) if len(field) > 0 { for _, volume := range field { - // Check if this volume has VirtioFS - if volume.Source.VirtioFS != nil { - } if volume.Source.Container != nil && volume.Source.VirtioFS != nil { return true } From 98661f506b65a83a65264f897cd574faf180bb00 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 19:42:15 -0500 Subject: [PATCH 25/35] finish new structure (added virtiofs state) --- core/ports/services.go | 2 +- core/steps/runtime/virtiofs.go | 2 +- infrastructure/virtiofs/state.go | 64 +++++++++++++++++++++++++++++ infrastructure/virtiofs/virtiofs.go | 53 +++++++++++++++++++++++- 4 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 infrastructure/virtiofs/state.go diff --git a/core/ports/services.go b/core/ports/services.go index 25f4d4cc..b6198a0a 100644 --- a/core/ports/services.go +++ b/core/ports/services.go @@ -199,5 +199,5 @@ type VirtioFSCreateInput struct { // MicroVMService is the port definition for a microvm service. type VirtioFSService interface { // Create will create a new microvm. - Create(ctx context.Context, inout VirtioFSCreateInput) error + Create(ctx context.Context, vmid *models.VMID, inout VirtioFSCreateInput) error } \ No newline at end of file diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs.go index c4e04b6e..ed455266 100644 --- a/core/steps/runtime/virtiofs.go +++ b/core/steps/runtime/virtiofs.go @@ -68,7 +68,7 @@ func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, erro Path: s.volume.Source.VirtioFS.Path, } - if err := s.vFSService.Create(ctx, vol); err != nil { + if err := s.vFSService.Create(ctx, s.vmid, vol); err != nil { return nil, fmt.Errorf("creating microvm: %w", err) } return nil,nil diff --git a/infrastructure/virtiofs/state.go b/infrastructure/virtiofs/state.go new file mode 100644 index 00000000..3f6f0237 --- /dev/null +++ b/infrastructure/virtiofs/state.go @@ -0,0 +1,64 @@ +package virtiofs + +import ( + "fmt" + + "github.com/spf13/afero" + + "github.com/liquidmetal-dev/flintlock/core/models" + "github.com/liquidmetal-dev/flintlock/infrastructure/microvm/shared" +) + +const ( + pidVirtioFSFileName = "virtiofs.pid" + stdErrVirtioFSFileName = "virtiofs.stderr" + stdOutVirtioFSFileName = "virtiofs.stdout" + socketVirtiofsFileName = "virtiofs.sock" +) + +type State interface { + + VirtioPID() (int, error) + VirtioFSPIDPath() string + SetVirtioFSPid(pid int) error + + VirtioFSPath() string + VirtioFSStdoutPath() string + VirtioFSStderrPath() string +} + +func NewState(vmid models.VMID, stateDir string, fs afero.Fs) State { + return &fsState{ + stateRoot: fmt.Sprintf("%s/%s", stateDir, vmid.String()), + fs: fs, + } +} + +type fsState struct { + stateRoot string + fs afero.Fs +} + +func (s *fsState) VirtioFSPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, socketVirtiofsFileName) +} + +func (s *fsState) VirtioFSStdoutPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, stdOutVirtioFSFileName) +} + +func (s *fsState) VirtioFSStderrPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, stdErrVirtioFSFileName) +} + +func (s *fsState) VirtioFSPIDPath() string { + return fmt.Sprintf("%s/%s", s.stateRoot, pidVirtioFSFileName) +} + +func (s *fsState) VirtioPID() (int, error) { + return shared.PIDReadFromFile(s.VirtioFSPIDPath(), s.fs) +} + +func (s *fsState) SetVirtioFSPid(pid int) error { + return shared.PIDWriteToFile(pid, s.VirtioFSPIDPath(), s.fs) +} \ No newline at end of file diff --git a/infrastructure/virtiofs/virtiofs.go b/infrastructure/virtiofs/virtiofs.go index bf832456..c9e05529 100644 --- a/infrastructure/virtiofs/virtiofs.go +++ b/infrastructure/virtiofs/virtiofs.go @@ -1,10 +1,17 @@ package virtiofs import ( + "fmt" + "os" + "os/exec" "context" + "bytes" "github.com/spf13/afero" "github.com/liquidmetal-dev/flintlock/core/ports" "github.com/liquidmetal-dev/flintlock/internal/config" + "github.com/liquidmetal-dev/flintlock/pkg/defaults" + "github.com/liquidmetal-dev/flintlock/pkg/process" + "github.com/liquidmetal-dev/flintlock/core/models" ) // New will create a new instance of the VirtioFS. @@ -22,7 +29,49 @@ type vFSService struct { fs afero.Fs } -// Create will create a new disk. -func (s *vFSService) Create(_ context.Context, input ports.VirtioFSCreateInput) error { +// Create will start and create a virtiofsd process +func (s *vFSService) Create(ctx context.Context, vmid *models.VMID, input ports.VirtioFSCreateInput) error { + state := NewState(*vmid,s.config.StateRootDir, s.fs) + procVFS, err := s.startVirtioFS(ctx ,input,state) + if err != nil { + return fmt.Errorf("starting virtiofs process: %w", err) + } + if err = state.SetVirtioFSPid(procVFS.Pid); err != nil { + return fmt.Errorf("saving pid %d to file: %w", procVFS.Pid, err) + } return nil +} + + + +func (s *vFSService) startVirtioFS(_ context.Context, + input ports.VirtioFSCreateInput, + state State, +) (*os.Process, error) { + options := fmt.Sprintf("source=%s,cache=none,sandbox=chroot,announce_submounts,allow_direct_io", input.Path) + cmdVirtioFS := exec.Command(s.config.VirtioFSBin, + "--socket-path="+state.VirtioFSPath(), + "--thread-pool-size=32", + "-o", options) + stdOutFileVirtioFS, err := s.fs.OpenFile(state.VirtioFSStdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening stdout file %s: %w", state.VirtioFSStdoutPath(), err) + } + + stdErrFileVirtioFS, err := s.fs.OpenFile(state.VirtioFSStderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) + if err != nil { + return nil, fmt.Errorf("opening sterr file %s: %w", state.VirtioFSStderrPath(), err) + } + + cmdVirtioFS.Stderr = stdErrFileVirtioFS + cmdVirtioFS.Stdout = stdOutFileVirtioFS + cmdVirtioFS.Stdin = &bytes.Buffer{} + + var startErr error + process.DetachedStart(cmdVirtioFS) + + if startErr != nil { + return nil, fmt.Errorf("starting virtiofsd process: %w", err) + } + return cmdVirtioFS.Process, nil } \ No newline at end of file From 5daf4673ff52ca512e19d4b32b4272a0e1c59605 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 19:48:48 -0500 Subject: [PATCH 26/35] adding flag back to for virtiofs --- internal/command/flags/flags.go | 11 ++++++++++- internal/command/run/run.go | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/command/flags/flags.go b/internal/command/flags/flags.go index 8e56e6f2..91818c0f 100644 --- a/internal/command/flags/flags.go +++ b/internal/command/flags/flags.go @@ -32,6 +32,7 @@ const ( debugEndpointFlag = "debug-endpoint" cloudHypervisorBinFlag = "cloudhypervisor-bin" cloudHypervisorDetachFlag = "cloudhypervisor-detach" + virtioFSBinFlag = "virtiofs-bin" ) // AddGRPCServerFlagsToCommand will add gRPC server flags to the supplied command. @@ -162,6 +163,7 @@ func AddMicrovmProviderFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { cmd.Flags().StringVar(&cfg.DefaultVMProvider, "default-provider", firecracker.ProviderName, "The name of the microvm provider to use by default if not supplied in the create request.") } + // AddContainerDFlagsToCommand will add the containerd specific flags to the supplied cobra command. func AddContainerDFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { cmd.Flags().StringVar(&cfg.CtrSocketPath, @@ -187,6 +189,13 @@ func AddDebugFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { "The endpoint for the debug web server to listen on. It must include a port (e.g. localhost:10500). An empty string means disable the debug endpoint.") } +func AddVirtioFSFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { + cmd.Flags().StringVar(&cfg.VirtioFSBin, + virtioFSBinFlag, + defaults.VirtioFSBin, + "The path to the virtiofs binary to use.") +} + func addFirecrackerFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { cmd.Flags().StringVar(&cfg.FirecrackerBin, firecrackerBinFlag, @@ -207,4 +216,4 @@ func addCloudHypervisorFlagsToCommand(cmd *cobra.Command, cfg *config.Config) { cloudHypervisorDetachFlag, defaults.CloudHypervisorDetach, "If true the child cloud hypervisor processes will be detached from the parent flintlock process.") -} +} \ No newline at end of file diff --git a/internal/command/run/run.go b/internal/command/run/run.go index 206af178..9bd09b29 100644 --- a/internal/command/run/run.go +++ b/internal/command/run/run.go @@ -81,6 +81,7 @@ func NewCommand(cfg *config.Config) (*cobra.Command, error) { cmdflags.AddMicrovmProviderFlagsToCommand(cmd, cfg) cmdflags.AddDebugFlagsToCommand(cmd, cfg) cmdflags.AddGWServerFlagsToCommand(cmd, cfg) + cmdflags.AddVirtioFSFlagsToCommand(cmd, cfg) if err := cmdflags.AddNetworkFlagsToCommand(cmd, cfg); err != nil { return nil, fmt.Errorf("adding network flags to run command: %w", err) From b0ba078d9dea82944c879853caf065b24c40a546 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 20:04:01 -0500 Subject: [PATCH 27/35] fix tests --- pkg/validation/validate.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/validation/validate.go b/pkg/validation/validate.go index aa3c802b..389a97b5 100644 --- a/pkg/validation/validate.go +++ b/pkg/validation/validate.go @@ -84,7 +84,7 @@ func customMicroVMSpecStructLevelValidation(structLevel playgroundValidator.Stru func customNoVirtioFSValidator(fieldLevel playgroundValidator.FieldLevel) bool { field, _ := fieldLevel.Field().Interface().(models.Volume) - return field.Source.VirtioFS != nil + return field.Source.VirtioFS == nil } func customOnlyOneVirtioFSValidator(fieldLevel playgroundValidator.FieldLevel) bool { @@ -98,7 +98,7 @@ func customOnlyOneVirtioFSValidator(fieldLevel playgroundValidator.FieldLevel) b } } } - return virtioFSCount > 1 + return !(virtioFSCount > 1) } func customMultipleVolSources(fieldLevel playgroundValidator.FieldLevel) bool { @@ -106,9 +106,9 @@ func customMultipleVolSources(fieldLevel playgroundValidator.FieldLevel) bool { if len(field) > 0 { for _, volume := range field { if volume.Source.Container != nil && volume.Source.VirtioFS != nil { - return true + return false } } } - return false + return true } \ No newline at end of file From e410f2e7098a597542fabfc0d8f280dec356bcbe Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 29 Dec 2024 21:50:44 -0500 Subject: [PATCH 28/35] adding creation call for tests --- core/plans/microvm_create_update.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/plans/microvm_create_update.go b/core/plans/microvm_create_update.go index 6381dbec..ca406e15 100644 --- a/core/plans/microvm_create_update.go +++ b/core/plans/microvm_create_update.go @@ -68,7 +68,7 @@ func (p *microvmCreateOrUpdatePlan) Create(ctx context.Context) ([]planner.Proce // MicroVM provider doesn't have virtiofs if provider.Capabilities().Has(models.VirtioFSCapability) { - if err := p.addVirtioFSSteps(ctx, p.vm); err != nil { + if err := p.addVirtioFSSteps(ctx, p.vm, ports.VirtioFSService); err != nil { return nil, fmt.Errorf("adding virtiofs steps: %w", err) } } @@ -130,6 +130,7 @@ func (p *microvmCreateOrUpdatePlan) addStep(ctx context.Context, step planner.Pr func (p *microvmCreateOrUpdatePlan) addVirtioFSSteps(ctx context.Context, vm *models.MicroVM, + vfsService ports.VirtioFSService, ) error { for i := range vm.Spec.AdditionalVolumes { @@ -140,9 +141,9 @@ func (p *microvmCreateOrUpdatePlan) addVirtioFSSteps(ctx context.Context, status = &models.VolumeStatus{} vm.Status.Volumes[vol.ID] = status } - // if err := p.addStep(ctx, runtime.NewVirtioFSMount(&vm.ID, &vol, status, p.stateDir)); err != nil { - // return fmt.Errorf("adding volume mount step: %w", err) - // } + if err := p.addStep(ctx, runtime.NewVirtioFSMount(&vm.ID, &vol, status, vfsService)); err != nil { + return fmt.Errorf("adding volume mount step: %w", err) + } } } From 7b63c755aeee5eaf209fd126feb8f8bab74548d0 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 5 Jan 2025 10:17:24 -0500 Subject: [PATCH 29/35] fixing state dir for virtiofs --- infrastructure/virtiofs/state.go | 8 +++++++- infrastructure/virtiofs/virtiofs.go | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/infrastructure/virtiofs/state.go b/infrastructure/virtiofs/state.go index 3f6f0237..9d782559 100644 --- a/infrastructure/virtiofs/state.go +++ b/infrastructure/virtiofs/state.go @@ -18,6 +18,7 @@ const ( type State interface { + Root() string VirtioPID() (int, error) VirtioFSPIDPath() string SetVirtioFSPid(pid int) error @@ -25,11 +26,12 @@ type State interface { VirtioFSPath() string VirtioFSStdoutPath() string VirtioFSStderrPath() string + } func NewState(vmid models.VMID, stateDir string, fs afero.Fs) State { return &fsState{ - stateRoot: fmt.Sprintf("%s/%s", stateDir, vmid.String()), + stateRoot: fmt.Sprintf("%s/vm/%s", stateDir, vmid.String()), fs: fs, } } @@ -39,6 +41,10 @@ type fsState struct { fs afero.Fs } +func (s *fsState) Root() string { + return s.stateRoot +} + func (s *fsState) VirtioFSPath() string { return fmt.Sprintf("%s/%s", s.stateRoot, socketVirtiofsFileName) } diff --git a/infrastructure/virtiofs/virtiofs.go b/infrastructure/virtiofs/virtiofs.go index c9e05529..3d6a41ea 100644 --- a/infrastructure/virtiofs/virtiofs.go +++ b/infrastructure/virtiofs/virtiofs.go @@ -32,6 +32,9 @@ type vFSService struct { // Create will start and create a virtiofsd process func (s *vFSService) Create(ctx context.Context, vmid *models.VMID, input ports.VirtioFSCreateInput) error { state := NewState(*vmid,s.config.StateRootDir, s.fs) + if err := s.ensureState(state); err != nil { + return fmt.Errorf("ensuring state dir: %w", err) + } procVFS, err := s.startVirtioFS(ctx ,input,state) if err != nil { return fmt.Errorf("starting virtiofs process: %w", err) @@ -74,4 +77,19 @@ func (s *vFSService) startVirtioFS(_ context.Context, return nil, fmt.Errorf("starting virtiofsd process: %w", err) } return cmdVirtioFS.Process, nil -} \ No newline at end of file +} + + +func (s *vFSService) ensureState(state State) error { + exists, err := afero.DirExists(s.fs, state.Root()) + if err != nil { + return fmt.Errorf("checking if state dir %s exists: %w", state.Root(), err) + } + + if !exists { + if err = s.fs.MkdirAll(state.Root(), defaults.DataDirPerm); err != nil { + return fmt.Errorf("creating state directory %s: %w", state.Root(), err) + } + } + return nil +} From 55aa5c3178263c8e0f58c1a5a7659e2ab6930d03 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 5 Jan 2025 12:54:53 -0500 Subject: [PATCH 30/35] fix tests and push working prototype --- core/plans/microvm_create_update_test.go | 2 +- core/ports/services.go | 2 +- core/steps/runtime/virtiofs.go | 13 +++---- .../microvm/cloudhypervisor/create.go | 13 +++++-- .../microvm/cloudhypervisor/state.go | 36 ------------------- infrastructure/virtiofs/state.go | 2 +- infrastructure/virtiofs/virtiofs.go | 16 +++++---- 7 files changed, 30 insertions(+), 54 deletions(-) diff --git a/core/plans/microvm_create_update_test.go b/core/plans/microvm_create_update_test.go index 072c5851..d0003ace 100644 --- a/core/plans/microvm_create_update_test.go +++ b/core/plans/microvm_create_update_test.go @@ -41,7 +41,7 @@ func TestMicroVMCreateOrUpdatePlan(t *testing.T) { EXPECT(). Create(gomock.Any(), gomock.Any()) - mList.MicroVMService.EXPECT().Capabilities().Return(models.Capabilities{}) + mList.MicroVMService.EXPECT().Capabilities().Return(models.Capabilities{}).Times(2) mList.MicroVMService. EXPECT(). diff --git a/core/ports/services.go b/core/ports/services.go index b6198a0a..94fc08a5 100644 --- a/core/ports/services.go +++ b/core/ports/services.go @@ -199,5 +199,5 @@ type VirtioFSCreateInput struct { // MicroVMService is the port definition for a microvm service. type VirtioFSService interface { // Create will create a new microvm. - Create(ctx context.Context, vmid *models.VMID, inout VirtioFSCreateInput) error + Create(ctx context.Context, vmid *models.VMID, inout VirtioFSCreateInput) (*models.Mount,error) } \ No newline at end of file diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs.go index ed455266..898f4c86 100644 --- a/core/steps/runtime/virtiofs.go +++ b/core/steps/runtime/virtiofs.go @@ -47,10 +47,8 @@ func (s *volumeVirtioFSMount) ShouldDo(ctx context.Context) (bool, error) { if s.status == nil || s.status.Mount.Source == "" { return true, nil } - //TODO: MAKE THIS A VALID CHECK IF IT's MOUNTED - mounted := false - - return !mounted,nil + + return false,nil } // Do will perform the operation/procedure. @@ -67,10 +65,13 @@ func (s *volumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, erro vol := ports.VirtioFSCreateInput{ Path: s.volume.Source.VirtioFS.Path, } - - if err := s.vFSService.Create(ctx, s.vmid, vol); err != nil { + mount, err := s.vFSService.Create(ctx, s.vmid, vol) + if err != nil { return nil, fmt.Errorf("creating microvm: %w", err) } + if mount != nil { + s.status.Mount = *mount + } return nil,nil } diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index b306534f..dbeaf5fe 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -16,6 +16,9 @@ import ( "github.com/liquidmetal-dev/flintlock/pkg/defaults" "github.com/liquidmetal-dev/flintlock/pkg/log" "github.com/liquidmetal-dev/flintlock/pkg/process" + + virtiofs "github.com/liquidmetal-dev/flintlock/infrastructure/virtiofs" + ) // Create will create a new microvm. @@ -25,7 +28,6 @@ func (p *provider) Create(ctx context.Context, vm *models.MicroVM) error { "vmid": vm.ID.String(), }) logger.Debugf("creating microvm") - vmState := NewState(vm.ID, p.config.StateRoot, p.fs) if err := p.ensureState(vmState); err != nil { return fmt.Errorf("ensuring state dir: %w", err) @@ -119,7 +121,6 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( } args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) - args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024", state.VirtioFSPath())) for _, vol := range vm.Spec.AdditionalVolumes { @@ -127,7 +128,13 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( if !ok { return nil, cerrors.NewVolumeNotMounted(vol.ID) } - args = append(args, "path="+status.Mount.Source) + if vol.Source.VirtioFS != nil { + vfsstate := virtiofs.NewState(vm.ID,p.config.StateRoot, p.fs) + args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024", vfsstate.VirtioFSPath())) + + } else { + args = append(args, "path="+status.Mount.Source) + } } // Network interfaces diff --git a/infrastructure/microvm/cloudhypervisor/state.go b/infrastructure/microvm/cloudhypervisor/state.go index 2dcfa37e..f200eb0f 100644 --- a/infrastructure/microvm/cloudhypervisor/state.go +++ b/infrastructure/microvm/cloudhypervisor/state.go @@ -14,10 +14,6 @@ const ( logFileName = "cloudhypervisor.log" stdOutFileName = "cloudhypervisor.stdout" stdErrFileName = "cloudhypervisor.stderr" - pidVirtioFSFileName = "virtiofs.pid" - stdErrVirtioFSFileName = "virtiofs.stderr" - stdOutVirtioFSFileName = "virtiofs.stdout" - socketVirtiofsFileName = "virtiofs.sock" socketFileName = "cloudhypervisor.sock" cloudInitFileName = "cloud-init.img" ) @@ -34,14 +30,6 @@ type State interface { StderrPath() string SockPath() string - VirtioPID() (int, error) - VirtioFSPIDPath() string - SetVirtioFSPid(pid int) error - - VirtioFSPath() string - VirtioFSStdoutPath() string - VirtioFSStderrPath() string - CloudInitImage() string } @@ -91,28 +79,4 @@ func (s *fsState) CloudInitImage() string { func (s *fsState) SetPid(pid int) error { return shared.PIDWriteToFile(pid, s.PIDPath(), s.fs) -} - -func (s *fsState) VirtioFSPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, socketVirtiofsFileName) -} - -func (s *fsState) VirtioFSStdoutPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, stdOutVirtioFSFileName) -} - -func (s *fsState) VirtioFSStderrPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, stdErrVirtioFSFileName) -} - -func (s *fsState) VirtioFSPIDPath() string { - return fmt.Sprintf("%s/%s", s.stateRoot, pidVirtioFSFileName) -} - -func (s *fsState) VirtioPID() (int, error) { - return shared.PIDReadFromFile(s.VirtioFSPIDPath(), s.fs) -} - -func (s *fsState) SetVirtioFSPid(pid int) error { - return shared.PIDWriteToFile(pid, s.VirtioFSPIDPath(), s.fs) } \ No newline at end of file diff --git a/infrastructure/virtiofs/state.go b/infrastructure/virtiofs/state.go index 9d782559..a682d431 100644 --- a/infrastructure/virtiofs/state.go +++ b/infrastructure/virtiofs/state.go @@ -31,7 +31,7 @@ type State interface { func NewState(vmid models.VMID, stateDir string, fs afero.Fs) State { return &fsState{ - stateRoot: fmt.Sprintf("%s/vm/%s", stateDir, vmid.String()), + stateRoot: fmt.Sprintf("%s/%s", stateDir, vmid.String()), fs: fs, } } diff --git a/infrastructure/virtiofs/virtiofs.go b/infrastructure/virtiofs/virtiofs.go index 3d6a41ea..e5531c63 100644 --- a/infrastructure/virtiofs/virtiofs.go +++ b/infrastructure/virtiofs/virtiofs.go @@ -30,19 +30,23 @@ type vFSService struct { } // Create will start and create a virtiofsd process -func (s *vFSService) Create(ctx context.Context, vmid *models.VMID, input ports.VirtioFSCreateInput) error { - state := NewState(*vmid,s.config.StateRootDir, s.fs) +func (s *vFSService) Create(ctx context.Context, vmid *models.VMID, input ports.VirtioFSCreateInput) (*models.Mount, error) { + state := NewState(*vmid,s.config.StateRootDir + "/vm", s.fs) if err := s.ensureState(state); err != nil { - return fmt.Errorf("ensuring state dir: %w", err) + return nil, fmt.Errorf("ensuring state dir: %w", err) } procVFS, err := s.startVirtioFS(ctx ,input,state) if err != nil { - return fmt.Errorf("starting virtiofs process: %w", err) + return nil,fmt.Errorf("starting virtiofs process: %w", err) } if err = state.SetVirtioFSPid(procVFS.Pid); err != nil { - return fmt.Errorf("saving pid %d to file: %w", procVFS.Pid, err) + return nil,fmt.Errorf("saving pid %d to file: %w", procVFS.Pid, err) } - return nil + mount := models.Mount{ + Source: state.VirtioFSPath(), + Type: "hostpath", + } + return &mount,nil } From f3e5f3a552c13a32e8953072d1717e1c07e3424b Mon Sep 17 00:00:00 2001 From: Steven Fraser Date: Sun, 5 Jan 2025 12:56:02 -0500 Subject: [PATCH 31/35] Update core/ports/services.go Co-authored-by: Richard Case --- core/ports/services.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ports/services.go b/core/ports/services.go index 94fc08a5..79bc5223 100644 --- a/core/ports/services.go +++ b/core/ports/services.go @@ -198,6 +198,6 @@ type VirtioFSCreateInput struct { // MicroVMService is the port definition for a microvm service. type VirtioFSService interface { - // Create will create a new microvm. + // Create will create a new virtiofs share. Create(ctx context.Context, vmid *models.VMID, inout VirtioFSCreateInput) (*models.Mount,error) } \ No newline at end of file From 5c77bff4f363015156860ff9757007369b40de75 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Sun, 5 Jan 2025 17:47:15 -0500 Subject: [PATCH 32/35] adding inital delete step --- core/plans/microvm_delete.go | 27 ++++++++ core/ports/services.go | 8 ++- .../{virtiofs.go => virtiofs_create.go} | 2 +- core/steps/runtime/virtiofs_delete.go | 69 +++++++++++++++++++ infrastructure/virtiofs/virtiofs.go | 65 +++++++++++++++-- 5 files changed, 165 insertions(+), 6 deletions(-) rename core/steps/runtime/{virtiofs.go => virtiofs_create.go} (98%) create mode 100644 core/steps/runtime/virtiofs_delete.go diff --git a/core/plans/microvm_delete.go b/core/plans/microvm_delete.go index 9f8f0f6d..ee90d68c 100644 --- a/core/plans/microvm_delete.go +++ b/core/plans/microvm_delete.go @@ -68,6 +68,10 @@ func (p *microvmDeletePlan) Create(ctx context.Context) ([]planner.Procedure, er return nil, fmt.Errorf("adding microvm delete step: %w", err) } + if err := p.addVirtioFSSteps(ctx, p.vm, ports.VirtioFSService, provider); err != nil { + return nil, fmt.Errorf("adding virtiofs steps: %w", err) + } + if err := p.addStep(ctx, runtime.NewRepoRelease(p.vm, ports.Repo)); err != nil { return nil, fmt.Errorf("adding release lease step: %w", err) } @@ -139,3 +143,26 @@ func (p *microvmDeletePlan) addNetworkSteps( return nil } + + +func (p *microvmDeletePlan) addVirtioFSSteps( + ctx context.Context, + vm *models.MicroVM, + vfsService ports.VirtioFSService, + vmService ports.MicroVMService, +) error { + for i := range vm.Spec.AdditionalVolumes { + vol := vm.Spec.AdditionalVolumes[i] + if vol.Source.VirtioFS != nil { + status:= vm.Status.Volumes[vol.ID] + if status != nil && status.Mount.Source != "" { + step := runtime.NewDeleteVirtioFSMount(&vm.ID, &vol,status,vmService,vfsService) + if err := p.addStep(ctx, step); err != nil { + return fmt.Errorf("adding delete network interface step: %w", err) + } + } + } + } + + return nil +} \ No newline at end of file diff --git a/core/ports/services.go b/core/ports/services.go index 79bc5223..deacf602 100644 --- a/core/ports/services.go +++ b/core/ports/services.go @@ -195,9 +195,15 @@ type VirtioFSCreateInput struct { Path string } +type VirtioFSDeleteInput struct { + Path string +} -// MicroVMService is the port definition for a microvm service. +// VirtiofsService is the port definition for a VirtioFS service. type VirtioFSService interface { // Create will create a new virtiofs share. Create(ctx context.Context, vmid *models.VMID, inout VirtioFSCreateInput) (*models.Mount,error) + Delete(ctx context.Context, vmid *models.VMID) (error) + HasVirtioFSDProcess(ctx context.Context, vmid *models.VMID) (bool, error) + } \ No newline at end of file diff --git a/core/steps/runtime/virtiofs.go b/core/steps/runtime/virtiofs_create.go similarity index 98% rename from core/steps/runtime/virtiofs.go rename to core/steps/runtime/virtiofs_create.go index 898f4c86..103b6142 100644 --- a/core/steps/runtime/virtiofs.go +++ b/core/steps/runtime/virtiofs_create.go @@ -34,7 +34,7 @@ type volumeVirtioFSMount struct { // Name is the name of the procedure/operation. func (s *volumeVirtioFSMount) Name() string { - return "runtime_virtiofs" + return "runtime_virtiofs_create" } func (s *volumeVirtioFSMount) ShouldDo(ctx context.Context) (bool, error) { diff --git a/core/steps/runtime/virtiofs_delete.go b/core/steps/runtime/virtiofs_delete.go new file mode 100644 index 00000000..5a6e5d97 --- /dev/null +++ b/core/steps/runtime/virtiofs_delete.go @@ -0,0 +1,69 @@ +package runtime + +import ( + "context" + "fmt" + cerrs "github.com/liquidmetal-dev/flintlock/core/errors" + "github.com/liquidmetal-dev/flintlock/core/models" + "github.com/liquidmetal-dev/flintlock/pkg/log" + "github.com/liquidmetal-dev/flintlock/pkg/planner" + "github.com/sirupsen/logrus" + "github.com/liquidmetal-dev/flintlock/core/ports" +) + +func NewDeleteVirtioFSMount(vmid *models.VMID, + volume *models.Volume, + status *models.VolumeStatus, + vmSvc ports.MicroVMService, + vfsSvc ports.VirtioFSService, +) planner.Procedure { + return &deleteVolumeVirtioFSMount{ + vmid: vmid, + volume: volume, + status: status, + vFSService: vfsSvc, + vmSvc: vmSvc, + vfsSvc: vfsSvc, + } +} + +type deleteVolumeVirtioFSMount struct { + vmid *models.VMID + volume *models.Volume + status *models.VolumeStatus + vFSService ports.VirtioFSService + vmSvc ports.MicroVMService + vfsSvc ports.VirtioFSService +} + +// Name is the name of the procedure/operation. +func (s *deleteVolumeVirtioFSMount) Name() string { + return "runtime_virtiofs_delete" +} + +func (s *deleteVolumeVirtioFSMount) ShouldDo(ctx context.Context) (bool, error) { + logger := log.GetLogger(ctx).WithFields(logrus.Fields{ + "step": s.Name(), + "id": s.volume.ID, + }) + logger.Debug("checking if procedure should be run") + + + return s.vFSService.HasVirtioFSDProcess(ctx,s.vmid) +} + +// Do will perform the operation/procedure. +func (s *deleteVolumeVirtioFSMount) Do(ctx context.Context) ([]planner.Procedure, error) { + if s.status == nil { + return nil, cerrs.ErrMissingStatusInfo + } + if err := s.vFSService.Delete(ctx, s.vmid); err != nil { + return nil, fmt.Errorf("deleting viritofsd: %w", err) + } + + return nil,nil +} + +func (s *deleteVolumeVirtioFSMount) Verify(_ context.Context) error { + return nil +} \ No newline at end of file diff --git a/infrastructure/virtiofs/virtiofs.go b/infrastructure/virtiofs/virtiofs.go index e5531c63..0ae3dfe8 100644 --- a/infrastructure/virtiofs/virtiofs.go +++ b/infrastructure/virtiofs/virtiofs.go @@ -1,17 +1,22 @@ package virtiofs import ( + "bytes" + "context" "fmt" "os" "os/exec" - "context" - "bytes" - "github.com/spf13/afero" + "syscall" + "time" + + "github.com/liquidmetal-dev/flintlock/core/models" "github.com/liquidmetal-dev/flintlock/core/ports" "github.com/liquidmetal-dev/flintlock/internal/config" "github.com/liquidmetal-dev/flintlock/pkg/defaults" + "github.com/liquidmetal-dev/flintlock/pkg/log" "github.com/liquidmetal-dev/flintlock/pkg/process" - "github.com/liquidmetal-dev/flintlock/core/models" + "github.com/sirupsen/logrus" + "github.com/spf13/afero" ) // New will create a new instance of the VirtioFS. @@ -49,6 +54,58 @@ func (s *vFSService) Create(ctx context.Context, vmid *models.VMID, input ports. return &mount,nil } +// Create will start and create a virtiofsd process +func (s *vFSService) Delete(ctx context.Context, vmid *models.VMID) (error) { + logger := log.GetLogger(ctx).WithFields(logrus.Fields{ + "service": "virtiofs_delete", + "vmid": vmid.String(), + }) + state := NewState(*vmid,s.config.StateRootDir + "/vm", s.fs) + pid, pidErr := state.VirtioPID() + if pidErr != nil { + fmt.Printf("unable to get PID: %s", pidErr) + } + fmt.Printf("Found Pid %d\n", pid) + processExists, err := process.Exists(pid) + if err != nil { + return fmt.Errorf("checking if virtiofsd process is running: %w", err) + } + if !processExists { + return nil + } + logger.Debugf("sending SIGTERM to %d", pid) + + if sigErr := process.SendSignal(pid, syscall.SIGTERM); sigErr != nil { + return fmt.Errorf("failed to terminate with SIGHUP: %w", sigErr) + } + + ctxTimeout, cancel := context.WithTimeout(ctx,200*time.Millisecond) + defer cancel() + + // Make sure the virtiofsd is stopped. + if err := process.WaitWithContext(ctxTimeout, pid); err != nil { + return fmt.Errorf("failed to wait for pid %d: %w", pid, err) + } + + return nil +} + +// Create will start and create a virtiofsd process +func (s *vFSService) HasVirtioFSDProcess(ctx context.Context, vmid *models.VMID) (bool,error) { + state := NewState(*vmid,s.config.StateRootDir + "/vm", s.fs) + pid, pidErr := state.VirtioPID() + if pidErr != nil { + return false,nil + } + processExists, err := process.Exists(pid) + if err != nil { + return false,nil + } + if !processExists { + return false,nil + } + return true,nil +} func (s *vFSService) startVirtioFS(_ context.Context, From 744f32255c86e3fd88d83e3cd282fa6b0b736939 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Mon, 6 Jan 2025 09:23:11 -0500 Subject: [PATCH 33/35] adding virtiofs capability check --- core/plans/microvm_delete.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/plans/microvm_delete.go b/core/plans/microvm_delete.go index ee90d68c..56b4a33b 100644 --- a/core/plans/microvm_delete.go +++ b/core/plans/microvm_delete.go @@ -67,11 +67,13 @@ func (p *microvmDeletePlan) Create(ctx context.Context) ([]planner.Procedure, er if err := p.addStep(ctx, microvm.NewDeleteStep(p.vm, provider)); err != nil { return nil, fmt.Errorf("adding microvm delete step: %w", err) } - - if err := p.addVirtioFSSteps(ctx, p.vm, ports.VirtioFSService, provider); err != nil { - return nil, fmt.Errorf("adding virtiofs steps: %w", err) + if provider.Capabilities().Has(models.VirtioFSCapability) { + if err := p.addVirtioFSSteps(ctx, p.vm, ports.VirtioFSService, provider); err != nil { + return nil, fmt.Errorf("adding virtiofs steps: %w", err) + } } + if err := p.addStep(ctx, runtime.NewRepoRelease(p.vm, ports.Repo)); err != nil { return nil, fmt.Errorf("adding release lease step: %w", err) } From 9d22d0d0bfe20156e04638f5c3488a95948eb3ac Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Mon, 6 Jan 2025 09:29:25 -0500 Subject: [PATCH 34/35] moving shared memory under virtiofs --- infrastructure/microvm/cloudhypervisor/create.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/infrastructure/microvm/cloudhypervisor/create.go b/infrastructure/microvm/cloudhypervisor/create.go index dbeaf5fe..021cedaf 100644 --- a/infrastructure/microvm/cloudhypervisor/create.go +++ b/infrastructure/microvm/cloudhypervisor/create.go @@ -112,7 +112,6 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( // CPU and memory args = append(args, "--cpus", fmt.Sprintf("boot=%d", vm.Spec.VCPU)) - args = append(args, "--memory", fmt.Sprintf("size=%dM,shared=on", vm.Spec.MemoryInMb)) // Volumes (root, additional, metadata) rootVolumeStatus, volumeStatusFound := vm.Status.Volumes[vm.Spec.RootVolume.ID] @@ -122,7 +121,7 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( args = append(args, "--disk", "path="+rootVolumeStatus.Mount.Source) args = append(args, fmt.Sprintf("path=%s,readonly=on", state.CloudInitImage())) - + hasVirtioFS := false for _, vol := range vm.Spec.AdditionalVolumes { status, ok := vm.Status.Volumes[vol.ID] if !ok { @@ -131,11 +130,17 @@ func (p *provider) buildArgs(vm *models.MicroVM, state State, _ *logrus.Entry) ( if vol.Source.VirtioFS != nil { vfsstate := virtiofs.NewState(vm.ID,p.config.StateRoot, p.fs) args = append(args, "--fs", fmt.Sprintf("tag=user,socket=%s,num_queues=1,queue_size=1024", vfsstate.VirtioFSPath())) + hasVirtioFS = true } else { args = append(args, "path="+status.Mount.Source) } } + if hasVirtioFS { + args = append(args, "--memory", fmt.Sprintf("size=%dM,shared=on", vm.Spec.MemoryInMb)) + } else { + args = append(args, "--memory", fmt.Sprintf("size=%dM", vm.Spec.MemoryInMb)) + } // Network interfaces for i := range vm.Spec.NetworkInterfaces { From 89bdf199910e4b6acc5d5003418c1256b8f32f91 Mon Sep 17 00:00:00 2001 From: Steve Fraser Date: Mon, 6 Jan 2025 09:37:49 -0500 Subject: [PATCH 35/35] adding error checking for virtiofs --- core/application/commands.go | 7 +++++++ core/application/errors.go | 1 + 2 files changed, 8 insertions(+) diff --git a/core/application/commands.go b/core/application/commands.go index da8ed02c..dcaeb4cd 100644 --- a/core/application/commands.go +++ b/core/application/commands.go @@ -94,6 +94,13 @@ func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M } } } + if !provider.Capabilities().Has(models.VirtioFSCapability) { + for _, volume := range mvm.Spec.AdditionalVolumes { + if volume.Source.VirtioFS != nil { + return nil, errVirtioFSNotSupported + } + } + } err = a.addInstanceData(mvm, logger) if err != nil { diff --git a/core/application/errors.go b/core/application/errors.go index f3d25b2b..d295181b 100644 --- a/core/application/errors.go +++ b/core/application/errors.go @@ -10,6 +10,7 @@ import ( var ( errUIDRequired = errors.New("uid is required") errMacvtapNotSupported = errors.New("macvtap network interfaces not supported by the microvm provider") + errVirtioFSNotSupported = errors.New("Virtiofs not supported by the microvm provider") ) type specAlreadyExistsError struct {