// CreateVolume is a CSI API which creates a volume on OSD
// This function supports snapshots if the parent volume id is supplied
// in the parameters.
546309
func (s *OsdCsiServer) CreateVolume(
	ctx context.Context,
	req *csi.CreateVolumeRequest,
) (*csi.CreateVolumeResponse, error) {

	// Log request
	logrus.Debugf("CreateVolume req[%#v]", *req)

	if len(req.GetName()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Name must be provided")
	}
	if req.GetVolumeCapabilities() == nil || len(req.GetVolumeCapabilities()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Volume capabilities must be provided")
	}

	// Get parameters
	spec, locator, source, err := s.specHandler.SpecFromOpts(req.GetParameters())
	if err != nil {
		e := fmt.Sprintf("Unable to get parameters: %s\n", err.Error())
		logrus.Errorln(e)
		return nil, status.Error(codes.InvalidArgument, e)
	}

	// Get Size
	if req.GetCapacityRange() != nil && req.GetCapacityRange().GetRequiredBytes() != 0 {
		spec.Size = uint64(req.GetCapacityRange().GetRequiredBytes())
	} else {
		spec.Size = defaultCSIVolumeSize
	}

	// Create response
	volume := &csi.Volume{}
	resp := &csi.CreateVolumeResponse{
		Volume: volume,
	}

	// Check if the volume has already been created or is in process of creation
	v, err := util.VolumeFromName(s.driver, req.GetName())
	if err == nil {
		// Check the requested arguments match that of the existing volume
		if spec.Size != v.GetSpec().GetSize() {
			return nil, status.Errorf(
				codes.AlreadyExists,
				"Existing volume has a size of %v which differs from requested size of %v",
				v.GetSpec().GetSize(),
				spec.Size)
		}
		if v.GetSpec().GetShared() != csiRequestsSharedVolume(req) {
			return nil, status.Errorf(
				codes.AlreadyExists,
				"Existing volume has shared=%v while request is asking for shared=%v",
				v.GetSpec().GetShared(),
				csiRequestsSharedVolume(req))
		}
		if v.GetSource().GetParent() != source.GetParent() {
			return nil, status.Error(codes.AlreadyExists, "Existing volume has conflicting parent value")
		}

		// Return information on existing volume
		osdToCsiVolumeInfo(volume, v)
		return resp, nil
	}

	// Check if this is a cloning request to create a volume from a snapshot
	if req.GetVolumeContentSource().GetSnapshot() != nil {
		source.Parent = req.GetVolumeContentSource().GetSnapshot().GetId()
	}

	// Check if the caller is asking to create a snapshot or for a new volume
	var id string
	if source != nil && len(source.GetParent()) != 0 {
		// Get parent volume information
		parent, err := util.VolumeFromName(s.driver, source.Parent)
		if err != nil {
			e := fmt.Sprintf("unable to get parent volume information: %s\n", err.Error())
			logrus.Errorln(e)
			return nil, status.Error(codes.InvalidArgument, e)
		}

		// Create a snapshot from the parent
		id, err = s.driver.Snapshot(parent.GetId(), false, &api.VolumeLocator{
			Name: req.GetName(),
		},
			false)
		if err != nil {
			e := fmt.Sprintf("unable to create snapshot: %s\n", err.Error())
			logrus.Errorln(e)
			return nil, status.Error(codes.Internal, e)
		}
	} else {
		// Get Capabilities and Size
		spec.Shared = csiRequestsSharedVolume(req)

		// Create the volume
		locator.Name = req.GetName()

		// get enforced policy specs
		// 0.3 Does not support user context or auth
		spec, err = sdkVol.GetDefaultVolSpecs(context.Background(), spec, false /* not an update */)
		if err != nil {
			return nil, status.Errorf(codes.Internal, err.Error())
		}
		id, err = s.driver.Create(locator, source, spec)
		if err != nil {
			return nil, status.Error(codes.Internal, err.Error())
		}
	}

	// id must have been set
	v, err = util.VolumeFromName(s.driver, id)
	if err != nil {
		e := fmt.Sprintf("Unable to find newly created volume: %s", err.Error())
		logrus.Errorln(e)
		return nil, status.Error(codes.Internal, e)
	}
	osdToCsiVolumeInfo(volume, v)
	return resp, nil
}
585236
func (d *driver) VolumeCreate(
	ctx types.Context,
	volumeName string,
	opts *types.VolumeCreateOpts) (*types.Volume, error) {

	fields := map[string]interface{}{
		"driverName": d.Name(),
		"volumeName": volumeName,
		"opts":       opts,
	}

	zone, err := d.validZone(ctx)
	if err != nil {
		return nil, err
	}

	// No zone information from request, driver, or IID
	if (zone == nil || *zone == "") && (opts.AvailabilityZone == nil || *opts.AvailabilityZone == "") {
		return nil, goof.New("Zone is required for VolumeCreate")
	}

	if zone != nil && *zone != "" {
		if opts.AvailabilityZone != nil && *opts.AvailabilityZone != "" {
			// If request and driver/IID have zone, they must match
			if *zone != *opts.AvailabilityZone {
				return nil, goof.WithFields(fields,
					"Cannot create volume in given zone")
			}
		} else {
			// Set the zone to the driver/IID config
			opts.AvailabilityZone = zone
		}

	}

	volumeName = d.convUnderscores(volumeName)
	fields["volumeName"] = volumeName
	if !utils.IsValidDiskName(&volumeName) {
		return nil, goof.WithFields(fields,
			"Volume name does not meet GCE naming requirements")
	}

	if opts.Size == nil {
		size := int64(minDiskSizeGB)
		opts.Size = &size
	}

	fields["size"] = *opts.Size

	if *opts.Size < minDiskSizeGB {
		fields["minSize"] = minDiskSizeGB
		return nil, goof.WithFields(fields, "volume size too small")
	}

	ctx.WithFields(fields).Debug("creating volume")

	// Check if volume with same name exists
	gceDisk, err := d.getDisk(ctx, opts.AvailabilityZone, &volumeName)
	if err != nil {
		return nil, goof.WithFieldsE(fields,
			"error querying for existing volume", err)
	}
	if gceDisk != nil {
		return nil, goof.WithFields(fields,
			"volume name already exists")
	}

	err = d.createVolume(ctx, &volumeName, opts)
	if err != nil {
		return nil, goof.WithFieldsE(
			fields, "error creating volume", err)
	}

	// Return the volume created
	return d.VolumeInspect(ctx, volumeName,
		&types.VolumeInspectOpts{
			Attachments: types.VolAttNone,
		},
	)
}
80361
func (s *posix) CreateFile(volume, path string, fileSize int64, r io.Reader) (err error) {
	if fileSize < -1 {
		return errInvalidArgument
	}
	defer func() {
		if err == errFaultyDisk {
			atomic.AddInt32(&s.ioErrCount, 1)
		}
	}()

	if atomic.LoadInt32(&s.ioErrCount) > maxAllowedIOError {
		return errFaultyDisk
	}

	// Validate if disk is indeed free.
	if err = checkDiskFree(s.diskPath, fileSize); err != nil {
		if isSysErrIO(err) {
			return errFaultyDisk
		}
		return err
	}

	if err = s.checkDiskFound(); err != nil {
		return err
	}

	volumeDir, err := s.getVolDir(volume)
	if err != nil {
		return err
	}
	// Stat a volume entry.
	_, err = os.Stat((volumeDir))
	if err != nil {
		if os.IsNotExist(err) {
			return errVolumeNotFound
		} else if isSysErrIO(err) {
			return errFaultyDisk
		}
		return err
	}

	filePath := pathJoin(volumeDir, path)
	if err = checkPathLength((filePath)); err != nil {
		return err
	}

	// Create top level directories if they don't exist.
	// with mode 0777 mkdir honors system umask.
	if err = mkdirAll(slashpath.Dir(filePath), 0777); err != nil {
		return err
	}

	w, err := disk.OpenFileDirectIO(filePath, os.O_CREATE|os.O_WRONLY|os.O_EXCL|os.O_SYNC, 0666)
	if err != nil {
		switch {
		case os.IsPermission(err):
			return errFileAccessDenied
		case os.IsExist(err):
			return errFileAccessDenied
		case isSysErrIO(err):
			return errFaultyDisk
		default:
			return err
		}
	}
	defer w.Close()

	var e error
	if fileSize > 0 {
		// Allocate needed disk space to append data
		e = Fallocate(int(w.Fd()), 0, fileSize)
	}

	// Ignore errors when Fallocate is not supported in the current system
	if e != nil && !isSysErrNoSys(e) && !isSysErrOpNotSupported(e) {
		switch {
		case isSysErrNoSpace(e):
			err = errDiskFull
		case isSysErrIO(e):
			err = errFaultyDisk
		default:
			// For errors: EBADF, EINTR, EINVAL, ENODEV, EPERM, ESPIPE  and ETXTBSY
			// Appending was failed anyway, returns unexpected error
			err = errUnexpected
		}
		return err
	}

	bufp := s.pool.Get().(*[]byte)
	defer s.pool.Put(bufp)

	buf := *bufp

	// Writes remaining bytes in the buffer.
	writeRemaining := func(w *os.File, buf []byte) (remainingWritten int, err error) {
		var n int
		remaining := len(buf)
		// The following logic writes the remainging data such that it writes whatever best is possible (aligned buffer)
		// in O_DIRECT mode and remaining (unaligned buffer) in non-O_DIRECT mode.
		remainingAligned := (remaining / directioAlignSize) * directioAlignSize
		remainingAlignedBuf := buf[:remainingAligned]
		remainingUnalignedBuf := buf[remainingAligned:]
		if len(remainingAlignedBuf) > 0 {
			n, err = w.Write(remainingAlignedBuf)
			if err != nil {
				return 0, err
			}
			remainingWritten += n
		}
		if len(remainingUnalignedBuf) > 0 {
			// Write on O_DIRECT fds fail if buffer is not 4K aligned, hence disable O_DIRECT.
			if err = disk.DisableDirectIO(w); err != nil {
				return 0, err
			}
			n, err = w.Write(remainingUnalignedBuf)
			if err != nil {
				return 0, err
			}
			remainingWritten += n
		}
		return remainingWritten, nil
	}

	var written int
	for {
		var n int
		n, err = io.ReadFull(r, buf)
		switch err {
		case nil:
			n, err = w.Write(buf)
			if err != nil {
				return err
			}
			written += n
		case io.ErrUnexpectedEOF:
			n, err = writeRemaining(w, buf[:n])
			if err != nil {
				return err
			}
			written += n
			fallthrough
		case io.EOF:
			if fileSize != -1 {
				if written < int(fileSize) {
					return errLessData
				}
				if written > int(fileSize) {
					return errMoreData
				}
			}
			return nil
		default:
			return err
		}
	}
}
15164
func (d *driver) VolumeCreate(ctx types.Context, volumeName string,
	opts *types.VolumeCreateOpts) (*types.Volume, error) {
	// Initialize for logging
	fields := map[string]interface{}{
		"driverName": d.Name(),
		"volumeName": volumeName,
		"opts":       opts,
	}

	ctx.WithFields(fields).Debug("creating volume")

	if opts.Size == nil {
		size := int64(minSizeGiB)
		opts.Size = &size
	}

	fields["size"] = *opts.Size

	if *opts.Size < minSizeGiB {
		fields["minSize"] = minSizeGiB
		return nil, goof.WithFields(fields, "volume size too small")
	}

	// Check if volume with same name exists
	ec2vols, err := d.getVolume(ctx, "", volumeName)
	if err != nil {
		return nil, goof.WithFieldsE(fields, "error getting volume", err)
	}
	volumes, convErr := d.toTypesVolume(ctx, ec2vols, 0)
	if convErr != nil {
		return nil, goof.WithFieldsE(
			fields, "error converting to types.Volume", convErr)
	}

	if len(volumes) > 0 {
		return nil, goof.WithFields(fields, "volume name already exists")
	}

	// Pass libStorage types.Volume to helper function which calls EC2 API
	vol, err := d.createVolume(ctx, volumeName, "", opts)
	if err != nil {
		return nil, goof.WithFieldsE(fields, "error creating volume", err)
	}

	// Return the volume created
	return d.VolumeInspect(ctx, *vol.VolumeId, &types.VolumeInspectOpts{
		Attachments: types.VolAttReqTrue,
	})
}
683415
func (os *OpenStack) CreateSnapshot(sourceVolumeID, name, description string, tags map[string]string) (string, string, error) {
	snapshots, err := os.snapshotService()
	if err != nil || snapshots == nil {
		glog.Errorf("Unable to initialize cinder client for region: %s", os.region)
		return "", "", fmt.Errorf("Failed to create snapshot for volume %s: %v", sourceVolumeID, err)
	}

	opts := SnapshotCreateOpts{
		VolumeID:    sourceVolumeID,
		Name:        name,
		Description: description,
	}
	if tags != nil {
		opts.Metadata = tags
	}

	snapshotID, status, err := snapshots.createSnapshot(opts)

	if err != nil {
		glog.Errorf("Failed to snapshot volume %s : %v", sourceVolumeID, err)
		return "", "", err
	}

	glog.Infof("Created snapshot %v from volume: %v", snapshotID, sourceVolumeID)
	return snapshotID, status, nil
}
1351690
func (s *OsdCsiServer) CreateSnapshot(
	ctx context.Context,
	req *csi.CreateSnapshotRequest,
) (*csi.CreateSnapshotResponse, error) {

	if len(req.GetSourceVolumeId()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Volume id must be provided")
	} else if len(req.GetName()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Name must be provided")
	}

	// Check if the snapshot with this name already exists
	v, err := util.VolumeFromName(s.driver, req.GetName())
	if err == nil {
		// Verify the parent is the same
		if req.GetSourceVolumeId() != v.GetSource().GetParent() {
			return nil, status.Error(codes.AlreadyExists, "Requested snapshot already exists for another source volume id")
		}

		// Return current snapshot info
		createdAt, err := ptypes.Timestamp(v.GetCtime())
		if err != nil {
			return nil, status.Errorf(codes.Internal, "Failed to get time snapshot was created: %v", err)
		}
		return &csi.CreateSnapshotResponse{
			Snapshot: &csi.Snapshot{
				Id:             v.GetId(),
				SourceVolumeId: v.GetSource().GetParent(),
				CreatedAt:      createdAt.Unix(),
				Status: &csi.SnapshotStatus{
					// This means that we are not uploading our snapshot
					// We may add support for cloud snaps in future patches
					Type: csi.SnapshotStatus_READY,
				},
			},
		}, nil
	}

	// Get any labels passed in by the CO
	_, locator, _, err := s.specHandler.SpecFromOpts(req.GetParameters())
	if err != nil {
		return nil, status.Errorf(codes.InvalidArgument, "Unable to get parameters: %v", err)
	}

	// Create snapshot
	readonly := true
	snapshotID, err := s.driver.Snapshot(req.GetSourceVolumeId(), readonly, &api.VolumeLocator{
		Name:         req.GetName(),
		VolumeLabels: locator.GetVolumeLabels(),
	}, false)
	if err != nil {
		if err == kvdb.ErrNotFound {
			return nil, status.Errorf(codes.NotFound, "Volume id %s not found", req.GetSourceVolumeId())
		}
		return nil, status.Errorf(codes.Internal, "Failed to create snapshot: %v", err)
	}

	snapInfo, err := util.VolumeFromName(s.driver, snapshotID)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "Failed to get information about the snapshot: %v", err)
	}
	createdAt, err := ptypes.Timestamp(snapInfo.GetCtime())
	if err != nil {
		return nil, status.Errorf(codes.Internal, "Failed to get time snapshot was created: %v", err)
	}

	return &csi.CreateSnapshotResponse{
		Snapshot: &csi.Snapshot{
			Id:             snapshotID,
			SourceVolumeId: req.GetSourceVolumeId(),
			CreatedAt:      createdAt.Unix(),
			Status: &csi.SnapshotStatus{
				// This means that we are not uploading our snapshot
				// We may add support flow cloud snaps in future patches
				Type: csi.SnapshotStatus_READY,
			},
		},
	}, nil
}
337848
func createSecretVolumes(tmpl *wfv1.Template) ([]apiv1.Volume, []apiv1.VolumeMount) {
	var allVolumesMap = make(map[string]apiv1.Volume)
	var uniqueKeyMap = make(map[string]bool)
	var secretVolumes []apiv1.Volume
	var secretVolMounts []apiv1.VolumeMount

	createArchiveLocationSecret(tmpl, allVolumesMap, uniqueKeyMap)

	for _, art := range tmpl.Outputs.Artifacts {
		createSecretVolume(allVolumesMap, art, uniqueKeyMap)
	}
	for _, art := range tmpl.Inputs.Artifacts {
		createSecretVolume(allVolumesMap, art, uniqueKeyMap)
	}

	for volMountName, val := range allVolumesMap {
		secretVolumes = append(secretVolumes, val)
		secretVolMounts = append(secretVolMounts, apiv1.VolumeMount{
			Name:      volMountName,
			MountPath: common.SecretVolMountPath + "/" + val.Name,
			ReadOnly:  true,
		})
	}

	return secretVolumes, secretVolMounts
}
402995
func (s *VolumeServer) Create(
	ctx context.Context,
	req *api.SdkVolumeCreateRequest,
) (*api.SdkVolumeCreateResponse, error) {
	if s.cluster() == nil || s.driver(ctx) == nil {
		return nil, status.Error(codes.Unavailable, "Resource has not been initialized")
	}

	if len(req.GetName()) == 0 {
		return nil, status.Error(
			codes.InvalidArgument,
			"Must supply a unique name")
	} else if req.GetSpec() == nil {
		return nil, status.Error(
			codes.InvalidArgument,
			"Must supply spec object")
	}

	locator := &api.VolumeLocator{
		Name:         req.GetName(),
		VolumeLabels: req.GetLabels(),
	}
	source := &api.Source{}

	// Validate/Update given spec according to default storage policy set
	// In case policy is not set, should fall back to default way
	// of creating volume
	spec, err := GetDefaultVolSpecs(ctx, req.GetSpec(), false)
	if err != nil {
		return nil, err
	}

	// Copy any labels from the spec to the locator
	locator = locator.MergeVolumeSpecLabels(spec)

	// Convert node IP to ID if necessary for API calls
	if err := s.updateReplicaSpecNodeIPstoIds(spec.GetReplicaSet()); err != nil {
		return nil, status.Errorf(codes.Internal, "Failed to get replicat set information: %v", err)
	}

	// Create volume
	id, err := s.create(ctx, locator, source, spec)
	if err != nil {
		return nil, err
	}

	return &api.SdkVolumeCreateResponse{
		VolumeId: id,
	}, nil
}
603311
func (lvs *loopVolumeSource) CreateVolumes(ctx context.ProviderCallContext, args []storage.VolumeParams) ([]storage.CreateVolumesResult, error) {
	results := make([]storage.CreateVolumesResult, len(args))
	for i, arg := range args {
		volume, err := lvs.createVolume(arg)
		if err != nil {
			results[i].Error = errors.Annotate(err, "creating volume")
		}
		results[i].Volume = &volume
	}
	return results, nil
}
909735
func (c *Client) CreateVolumeDir(
	ctx context.Context,
	volumeName, dirPath string,
	fileMode os.FileMode,
	overwrite, recursive bool) error {

	return apiv2.ContainerCreateDir(
		ctx, c.API, volumeName, dirPath,
		apiv2.FileMode(fileMode), overwrite, recursive)
}
543130
func (s *VolumeServer) SnapshotCreate(
	ctx context.Context,
	req *api.SdkVolumeSnapshotCreateRequest,
) (*api.SdkVolumeSnapshotCreateResponse, error) {
	if s.cluster() == nil || s.driver(ctx) == nil {
		return nil, status.Error(codes.Unavailable, "Resource has not been initialized")
	}

	if len(req.GetVolumeId()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Must supply volume id")
	} else if len(req.GetName()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Must supply a name")
	}

	// Get access rights
	if err := s.checkAccessForVolumeId(ctx, req.GetVolumeId(), api.Ownership_Read); err != nil {
		return nil, err
	}

	readonly := true
	snapshotID, err := s.driver(ctx).Snapshot(req.GetVolumeId(), readonly, &api.VolumeLocator{
		Name:         req.GetName(),
		VolumeLabels: req.GetLabels(),
	}, false)
	if err != nil {
		if err == kvdb.ErrNotFound {
			return nil, status.Errorf(
				codes.NotFound,
				"Id %s not found",
				req.GetVolumeId())
		}
		return nil, status.Errorf(codes.Internal, "Failed to create snapshot: %v", err.Error())
	}

	return &api.SdkVolumeSnapshotCreateResponse{
		SnapshotId: snapshotID,
	}, nil
}
1116013
func (v *azureVolumeSource) createManagedDiskVolume(ctx context.ProviderCallContext, p storage.VolumeParams) (*storage.Volume, error) {
	cfg, err := newAzureStorageConfig(p.Attributes)
	if err != nil {
		return nil, errors.Trace(err)
	}

	diskTags := make(map[string]*string)
	for k, v := range p.ResourceTags {
		diskTags[k] = to.StringPtr(v)
	}
	diskName := p.Tag.String()
	sizeInGib := mibToGib(p.Size)
	diskModel := compute.Disk{
		Name:     to.StringPtr(diskName),
		Location: to.StringPtr(v.env.location),
		Tags:     diskTags,
		Sku: &compute.DiskSku{
			Name: cfg.storageType,
		},
		DiskProperties: &compute.DiskProperties{
			CreationData: &compute.CreationData{CreateOption: compute.Empty},
			DiskSizeGB:   to.Int32Ptr(int32(sizeInGib)),
		},
	}

	diskClient := compute.DisksClient{v.env.disk}
	sdkCtx := stdcontext.Background()
	future, err := diskClient.CreateOrUpdate(sdkCtx, v.env.resourceGroup, diskName, diskModel)
	if err != nil {
		return nil, errorutils.HandleCredentialError(errors.Annotatef(err, "creating disk for volume %q", p.Tag.Id()), ctx)
	}
	err = future.WaitForCompletionRef(sdkCtx, diskClient.Client)
	if err != nil {
		return nil, errorutils.HandleCredentialError(errors.Annotatef(err, "creating disk for volume %q", p.Tag.Id()), ctx)
	}
	result, err := future.Result(diskClient)
	if err != nil && !isNotFoundResult(result.Response) {
		return nil, errors.Annotatef(err, "creating disk for volume %q", p.Tag.Id())
	}

	volume := storage.Volume{
		p.Tag,
		storage.VolumeInfo{
			VolumeId:   diskName,
			Size:       gibToMib(uint64(to.Int32(result.DiskSizeGB))),
			Persistent: true,
		},
	}
	return &volume, nil
}
378688
func (d *driver) createVolume(
	ctx types.Context,
	volumeName, snapshotID string,
	opts *types.VolumeCreateOpts) (*awsec2.Volume, error) {

	var (
		encryption bool
		kmsKeyID   string
	)

	if opts.Encrypted != nil && *opts.Encrypted {
		encryption = true
		if opts.EncryptionKey != nil && len(*opts.EncryptionKey) > 0 {
			ctx.Debug("creating encrypted volume w client enc key")
			kmsKeyID = *opts.EncryptionKey
		} else if len(d.kmsKeyID) > 0 {
			ctx.Debug("creating encrypted volume w server enc key")
			kmsKeyID = *aws.String(d.kmsKeyID)
		} else {
			ctx.Debug("creating encrypted volume w default enc key")
		}
	}

	var resp *awsec2.Volume

	_, err := fcagent.CreateVol(volumeName, int(*opts.Size), encryption, kmsKeyID)
	if err != nil {
		return &awsec2.Volume{}, goof.WithError(
			"error creating FittedCloud volume", err)
	}
	ec2vols, err1 := d.getVolume(ctx, "", volumeName)
	if err1 != nil {
		return &awsec2.Volume{}, goof.WithError(
			"error getting volume", err1)
	}
	resp = ec2vols[0]

	return resp, nil
}
534793
func (v *azureVolumeSource) createManagedDiskVolumes(ctx context.ProviderCallContext, params []storage.VolumeParams, results []storage.CreateVolumesResult) {
	for i, p := range params {
		if results[i].Error != nil {
			continue
		}
		volume, err := v.createManagedDiskVolume(ctx, p)
		if err != nil {
			results[i].Error = err
			continue
		}
		results[i].Volume = volume
	}
}
307677
func (r *Root) Create(name string, opts map[string]string) (volume.Volume, error) {
	if err := r.validateName(name); err != nil {
		return nil, err
	}

	r.m.Lock()
	defer r.m.Unlock()

	v, exists := r.volumes[name]
	if exists {
		return v, nil
	}

	path := r.DataPath(name)
	if err := idtools.MkdirAllAndChown(path, 0755, r.rootIdentity); err != nil {
		return nil, errors.Wrapf(errdefs.System(err), "error while creating volume path '%s'", path)
	}

	var err error
	defer func() {
		if err != nil {
			os.RemoveAll(filepath.Dir(path))
		}
	}()

	v = &localVolume{
		driverName: r.Name(),
		name:       name,
		path:       path,
	}

	if len(opts) != 0 {
		if err = setOpts(v, opts); err != nil {
			return nil, err
		}
		var b []byte
		b, err = json.Marshal(v.opts)
		if err != nil {
			return nil, err
		}
		if err = ioutil.WriteFile(filepath.Join(filepath.Dir(path), "opts.json"), b, 600); err != nil {
			return nil, errdefs.System(errors.Wrap(err, "error while persisting volume options"))
		}
	}

	r.volumes[name] = v
	return v, nil
}
1238696
func (v OpenEBSVolume) CreateVolume(vs mayav1.VolumeSpec) (string, error) {

	addr := os.Getenv("MAPI_ADDR")
	if addr == "" {
		err := errors.New("MAPI_ADDR environment variable not set")
		glog.Errorf("Error getting maya-apiserver IP Address: %v", err)
		return "Error getting maya-apiserver IP Address", err
	}
	url := addr + "/latest/volumes/"

	vs.Kind = "PersistentVolumeClaim"
	vs.APIVersion = "v1"

	//Marshal serializes the value provided into a YAML document
	yamlValue, _ := yaml.Marshal(vs)

	glog.V(2).Infof("[DEBUG] volume Spec Created:\n%v\n", string(yamlValue))

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(yamlValue))

	req.Header.Add("Content-Type", "application/yaml")

	c := &http.Client{
		Timeout: timeout,
	}
	resp, err := c.Do(req)
	if err != nil {
		glog.Errorf("Error when connecting maya-apiserver %v", err)
		return "Could not connect to maya-apiserver", err
	}
	defer resp.Body.Close()

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		glog.Errorf("Unable to read response from maya-apiserver %v", err)
		return "Unable to read response from maya-apiserver", err
	}

	code := resp.StatusCode
	if code != http.StatusOK {
		glog.Errorf("Status error: %v\n", http.StatusText(code))
		return "HTTP Status error from maya-apiserver", err
	}

	glog.Infof("volume Successfully Created:\n%v\n", string(data))
	return "volume Successfully Created", nil
}
94262
func (d *driver) Create(
	locator *api.VolumeLocator,
	source *api.Source,
	spec *api.VolumeSpec) (string, error) {

	if spec.Size == 0 {
		return "", fmt.Errorf("Volume size cannot be zero")
	} else if spec.GetHaLevel() == 0 {
		return "", fmt.Errorf("HA level cannot be zero")
	}

	volumeID := strings.TrimSuffix(uuid.New(), "\n")

	if _, err := d.GetVol(volumeID); err == nil {
		return "", fmt.Errorf("volume with that id already exists")
	}

	// snapshot passes nil volumelabels
	if locator.VolumeLabels == nil {
		locator.VolumeLabels = make(map[string]string)
	}

	v := common.NewVolume(
		volumeID,
		api.FSType_FS_TYPE_XFS,
		locator,
		source,
		spec,
	)

	if err := d.CreateVol(v); err != nil {
		return "", err
	}
	return v.Id, nil
}