Exemplo n.º 1
0
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)
}
Exemplo n.º 2
0
func (d *Driver) GetBackupInfo(backupURL string) (map[string]string, error) {
	objVolume, err := objectstore.LoadVolume(backupURL)
	if err != nil {
		return nil, err
	}
	if objVolume.Driver != d.Name() {
		return nil, fmt.Errorf("BUG: Wrong driver handling DeleteBackup(), driver should be %v but is %v", objVolume.Driver, d.Name())
	}
	return objectstore.GetBackupInfo(backupURL)
}
Exemplo n.º 3
0
func (d *Driver) DeleteBackup(backupURL string) error {
	objVolume, err := objectstore.LoadVolume(backupURL)
	if err != nil {
		return err
	}
	if objVolume.Driver != d.Name() {
		return fmt.Errorf("BUG: Wrong driver handling DeleteBackup(), driver should be %v but is %v", objVolume.Driver, d.Name())
	}
	return objectstore.DeleteSingleFileBackup(backupURL)
}
Exemplo n.º 4
0
func (s *daemon) getBackupOpsForBackup(requestURL string) (convoydriver.BackupOperations, error) {
	objVolume, err := objectstore.LoadVolume(requestURL)
	if err != nil {
		return nil, err
	}
	driver := s.ConvoyDrivers[objVolume.Driver]
	if driver == nil {
		return nil, fmt.Errorf("Cannot find driver %v for restoring", objVolume.Driver)
	}
	return driver.BackupOps()
}
Exemplo n.º 5
0
func (d *Driver) DeleteBackup(backupURL string) error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	objVolume, err := objectstore.LoadVolume(backupURL)
	if err != nil {
		return err
	}
	if objVolume.Driver != d.Name() {
		return fmt.Errorf("BUG: Wrong driver handling DeleteBackup(), driver should be %v but is %v", objVolume.Driver, d.Name())
	}
	return objectstore.DeleteDeltaBlockBackup(backupURL)
}
Exemplo n.º 6
0
func (s *daemon) getBackupOpsForBackup(requestURL string) (convoydriver.BackupOperations, error) {
	driverName := ""

	if _, err := objectstore.GetObjectStoreDriver(requestURL); err == nil {
		// Known objectstore driver
		objVolume, err := objectstore.LoadVolume(requestURL)
		if err != nil {
			return nil, err
		}
		driverName = objVolume.Driver
	} else {
		// Try Convoy driver
		u, err := url.Parse(requestURL)
		if err != nil {
			return nil, err
		}
		driverName = u.Scheme
	}
	driver := s.ConvoyDrivers[driverName]
	if driver == nil {
		return nil, fmt.Errorf("Cannot find driver %v for restoring", driverName)
	}
	return driver.BackupOps()
}
Exemplo n.º 7
0
func (d *Driver) CreateVolume(id string, opts map[string]string) error {
	var (
		size int64
		err  error
	)
	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())
		}
		size, err = d.getSize(opts, objVolume.Size)
		if err != nil {
			return err
		}
		if size != objVolume.Size {
			return fmt.Errorf("Volume size must match with backup's size")
		}
	} else {
		size, err = d.getSize(opts, d.DefaultVolumeSize)
		if err != nil {
			return err
		}
	}

	if size%(d.ThinpoolBlockSize*SECTOR_SIZE) != 0 {
		return fmt.Errorf("Size must be multiple of block size")

	}
	volume := d.blankVolume(id)
	exists, err := util.ObjectExists(volume)
	if err != nil {
		return err
	}
	if exists {
		return generateError(logrus.Fields{
			LOG_FIELD_VOLUME: id,
		}, "Already has volume with specific uuid")
	}

	devID, err := d.allocateDevID()
	if err != nil {
		return err
	}
	log.WithFields(logrus.Fields{
		LOG_FIELD_REASON:          LOG_REASON_START,
		LOG_FIELD_EVENT:           LOG_EVENT_CREATE,
		LOG_FIELD_OBJECT:          LOG_OBJECT_VOLUME,
		LOG_FIELD_VOLUME:          id,
		DM_LOG_FIELD_VOLUME_DEVID: devID,
	}).Debugf("Creating volume")
	err = devicemapper.CreateDevice(d.ThinpoolDevice, devID)
	if err != nil {
		return err
	}

	log.WithFields(logrus.Fields{
		LOG_FIELD_REASON:          LOG_REASON_START,
		LOG_FIELD_EVENT:           LOG_EVENT_ACTIVATE,
		LOG_FIELD_OBJECT:          LOG_OBJECT_VOLUME,
		LOG_FIELD_VOLUME:          id,
		DM_LOG_FIELD_VOLUME_DEVID: devID,
	}).Debugf("Activating device for volume")
	err = devicemapper.ActivateDevice(d.ThinpoolDevice, id, devID, uint64(size))
	if err != nil {
		log.WithFields(logrus.Fields{
			LOG_FIELD_REASON:          LOG_REASON_ROLLBACK,
			LOG_FIELD_EVENT:           LOG_EVENT_REMOVE,
			LOG_FIELD_OBJECT:          LOG_OBJECT_VOLUME,
			LOG_FIELD_VOLUME:          id,
			DM_LOG_FIELD_VOLUME_DEVID: devID,
		}).Debugf("Removing device for volume due to fail to activate")
		if err := devicemapper.DeleteDevice(d.ThinpoolDevice, devID); err != nil {
			log.WithFields(logrus.Fields{
				LOG_FIELD_REASON:          LOG_REASON_FAILURE,
				LOG_FIELD_EVENT:           LOG_EVENT_REMOVE,
				LOG_FIELD_OBJECT:          LOG_OBJECT_VOLUME,
				LOG_FIELD_VOLUME:          id,
				DM_LOG_FIELD_VOLUME_DEVID: devID,
			}).Debugf("Failed to remove device")
		}
		return err
	}

	volume.DevID = devID
	volume.Size = size
	volume.Snapshots = make(map[string]Snapshot)
	if err := util.ObjectSave(volume); err != nil {
		return err
	}

	dev, err := d.GetVolumeDevice(id)
	if err != nil {
		return err
	}
	if backupURL == "" {
		// format the device
		if _, err := util.Execute("mkfs", []string{"-t", "ext4", dev}); err != nil {
			return err
		}
	} else {
		if err := objectstore.RestoreDeltaBlockBackup(backupURL, dev); err != nil {
			return err
		}
	}

	return nil
}