Beispiel #1
0
func (d *driver) InstanceInspect(
	ctx types.Context,
	opts types.Store) (*types.Instance, error) {

	iid := context.MustInstanceID(ctx)
	if iid.ID != "" {
		return &types.Instance{InstanceID: iid}, nil
	}

	var (
		err     error
		sdcGUID string
		sdc     *sio.Sdc
	)

	if err = iid.UnmarshalMetadata(&sdcGUID); err != nil {
		return nil, err
	}

	sdcGUID = strings.ToUpper(sdcGUID)
	if sdc, err = d.system.FindSdc("SdcGuid", sdcGUID); err != nil {
		return nil, scaleio.ErrFindingSDC(sdcGUID, err)
	}

	if sdc != nil {
		return &types.Instance{
			InstanceID: &types.InstanceID{
				ID:     sdc.Sdc.ID,
				Driver: d.Name(),
			},
		}, nil
	}

	return nil, scaleio.ErrNoSDCGUID
}
Beispiel #2
0
func (d *driver) InstanceInspect(
	ctx types.Context,
	opts types.Store) (*types.Instance, error) {

	var err error
	if ctx, err = context.WithStorageSession(ctx); err != nil {
		return nil, err
	}

	context.MustSession(ctx)

	iid := context.MustInstanceID(ctx)
	if iid.ID != "" {
		return &types.Instance{Name: "vfsInstance", InstanceID: iid}, nil
	}

	var hostname string
	if err := iid.UnmarshalMetadata(&hostname); err != nil {
		return nil, err
	}

	return &types.Instance{
		Name: "vfsInstance",
		InstanceID: &types.InstanceID{
			ID:     hostname,
			Driver: iid.Driver,
		},
	}, nil
}
Beispiel #3
0
func (d *driver) detachVolume(
	ctx types.Context, volumeID, volumeName string) error {

	iid := context.MustInstanceID(ctx)

	m, err := d.findMachineByInstanceID(ctx, iid)
	if err != nil {
		return err
	}

	if err := m.Refresh(); err != nil {
		return err
	}
	defer m.Release()

	media, err := d.vbox.GetMedium(volumeID, volumeName)
	if err != nil {
		return err
	}

	if len(media) == 0 {
		return goof.New("no volume returned")
	}
	if len(media) > 1 {
		return goof.New("too many volumes returned")
	}

	if err := media[0].DetachMachines(); err != nil {
		return err
	}

	return nil
}
Beispiel #4
0
func (d *driver) VolumeAttach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeAttachOpts) (*types.Volume, string, error) {

	var modVol *types.Volume
	for _, vol := range d.volumes {
		if vol.ID == volumeID {
			modVol = vol
			break
		}
	}

	modVol.Attachments = []*types.VolumeAttachment{
		&types.VolumeAttachment{
			DeviceName: *opts.NextDevice,
			MountPoint: "",
			InstanceID: context.MustInstanceID(ctx),
			Status:     "attached",
			VolumeID:   modVol.ID,
		},
	}

	return modVol, "1234", nil
}
Beispiel #5
0
func (d *driver) VolumeDetach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeDetachOpts) (*types.Volume, error) {

	context.MustSession(ctx)

	vol, err := d.getVolumeByID(volumeID)
	if err != nil {
		return nil, err
	}

	iid := context.MustInstanceID(ctx)

	y := -1
	for x, att := range vol.Attachments {
		if att.InstanceID.ID == iid.ID {
			y = x
			break
		}
	}

	if y > -1 {
		vol.Attachments = append(vol.Attachments[:y], vol.Attachments[y+1:]...)
		if err := d.writeVolume(vol); err != nil {
			return nil, err
		}
	}

	vol.Attachments = nil
	return vol, nil
}
Beispiel #6
0
func (d *driver) VolumeAttach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeAttachOpts) (*types.Volume, string, error) {

	context.MustSession(ctx)

	vol, err := d.getVolumeByID(volumeID)
	if err != nil {
		return nil, "", err
	}

	nextDevice := ""
	if opts.NextDevice != nil {
		nextDevice = *opts.NextDevice
	}

	att := &types.VolumeAttachment{
		VolumeID:   vol.ID,
		InstanceID: context.MustInstanceID(ctx),
		DeviceName: nextDevice,
		Status:     "attached",
	}

	vol.Attachments = append(vol.Attachments, att)
	if err := d.writeVolume(vol); err != nil {
		return nil, "", err
	}

	vol.Attachments = []*types.VolumeAttachment{att}

	return vol, nextDevice, nil
}
Beispiel #7
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) {

	svc := mustSession(ctx)

	vol, err := d.VolumeInspect(ctx, volumeID,
		&types.VolumeInspectOpts{Attachments: types.VolAttReqTrue})
	if err != nil {
		return nil, "", err
	}

	iid := context.MustInstanceID(ctx)

	var ma *types.VolumeAttachment
	for _, att := range vol.Attachments {
		if att.InstanceID.ID == iid.ID {
			ma = att
			break
		}
	}

	// No mount targets were found
	if ma == nil {

		secGrpIDs := d.secGroups
		if v, ok := iid.Fields[efs.InstanceIDFieldSecurityGroups]; ok {
			iSecGrpIDs := strings.Split(v, ";")
			ctx.WithField("secGrpIDs", iSecGrpIDs).Debug(
				"using instance security group IDs")
			secGrpIDs = iSecGrpIDs
		}

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

		request := &awsefs.CreateMountTargetInput{
			FileSystemId:   aws.String(vol.ID),
			SubnetId:       aws.String(iid.ID),
			SecurityGroups: aws.StringSlice(secGrpIDs),
		}
		// TODO(mhrabovcin): Should we block here until MountTarget is in
		// "available" LifeCycleState? Otherwise mount could fail until creation
		//  is completed.
		_, err = svc.CreateMountTarget(request)
		// Failed to create mount target
		if err != nil {
			return nil, "", err
		}
	}

	return vol, "", err
}
Beispiel #8
0
// InstanceInspect returns an instance.
func (d *driver) InstanceInspect(
	ctx types.Context,
	opts types.Store) (*types.Instance, error) {

	iid := context.MustInstanceID(ctx)
	return &types.Instance{
		Name:         iid.ID,
		Region:       iid.Fields[efs.InstanceIDFieldRegion],
		InstanceID:   iid,
		ProviderName: iid.Driver,
	}, nil
}
Beispiel #9
0
func (d *driver) VolumeAttach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeAttachOpts) (*types.Volume, string, error) {

	iid := context.MustInstanceID(ctx)

	mapVolumeSdcParam := &siotypes.MapVolumeSdcParam{
		SdcID: iid.ID,
		AllowMultipleMappings: "false",
		AllSdcs:               "",
	}

	vol, err := d.VolumeInspect(
		ctx, volumeID, &types.VolumeInspectOpts{
			Attachments: types.VolAttReqTrue,
		})
	if err != nil {
		return nil, "", goof.WithError("error getting volume", err)
	}

	if len(vol.Attachments) > 0 && !opts.Force {
		return nil, "", goof.New("volume already attached to a host")
	}

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

	targetVolume := sio.NewVolume(d.client)
	targetVolume.Volume = &siotypes.Volume{ID: vol.ID}

	err = targetVolume.MapVolumeSdc(mapVolumeSdcParam)
	if err != nil {
		return nil, "", goof.WithError("error mapping volume sdc", err)
	}

	attachedVol, err := d.VolumeInspect(
		ctx, volumeID, &types.VolumeInspectOpts{
			Attachments: types.VolAttReqTrue,
			Opts:        opts.Opts,
		})
	if err != nil {
		return nil, "", goof.WithError("error getting volume", err)
	}

	return attachedVol, attachedVol.ID, nil
}
Beispiel #10
0
// 	// InstanceInspect returns an instance.
func (d *driver) InstanceInspect(
	ctx types.Context,
	opts types.Store) (*types.Instance, error) {

	iid := context.MustInstanceID(ctx)
	if iid.ID != "" {
		return &types.Instance{InstanceID: iid}, nil
	}
	var rsSubnetID string
	if err := iid.UnmarshalMetadata(&rsSubnetID); err != nil {
		return nil, err
	}
	instanceID := &types.InstanceID{ID: rsSubnetID, Driver: d.Name()}
	return &types.Instance{InstanceID: instanceID}, nil
}
Beispiel #11
0
// InstanceInspect returns an instance.
func (d *driver) InstanceInspect(
	ctx types.Context,
	opts types.Store) (*types.Instance, error) {

	iid := context.MustInstanceID(ctx)
	if iid.ID != "" {
		return &types.Instance{InstanceID: iid}, nil
	}

	if err := d.refreshSession(ctx); err != nil {
		return nil, err
	}

	var macAddrs []string
	if err := iid.UnmarshalMetadata(&macAddrs); err != nil {
		return nil, err
	}

	var (
		m   *vboxc.Machine
		err error
	)

	if m, err = d.findMachineByMacAddrs(ctx, macAddrs); err != nil {

		nameOrID := d.config.GetString("virtualbox.localMachineNameOrId")

		if m, err = d.findMachineByNameOrID(ctx, nameOrID); err != nil {

			return nil, goof.WithFieldsE(
				log.Fields{
					"macAddres":                       macAddrs,
					"virtualbox.localMachineNameOrId": nameOrID,
				}, "failed to find local machine", err)
		}
	}

	if m == nil {
		return nil, goof.New("machine not found")
	}

	return &types.Instance{
		InstanceID: &types.InstanceID{
			ID:     m.ID,
			Driver: vbox.Name,
		},
	}, nil
}
Beispiel #12
0
func (d *driver) Volumes(
	ctx types.Context,
	opts *types.VolumesOpts) ([]*types.Volume, error) {

	xiid := executor.GetInstanceID()

	if serviceName, ok := context.ServiceName(ctx); ok && serviceName == Name {
		if ld, ok := context.LocalDevices(ctx); ok {
			ldm := ld.DeviceMap

			if opts.Attachments {

				iid := context.MustInstanceID(ctx)
				if iid.ID == xiid.ID {

					d.volumes[0].Attachments = []*types.VolumeAttachment{
						&types.VolumeAttachment{
							DeviceName: "/dev/xvda",
							MountPoint: ldm["/dev/xvda"],
							InstanceID: iid,
							Status:     "attached",
							VolumeID:   d.volumes[0].ID,
						},
						&types.VolumeAttachment{
							DeviceName: "/dev/xvdb",
							MountPoint: ldm["/dev/xvdb"],
							InstanceID: iid,
							Status:     "attached",
							VolumeID:   d.volumes[1].ID,
						},
						&types.VolumeAttachment{
							DeviceName: "/dev/xvdc",
							MountPoint: ldm["/dev/xvdc"],
							InstanceID: iid,
							Status:     "attached",
							VolumeID:   d.volumes[2].ID,
						},
					}
				}
			}

		}
	}

	return d.volumes, nil
}
Beispiel #13
0
func (d *driver) VolumeDetach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeDetachOpts) (*types.Volume, error) {

	iid := context.MustInstanceID(ctx)

	volumes, err := d.getVolume(volumeID, "", 0)
	if err != nil {
		return nil, goof.WithError("error getting volume", err)
	}

	if len(volumes) == 0 {
		return nil, goof.New("no volumes returned")
	}

	targetVolume := sio.NewVolume(d.client)
	targetVolume.Volume = volumes[0]

	unmapVolumeSdcParam := &siotypes.UnmapVolumeSdcParam{
		SdcID:                "",
		IgnoreScsiInitiators: "true",
		AllSdcs:              "",
	}

	if opts.Force {
		unmapVolumeSdcParam.AllSdcs = "true"
	} else {
		unmapVolumeSdcParam.SdcID = iid.ID
	}

	if err := targetVolume.UnmapVolumeSdc(unmapVolumeSdcParam); err != nil {
		return nil, err
	}

	vol, err := d.VolumeInspect(ctx, volumeID, &types.VolumeInspectOpts{
		Attachments: types.VolAttReqTrue,
	})
	if err != nil {
		return nil, err
	}

	return vol, nil
}
Beispiel #14
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 #15
0
// Volumes returns all volumes or a filtered list of volumes.
func (d *driver) getVolumeMapping(ctx types.Context) ([]*types.Volume, error) {

	var (
		err         error
		mapDiskByID map[string]string
		mas         []*vboxw.IMediumAttachment
		m           *vboxc.Machine
		iid         = context.MustInstanceID(ctx)
	)

	m, err = d.findMachineByInstanceID(ctx, iid)
	if err != nil {
		return nil, err
	}

	if err := m.Refresh(); err != nil {
		return nil, err
	}
	defer m.Release()

	ld, ok := context.LocalDevices(ctx)
	if !ok {
		return nil, goof.New("missing local devices")
	}
	mapDiskByID = ld.DeviceMap

	mas, err = m.GetMediumAttachments()
	if err != nil {
		return nil, err
	}

	var blockDevices []*types.Volume
	for _, ma := range mas {
		medium := d.vbox.NewMedium(ma.Medium)
		defer medium.Release()

		mid, err := medium.GetID()
		if err != nil {
			return nil, err
		}
		smid := strings.Split(mid, "-")
		if len(smid) == 0 {
			continue
		}

		location, err := medium.GetLocation()
		if err != nil {
			return nil, err
		}

		var bdn string
		var ok bool
		if bdn, ok = mapDiskByID[smid[0]]; !ok {
			continue
		}
		sdBlockDevice := &types.Volume{
			Name:   bdn,
			ID:     mid,
			Status: location,
		}
		blockDevices = append(blockDevices, sdBlockDevice)

	}
	return blockDevices, nil
}
Beispiel #16
0
func mustInstanceIDID(ctx types.Context) *string {
	return &context.MustInstanceID(ctx).ID
}