From 8b5a10459f83410f5e87617d64a81a5db64f713a Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Thu, 19 May 2022 15:30:53 +0200 Subject: [PATCH] Add virtiofs device support This makes it possible to share files with the VM. For now it's limited to one shared directory, which should be enough for our initial needs. https://github.com/Code-Hex/vz/pull/28 is not merged yet, so this relies on a Code-Hex/vz fork in my own GitHub namespace which has the shared folder API. This fixes https://github.com/code-ready/vfkit/issues/2 --- go.mod | 8 ++++--- go.sum | 12 +++++------ pkg/client/cmdline.go | 23 ++++++++++++++++++++ pkg/config/virtio.go | 50 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 316f7be7..18628ddc 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,14 @@ module github.com/code-ready/vfkit go 1.16 require ( - github.com/Code-Hex/vz v0.0.5-0.20220406150231-a2ebc854a261 + github.com/Code-Hex/vz v0.0.5-0.20211218053248-d70a0533bf8e github.com/docker/go-units v0.4.0 github.com/h2non/filetype v1.1.3 - github.com/rs/xid v1.4.0 // indirect + github.com/rs/xid v1.3.0 // indirect github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.3.0 - golang.org/x/sys v0.0.0-20220519141025-dcacdad47464 + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 inet.af/tcpproxy v0.0.0-20210824174053-2e577fef49e2 ) + +replace github.com/Code-Hex/vz => github.com/cfergeau/vz v0.0.5-0.20220629154958-9aad23fce70e diff --git a/go.sum b/go.sum index 4b799594..ed2820d8 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,6 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Code-Hex/vz v0.0.5-0.20220406150231-a2ebc854a261 h1:7cU//dP3rZzrIdk1ytc2h5/N3ikjVJljvb5KbU7+lGs= -github.com/Code-Hex/vz v0.0.5-0.20220406150231-a2ebc854a261/go.mod h1:BMgSoDpuZx8xZe5Ycxf5DJ5OewlWadVu40v/O1ZmVuQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -72,6 +70,8 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cfergeau/vz v0.0.5-0.20220629154958-9aad23fce70e h1:W34omdFFqjYSMud3wFeomOWqG9fO6MJ8hcADzEK4RKk= +github.com/cfergeau/vz v0.0.5-0.20220629154958-9aad23fce70e/go.mod h1:BMgSoDpuZx8xZe5Ycxf5DJ5OewlWadVu40v/O1ZmVuQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -302,8 +302,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= @@ -533,8 +533,8 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220519141025-dcacdad47464 h1:MpIuURY70f0iKp/oooEFtB2oENcHITo/z1b6u41pKCw= -golang.org/x/sys v0.0.0-20220519141025-dcacdad47464/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/pkg/client/cmdline.go b/pkg/client/cmdline.go index 8a0a4d1c..7bf2925d 100644 --- a/pkg/client/cmdline.go +++ b/pkg/client/cmdline.go @@ -45,6 +45,11 @@ type virtioSerial struct { logFile string } +type virtioFs struct { + sharedDir string + mountTag string +} + func NewVirtualMachine(vcpus uint, memoryBytes uint64, bootloader *Bootloader) *VirtualMachine { return &VirtualMachine{ vcpus: vcpus, @@ -194,3 +199,21 @@ func (dev *virtioSerial) ToCmdLine() ([]string, error) { } return []string{"--device", fmt.Sprintf("virtio-serial,logFilePath=%s", dev.logFile)}, nil } + +func VirtioFsNew(sharedDir string, mountTag string) (VirtioDevice, error) { + return &virtioFs{ + sharedDir: sharedDir, + mountTag: mountTag, + }, nil +} + +func (dev *virtioFs) ToCmdLine() ([]string, error) { + if dev.sharedDir == "" { + return nil, fmt.Errorf("virtio-fs needs the path to the directory to share") + } + if dev.mountTag != "" { + return []string{"--device", fmt.Sprintf("virtio-fs,sharedDir=%s,mountTag=%s", dev.sharedDir, dev.mountTag)}, nil + } else { + return []string{"--device", fmt.Sprintf("virtio-fs,sharedDir=%s", dev.sharedDir)}, nil + } +} diff --git a/pkg/config/virtio.go b/pkg/config/virtio.go index 11ea4d23..9fbf05b5 100644 --- a/pkg/config/virtio.go +++ b/pkg/config/virtio.go @@ -3,6 +3,7 @@ package config import ( "fmt" "net" + "path/filepath" "strconv" "strings" @@ -73,6 +74,8 @@ func deviceFromCmdLine(deviceOpts string) (VirtioDevice, error) { switch opts[0] { case "virtio-blk": dev = &virtioBlk{} + case "virtio-fs": + dev = &virtioFs{} case "virtio-net": dev = &virtioNet{} case "virtio-rng": @@ -249,3 +252,50 @@ func (dev *VirtioVsock) AddToVirtualMachineConfig(vmConfig *vz.VirtualMachineCon return nil } + +type virtioFs struct { + sharedDir string + mountTag string +} + +func (dev *virtioFs) FromOptions(options []option) error { + for _, option := range options { + switch option.key { + case "sharedDir": + dev.sharedDir = option.value + case "mountTag": + dev.mountTag = option.value + default: + return fmt.Errorf("Unknown option for virtio-fs devices: %s", option.key) + } + } + return nil +} + +func (dev *virtioFs) AddToVirtualMachineConfig(vmConfig *vz.VirtualMachineConfiguration) error { + log.Infof("Adding virtio-fs device") + if dev.sharedDir == "" { + return fmt.Errorf("missing mandatory 'sharedDir' option for virtio-fs device") + } + var mountTag string + if dev.mountTag != "" { + mountTag = dev.mountTag + } else { + mountTag = filepath.Base(dev.sharedDir) + } + + sharedDir, err := vz.NewSharedDirectory(dev.sharedDir, false) + if err != nil { + return err + } + sharedDirConfig := vz.NewSingleDirectoryShare(sharedDir) + fileSystemDeviceConfig, err := vz.NewVirtioFileSystemDeviceConfiguration(mountTag) + if err != nil { + return err + } + fileSystemDeviceConfig.SetDirectoryShare(sharedDirConfig) + vmConfig.SetDirectorySharingDevicesVirtualMachineConfiguration([]vz.DirectorySharingDeviceConfiguration{ + fileSystemDeviceConfig, + }) + return nil +}