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

Configurable shared folder #55

Open
wants to merge 2 commits into
base: master
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
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

# Docker Machine VMware Workstation Driver

[![Join the chat at https://gitter.im/pecigonzalo/docker-machine-vmwareworkstation](https://badges.gitter.im/pecigonzalo/docker-machine-vmwareworkstation.svg)](https://gitter.im/pecigonzalo/docker-machine-vmwareworkstation?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Expand Down Expand Up @@ -71,7 +72,7 @@ add it to your $PATH.
exit 1
fi

vmrun.exe list | grep \""${VM}"\" &> /dev/null
vmrun.exe list | grep "${VM}.vmx" &> /dev/null
VM_EXISTS_CODE=$?

set -e
Expand All @@ -90,13 +91,13 @@ add it to your $PATH.
if [ -n ${NO_PROXY+x} ]; then
PROXY_ENV="$PROXY_ENV --engine-env NO_PROXY=$NO_PROXY"
fi
"${DOCKER_MACHINE}" create -d vmwareworkstation $PROXY_ENV "${VM}"
MSYS_NO_PATHCONV=1 "${DOCKER_MACHINE}" create -d vmwareworkstation $PROXY_ENV "${VM}"
fi

STEP="Checking status on $VM"
VM_STATUS="$(${DOCKER_MACHINE} status ${VM} 2>&1)"
if [ "${VM_STATUS}" != "Running" ]; then
"${DOCKER_MACHINE}" start "${VM}"
MSYS_NO_PATHCONV=1 "${DOCKER_MACHINE}" start "${VM}"
yes | "${DOCKER_MACHINE}" regenerate-certs "${VM}"
fi

Expand Down Expand Up @@ -159,6 +160,9 @@ $ docker-machine create --driver=vmwareworkstation dev
- `--vmwareworkstation-cpu-count`: Number of CPUs to use to create the VM (-1 to use the number of CPUs available).
- `--vmwareworkstation-ssh-user`: SSH user
- `--vmwareworkstation-ssh-password`: SSH password
- `--vmwareworkstation-no-share`: Disable the mount of your home directory
- `--vmwareworkstation-share-folder`: Mount the specified directory instead of the default home location. Format: dir:name
- `--vmwareworkstation-guest-share-link`: Additional link to the shared mount in the guest

The `--vmwareworkstation-boot2docker-url` flag takes a few different forms. By
default, if no value is specified for this flag, Machine checks locally for a
Expand All @@ -183,6 +187,9 @@ Environment variables and default values:
| `--vmwareworkstation-memory-size` | `WORKSTATION_MEMORY_SIZE` | `1024` |
| `--vmwareworkstation-ssh-user` | `WORKSTATION_SSH_USER` | `docker` |
| `--vmwareworkstation-ssh-password` | `WORKSTATION_SSH_PASSWORD` | `tcuser` |
| `--vmwareworkstation-no-share` | `WORKSTATION_NO_SHARE` | `false` |
| `--vmwareworkstation-share-folder` | `WORKSTATION_SHARE_FOLDER` | Depends on host OS |
| `--vmwareworkstation-guest-share-link`| `WORKSTATION_GUEST_SHARE_LINK`| Depends on host OS |

## Development

Expand Down
163 changes: 79 additions & 84 deletions workstation.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ type Driver struct {
SSHPassword string
ConfigDriveISO string
ConfigDriveURL string
NoShare bool
ShareName string
ShareFolder string
GuestShareLink string
}

const (
Expand Down Expand Up @@ -105,6 +109,21 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
Usage: "SSH password",
Value: defaultSSHPass,
},
mcnflag.BoolFlag{
EnvVar: "WORKSTATION_NO_SHARE",
Name: "vmwareworkstation-no-share",
Usage: "Disable the mount of your home directory",
},
mcnflag.StringFlag{
EnvVar: "WORKSTATION_SHARE_FOLDER",
Name: "vmwareworkstation-share-folder",
Usage: "Mount the specified directory instead of the default home location. Format: dir:name",
},
mcnflag.StringFlag{
EnvVar: "WORKSTATION_GUEST_SHARE_LINK",
Name: "vmwareworkstation-guest-share-link",
Usage: "Additional link to the shared mount in the guest",
},
}
}

