Skip to content

Commit 5ed10e7

Browse files
huguesalaryzchee
authored andcommitted
Added the ability to setup multiple NFS Shares
By default (changeable with `xhyve-experimental-nfs-share-root`, see below) NFS shares are rooted at /xhyve-nfsshares to avoid the situation where a NFS Share `/usr` would be mounted at `/usr` 2 backward incompatible changes: - renamed `xhyve-experimental-nfs-share` to `xhyve-experimental-nfs-share-enable` - change `xhyve-experimental-nfs-share` from being a boolean to a string slice taking multiple path to be shared via NFS - NFS Shares are now mounted under a default directory /xhyve-nfsshares (the old code was mounting everything under `/` causing, for example, `/usr` to be mounted at `/usr`) Other change: - add `xhyve-experimental-nfs-share-root` to allow specifying where in the guest the NFS Shares will be rooted at Here's an example of how to use: `docker-machine -D create -d xhyve --xhyve-disk-size 40000 --xhyve-memory-size 4000 --xhyve-cpu-count 2 --xhyve-experimental-nfs-share-enable --xhyve-experimental-nfs-share /Users --xhyve-experimental-nfs-share /usr/ --xhyve-experimental-nfs-share-root /nfsharesfromhost test` This command will share the host folders /Users and /usr in the guest at /nfsharesfromhost/Users and /nfsharesfromhost/usr
1 parent 4fd5365 commit 5ed10e7

File tree

2 files changed

+52
-24
lines changed

2 files changed

+52
-24
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ Usage
118118
| `--xhyve-boot-initrd` | `XHYVE_BOOT_INITRD` | string | `''` |
119119
| `--xhyve-qcow2` | `XHYVE_QCOW2` | bool | `false` |
120120
| `--xhyve-virtio-9p` | `XHYVE_VIRTIO_9P` | bool | `false` |
121-
| `--xhyve-experimental-nfs-share` | `XHYVE_EXPERIMENTAL_NFS_SHARE` | bool | `false` |
121+
| `--xhyve-experimental-nfs-share-enable` | `XHYVE_EXPERIMENTAL_NFS_SHARE_ENABLE` | bool | Enable `NFS` folder share (experimental) | `false` |
122+
| `--xhyve-experimental-nfs-share` | `XHYVE_EXPERIMENTAL_NFS_SHARE` | string | Path to a host folder to be shared inside the guest | |
123+
| `--xhyve-experimental-nfs-share-root` | `XHYVE_EXPERIMENTAL_NFS_SHARE_ROOT` | string | root path at which the NFS shares will be mounted| `/xhyve-nfsshares` |
122124

123125
#### `--xhyve-boot2docker-url`
124126

xhyve/xhyve.go

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"os"
1717
"os/exec"
1818
"os/user"
19+
"path"
1920
"path/filepath"
2021
"regexp"
2122
"runtime"
@@ -53,6 +54,7 @@ const (
5354
defaultPrivateKeyPath = ""
5455
defaultUUID = ""
5556
defaultNFSShareEnable = false
57+
defaultNFSSharesRoot = "/xhyve-nfsshares"
5658
rootVolumeName = "root-volume"
5759
defaultDiskNumber = -1
5860
defaultVirtio9p = false
@@ -77,6 +79,8 @@ type Driver struct {
7779
Qcow2 bool
7880
RawDisk bool
7981
NFSShareEnable bool
82+
NFSShares []string
83+
NFSSharesRoot string
8084
Virtio9p bool
8185
Virtio9pFolder string
8286
NFSShare bool
@@ -115,6 +119,7 @@ func NewDriver(hostName, storePath string) *Driver {
115119
PrivateKeyPath: defaultPrivateKeyPath,
116120
UUID: defaultUUID,
117121
NFSShareEnable: defaultNFSShareEnable,
122+
NFSSharesRoot: defaultNFSSharesRoot,
118123
DiskNumber: defaultDiskNumber,
119124
Virtio9p: defaultVirtio9p,
120125
Qcow2: defaultQcow2,
@@ -162,11 +167,6 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
162167
Usage: "Size of disk for host in MB",
163168
Value: defaultDiskSize,
164169
},
165-
mcnflag.BoolFlag{
166-
EnvVar: "XHYVE_EXPERIMENTAL_NFS_SHARE",
167-
Name: "xhyve-experimental-nfs-share",
168-
Usage: "Setup NFS shared folder (requires root)",
169-
},
170170
mcnflag.IntFlag{
171171
EnvVar: "XHYVE_MEMORY_SIZE",
172172
Name: "xhyve-memory-size",
@@ -199,6 +199,17 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
199199
Name: "xhyve-experimental-nfs-share-enable",
200200
Usage: "Setup NFS shared folder (requires root)",
201201
},
202+
mcnflag.StringSliceFlag{
203+
EnvVar: "XHYVE_EXPERIMENTAL_NFS_SHARE",
204+
Name: "xhyve-experimental-nfs-share",
205+
Usage: "Setup NFS shared folder (requires root)",
206+
},
207+
mcnflag.StringFlag{
208+
EnvVar: "XHYVE_EXPERIMENTAL_NFS_SHARE_ROOT",
209+
Name: "xhyve-experimental-nfs-share-root",
210+
Usage: "root directory where the NFS shares will be mounted inside the machine",
211+
Value: defaultNFSSharesRoot,
212+
},
202213
}
203214
}
204215

