func (d *Driver) GetVolumeInfo(id string) (map[string]string, error) { d.mutex.Lock() defer d.mutex.Unlock() volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return nil, err } ebsVolume, err := d.ebsService.GetVolume(volume.EBSID) if err != nil { return nil, err } iops := "" if ebsVolume.Iops != nil { iops = strconv.FormatInt(*ebsVolume.Iops, 10) } info := map[string]string{ "Device": volume.Device, "MountPoint": volume.MountPoint, "UUID": volume.UUID, "EBSVolumeID": volume.EBSID, "AvailiablityZone": *ebsVolume.AvailabilityZone, "CreatedTime": (*ebsVolume.CreateTime).Format(time.RubyDate), "Size": strconv.FormatInt(*ebsVolume.Size*GB, 10), "State": *ebsVolume.State, "Type": *ebsVolume.VolumeType, "IOPS": iops, } return info, nil }
func (d *Driver) GetVolumeInfo(id string) (map[string]string, error) { d.mutex.RLock() defer d.mutex.RUnlock() volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return nil, err } gVolume := d.gVolumes[volume.VolumePool] if gVolume == nil { return nil, fmt.Errorf("Cannot find volume pool %v", volume.VolumePool) } size := "-1" prepareForVM := strconv.FormatBool(volume.PrepareForVM) if volume.PrepareForVM { size = strconv.FormatInt(volume.Size, 10) } return map[string]string{ OPT_VOLUME_NAME: volume.Name, "Path": volume.Path, OPT_MOUNT_POINT: volume.MountPoint, OPT_SIZE: size, OPT_PREPARE_FOR_VM: prepareForVM, OPT_VOLUME_CREATED_TIME: volume.CreatedTime, "GlusterFSVolume": volume.VolumePool, "GlusterFSServers": fmt.Sprintf("%v", gVolume.Servers), }, 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) 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) ListSnapshot(opts map[string]string) (map[string]map[string]string, error) { var ( volumeIDs []string err error ) d.mutex.RLock() defer d.mutex.RUnlock() snapshots := make(map[string]map[string]string) specifiedVolumeID, _ := util.GetFieldFromOpts(OPT_VOLUME_NAME, opts) if specifiedVolumeID != "" { volumeIDs = []string{ specifiedVolumeID, } } else { volumeIDs, err = d.listVolumeNames() if err != nil { return nil, err } } for _, volumeID := range volumeIDs { volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return nil, err } for snapshotID := range volume.Snapshots { snapshots[snapshotID], err = d.getSnapshotInfo(snapshotID, volumeID) if err != nil { return nil, err } } } return snapshots, 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 } 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) deactivatePool() error { dev := d.Device volumeIDs, err := dev.listVolumeIDs() if err != nil { return err } for _, id := range volumeIDs { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } if err := d.removeDevice(id); err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_EVENT: LOG_EVENT_ACTIVATE, LOG_FIELD_VOLUME: id, }).Debug("Deactivated volume device") } if err := removePool(dev.ThinpoolDevice); err != nil { return err } log.Debug("Deactivate the pool ", dev.ThinpoolDevice) return nil }
func (d *Driver) MountPoint(id string) (string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } return volume.MountPoint, 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 } 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) ListSnapshot(opts map[string]string) (map[string]map[string]string, error) { var ( volumeIDs []string err error ) snapshots := make(map[string]map[string]string) specifiedVolumeID := opts["VolumeID"] if specifiedVolumeID != "" { volumeIDs = []string{ specifiedVolumeID, } } else { volumeIDs, err = d.listVolumeIDs() if err != nil { return nil, err } } for _, volumeID := range volumeIDs { volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return nil, err } for snapshotID := range volume.Snapshots { snapshots[snapshotID], err = d.GetSnapshotInfo(snapshotID, volumeID) if err != nil { return nil, err } } } return snapshots, nil }
func (d *Driver) DeleteVolume(req Request) 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 } if volume.MountPoint != "" { return fmt.Errorf("Cannot delete volume %v. It is still mounted", id) } referenceOnly, _ := strconv.ParseBool(opts[OPT_REFERENCE_ONLY]) if !referenceOnly { log.Debugf("Cleaning up volume %v", id) gVolume := d.gVolumes[d.DefaultVolumePool] if err := util.VolumeMountPointDirectoryRemove(gVolume, volume.Name); err != nil { return err } } return util.ObjectDelete(volume) }
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) DeleteVolume(id string, opts map[string]string) error { d.mutex.Lock() defer d.mutex.Unlock() volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } referenceOnly, _ := strconv.ParseBool(opts[convoydriver.OPT_REFERENCE_ONLY]) if err := d.ebsService.DetachVolume(volume.EBSID); err != nil { if !referenceOnly { return err } //Ignore the error, remove the reference log.Warnf("Unable to detached %v(%v) due to %v, but continue with removing the reference", id, volume.EBSID, err) } else { log.Debugf("Detached %v(%v) from %v", id, volume.EBSID, volume.Device) } if !referenceOnly { if err := d.ebsService.DeleteVolume(volume.EBSID); err != nil { return err } log.Debugf("Deleted %v(%v)", id, volume.EBSID) } return util.ObjectDelete(volume) }
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) GetVolumeDevice(id string) (string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } return filepath.Join(DM_DIR, id), nil }
func (d *Driver) GetVolumeDevice(id string) (string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } return volume.GetDevice() }
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) MountPoint(req Request) (string, error) { id := req.Name volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } return volume.MountPoint, 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 (d *Driver) GetVolumeInfo(id string) (map[string]string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return nil, err } return map[string]string{ "Size": strconv.FormatInt(volume.Size, 10), convoydriver.OPT_PREPARE_FOR_VM: strconv.FormatBool(volume.PrepareForVM), }, nil }
func (d *Driver) MountPoint(id string) (string, error) { d.mutex.RLock() defer d.mutex.RUnlock() volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return "", err } return volume.MountPoint, 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 (s *daemon) loadVolume(uuid string) *Volume { volume := &Volume{ UUID: uuid, configPath: s.Root, } if err := util.ObjectLoad(volume); err != nil { log.Errorf("Fail to load volume! %v", err) return nil } return volume }
func (d *Driver) GetVolumeInfo(id string) (map[string]string, error) { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return nil, err } return map[string]string{ "Size": strconv.FormatInt(volume.Size, 10), OPT_PREPARE_FOR_VM: strconv.FormatBool(volume.PrepareForVM), OPT_VOLUME_CREATED_TIME: volume.CreatedTime, OPT_VOLUME_NAME: volume.Name, }, 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) GetVolumeInfo(id string) (map[string]string, error) { d.mutex.RLock() defer d.mutex.RUnlock() volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return nil, err } return map[string]string{ "Path": volume.Path, convoydriver.OPT_MOUNT_POINT: volume.MountPoint, }, nil }
func (d *Driver) getSnapshotAndVolume(snapshotID, volumeID string) (*Snapshot, *Volume, error) { volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return nil, nil, err } snap, exists := volume.Snapshots[snapshotID] if !exists { return nil, nil, generateError(logrus.Fields{ LOG_FIELD_VOLUME: volumeID, LOG_FIELD_SNAPSHOT: snapshotID, }, "cannot find snapshot of volume") } return &snap, volume, nil }
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) 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) 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) }