Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run: Add support for --bind (on linux, with virtiofsd) #36

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type osVmConfig struct {
RemoveVm bool // Kill the running VM when it exits
RemoveDiskImage bool // After exit of the VM, remove the disk image
Quiet bool
BindMounts []string
}

var (
Expand Down Expand Up @@ -58,6 +59,7 @@ func init() {
runCmd.Flags().BoolVar(&vmConfig.Quiet, "quiet", false, "Suppress output from bootc disk creation and VM boot console")
runCmd.Flags().StringVar(&diskImageConfigInstance.RootSizeMax, "root-size-max", "", "Maximum size of root filesystem in bytes; optionally accepts M, G, T suffixes")
runCmd.Flags().StringVar(&diskImageConfigInstance.DiskSize, "disk-size", "", "Allocate a disk image of this size in bytes; optionally accepts M, G, T suffixes")
runCmd.Flags().StringArrayVar(&vmConfig.BindMounts, "bind", nil, "Create a virtiofs mount between host and guest, separated by a `:`")
}
Comment on lines +62 to 63
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not using "-v/--volume"?, even if not a great name is more coherent with podman

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, sorry when working on this I'd been in a mindset of porting features from coreos-assembler run. Will change.


func doRun(flags *cobra.Command, args []string) error {
Expand Down Expand Up @@ -141,6 +143,7 @@ func doRun(flags *cobra.Command, args []string) error {
CloudInitDir: vmConfig.CloudInitDir,
NoCredentials: vmConfig.NoCredentials,
CloudInitData: flags.Flags().Changed("cloudinit"),
BindMounts: vmConfig.BindMounts,
RemoveVm: vmConfig.RemoveVm,
Background: vmConfig.Background,
SSHPort: sshPort,
Expand Down
3 changes: 3 additions & 0 deletions pkg/vm/domain-template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<type>hvm</type>
<boot dev="hd"></boot>
</os>
<!-- https://github.com/fedora-selinux/selinux-policy/issues/2124 -->
<seclabel type="none" model="selinux"/>
<devices>
<serial type="pty" />
<disk device="disk" type="file">
Expand All @@ -33,6 +35,7 @@
</backend>
</tpm>
{{.CloudInitCDRom}}
{{.Filesystems}}
</devices>
<qemu:commandline>
<qemu:arg value='-netdev'/>
Expand Down
2 changes: 2 additions & 0 deletions pkg/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type RunVMParameters struct {
Cmd []string
RemoveVm bool
Background bool
BindMounts []string
}

type BootcVM interface {
Expand Down Expand Up @@ -97,6 +98,7 @@ type BootcVMCommon struct {
hasCloudInit bool
cloudInitDir string
cloudInitArgs string
BindMounts []string
bootcDisk bootc.BootcDisk
cacheDirLock utils.CacheLock
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/vm/vm_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func NewVM(params NewVMParameters) (vm *BootcVMMac, err error) {
return nil, fmt.Errorf("image ID is required")
}

if len(params.BindMounts) > 0 {
return fmt.Errorf("bind mounts are currently not supported on this platform")
}

longId, cacheDir, err := GetVMCachePath(params.ImageID, params.User)
if err != nil {
return nil, fmt.Errorf("unable to get VM cache path: %w", err)
Expand Down
28 changes: 28 additions & 0 deletions pkg/vm/vm_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"path/filepath"
"strconv"
"strings"
"text/template"
"time"

Expand Down Expand Up @@ -120,6 +121,7 @@ func (v *BootcVMLinux) Run(params RunVMParameters) (err error) {
v.cmd = params.Cmd
v.hasCloudInit = params.CloudInitData
v.cloudInitDir = params.CloudInitDir
v.BindMounts = params.BindMounts
v.vmUsername = params.VMUser
v.sshIdentity = params.SSHIdentity

Expand Down Expand Up @@ -192,6 +194,7 @@ func (v *BootcVMLinux) parseDomainTemplate() (domainXML string, err error) {
Name string
CloudInitCDRom string
CloudInitSMBios string
Filesystems string
}

templateParams := TemplateParams{
Expand Down Expand Up @@ -230,6 +233,31 @@ func (v *BootcVMLinux) parseDomainTemplate() (domainXML string, err error) {
`, v.cloudInitArgs)
}

bindMounts := ""
for _, mnt := range v.BindMounts {
parts := strings.SplitN(mnt, ":", 2)
if len(parts) < 2 {
return "", fmt.Errorf("invalid bind mount: %q", mnt)
}
src := parts[0]
absSrc, err := filepath.Abs(src)
if err != nil {
return "", fmt.Errorf("failed to resolve bind mount source %q", src)
}
dst := parts[1]
// Note we're not properly quoting for XML here, just relying
// on the Go quoting. Fixing that would involve pulling in a real
// XML library.
bindMounts += fmt.Sprintf(`
<filesystem type="mount" accessmode="passthrough">
<driver type="virtiofs"/>
<source dir=%q/>
<target dir=%q/>
</filesystem>
`, absSrc, dst)
}
templateParams.Filesystems = bindMounts

err = tmpl.Execute(&domainXMLBuf, templateParams)
if err != nil {
return "", fmt.Errorf("unable to execute domain template: %w", err)
Expand Down