@@ -245,7 +256,6 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
245256
}
246257
d.DiskSize = int64(flags.Int("xhyve-disk-size"))
247258
d.Memory = flags.Int("xhyve-memory-size")
248-
d.NFSShare = flags.Bool("xhyve-experimental-nfs-share")
249259
d.Qcow2 = flags.Bool("xhyve-qcow2")
250260
d.RawDisk = flags.Bool("xhyve-rawdisk")
251261
d.SSHPort = 22
@@ -257,6 +267,8 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
257267
d.Virtio9p = flags.Bool("xhyve-virtio-9p")
258268
d.Virtio9pFolder = "/Users"
259269
d.NFSShareEnable = flags.Bool("xhyve-experimental-nfs-share-enable")
270+
d.NFSShares = flags.StringSlice("xhyve-experimental-nfs-share")
271+
d.NFSSharesRoot = flags.String("xhyve-experimental-nfs-share-root")
260272

261273
return nil
262274
}
@@ -576,8 +588,10 @@ func (d *Driver) Remove() error {
576588

577589
if d.NFSShareEnable {
578590
log.Infof("Remove NFS share folder must be root. Please insert root password.")
579-
if _, err := nfsexports.Remove("", d.nfsExportIdentifier()); err != nil {
580-
log.Errorf("failed removing nfs share: %s", err.Error())
591+
for _, share := range d.NFSShares {
592+
if _, err := nfsexports.Remove("", d.nfsExportIdentifier(share)); err != nil {
593+
log.Errorf("failed removing nfs share (%s): %s", share, err.Error())
594+
}
581595
}
582596

583597
if err := nfsexports.ReloadDaemon(); err != nil {
@@ -999,27 +1013,39 @@ func (d *Driver) setupNFSShare() error {
9991013
return err
10001014
}
10011015

1002-
nfsConfig := fmt.Sprintf("/Users %s -alldirs -mapall=%s", d.IPAddress, user.Username)
1003-
1004-
if _, err := nfsexports.Add("", d.nfsExportIdentifier(), nfsConfig); err != nil {
1016+
hostIP, err := vmnet.GetNetAddr()
1017+
if err != nil {
10051018
return err
10061019
}
10071020

1008-
if err := nfsexports.ReloadDaemon(); err != nil {
1009-
return err
1021+
bootScriptName := "/var/lib/boot2docker/bootlocal.sh"
1022+
bootScript := fmt.Sprintf("#/bin/bash\\n")
1023+
1024+
bootScript += "sudo /usr/local/etc/init.d/nfs-client start\\n"
1025+
1026+
for _, share := range d.NFSShares {
1027+
if !path.IsAbs(share) {
1028+
share = d.ResolveStorePath(share)
1029+
}
1030+
nfsConfig := fmt.Sprintf("%s %s -alldirs -mapall=%s", share, d.IPAddress, user.Username)
1031+
1032+
if _, err := nfsexports.Add("", d.nfsExportIdentifier(share), nfsConfig); err != nil {
1033+
if strings.Contains(err.Error(), "conflicts with existing export") {
1034+
log.Info("Conflicting NFS Share not setup and ignored:", err)
1035+
continue
1036+
}
1037+
return err
1038+
}
1039+
1040+
root := path.Clean(d.NFSSharesRoot)
1041+
bootScript += fmt.Sprintf("sudo mkdir -p %s/%s\\n", root, share)
1042+
bootScript += fmt.Sprintf("sudo mount -t nfs -o noacl,async %s:%s %s/%s\\n", hostIP, share, root, share)
10101043
}
10111044

1012-
hostIP, err := vmnet.GetNetAddr()
1013-
if err != nil {
1045+
if err := nfsexports.ReloadDaemon(); err != nil {
10141046
return err
10151047
}
10161048

1017-
bootScriptName := "/var/lib/boot2docker/bootlocal.sh"
1018-
bootScript := fmt.Sprintf("#/bin/bash\\n"+
1019-
"sudo mkdir -p /Users\\n"+
1020-
"sudo /usr/local/etc/init.d/nfs-client start\\n"+
1021-
"sudo mount -t nfs -o noacl,async %s:/Users /Users\\n", hostIP)
1022-
10231049
writeScriptCmd := fmt.Sprintf("echo -e \"%s\" | sudo tee %s && sudo chmod +x %s && %s",
10241050
bootScript, bootScriptName, bootScriptName, bootScriptName)
10251051

@@ -1030,8 +1056,8 @@ func (d *Driver) setupNFSShare() error {
10301056
return nil
10311057
}
10321058

1033-
func (d *Driver) nfsExportIdentifier() string {
1034-
return fmt.Sprintf("docker-machine-driver-xhyve %s", d.MachineName)
1059+
func (d *Driver) nfsExportIdentifier(path string) string {
1060+
return fmt.Sprintf("docker-machine-driver-xhyve %s-%s", d.MachineName, path)
10351061
}
10361062

10371063
func (d *Driver) GetPid() (int, error) {

0 commit comments

Comments
 (0)