func (d *Driver) MountVolume(req Request) (string, error) { d.mutex.Lock() defer d.mutex.Unlock() id := req.Name opts := req.Options volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } specifiedPoint := opts[OPT_MOUNT_POINT] if specifiedPoint != "" { return "", fmt.Errorf("GlusterFS doesn't support specified mount point") } if volume.MountPoint == "" { volume.MountPoint = volume.Path } if volume.PrepareForVM { if err := util.MountPointPrepareImageFile(volume.MountPoint, volume.Size); err != nil { return "", err } } if err := util.ObjectSave(volume); err != nil { return "", err } return volume.MountPoint, nil }
func (d *Driver) CreateVolume(id string, opts map[string]string) error { d.mutex.Lock() defer d.mutex.Unlock() volumeName := opts[convoydriver.OPT_VOLUME_NAME] if volumeName == "" { volumeName = "volume-" + id[:8] } volume := d.blankVolume(id) exists, err := util.ObjectExists(volume) if err != nil { return err } if exists { return fmt.Errorf("volume %v already exists", id) } gVolume := d.gVolumes[d.DefaultVolumePool] volumePath := filepath.Join(gVolume.MountPoint, volumeName) if util.VolumeMountPointDirectoryExists(gVolume, volumeName) { log.Debugf("Found existing volume named %v, reuse it", volumeName) } else if err := util.VolumeMountPointDirectoryCreate(gVolume, volumeName); err != nil { return err } volume.Name = volumeName volume.Path = volumePath volume.VolumePool = gVolume.UUID return util.ObjectSave(volume) }
func (d *Driver) MountVolume(id string, opts map[string]string) (string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } if err := volume.Stack(d).MoveController(); err != nil { log.Errorf("Failed to move controller to %s", d.containerName) return "", err } mountPoint, err := util.VolumeMount(volume, opts[convoydriver.OPT_MOUNT_POINT], false) if err != nil { return "", err } if volume.PrepareForVM { if err := util.MountPointPrepareImageFile(mountPoint, volume.Size); err != nil { return "", err } } if err := util.ObjectSave(volume); err != nil { return "", err } return mountPoint, nil }
func (d *Driver) MountVolume(id string, opts map[string]string) (string, error) { d.mutex.Lock() defer d.mutex.Unlock() volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } specifiedPoint := opts[convoydriver.OPT_MOUNT_POINT] if specifiedPoint != "" { return "", fmt.Errorf("VFS doesn't support specified mount point") } if volume.MountPoint == "" { volume.MountPoint = volume.Path } if volume.PrepareForVM { if err := util.MountPointPrepareImageFile(volume.MountPoint, volume.Size); err != nil { return "", err } } if err := util.ObjectSave(volume); err != nil { return "", err } return volume.MountPoint, nil }
func (d *Driver) doCreateVolume(volume *Volume, stack *Stack, id string, opts map[string]string) error { // Doing find just to see if we are creating versus using an existing stack env, err := stack.Find() if err != nil { return err } // Always run create because it also ensures that things are active if _, err := stack.Create(); err != nil { return err } // If env was nil then we created stack so we need to format if env == nil { dev, _ := volume.GetDevice() err := Backoff(5*time.Minute, fmt.Sprintf("Failed to find %s", dev), func() (bool, error) { if _, err := os.Stat(dev); err == nil { return true, nil } return false, nil }) if err != nil { return err } log.Infof("Formatting %s", dev) if _, err := util.Execute("mkfs.ext4", []string{dev}); err != nil { return err } } return util.ObjectSave(volume) }
func (d *Driver) DeleteSnapshot(id, volumeID string) error { snapshot, volume, err := d.getSnapshotAndVolume(id, volumeID) if err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_REMOVE, LOG_FIELD_OBJECT: LOG_OBJECT_SNAPSHOT, LOG_FIELD_SNAPSHOT: id, LOG_FIELD_VOLUME: volumeID, }).Debugf("Deleting snapshot for volume") err = devicemapper.DeleteDevice(d.ThinpoolDevice, snapshot.DevID) if err != nil { return err } log.Debug("Deleted snapshot device") delete(volume.Snapshots, id) if err = util.ObjectSave(volume); err != nil { return err } return nil }
func (d *Driver) CreateSnapshot(id, volumeID string) error { d.mutex.Lock() defer d.mutex.Unlock() volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return err } if _, exists := volume.Snapshots[id]; exists { return fmt.Errorf("Snapshot %v already exists for volume %v", id, volumeID) } snapFile := d.getSnapshotFilePath(id, volumeID) if err := util.MkdirIfNotExists(filepath.Dir(snapFile)); err != nil { return err } if err := util.CompressDir(volume.Path, snapFile); err != nil { return err } volume.Snapshots[id] = Snapshot{ UUID: id, VolumeUUID: volumeID, FilePath: snapFile, } return util.ObjectSave(volume) }
func (d *Driver) MountVolume(id string, opts map[string]string) (string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } dev, err := d.GetVolumeDevice(id) if err != nil { return "", err } specifiedPoint := opts[convoydriver.OPT_MOUNT_POINT] mountPoint, err := d.getVolumeMountPoint(id, specifiedPoint) if err != nil { return "", err } if volume.MountPoint != "" && volume.MountPoint != mountPoint { return "", fmt.Errorf("volume %v already mounted at %v, but asked to mount at %v", id, volume.MountPoint, mountPoint) } if !mounted(dev, mountPoint) { log.Debugf("Volume %v is not mounted, mount it now to %v", id, mountPoint) _, err = util.Execute(MOUNT_BINARY, []string{dev, mountPoint}) if err != nil { return "", err } } volume.MountPoint = mountPoint if err := util.ObjectSave(volume); err != nil { return "", err } return mountPoint, nil }
func (d *Driver) CreateSnapshot(req Request) error { d.mutex.Lock() defer d.mutex.Unlock() id := req.Name volumeID, err := util.GetFieldFromOpts(OPT_VOLUME_NAME, req.Options) if err != nil { return err } volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return err } if _, exists := volume.Snapshots[id]; exists { return fmt.Errorf("Snapshot %v already exists for volume %v", id, volumeID) } snapFile := d.getSnapshotFilePath(id, volumeID) if err := util.MkdirIfNotExists(filepath.Dir(snapFile)); err != nil { return err } if err := util.CompressDir(volume.Path, snapFile); err != nil { return err } volume.Snapshots[id] = Snapshot{ Name: id, CreatedTime: util.Now(), VolumeUUID: volumeID, FilePath: snapFile, } return util.ObjectSave(volume) }
func (d *Driver) CreateVolume(id string, opts map[string]string) error { d.mutex.Lock() defer d.mutex.Unlock() backupURL := opts[convoydriver.OPT_BACKUP_URL] if backupURL != "" { objVolume, err := objectstore.LoadVolume(backupURL) if err != nil { return err } if objVolume.Driver != d.Name() { return fmt.Errorf("Cannot restore backup of %v to %v", objVolume.Driver, d.Name()) } } volumeName := opts[convoydriver.OPT_VOLUME_NAME] if volumeName == "" { volumeName = "volume-" + id[:8] } volume := d.blankVolume(id) exists, err := util.ObjectExists(volume) if err != nil { return err } if exists { return fmt.Errorf("volume %v already exists", id) } volume.PrepareForVM, err = strconv.ParseBool(opts[convoydriver.OPT_PREPARE_FOR_VM]) if err != nil { return err } if volume.PrepareForVM { volume.Size, err = d.getSize(opts, d.DefaultVolumeSize) if err != nil { return err } } volumePath := filepath.Join(d.Path, volumeName) if err := util.MkdirIfNotExists(volumePath); err != nil { return err } volume.Path = volumePath volume.Snapshots = make(map[string]Snapshot) if backupURL != "" { file, err := objectstore.RestoreSingleFileBackup(backupURL, volumePath) if err != nil { return err } // file would be removed after this because it's under volumePath if err := util.DecompressDir(file, volumePath); err != nil { return err } } return util.ObjectSave(volume) }
func Init(root string, config map[string]string) (convoydriver.ConvoyDriver, error) { dev := &Device{ Root: root, } exists, err := util.ObjectExists(dev) if err != nil { return nil, err } if exists { if err := util.ObjectLoad(dev); err != nil { return nil, err } } else { if err := util.MkdirIfNotExists(root); err != nil { return nil, err } path := config[VFS_PATH] if path == "" { return nil, fmt.Errorf("VFS driver base path unspecified") } if err := util.MkdirIfNotExists(path); err != nil { return nil, err } dev = &Device{ Root: root, Path: path, } if _, exists := config[VFS_DEFAULT_VOLUME_SIZE]; !exists { config[VFS_DEFAULT_VOLUME_SIZE] = DEFAULT_VOLUME_SIZE } volumeSize, err := util.ParseSize(config[VFS_DEFAULT_VOLUME_SIZE]) if err != nil || volumeSize == 0 { return nil, fmt.Errorf("Illegal default volume size specified") } dev.DefaultVolumeSize = volumeSize } // For upgrade case if dev.DefaultVolumeSize == 0 { dev.DefaultVolumeSize, err = util.ParseSize(DEFAULT_VOLUME_SIZE) if err != nil || dev.DefaultVolumeSize == 0 { return nil, fmt.Errorf("Illegal default volume size specified") } } if err := util.ObjectSave(dev); err != nil { return nil, err } d := &Driver{ mutex: &sync.RWMutex{}, Device: *dev, } return d, nil }
func (d *Driver) CreateSnapshot(req Request) error { var err error d.mutex.Lock() defer d.mutex.Unlock() id := req.Name volumeID, err := util.GetFieldFromOpts(OPT_VOLUME_NAME, req.Options) if err != nil { return err } volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return err } devID, err := d.allocateDevID() if err != nil { return err } snapshot, exists := volume.Snapshots[id] if exists { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: volumeID, LOG_FIELD_SNAPSHOT: id, }, "Already has snapshot with name") } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_CREATE, LOG_FIELD_OBJECT: LOG_OBJECT_SNAPSHOT, LOG_FIELD_SNAPSHOT: id, LOG_FIELD_VOLUME: volumeID, DM_LOG_FIELD_VOLUME_DEVID: volume.DevID, DM_LOG_FIELD_SNAPSHOT_DEVID: devID, }).Debugf("Creating snapshot") err = devicemapper.CreateSnapDevice(d.ThinpoolDevice, devID, volumeID, volume.DevID) if err != nil { return err } log.Debugf("Created snapshot device") snapshot = Snapshot{ Name: id, CreatedTime: util.Now(), DevID: devID, Activated: false, } volume.Snapshots[id] = snapshot if err := util.ObjectSave(volume); err != nil { return err } return nil }
func Init(root string, config map[string]string) (convoydriver.ConvoyDriver, error) { ebsService, err := NewEBSService() if err != nil { return nil, err } dev := &Device{ Root: root, } exists, err := util.ObjectExists(dev) if err != nil { return nil, err } if exists { if err := util.ObjectLoad(dev); err != nil { return nil, err } } else { if err := util.MkdirIfNotExists(root); err != nil { return nil, err } if config[EBS_DEFAULT_VOLUME_SIZE] == "" { config[EBS_DEFAULT_VOLUME_SIZE] = DEFAULT_VOLUME_SIZE } size, err := util.ParseSize(config[EBS_DEFAULT_VOLUME_SIZE]) if err != nil { return nil, err } if config[EBS_DEFAULT_VOLUME_TYPE] == "" { config[EBS_DEFAULT_VOLUME_TYPE] = DEFAULT_VOLUME_TYPE } volumeType := config[EBS_DEFAULT_VOLUME_TYPE] if err := checkVolumeType(volumeType); err != nil { return nil, err } dev = &Device{ Root: root, DefaultVolumeSize: size, DefaultVolumeType: volumeType, } if err := util.ObjectSave(dev); err != nil { return nil, err } } d := &Driver{ mutex: &sync.RWMutex{}, ebsService: ebsService, Device: *dev, } if err := d.remountVolumes(); err != nil { return nil, err } return d, nil }
func (d *Driver) allocateDevID() (int, error) { d.Mutex.Lock() defer d.Mutex.Unlock() d.LastDevID++ log.Debug("Current devID ", d.LastDevID) if err := util.ObjectSave(&d.Device); err != nil { return 0, err } return d.LastDevID, nil }
func (d *Driver) UmountVolume(id string) error { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } if err := util.VolumeUmount(volume); err != nil { return err } return util.ObjectSave(volume) }
func (d *Driver) DeleteSnapshot(id, volumeID string) error { d.mutex.Lock() defer d.mutex.Unlock() snapshot, volume, err := d.getSnapshotAndVolume(id, volumeID) if err != nil { return err } log.Debugf("Removing reference of snapshot %v(%v) of volume %v(%v)", id, snapshot.EBSID, volumeID, volume.EBSID) delete(volume.Snapshots, id) return util.ObjectSave(volume) }
func (d *Driver) UmountVolume(req Request) error { id := req.Name volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } if err := util.VolumeUmount(volume); err != nil { return err } return util.ObjectSave(volume) }
func (d *Driver) UmountVolume(id string) error { d.mutex.Lock() defer d.mutex.Unlock() volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } if volume.MountPoint != "" { volume.MountPoint = "" } return util.ObjectSave(volume) }
func (d *Driver) deleteSnapshot(id, volumeID string) error { volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return err } snapshot, exists := volume.Snapshots[id] if !exists { return fmt.Errorf("Snapshot %v doesn't exists for volume %v", id, volumeID) } if err := os.Remove(snapshot.FilePath); err != nil { return err } delete(volume.Snapshots, id) return util.ObjectSave(volume) }
func (d *Driver) CreateSnapshot(id, volumeID string) error { var err error volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return err } devID, err := d.allocateDevID() if err != nil { return err } snapshot, exists := volume.Snapshots[id] if exists { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: volumeID, LOG_FIELD_SNAPSHOT: id, }, "Already has snapshot with uuid") } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_CREATE, LOG_FIELD_OBJECT: LOG_OBJECT_SNAPSHOT, LOG_FIELD_SNAPSHOT: id, LOG_FIELD_VOLUME: volumeID, DM_LOG_FIELD_VOLUME_DEVID: volume.DevID, DM_LOG_FIELD_SNAPSHOT_DEVID: devID, }).Debugf("Creating snapshot") err = devicemapper.CreateSnapDevice(d.ThinpoolDevice, devID, volumeID, volume.DevID) if err != nil { return err } log.Debugf("Created snapshot device") snapshot = Snapshot{ DevID: devID, Activated: false, } volume.Snapshots[id] = snapshot if err := util.ObjectSave(volume); err != nil { return err } return nil }
func (d *Driver) MountVolume(id string, opts map[string]string) (string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } mountPoint, err := util.VolumeMount(volume, opts[convoydriver.OPT_MOUNT_POINT], false) if err != nil { return "", err } if err := util.ObjectSave(volume); err != nil { return "", err } return mountPoint, nil }
func (d *Driver) CreateSnapshot(req Request) error { d.mutex.Lock() defer d.mutex.Unlock() id := req.Name volumeID, err := util.GetFieldFromOpts(OPT_VOLUME_NAME, req.Options) if err != nil { return err } volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return err } snapshot, exists := volume.Snapshots[id] if exists { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: volumeID, LOG_FIELD_SNAPSHOT: id, }, "Already has snapshot with uuid") } tags := map[string]string{ "ConvoyVolumeName": volumeID, "ConvoySnapshotName": id, } request := &CreateSnapshotRequest{ VolumeID: volume.EBSID, Description: fmt.Sprintf("Convoy snapshot"), Tags: tags, } ebsSnapshotID, err := d.ebsService.CreateSnapshot(request) if err != nil { return err } log.Debugf("Creating snapshot %v(%v) of volume %v(%v)", id, ebsSnapshotID, volumeID, volume.EBSID) snapshot = Snapshot{ Name: id, VolumeName: volumeID, EBSID: ebsSnapshotID, } volume.Snapshots[id] = snapshot return util.ObjectSave(volume) }
func (d *Driver) CloseSnapshot(id, volumeID string) error { snapshot, volume, err := d.getSnapshotAndVolume(id, volumeID) if err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_DEACTIVATE, LOG_FIELD_OBJECT: LOG_OBJECT_SNAPSHOT, LOG_FIELD_SNAPSHOT: id, }).Debug() if err := devicemapper.RemoveDevice(id); err != nil { return err } snapshot.Activated = false return util.ObjectSave(volume) }
func (d *Driver) DeleteSnapshot(req Request) error { d.mutex.Lock() defer d.mutex.Unlock() id := req.Name volumeID, err := util.GetFieldFromOpts(OPT_VOLUME_NAME, req.Options) if err != nil { return err } snapshot, volume, err := d.getSnapshotAndVolume(id, volumeID) if err != nil { return err } log.Debugf("Removing reference of snapshot %v(%v) of volume %v(%v)", id, snapshot.EBSID, volumeID, volume.EBSID) delete(volume.Snapshots, id) return util.ObjectSave(volume) }
func (d *Driver) CreateVolume(id string, opts map[string]string) error { d.mutex.Lock() defer d.mutex.Unlock() volumeName := opts[convoydriver.OPT_VOLUME_NAME] if volumeName == "" { volumeName = "volume-" + id[:8] } volume := d.blankVolume(id) exists, err := util.ObjectExists(volume) if err != nil { return err } if exists { return fmt.Errorf("volume %v already exists", id) } volume.PrepareForVM, err = strconv.ParseBool(opts[convoydriver.OPT_PREPARE_FOR_VM]) if err != nil { return err } if volume.PrepareForVM { volume.Size, err = d.getSize(opts, d.DefaultVolumeSize) if err != nil { return err } } gVolume := d.gVolumes[d.DefaultVolumePool] volumePath := filepath.Join(gVolume.MountPoint, volumeName) if util.VolumeMountPointFileExists(gVolume, volumeName, util.FILE_TYPE_DIRECTORY) { log.Debugf("Found existing volume named %v, reuse it", volumeName) } else if err := util.VolumeMountPointDirectoryCreate(gVolume, volumeName); err != nil { return err } volume.Name = volumeName volume.Path = volumePath volume.VolumePool = gVolume.UUID return util.ObjectSave(volume) }
func (d *Driver) MountVolume(req Request) (string, error) { id := req.Name opts := req.Options volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } mountPoint, err := util.VolumeMount(volume, opts[OPT_MOUNT_POINT], false) if err != nil { return "", err } if err := util.ObjectSave(volume); err != nil { return "", err } return mountPoint, nil }
func (d *Driver) CreateVolume(req Request) error { d.mutex.Lock() defer d.mutex.Unlock() id := req.Name opts := req.Options volume := d.blankVolume(id) exists, err := util.ObjectExists(volume) if err != nil { return err } if exists { return fmt.Errorf("volume %v already exists", id) } volume.PrepareForVM, err = strconv.ParseBool(opts[OPT_PREPARE_FOR_VM]) if err != nil { return err } if volume.PrepareForVM { volume.Size, err = d.getSize(opts, d.DefaultVolumeSize) if err != nil { return err } } gVolume := d.gVolumes[d.DefaultVolumePool] volumePath := filepath.Join(gVolume.MountPoint, id) if util.VolumeMountPointFileExists(gVolume, id, util.FILE_TYPE_DIRECTORY) { log.Debugf("Found existing volume named %v, reuse it", id) } else if err := util.VolumeMountPointDirectoryCreate(gVolume, id); err != nil { return err } volume.Name = id volume.Path = volumePath volume.VolumePool = gVolume.UUID volume.CreatedTime = util.Now() return util.ObjectSave(volume) }
func (d *Driver) UmountVolume(id string) error { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } if volume.MountPoint == "" { log.Debugf("Umount a umounted volume %v", id) return nil } if _, err := util.Execute(UMOUNT_BINARY, []string{volume.MountPoint}); err != nil { return err } d.putVolumeMountPoint(volume.MountPoint) volume.MountPoint = "" if err := util.ObjectSave(volume); err != nil { return err } return nil }
func (d *Driver) UmountVolume(req Request) error { d.mutex.Lock() defer d.mutex.Unlock() id := req.Name volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } if err := util.VolumeUmount(volume); err != nil { return err } if err := util.ObjectSave(volume); err != nil { return err } return nil }
func Init(root string, config map[string]string) (convoydriver.ConvoyDriver, error) { dev := &Device{ Root: root, } exists, err := util.ObjectExists(dev) if err != nil { return nil, err } if exists { if err := util.ObjectLoad(dev); err != nil { return nil, err } } else { if err := util.MkdirIfNotExists(root); err != nil { return nil, err } path := config[VFS_PATH] if path == "" { return nil, fmt.Errorf("VFS driver base path unspecified") } if err := util.MkdirIfNotExists(path); err != nil { return nil, err } dev = &Device{ Root: root, Path: path, } if err := util.ObjectSave(dev); err != nil { return nil, err } } d := &Driver{ mutex: &sync.RWMutex{}, Device: *dev, } return d, nil }