// Run returns JSON responses to each command or an error func (mockCmd MockVmdkCmd) Run(cmd string, name string, opts map[string]string) ([]byte, error) { // We store no in memory state, so just try to recreate backingRoot every time rootName := fmt.Sprintf("%s/%d", backingRoot, os.Getpid()) err := fs.Mkdir(rootName) if err != nil { return nil, err } log.WithFields(log.Fields{"cmd": cmd}).Debug("Running Mock Cmd") switch cmd { case "create": err := createBlockDevice(name, opts) return nil, err case "list": return list() case "get": return nil, get(name) case "attach": return getBlockDeviceForName(name) case "detach": return nil, nil case "remove": err := remove(name) return nil, err } return []byte("null"), nil }
// Request attach and them mounts the volume. // Actual mount - send attach to ESX and do the in-guest magic // Returns mount point and error (or nil) func (d *vmdkDriver) mountVolume(name string, fstype string, isReadOnly bool) (string, error) { mountpoint := getMountPoint(name) // First, make sure that mountpoint exists. err := fs.Mkdir(mountpoint) if err != nil { log.WithFields( log.Fields{"name": name, "dir": mountpoint}, ).Error("Failed to make directory for volume mount ") return mountpoint, err } skipInotify := false watcher, err := inotify.NewWatcher() if err != nil { log.WithFields( log.Fields{"name": name, "dir": mountpoint}, ).Error("Failed to create watcher, skip inotify ") skipInotify = true } else { err = watcher.Watch(watchPath) if err != nil { log.WithFields( log.Fields{"name": name, "dir": mountpoint}, ).Error("Failed to watch /dev, skip inotify ") skipInotify = true } } // Have ESX attach the disk dev, err := d.ops.Attach(name, nil) if err != nil { return mountpoint, err } if d.useMockEsx { return mountpoint, fs.Mount(mountpoint, fstype, string(dev[:]), false) } device, err := fs.GetDevicePath(dev) if err != nil { return mountpoint, err } if skipInotify { time.Sleep(sleepBeforeMount) return mountpoint, fs.Mount(mountpoint, fstype, device, false) } loop: for { select { case ev := <-watcher.Event: log.Debug("event: ", ev) if ev.Name == device { // Log when the device is discovered log.WithFields( log.Fields{"name": name, "event": ev}, ).Info("Attach complete ") break loop } case err := <-watcher.Error: log.WithFields( log.Fields{"name": name, "device": device, "error": err}, ).Error("Hit error during watch ") break loop case <-time.After(devWaitTimeout): log.WithFields( log.Fields{"name": name, "timeout": devWaitTimeout, "device": device}, ).Warning("Reached timeout while waiting for device, trying to mount anyways ") break loop } } return mountpoint, fs.Mount(mountpoint, fstype, device, isReadOnly) }