コード例 #1
0
ファイル: vfs_storage.go プロジェクト: PaulCharlton/convoy
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
}
コード例 #2
0
ファイル: glusterfs.go プロジェクト: alwang1234/convoy
func (d *Driver) getSize(opts map[string]string, defaultVolumeSize int64) (int64, error) {
	size := opts[OPT_SIZE]
	if size == "" || size == "0" {
		size = strconv.FormatInt(defaultVolumeSize, 10)
	}
	return util.ParseSize(size)
}
コード例 #3
0
ファイル: volume.go プロジェクト: PaulCharlton/convoy
func getSize(c *cli.Context, err error) (int64, error) {
	size, err := util.GetFlag(c, "size", false, err)
	if err != nil {
		return 0, err
	}
	return util.ParseSize(size)
}
コード例 #4
0
ファイル: longhorn.go プロジェクト: srenkens/convoy
func (d *Driver) CreateVolume(id string, opts map[string]string) error {
	size, err := util.ParseSize(opts[convoydriver.OPT_SIZE])
	if err != nil {
		return err
	}
	if size == 0 {
		size = d.DefaultVolumeSize
	}

	volume := d.blankVolume(id)
	volume.Size = size
	volume.Name = opts["VolumeName"]
	volume.PrepareForVM, err = strconv.ParseBool(opts[convoydriver.OPT_PREPARE_FOR_VM])
	if err != nil {
		return err
	}

	stack := volume.Stack(d)

	if err := d.doCreateVolume(volume, stack, id, opts); err != nil {
		stack.Delete()
		return err
	}

	return nil
}
コード例 #5
0
ファイル: longhorn.go プロジェクト: alwang1234/convoy
func (d *Driver) CreateVolume(req Request) error {
	id := req.Name
	opts := req.Options

	size, err := util.ParseSize(opts[OPT_SIZE])
	if err != nil {
		return err
	}
	if size == 0 {
		size = d.DefaultVolumeSize
	}

	volume := d.blankVolume(id)
	volume.Size = size
	volume.Name = opts[OPT_VOLUME_NAME]
	volume.PrepareForVM, err = strconv.ParseBool(opts[OPT_PREPARE_FOR_VM])
	volume.CreatedTime = util.Now()
	if err != nil {
		return err
	}

	stack := volume.Stack(d)

	if err := d.doCreateVolume(volume, stack, id, opts); err != nil {
		stack.Delete()
		return err
	}

	return nil
}
コード例 #6
0
ファイル: docker.go プロジェクト: srenkens/convoy
func (s *daemon) getDockerVolume(r *http.Request, create bool) (*Volume, error) {
	request, err := getDockerVolumeRequest(r)
	if err != nil {
		return nil, err
	}

	name := request.Name
	var (
		volume     *Volume
		volumeName string
	)
	if util.ValidateName(name) {
		volumeName = name
		volume = s.loadVolumeByName(name)
	} else {
		// Not valid UUID or name
		return nil, fmt.Errorf("Invalid volume %s. Must be only contains 0-9, a-z, dash(-), underscore(_) and dot(.)", name)
	}

	if volume == nil {
		if create {
			log.Debugf("Create a new volume %v for docker", name)

			size, err := util.ParseSize(request.Opts["size"])
			if err != nil {
				return nil, err
			}
			iops := 0
			if request.Opts["iops"] != "" {
				iops, err = strconv.Atoi(request.Opts["iops"])
				if err != nil {
					return nil, err
				}
			}
			prepareForVM := false
			if request.Opts["vm"] != "" {
				prepareForVM, err = strconv.ParseBool(request.Opts["vm"])
				if err != nil {
					return nil, err
				}
			}
			request := &api.VolumeCreateRequest{
				Name:           volumeName,
				DriverName:     request.Opts["driver"],
				Size:           size,
				BackupURL:      request.Opts["backup"],
				DriverVolumeID: request.Opts["id"],
				Type:           request.Opts["type"],
				PrepareForVM:   prepareForVM,
				IOPS:           int64(iops),
			}
			volume, err = s.processVolumeCreate(request)
			if err != nil {
				return nil, err
			}
		}
	}

	return volume, nil
}
コード例 #7
0
ファイル: ebs.go プロジェクト: PaulCharlton/convoy
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
}
コード例 #8
0
ファイル: devmapper.go プロジェクト: ppawiggers/convoy
func verifyConfig(config map[string]string) (*Device, error) {
	dv := Device{
		DataDevice:     config[DM_DATA_DEV],
		MetadataDevice: config[DM_METADATA_DEV],
	}

	if dv.DataDevice == "" || dv.MetadataDevice == "" {
		return nil, fmt.Errorf("data device or metadata device unspecified")
	}

	if _, exists := config[DM_THINPOOL_NAME]; !exists {
		config[DM_THINPOOL_NAME] = DEFAULT_THINPOOL_NAME
	}
	dv.ThinpoolDevice = filepath.Join(DM_DIR, config[DM_THINPOOL_NAME])

	if _, exists := config[DM_THINPOOL_BLOCK_SIZE]; !exists {
		config[DM_THINPOOL_BLOCK_SIZE] = DEFAULT_BLOCK_SIZE
	}
	blockSize, err := util.ParseSize(config[DM_THINPOOL_BLOCK_SIZE])
	if err != nil {
		return nil, fmt.Errorf("Illegal block size specified")
	}
	if blockSize < BLOCK_SIZE_MIN || blockSize > BLOCK_SIZE_MAX || blockSize%BLOCK_SIZE_MULTIPLIER != 0 {
		return nil, fmt.Errorf("Block size must between %v and %v, and must be a multiple of %v",
			BLOCK_SIZE_MIN, BLOCK_SIZE_MAX, BLOCK_SIZE_MULTIPLIER)
	}
	dv.ThinpoolBlockSize = blockSize

	if _, exists := config[DM_DEFAULT_VOLUME_SIZE]; !exists {
		config[DM_DEFAULT_VOLUME_SIZE] = DEFAULT_VOLUME_SIZE
	}
	volumeSize, err := util.ParseSize(config[DM_DEFAULT_VOLUME_SIZE])
	if err != nil || volumeSize == 0 {
		return nil, fmt.Errorf("Illegal default volume size specified")
	}
	dv.DefaultVolumeSize = volumeSize

	return &dv, nil
}
コード例 #9
0
ファイル: snapshot.go プロジェクト: mehulsbhatt/convoy
func (s *daemon) doSnapshotInspect(version string, w http.ResponseWriter, r *http.Request, objs map[string]string) error {
	s.GlobalLock.RLock()
	defer s.GlobalLock.RUnlock()

	request := &api.SnapshotInspectRequest{}
	if err := decodeRequest(r, request); err != nil {
		return err
	}
	snapshotUUID := request.SnapshotUUID
	if err := util.CheckUUID(snapshotUUID); err != nil {
		return err
	}
	volumeUUID := s.SnapshotVolumeIndex.Get(snapshotUUID)
	if volumeUUID == "" {
		return fmt.Errorf("cannot find volume for snapshot %v", snapshotUUID)
	}

	volume := s.loadVolume(volumeUUID)
	if volume == nil {
		return fmt.Errorf("cannot find volume %v", volumeUUID)
	}
	if _, exists := volume.Snapshots[snapshotUUID]; !exists {
		return fmt.Errorf("cannot find snapshot %v of volume %v", snapshotUUID, volumeUUID)
	}

	driverInfo, err := s.getSnapshotDriverInfo(snapshotUUID, volume)
	if err != nil {
		return err
	}
	size, err := util.ParseSize(driverInfo[convoydriver.OPT_SIZE])
	if err != nil {
		return err
	}

	resp := api.SnapshotResponse{
		UUID:            snapshotUUID,
		VolumeUUID:      volume.UUID,
		VolumeName:      volume.Name,
		Size:            size,
		VolumeCreatedAt: volume.CreatedTime,
		Name:            volume.Snapshots[snapshotUUID].Name,
		CreatedTime:     volume.Snapshots[snapshotUUID].CreatedTime,
		DriverInfo:      driverInfo,
	}
	data, err := api.ResponseOutput(resp)
	if err != nil {
		return err
	}
	_, err = w.Write(data)
	return err
}
コード例 #10
0
ファイル: glusterfs.go プロジェクト: alwang1234/convoy
func Init(root string, config map[string]string) (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
		}

		serverList := config[GLUSTERFS_SERVERS]
		if serverList == "" {
			return nil, fmt.Errorf("Missing required parameter: %v", GLUSTERFS_SERVERS)
		}

		servers := strings.Split(serverList, ",")
		for _, server := range servers {
			if !util.ValidNetworkAddr(server) {
				return nil, fmt.Errorf("Invalid or unsolvable address: %v", server)
			}
		}

		defaultVolumePool := config[GLUSTERFS_DEFAULT_VOLUME_POOL]
		if defaultVolumePool == "" {
			return nil, fmt.Errorf("Missing required parameter: %v", GLUSTERFS_DEFAULT_VOLUME_POOL)
		}

		if _, exists := config[GLUSTERFS_DEFAULT_VOLUME_SIZE]; !exists {
			config[GLUSTERFS_DEFAULT_VOLUME_SIZE] = DEFAULT_VOLUME_SIZE
		}
		volumeSize, err := util.ParseSize(config[GLUSTERFS_DEFAULT_VOLUME_SIZE])
		if err != nil || volumeSize == 0 {
			return nil, fmt.Errorf("Illegal default volume size specified")
		}
		dev.DefaultVolumeSize = volumeSize

		dev = &Device{
			Root:              root,
			Servers:           servers,
			DefaultVolumePool: defaultVolumePool,
		}
	}

	// 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")
		}
	}

	d := &Driver{
		mutex:    &sync.RWMutex{},
		gVolumes: map[string]*GlusterFSVolume{},
		Device:   *dev,
	}
	gVolume := &GlusterFSVolume{
		UUID:       dev.DefaultVolumePool,
		Servers:    dev.Servers,
		configPath: d.Root,
	}
	// We would always mount the default volume pool
	// TODO: Also need to mount any existing volume's pool
	if _, err := util.VolumeMount(gVolume, "", true); err != nil {
		return nil, err
	}
	d.gVolumes[d.DefaultVolumePool] = gVolume

	if err := util.ObjectSave(dev); err != nil {
		return nil, err
	}
	return d, nil
}
コード例 #11
0
ファイル: longhorn.go プロジェクト: srenkens/convoy
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
		}
		dev.RancherURL = override(dev.RancherURL, config[LH_RANCHER_URL])
		dev.RancherAccessKey = override(dev.RancherAccessKey, config[LH_RANCHER_ACCESS_KEY])
		dev.RancherSecretKey = override(dev.RancherSecretKey, config[LH_RANCHER_SECRET_KEY])
	} else {
		if err := util.MkdirIfNotExists(root); err != nil {
			return nil, err
		}

		url := config[LH_RANCHER_URL]
		accessKey := config[LH_RANCHER_ACCESS_KEY]
		secretKey := config[LH_RANCHER_SECRET_KEY]

		if url == "" || accessKey == "" || secretKey == "" {
			return nil, fmt.Errorf("Missing required parameter. lh.rancherurl or lh.rancheraccesskey or lh.ranchersecretkey")
		}

		if _, exists := config[LH_DEFAULT_VOLUME_SIZE]; !exists {
			config[LH_DEFAULT_VOLUME_SIZE] = DEFAULT_VOLUME_SIZE
		}
		volumeSize, err := util.ParseSize(config[LH_DEFAULT_VOLUME_SIZE])
		if err != nil || volumeSize == 0 {
			return nil, fmt.Errorf("Illegal default volume size specified")
		}

		dev = &Device{
			Root:              root,
			RancherURL:        url,
			RancherAccessKey:  accessKey,
			RancherSecretKey:  secretKey,
			DefaultVolumeSize: volumeSize,
		}
	}

	containerName := config[LH_CONTAINER_NAME]
	if containerName == "" {
		handler := metadata.NewClient(RANCHER_METADATA_URL)
		container, err := handler.GetSelfContainer()
		if err != nil {
			return nil, err
		}
		containerName = container.UUID
	}

	log.Debugf("Try to connect to Rancher server at %s [%s:%s]", dev.RancherURL, dev.RancherAccessKey, dev.RancherSecretKey)
	client, err := rancherClient.NewRancherClient(&rancherClient.ClientOpts{
		Url:       dev.RancherURL,
		AccessKey: dev.RancherAccessKey,
		SecretKey: dev.RancherSecretKey,
	})
	if err != nil {
		return nil, fmt.Errorf("Failed to establish connection to Rancher server")
	}

	if err := util.ObjectSave(dev); err != nil {
		return nil, err
	}
	d := &Driver{
		client:        client,
		containerName: containerName,
		Device:        *dev,
	}

	return d, nil
}