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