summaryrefslogtreecommitdiff
path: root/pkg/machine/qemu
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/machine/qemu')
-rw-r--r--pkg/machine/qemu/config.go9
-rw-r--r--pkg/machine/qemu/machine.go48
2 files changed, 56 insertions, 1 deletions
diff --git a/pkg/machine/qemu/config.go b/pkg/machine/qemu/config.go
index 8404079a2..177487953 100644
--- a/pkg/machine/qemu/config.go
+++ b/pkg/machine/qemu/config.go
@@ -11,6 +11,8 @@ type MachineVM struct {
CPUs uint64
// The command line representation of the qemu command
CmdLine []string
+ // Mounts is the list of remote filesystems to mount
+ Mounts []Mount
// IdentityPath is the fq path to the ssh priv key
IdentityPath string
// IgnitionFilePath is the fq path to the .ign file
@@ -33,6 +35,13 @@ type MachineVM struct {
RemoteUsername string
}
+type Mount struct {
+ Type string
+ Tag string
+ Source string
+ Target string
+}
+
type Monitor struct {
// Address portion of the qmp monitor (/tmp/tmp.sock)
Address string
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index a80a11573..7bef4ff8e 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -167,6 +167,21 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
// Add arch specific options including image location
v.CmdLine = append(v.CmdLine, v.addArchOptions()...)
+ mounts := []Mount{}
+ for i, volume := range opts.Volumes {
+ tag := fmt.Sprintf("vol%d", i)
+ paths := strings.SplitN(volume, ":", 2)
+ source := paths[0]
+ target := source
+ if len(paths) > 1 {
+ target = paths[1]
+ }
+ addVirtfsOptions := []string{"-virtfs", fmt.Sprintf("local,path=%s,mount_tag=%s,security_model=mapped-xattr", source, tag)}
+ v.CmdLine = append(v.CmdLine, addVirtfsOptions...)
+ mounts = append(mounts, Mount{Type: "9p", Tag: tag, Source: source, Target: target})
+ }
+ v.Mounts = mounts
+
// Add location of bootable image
v.CmdLine = append(v.CmdLine, "-drive", "if=virtio,file="+v.ImagePath)
// This kind of stinks but no other way around this r/n
@@ -329,7 +344,28 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return err
}
_, err = bufio.NewReader(conn).ReadString('\n')
- return err
+ if err != nil {
+ return err
+ }
+
+ if len(v.Mounts) > 0 {
+ for !v.isRunning() || !v.isListening() {
+ time.Sleep(100 * time.Millisecond)
+ }
+ }
+ for _, mount := range v.Mounts {
+ fmt.Printf("Mounting volume... %s:%s\n", mount.Source, mount.Target)
+ // create mountpoint directory if it doesn't exist
+ err = v.SSH(name, machine.SSHOptions{Args: []string{"-q", "--", "sudo", "mkdir", "-p", mount.Target}})
+ if err != nil {
+ return err
+ }
+ err = v.SSH(name, machine.SSHOptions{Args: []string{"-q", "--", "sudo", "mount", "-t", mount.Type, "-o", "trans=virtio", mount.Tag, mount.Target, "-o", "version=9p2000.L,msize=131072"}})
+ if err != nil {
+ return err
+ }
+ }
+ return nil
}
// Stop uses the qmp monitor to call a system_powerdown
@@ -506,6 +542,16 @@ func (v *MachineVM) isRunning() bool {
return true
}
+func (v *MachineVM) isListening() bool {
+ // Check if we can dial it
+ conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", "localhost", v.Port), 10*time.Millisecond)
+ if err != nil {
+ return false
+ }
+ conn.Close()
+ return true
+}
+
// SSH opens an interactive SSH session to the vm specified.
// Added ssh function to VM interface: pkg/machine/config/go : line 58
func (v *MachineVM) SSH(name string, opts machine.SSHOptions) error {