Expand Down Expand Up @@ -151,6 +170,30 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.SSHUser = flags.String("vmwareworkstation-ssh-user")
d.SSHPassword = flags.String("vmwareworkstation-ssh-password")
d.SSHPort = 22
d.NoShare = flags.Bool("vmwareworkstation-no-share")

switch runtime.GOOS {
case "darwin": // TODO OSX linux working
d.ShareName = "Users"
d.ShareFolder = "/Users"
case "linux": // TODO Test linux working
d.ShareName = "hosthome"
d.ShareFolder = "/home"
case "windows":
d.ShareName = "Users"
d.ShareFolder = `C:\Users\`
d.GuestShareLink = "c/Users"
}


d.NoShare = flags.Bool("vmwareworkstation-no-share")
if flags.String("vmwareworkstation-share-folder") != "" {
d.ShareName, d.ShareFolder = parseShareFolder(flags.String("vmwareworkstation-share-folder"))
d.GuestShareLink = ""
}
if flags.String("vmwareworkstation-guest-share-link") != "" {
d.GuestShareLink = flags.String("vmwareworkstation-guest-share-link")
}

// We support a maximum of 16 cpu to be consistent with Virtual Hardware 10
// specs.
Expand Down Expand Up @@ -352,36 +395,46 @@ func (d *Driver) Create() error {
// Enable Shared Folders
vmrun("-gu", B2DUser, "-gp", B2DPass, "enableSharedFolders", d.vmxPath())

var shareName, shareDir, guestFolder, guestCompatLink string // TODO configurable at some point
switch runtime.GOOS {
case "linux": // TODO Test linux working
shareName = "Home"
shareDir = "/Home"
guestFolder = "/Users"
guestCompatLink = "/Home"
case "windows":
shareName = "Users"
shareDir = `C:\Users\`
guestFolder = "/Users"
guestCompatLink = "/c/Users"
if err := mountSharedFolder(d); err != nil {
return err
}

if shareDir != "" {
if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) {
return nil
}

func parseShareFolder(shareFolder string) (string, string) {
split := strings.Split(shareFolder, ":")
shareName := strings.Join(split[:len(split)-1], ":")
shareDir := split[len(split)-1]
return shareDir, shareName
}

func mountSharedFolder (d *Driver) error {
log.Debugf("Mounting Shared Folders...")
if d.ShareFolder != "" && !d.NoShare {
if _, err := os.Stat(d.ShareFolder); err != nil && !os.IsNotExist(err) {
log.Error("Shared folder %s does not exist on host", d.ShareFolder)
return err
} else if !os.IsNotExist(err) {
// add shared folder, create mountpoint and mount it.
vmrun("-gu", B2DUser, "-gp", B2DPass, "addSharedFolder", d.vmxPath(), shareName, shareDir)

var rootGuestCompat = strings.Split(guestCompatLink, "/")[1]
command := "[ ! -d " + guestFolder + " ]&& sudo mkdir " + guestFolder +
";[ ! -d /" + rootGuestCompat + " ]&& sudo mkdir -p /" + rootGuestCompat +
";[ ! -d " + guestCompatLink + " ]&& sudo ln -s " + guestFolder + " " + guestCompatLink +
";[ -f /usr/local/bin/vmhgfs-fuse ]&& sudo /usr/local/bin/vmhgfs-fuse -o allow_other .host:/" +
shareName + " " + guestFolder + " || sudo mount -t vmhgfs .host:/" + shareName + " " + guestFolder
log.Infof("Adding shared folder %s and mapping to /%s ...", d.ShareFolder, d.ShareName)
vmrun("-gu", B2DUser, "-gp", B2DPass, "addSharedFolder", d.vmxPath(), d.ShareName, strings.Replace(d.ShareFolder, `/`, `\`, -1))

command := "[ ! -d /" + d.ShareName + " ]&& sudo mkdir -p /" + d.ShareName +
";[ -f /usr/local/bin/vmhgfs-fuse ]&& sudo /usr/local/bin/vmhgfs-fuse -o allow_other .host:" + d.ShareName + " /" + d.ShareName;

if d.GuestShareLink != "" {
log.Infof("Creating link %s to shared folder in guest", d.GuestShareLink)
var rootGuestCompat = "/" + strings.Split(d.GuestShareLink, "/")[1]
command += ";[ ! -d " + rootGuestCompat + " ]&& sudo mkdir -p " + rootGuestCompat +
";[ ! -d " + d.GuestShareLink + " ]&& sudo ln -s /" + d.ShareName + " " + d.GuestShareLink

}
log.Debug(command)
vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", command)
}
} else {
log.Infof("No shared folders")
}
return nil
}
Expand All @@ -395,37 +448,8 @@ func (d *Driver) Start() error {
return nil
}

log.Debugf("Mounting Shared Folders...")
var shareName, shareDir, guestFolder, guestCompatLink string // TODO configurable at some point
switch runtime.GOOS {
case "linux": // TODO Test linux working
shareName = "Home"
shareDir = "/Home"
guestFolder = "/Users"
guestCompatLink = "/Home"
case "windows":
shareName = "Users"
shareDir = `C:\Users\`
guestFolder = "/Users"
guestCompatLink = "/c/Users"
}

if shareDir != "" {
if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) {
return err
} else if !os.IsNotExist(err) {
// create mountpoint and mount shared folder
var rootGuestCompat = strings.Split(guestCompatLink, "/")[1]
// TODO make it an array and do foreach run
command := "[ ! -d " + guestFolder + " ]&& sudo mkdir " + guestFolder +
";[ ! -d /" + rootGuestCompat + " ]&& sudo mkdir -p /" + rootGuestCompat +
";[ ! -d " + guestCompatLink + " ]&& sudo ln -s " + guestFolder + " " + guestCompatLink +
";[ -f /usr/local/bin/vmhgfs-fuse ]&& sudo /usr/local/bin/vmhgfs-fuse -o allow_other .host:/" +
shareName + " " + guestFolder + " || sudo mount -t vmhgfs .host:/" + shareName + " " + guestFolder
log.Debug(command)

vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", command)
}
if err := mountSharedFolder(d); err != nil {
return err
}

return nil
Expand All @@ -451,37 +475,8 @@ func (d *Driver) Remove() error {
func (d *Driver) Restart() error {
_, _, err := vmrun("reset", d.vmxPath(), "nogui")

log.Debugf("Mounting Shared Folders...")
var shareName, shareDir, guestFolder, guestCompatLink string // TODO configurable at some point
switch runtime.GOOS {
case "linux": // TODO Test linux working
shareName = "Home"
shareDir = "/Home"
guestFolder = "/Users"
guestCompatLink = "/Home"
case "windows":
shareName = "Users"
shareDir = `C:\Users\`
guestFolder = "/Users"
guestCompatLink = "/c/Users"
}

if shareDir != "" {
if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) {
return err
} else if !os.IsNotExist(err) {
// create mountpoint and mount shared folder
var rootGuestCompat = strings.Split(guestCompatLink, "/")[1]
// TODO make it an array and do foreach run
command := "[ ! -d " + guestFolder + " ]&& sudo mkdir " + guestFolder +
";[ ! -d /" + rootGuestCompat + " ]&& sudo mkdir -p /" + rootGuestCompat +
";[ ! -d " + guestCompatLink + " ]&& sudo ln -s " + guestFolder + " " + guestCompatLink +
";[ -f /usr/local/bin/vmhgfs-fuse ]&& sudo /usr/local/bin/vmhgfs-fuse -o allow_other .host:/" +
shareName + " " + guestFolder + " || sudo mount -t vmhgfs .host:/" + shareName + " " + guestFolder
log.Debug(command)

vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", command)
}
if err := mountSharedFolder(d); err != nil {
return err
}

return err
Expand Down