Beispiel #1
0
func (d *driver) VolumeRemove(
	ctx types.Context,
	volumeID string,
	opts types.Store) error {

	ctx.WithFields(log.Fields{
		"volumeID": volumeID,
	}).Debug("mockDriver.VolumeRemove")

	var xToRemove int
	var volume *types.Volume
	for x, v := range d.volumes {
		if strings.ToLower(v.ID) == strings.ToLower(volumeID) {
			volume = v
			xToRemove = x
			break
		}
	}

	if volume == nil {
		return utils.NewNotFoundError(volumeID)
	}

	d.volumes = append(d.volumes[:xToRemove], d.volumes[xToRemove+1:]...)

	return nil
}
func (d *idm) List(
	ctx types.Context,
	opts types.Store) ([]types.VolumeMapping, error) {

	fields := log.Fields{
		"opts": opts}
	ctx.WithFields(fields).Debug("listing volumes")

	volMaps, err := d.IntegrationDriver.List(ctx.Join(d.ctx), opts)
	if err != nil {
		return nil, err
	}

	volMapsWithNames := []types.VolumeMapping{}
	for _, vm := range volMaps {
		if vm.VolumeName() != "" {
			volMapsWithNames = append(volMapsWithNames, vm)
		}
	}

	if !d.pathCacheEnabled() {
		return volMapsWithNames, nil
	}

	for _, vm := range volMapsWithNames {
		vmn := vm.VolumeName()
		if !d.isCounted(vmn) && vm.MountPoint() != "" {
			d.initCount(vmn)
		}
	}

	return volMapsWithNames, nil
}
func (d *idm) Mount(
	ctx types.Context,
	volumeID, volumeName string,
	opts *types.VolumeMountOpts) (string, *types.Volume, error) {

	opts.Preempt = d.preempt()

	fields := log.Fields{
		"volumeName": volumeName,
		"volumeID":   volumeID,
		"opts":       opts}
	ctx.WithFields(fields).Debug("mounting volume")

	mp, vol, err := d.IntegrationDriver.Mount(
		ctx.Join(d.ctx), volumeID, volumeName, opts)
	if err != nil {
		return "", nil, err
	}

	// if the volume has attachments assign the new mount point to the
	// MountPoint field of the first attachment element
	if len(vol.Attachments) > 0 {
		vol.Attachments[0].MountPoint = mp
	}

	d.incCount(volumeName)
	return mp, vol, err
}
Beispiel #4
0
// Init initializes the driver.
func (d *driver) Init(ctx types.Context, config gofig.Config) error {
	d.config = config

	fields := map[string]interface{}{
		"provider":        vbox.Name,
		"moduleName":      vbox.Name,
		"endpoint":        d.endpoint(),
		"userName":        d.username(),
		"tls":             d.tls(),
		"volumePath":      d.volumePath(),
		"controllerName":  d.controllerName(),
		"machineNameOrId": d.machineNameID(""),
	}

	ctx.Info("initializing driver: ", fields)
	d.vbox = vboxc.New(d.username(), d.password(),
		d.endpoint(), d.tls(), d.controllerName())

	if err := d.vbox.Logon(); err != nil {
		return goof.WithFieldsE(fields,
			"error logging in", err)
	}

	ctx.WithFields(fields).Info("storage driver initialized")
	return nil
}
// Handle is the type's Handler function.
func (h *queryParamsHandler) Handle(
	ctx types.Context,
	w http.ResponseWriter,
	req *http.Request,
	store types.Store) error {

	for k, v := range req.URL.Query() {
		ctx.WithFields(log.Fields{
			"key":        k,
			"value":      v,
			"len(value)": len(v),
		}).Debug("query param")
		switch len(v) {
		case 0:
			store.Set(k, true)
		case 1:
			if len(v[0]) == 0 {
				store.Set(k, true)
			} else {
				if i, err := strconv.ParseInt(v[0], 10, 64); err == nil {
					store.Set(k, i)
				} else if b, err := strconv.ParseBool(v[0]); err == nil {
					store.Set(k, b)
				} else {
					store.Set(k, v[0])
				}
			}
		default:
			store.Set(k, v)
		}
	}
	return h.handler(ctx, w, req, store)
}
// 	// VolumeDetach detaches a volume.
func (d *driver) VolumeDetach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeDetachOpts) (*types.Volume, error) {
	fields := eff(map[string]interface{}{
		"moduleName": ctx,
		"volumeId":   volumeID,
	})

	if volumeID == "" {
		return nil, goof.WithFields(fields, "volumeId is required for VolumeDetach")
	}
	vols, err := d.getVolume(ctx, volumeID, "", types.VolAttReqTrue)
	if err != nil {
		return nil, err
	}

	resp := volumeattach.Delete(
		d.client, vols[0].Attachments[0].InstanceID.ID, volumeID)
	if resp.Err != nil {
		return nil, goof.WithFieldsE(fields, "error detaching volume", resp.Err)
	}
	ctx.WithFields(fields).Debug("waiting for volume to detach")
	volume, err := d.waitVolumeAttachStatus(ctx, volumeID, false)
	if err == nil {
		return volume, nil
	}
	log.WithFields(fields).Debug("volume detached")
	return nil, nil
}
Beispiel #7
0
func (s *server) createMux(ctx types.Context) *mux.Router {
	m := mux.NewRouter()
	for _, apiRouter := range s.routers {
		for _, r := range apiRouter.Routes() {

			ctx := ctx.WithValue(context.RouteKey, r)

			f := s.makeHTTPHandler(ctx, r)
			mr := m.Path(r.GetPath())
			mr = mr.Name(r.GetName())
			mr = mr.Methods(r.GetMethod())
			mr = mr.Queries(r.GetQueries()...)
			mr.Handler(f)

			if l, ok := context.GetLogLevel(ctx); ok && l >= log.DebugLevel {
				ctx.WithFields(log.Fields{
					"path":         r.GetPath(),
					"method":       r.GetMethod(),
					"queries":      r.GetQueries(),
					"len(queries)": len(r.GetQueries()),
				}).Debug("registered route")
			} else {
				ctx.Info("registered route")
			}
		}
	}
	return m
}
Beispiel #8
0
// Validate validates the provided data (d) against the provided schema (s).
func Validate(ctx types.Context, s, d []byte) error {

	if ctx == nil {
		log.StandardLogger().WithFields(log.Fields{
			"schema": string(s),
			"body":   string(d),
		}).Debug("validating schema")
	} else {
		ctx.WithFields(log.Fields{
			"schema": string(s),
			"body":   string(d),
		}).Debug("validating schema")
	}

	validator, err := getSchemaValidator(s)
	if err != nil {
		return err
	}

	if len(d) == 0 {
		d = []byte("{}")
	}

	data, err := ucl.Parse(bytes.NewReader(d))
	if err != nil {
		return err
	}
	return validator.Validate(data)
}
Beispiel #9
0
// Inspect returns a specific volume as identified by the provided
// volume name.
func (d *driver) Inspect(
	ctx types.Context,
	volumeName string,
	opts types.Store) (types.VolumeMapping, error) {

	fields := log.Fields{
		"volumeName": volumeName,
		"opts":       opts}
	ctx.WithFields(fields).Info("inspecting volume")

	objs, err := d.List(ctx, opts)
	if err != nil {
		return nil, err
	}

	var obj types.VolumeMapping
	for _, o := range objs {
		if strings.ToLower(volumeName) == strings.ToLower(o.VolumeName()) {
			obj = o
			break
		}
	}

	if obj == nil {
		return nil, utils.NewNotFoundError(volumeName)
	}

	fields = log.Fields{
		"volumeName": volumeName,
		"volume":     obj}
	ctx.WithFields(fields).Info("volume inspected")

	return obj, nil
}
Beispiel #10
0
func (d *driver) SnapshotRemove(
	ctx types.Context,
	snapshotID string,
	opts types.Store) error {

	ctx.WithFields(log.Fields{
		"snapshotID": snapshotID,
	}).Debug("mockDriver.SnapshotRemove")

	var xToRemove int
	var snapshot *types.Snapshot
	for x, s := range d.snapshots {
		if strings.ToLower(s.ID) == strings.ToLower(snapshotID) {
			snapshot = s
			xToRemove = x
			break
		}
	}

	if snapshot == nil {
		return utils.NewNotFoundError(snapshotID)
	}

	d.snapshots = append(d.snapshots[:xToRemove], d.snapshots[xToRemove+1:]...)

	return nil
}
Beispiel #11
0
// Create will create a new volume with the volumeName and opts.
func (d *driver) Create(
	ctx types.Context,
	volumeName string,
	opts *types.VolumeCreateOpts) (*types.Volume, error) {

	if volumeName == "" {
		return nil, goof.New("missing volume name or ID")
	}

	optsNew := &types.VolumeCreateOpts{}
	az := d.availabilityZone()
	optsNew.AvailabilityZone = &az
	i, _ := strconv.Atoi(d.size())
	size := int64(i)
	optsNew.Size = &size
	volumeType := d.volumeType()
	optsNew.Type = &volumeType
	io, _ := strconv.Atoi(d.iops())
	IOPS := int64(io)
	optsNew.IOPS = &IOPS

	if opts.Opts.IsSet("availabilityZone") {
		az = opts.Opts.GetString("availabilityZone")
	}
	if opts.Opts.IsSet("size") {
		size = opts.Opts.GetInt64("size")
	}
	if opts.Opts.IsSet("volumeType") {
		volumeType = opts.Opts.GetString("volumeType")
	}
	if opts.Opts.IsSet("type") {
		volumeType = opts.Opts.GetString("type")
	}
	if opts.Opts.IsSet("iops") {
		IOPS = opts.Opts.GetInt64("iops")
	}

	optsNew.Opts = opts.Opts

	ctx.WithFields(log.Fields{
		"volumeName":       volumeName,
		"availabilityZone": az,
		"size":             size,
		"volumeType":       volumeType,
		"IOPS":             IOPS,
		"opts":             opts}).Info("creating volume")

	client := context.MustClient(ctx)
	vol, err := client.Storage().VolumeCreate(ctx, volumeName, optsNew)
	if err != nil {
		return nil, err
	}

	ctx.WithFields(log.Fields{
		"volumeName": volumeName,
		"vol":        vol}).Info("volume created")

	return vol, nil
}
Beispiel #12
0
// Volumes returns all volumes or a filtered list of volumes.
func (d *driver) Volumes(
	ctx types.Context,
	opts *types.VolumesOpts) ([]*types.Volume, error) {

	svc := mustSession(ctx)

	fileSystems, err := d.getAllFileSystems(svc)
	if err != nil {
		return nil, err
	}

	var volumesSD []*types.Volume
	for _, fileSystem := range fileSystems {
		// Make sure that name is popullated
		if fileSystem.Name == nil {
			ctx.WithFields(log.Fields{
				"filesystemid": *fileSystem.FileSystemId,
			}).Warn("missing EFS filesystem name")
			continue
		}

		// Only volumes with partition prefix
		if !strings.HasPrefix(*fileSystem.Name, d.tag+tagDelimiter) {
			continue
		}

		// Only volumes in "available" state
		if *fileSystem.LifeCycleState != awsefs.LifeCycleStateAvailable {
			continue
		}

		volumeSD := &types.Volume{
			Name:        d.getPrintableName(*fileSystem.Name),
			ID:          *fileSystem.FileSystemId,
			Size:        *fileSystem.SizeInBytes.Value,
			Attachments: nil,
		}

		var atts []*types.VolumeAttachment
		if opts.Attachments.Requested() {
			atts, err = d.getVolumeAttachments(
				ctx, *fileSystem.FileSystemId, opts.Attachments)
			if err != nil {
				return nil, err
			}
		}
		if len(atts) > 0 {
			volumeSD.Attachments = atts
		}
		volumesSD = append(volumesSD, volumeSD)
	}

	return volumesSD, nil
}
Beispiel #13
0
// VolumeInspect inspects a single volume.
func (d *driver) VolumeInspect(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeInspectOpts) (*types.Volume, error) {

	resp, err := mustSession(ctx).DescribeFileSystems(
		&awsefs.DescribeFileSystemsInput{FileSystemId: aws.String(volumeID)})
	if err != nil {
		return nil, err
	}

	if len(resp.FileSystems) == 0 {
		return nil, types.ErrNotFound{}
	}

	fileSystem := resp.FileSystems[0]

	// Only volumes in "available" state
	if *fileSystem.LifeCycleState != awsefs.LifeCycleStateAvailable {
		return nil, nil
	}

	// Name is optional via tag so make sure it exists
	var fileSystemName string
	if fileSystem.Name != nil {
		fileSystemName = *fileSystem.Name
	} else {
		ctx.WithFields(log.Fields{
			"filesystemid": *fileSystem.FileSystemId,
		}).Warn("missing EFS filesystem name")
	}

	volume := &types.Volume{
		Name:        d.getPrintableName(fileSystemName),
		ID:          *fileSystem.FileSystemId,
		Size:        *fileSystem.SizeInBytes.Value,
		Attachments: nil,
	}

	var atts []*types.VolumeAttachment

	if opts.Attachments.Requested() {
		atts, err = d.getVolumeAttachments(
			ctx, *fileSystem.FileSystemId, opts.Attachments)
		if err != nil {
			return nil, err
		}
	}
	if len(atts) > 0 {
		volume.Attachments = atts
	}
	return volume, nil
}
func (d *idm) Inspect(
	ctx types.Context,
	volumeName string,
	opts types.Store) (types.VolumeMapping, error) {

	fields := log.Fields{
		"volumeName": volumeName,
		"opts":       opts}
	ctx.WithFields(fields).Debug("inspecting volume")

	return d.IntegrationDriver.Inspect(ctx.Join(d.ctx), volumeName, opts)
}
Beispiel #15
0
// LocalDevices returns a map of the system's local devices.
func (d *driver) LocalDevices(
	ctx types.Context,
	opts *types.LocalDevicesOpts) (*types.LocalDevices, error) {

	ctx.WithFields(log.Fields{
		"vfs.root": d.rootDir,
		"dev.path": d.devFilePath,
	}).Debug("config info")

	var devFileRWL *sync.RWMutex
	func() {
		devFileLocksRWL.RLock()
		defer devFileLocksRWL.RUnlock()
		devFileRWL = devFileLocks[d.devFilePath]
	}()
	devFileRWL.Lock()
	defer devFileRWL.Unlock()

	if !gotil.FileExists(d.devFilePath) {
		return nil, goof.New("device file missing")
	}

	f, err := os.Open(d.devFilePath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	localDevs := map[string]string{}

	scn := bufio.NewScanner(f)
	for {
		if !scn.Scan() {
			break
		}

		m := devRX.FindSubmatch(scn.Bytes())
		if len(m) == 0 {
			continue
		}

		dev := m[1]
		var mountPoint []byte
		if len(m) > 2 {
			mountPoint = m[2]
		}

		localDevs[string(dev)] = string(mountPoint)
	}

	return &types.LocalDevices{Driver: vfs.Name, DeviceMap: localDevs}, nil
}
func (d *idm) Detach(
	ctx types.Context,
	volumeName string,
	opts *types.VolumeDetachOpts) error {

	fields := log.Fields{
		"volumeName": volumeName,
		"opts":       opts}
	ctx.WithFields(fields).Debug("detaching volume")

	return d.IntegrationDriver.Detach(ctx.Join(d.ctx), volumeName, opts)

}
Beispiel #17
0
// StartModule starts the module with the provided instance name.
func StartModule(ctx apitypes.Context, config gofig.Config, name string) error {

	modInstancesRwl.RLock()
	defer modInstancesRwl.RUnlock()

	name = strings.ToLower(name)
	lf := map[string]interface{}{"name": name}

	mod, modExists := modInstances[name]

	if !modExists {
		return goof.WithFields(lf, "unknown module instance")
	}

	lf["typeName"] = mod.Type.Name
	lf["address"] = mod.Config.Address

	started := make(chan bool)
	timeout := make(chan bool)
	startError := make(chan error)

	go func() {

		sErr := mod.Inst.Start()
		if sErr != nil {
			startError <- sErr
		} else {
			started <- true
		}
	}()

	go func() {
		time.Sleep(startTimeout(config))
		timeout <- true
	}()

	select {
	case <-started:
		mod.IsStarted = true
		ctx.WithFields(lf).Info("started module")
	case <-timeout:
		return goof.New("timed out while monitoring module start")
	case sErr := <-startError:
		return sErr
	}

	return nil
}
Beispiel #18
0
func (d *driver) Init(ctx types.Context, config gofig.Config) error {
	d.config = config

	ctx.WithFields(log.Fields{
		types.ConfigIgVolOpsMountRootPath:       d.volumeRootPath(),
		types.ConfigIgVolOpsCreateDefaultType:   d.volumeType(),
		types.ConfigIgVolOpsCreateDefaultIOPS:   d.iops(),
		types.ConfigIgVolOpsCreateDefaultSize:   d.size(),
		types.ConfigIgVolOpsCreateDefaultAZ:     d.availabilityZone(),
		types.ConfigIgVolOpsCreateDefaultFsType: d.fsType(),
		types.ConfigIgVolOpsMountPath:           d.mountDirPath(),
		types.ConfigIgVolOpsCreateImplicit:      d.volumeCreateImplicit(),
	}).Info("docker integration driver successfully initialized")

	return nil
}
func (d *idm) Remove(
	ctx types.Context,
	volumeName string,
	opts types.Store) error {

	fields := log.Fields{
		"volumeName": volumeName,
		"opts":       opts}
	ctx.WithFields(fields).Debug("removing volume")

	if d.disableRemove() {
		ctx.Debug("disableRemove skipped deletion")
		return nil
	}
	return d.IntegrationDriver.Remove(ctx.Join(d.ctx), volumeName, opts)
}
func (d *idm) Create(
	ctx types.Context,
	volumeName string,
	opts *types.VolumeCreateOpts) (*types.Volume, error) {

	fields := log.Fields{
		"volumeName": volumeName,
		"opts":       opts}
	ctx.WithFields(fields).Debug("creating volume")

	if d.disableCreate() {
		ctx.Debug("disableRemove skipped creation")
		return nil, nil
	}
	return d.IntegrationDriver.Create(ctx.Join(d.ctx), volumeName, opts)
}
Beispiel #21
0
func (c *client) updateExecutor(ctx types.Context) error {

	if c.isController() {
		return utils.NewUnsupportedForClientTypeError(
			c.clientType, "updateExecutor")
	}

	ctx.Debug("updating executor")

	lsxi := c.lsxCache.GetExecutorInfo(types.LSX.Name())
	if lsxi == nil {
		return goof.WithField("lsx", types.LSX, "unknown executor")
	}

	ctx.Debug("waiting on executor lock")
	if err := c.lsxMutexWait(); err != nil {
		return err
	}
	defer func() {
		ctx.Debug("signalling executor lock")
		if err := c.lsxMutexSignal(); err != nil {
			panic(err)
		}
	}()

	if !types.LSX.Exists() {
		ctx.Debug("executor does not exist, download executor")
		return c.downloadExecutor(ctx)
	}

	ctx.Debug("executor exists, getting local checksum")

	checksum, err := c.getExecutorChecksum(ctx)
	if err != nil {
		return err
	}

	if lsxi.MD5Checksum != checksum {
		ctx.WithFields(log.Fields{
			"remoteChecksum": lsxi.MD5Checksum,
			"localChecksum":  checksum,
		}).Debug("executor checksums do not match, download executor")
		return c.downloadExecutor(ctx)
	}

	return nil
}
Beispiel #22
0
func (d *driver) Format(
	ctx types.Context,
	deviceName string,
	opts *types.DeviceFormatOpts) error {

	fsType, err := probeFsType(deviceName)
	if err != nil && err != errUnknownFileSystem {
		return err
	}
	fsDetected := fsType != ""

	ctx.WithFields(log.Fields{
		"fsDetected":  fsDetected,
		"fsType":      fsType,
		"deviceName":  deviceName,
		"overwriteFs": opts.OverwriteFS,
		"driverName":  driverName}).Info("probe information")

	if opts.OverwriteFS || !fsDetected {
		switch opts.NewFSType {
		case "ext4":
			if err := exec.Command(
				"mkfs.ext4", "-F", deviceName).Run(); err != nil {
				return goof.WithFieldE(
					"deviceName", deviceName,
					"error creating filesystem",
					err)
			}
		case "xfs":
			if err := exec.Command(
				"mkfs.xfs", "-f", deviceName).Run(); err != nil {
				return goof.WithFieldE(
					"deviceName", deviceName,
					"error creating filesystem",
					err)
			}
		default:
			return errUnsupportedFileSystem
		}
	}

	return nil
}
Beispiel #23
0
func getConfiguredModules(
	ctx apitypes.Context, c gofig.Config) ([]*Config, error) {

	mods := c.Get("rexray.modules")
	modMap, ok := mods.(map[string]interface{})
	if !ok {
		return nil, goof.New("invalid format rexray.modules")
	}
	ctx.WithField("count", len(modMap)).Debug("got modules map")

	modConfigs := []*Config{}

	for name := range modMap {
		name = strings.ToLower(name)

		ctx.WithField("name", name).Debug("processing module config")
		sc := c.Scope(fmt.Sprintf("rexray.modules.%s", name))

		if disabled := sc.GetBool("disabled"); disabled {
			ctx.WithField("name", name).Debug("ignoring disabled module config")
			continue
		}

		mc := &Config{
			Name:        name,
			Type:        strings.ToLower(sc.GetString("type")),
			Description: sc.GetString("desc"),
			Address:     sc.GetString("host"),
			Config:      sc,
		}

		ctx.WithFields(log.Fields{
			"name": mc.Name,
			"type": mc.Type,
			"desc": mc.Description,
			"addr": mc.Address,
		}).Info("created new mod config")

		modConfigs = append(modConfigs, mc)
	}

	return modConfigs, nil
}
Beispiel #24
0
// Path will return the mounted path of the volumeName or volumeID.
func (d *driver) Path(
	ctx types.Context,
	volumeID, volumeName string,
	opts types.Store) (string, error) {

	ctx.WithFields(log.Fields{
		"volumeName": volumeName,
		"volumeID":   volumeID,
		"opts":       opts}).Info("getting path to volume")

	vol, err := d.volumeInspectByIDOrName(
		ctx, volumeID, volumeName, types.VolAttReqTrue, opts)
	if err != nil {
		return "", err
	} else if vol == nil {
		return "", utils.NewNotFoundError(
			fmt.Sprintf("volumeID=%s,volumeName=%s", volumeID, volumeName))
	}

	if len(vol.Attachments) == 0 {
		return "", nil
	}

	client := context.MustClient(ctx)

	mounts, err := client.OS().Mounts(
		ctx, vol.Attachments[0].DeviceName, "", opts)
	if err != nil {
		return "", err
	}

	if len(mounts) == 0 {
		return "", nil
	}

	volPath := d.volumeMountPath(mounts[0].MountPoint)

	ctx.WithFields(log.Fields{
		"volPath": volPath,
		"vol":     vol}).Info("returning path to volume")

	return volPath, nil
}
Beispiel #25
0
// InitializeModule initializes a module.
func InitializeModule(
	ctx apitypes.Context, modConfig *Config) (*Instance, error) {

	modInstancesRwl.Lock()
	defer modInstancesRwl.Unlock()

	ctx.WithField("name", modConfig.Name).Debug("initializing module instance")

	typeName := strings.ToLower(modConfig.Type)

	lf := log.Fields{
		"typeName": typeName,
		"address":  modConfig.Address,
	}

	mt, modTypeExists := modTypes[typeName]
	if !modTypeExists {
		return nil, goof.WithFields(lf, "unknown module type")
	}

	mod, initErr := mt.InitFunc(ctx, modConfig)
	if initErr != nil {
		return nil, initErr
	}

	modName := mod.Name()

	modInst := &Instance{
		Type:        mt,
		TypeName:    typeName,
		Inst:        mod,
		Name:        modName,
		Config:      modConfig,
		Description: mod.Description(),
	}
	modInstances[modName] = modInst

	lf["name"] = modName
	ctx.WithFields(lf).Info("initialized module instance")

	return modInst, nil
}
func (d *idm) Init(ctx types.Context, config gofig.Config) error {
	if err := d.IntegrationDriver.Init(ctx, config); err != nil {
		return err
	}

	d.ctx = ctx
	d.config = config
	d.used = map[string]int{}

	d.initPathCache(ctx)

	ctx.WithFields(log.Fields{
		types.ConfigIgVolOpsPathCacheEnabled:  d.pathCacheEnabled(),
		types.ConfigIgVolOpsPathCacheAsync:    d.pathCacheAsync(),
		types.ConfigIgVolOpsUnmountIgnoreUsed: d.ignoreUsedCount(),
		types.ConfigIgVolOpsMountPreempt:      d.preempt(),
		types.ConfigIgVolOpsCreateDisable:     d.disableCreate(),
		types.ConfigIgVolOpsRemoveDisable:     d.disableRemove(),
	}).Info("libStorage integration driver successfully initialized")

	return nil
}
Beispiel #27
0
// 	// VolumeAttach attaches a volume and provides a token clients can use
// 	// to validate that device has appeared locally.
func (d *driver) VolumeAttach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeAttachOpts) (*types.Volume, string, error) {
	iid := context.MustInstanceID(ctx)
	fields := eff(map[string]interface{}{
		"volumeId":   volumeID,
		"instanceId": iid.ID,
	})

	if opts.Force {
		if _, err := d.VolumeDetach(ctx, volumeID,
			&types.VolumeDetachOpts{}); err != nil {
			return nil, "", err
		}
	}

	options := &volumeattach.CreateOpts{
		VolumeID: volumeID,
	}
	if opts.NextDevice != nil {
		options.Device = *opts.NextDevice
	}

	volumeAttach, err := volumeattach.Create(d.client, iid.ID, options).Extract()
	if err != nil {
		return nil, "", goof.WithFieldsE(
			fields, "error attaching volume", err)
	}

	ctx.WithFields(fields).Debug("waiting for volume to attach")
	volume, err := d.waitVolumeAttachStatus(ctx, volumeID, true)
	if err != nil {
		return nil, "", goof.WithFieldsE(
			fields, "error waiting for volume to attach", err)
	}
	return volume, volumeAttach.Device, nil
}
Beispiel #28
0
func (d *driver) VolumeCopy(
	ctx types.Context,
	volumeID, volumeName string,
	opts types.Store) (*types.Volume, error) {

	ctx.WithFields(log.Fields{
		"volumeID":   volumeID,
		"volumeName": volumeName,
	}).Debug("mockDriver.VolumeCopy")

	lenVols := len(d.volumes)

	var ogvol *types.Volume
	for _, v := range d.volumes {
		if strings.ToLower(v.ID) == strings.ToLower(volumeID) {
			ogvol = v
			break
		}
	}

	volume := &types.Volume{
		Name:             volumeName,
		ID:               fmt.Sprintf("vol-%03d", lenVols+1),
		AvailabilityZone: ogvol.AvailabilityZone,
		Type:             ogvol.Type,
		Size:             ogvol.Size,
		Fields:           map[string]string{},
	}

	for k, v := range ogvol.Fields {
		volume.Fields[k] = v
	}

	d.volumes = append(d.volumes, volume)

	return volume, nil

}
func (d *idm) Path(
	ctx types.Context,
	volumeID, volumeName string,
	opts types.Store) (string, error) {

	fields := log.Fields{
		"volumeName": volumeName,
		"volumeID":   volumeID,
		"opts":       opts}
	ctx.WithFields(fields).Debug("getting path to volume")

	if !d.pathCacheEnabled() {
		return d.IntegrationDriver.Path(
			ctx.Join(d.ctx), volumeID, volumeName, opts)
	}

	if !d.isCounted(volumeName) {
		ctx.WithFields(fields).Debug("skipping path lookup")
		return "", nil
	}

	return d.IntegrationDriver.Path(ctx.Join(d.ctx), volumeID, volumeName, opts)
}
func (d *idm) Unmount(
	ctx types.Context,
	volumeID, volumeName string,
	opts types.Store) (*types.Volume, error) {

	fields := log.Fields{
		"volumeName": volumeName,
		"volumeID":   volumeID,
		"opts":       opts}
	ctx.WithFields(fields).Debug("unmounting volume")

	if d.ignoreUsedCount() ||
		d.resetCount(volumeName) ||
		!d.isCounted(volumeName) {

		d.initCount(volumeName)
		return d.IntegrationDriver.Unmount(
			ctx.Join(d.ctx), volumeID, volumeName, opts)
	}

	d.decCount(volumeName)
	return nil, nil
}