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 }
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 }
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 }
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 }
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 }
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 }
// 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 }
// 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 }
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 }
// // 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 }
// 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 }
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 }
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 }
// // 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 }
// 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 }
func mustInstanceIDID(ctx types.Context) *string { return &context.MustInstanceID(ctx).ID }