func (d *idm) initPathCache(ctx types.Context) { if !d.pathCacheEnabled() { ctx.Info("path cache initializion disabled") return } if name, ok := context.ServiceName(ctx); !ok || name == "" { ctx.Info("path cache initializion disabled; no service name in ctx") return } f := func(async bool) { ctx.WithField("async", async).Info("initializing the path cache") _, err := d.List(ctx, apiutils.NewStoreWithData(initPathCacheMap)) if err != nil { ctx.WithField("async", async).WithError(err).Error( "error initializing the path cache") } else { ctx.WithField("async", async).Debug("initialized the path cache") } } if d.pathCacheAsync() { go f(true) } else { f(false) } }
func (c *client) NextDevice( ctx types.Context, opts types.Store) (string, error) { if c.isController() { return "", utils.NewUnsupportedForClientTypeError( c.clientType, "NextDevice") } if supported, _ := c.Supported(ctx, opts); !supported { return "", errExecutorNotSupported } ctx = context.RequireTX(ctx.Join(c.ctx)) serviceName, ok := context.ServiceName(ctx) if !ok { return "", goof.New("missing service name") } si, err := c.getServiceInfo(serviceName) if err != nil { return "", err } driverName := si.Driver.Name out, err := c.runExecutor(ctx, driverName, types.LSXCmdNextDevice) if err != nil { return "", err } ctx.Debug("xli nextdevice success") return gotil.Trim(string(out)), nil }
func (d *driver) VolumeAttach( ctx types.Context, volumeID string, opts *types.VolumeAttachOpts) (*types.Volume, string, error) { if d.isController() { return nil, "", utils.NewUnsupportedForClientTypeError( d.clientType, "VolumeAttach") } ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, "", goof.New("missing service name") } nextDevice, err := d.NextDevice(ctx, utils.NewStore()) if err != nil { return nil, "", err } var nextDevicePtr *string if nextDevice != "" { nextDevicePtr = &nextDevice } req := &types.VolumeAttachRequest{ NextDeviceName: nextDevicePtr, Force: opts.Force, Opts: opts.Opts.Map(), } return d.client.VolumeAttach(ctx, serviceName, volumeID, req) }
func (c *client) Supported( ctx types.Context, opts types.Store) (bool, error) { if c.isController() { return false, utils.NewUnsupportedForClientTypeError( c.clientType, "Supported") } ctx = context.RequireTX(ctx.Join(c.ctx)) serviceName, ok := context.ServiceName(ctx) if !ok { return false, goof.New("missing service name") } si, err := c.getServiceInfo(serviceName) if err != nil { return false, err } driverName := strings.ToLower(si.Driver.Name) // check to see if the driver's executor is supported on this host if ok := c.supportedCache.IsSet(driverName); ok { return c.supportedCache.GetBool(driverName), nil } out, err := c.runExecutor(ctx, driverName, types.LSXCmdSupported) if err != nil { if err == types.ErrNotImplemented { ctx.WithField("serviceDriver", driverName).Warn( "supported cmd not implemented") c.supportedCache.Set(driverName, true) ctx.WithField("supported", true).Debug("cached supported flag") return true, nil } return false, err } if len(out) == 0 { return false, nil } out = bytes.TrimSpace(out) b, err := strconv.ParseBool(string(out)) if err != nil { return false, err } c.supportedCache.Set(driverName, b) ctx.WithField("supported", b).Debug("cached supported flag") return b, nil }
func (d *driver) SnapshotRemove( ctx types.Context, snapshotID string, opts types.Store) error { ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return goof.New("missing service name") } return d.client.SnapshotRemove(ctx, serviceName, snapshotID) }
func (d *driver) Type(ctx types.Context) (types.StorageType, error) { serviceName, ok := context.ServiceName(ctx) if !ok { return "", goof.New("missing service name") } si, err := d.getServiceInfo(serviceName) if err != nil { return "", err } return si.Driver.Type, nil }
func (d *driver) VolumeInspect( ctx types.Context, volumeID string, opts *types.VolumeInspectOpts) (*types.Volume, error) { ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } return d.client.VolumeInspect(ctx, serviceName, volumeID, opts.Attachments) }
func (d *driver) NextDeviceInfo( ctx types.Context) (*types.NextDeviceInfo, error) { serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } si, err := d.getServiceInfo(serviceName) if err != nil { return nil, err } return si.Driver.NextDevice, nil }
func (d *driver) InstanceInspect( ctx types.Context, opts types.Store) (*types.Instance, error) { if d.isController() { return nil, utils.NewUnsupportedForClientTypeError( d.clientType, "InstanceInspect") } serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } return d.client.InstanceInspect(ctx, serviceName) }
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) VolumeSnapshot( ctx types.Context, volumeID, snapshotName string, opts types.Store) (*types.Snapshot, error) { ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } req := &types.VolumeSnapshotRequest{ SnapshotName: snapshotName, Opts: opts.Map(), } return d.client.VolumeSnapshot(ctx, serviceName, volumeID, req) }
func (c *client) WaitForDevice( ctx types.Context, opts *types.WaitForDeviceOpts) (bool, *types.LocalDevices, error) { if c.isController() { return false, nil, utils.NewUnsupportedForClientTypeError( c.clientType, "WaitForDevice") } if supported, _ := c.Supported(ctx, opts.Opts); !supported { return false, nil, errExecutorNotSupported } ctx = context.RequireTX(ctx.Join(c.ctx)) serviceName, ok := context.ServiceName(ctx) if !ok { return false, nil, goof.New("missing service name") } si, err := c.getServiceInfo(serviceName) if err != nil { return false, nil, err } driverName := si.Driver.Name out, err := c.runExecutor( ctx, driverName, types.LSXCmdWaitForDevice, opts.ScanType.String(), opts.Token, opts.Timeout.String()) if err != types.ErrTimedOut { return false, nil, err } matched := err == nil ld, err := unmarshalLocalDevices(ctx, out) if err != nil { return false, nil, err } ctx.Debug("xli waitfordevice success") return matched, ld, nil }
func (d *driver) SnapshotCopy( ctx types.Context, snapshotID, snapshotName, destinationID string, opts types.Store) (*types.Snapshot, error) { ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } req := &types.SnapshotCopyRequest{ SnapshotName: snapshotName, DestinationID: destinationID, Opts: opts.Map(), } return d.client.SnapshotCopy(ctx, serviceName, snapshotID, req) }
// List returns all available volume mappings. func (d *driver) List( ctx types.Context, opts types.Store) ([]types.VolumeMapping, error) { client := context.MustClient(ctx) vols, err := client.Storage().Volumes( ctx, &types.VolumesOpts{ Attachments: opts.GetAttachments(), Opts: opts, }, ) if err != nil { return nil, err } serviceName, serviceNameOK := context.ServiceName(ctx) if !serviceNameOK { return nil, goof.New("service name is missing") } volMaps := []types.VolumeMapping{} for _, v := range vols { vs := make(map[string]interface{}) vs["name"] = v.Name vs["size"] = v.Size vs["iops"] = v.IOPS vs["type"] = v.Type vs["availabilityZone"] = v.AvailabilityZone vs["fields"] = v.Fields vs["service"] = serviceName vs["server"] = serviceName volMaps = append(volMaps, &volumeMapping{ Name: v.Name, VolumeMountPoint: v.MountPoint(), VolumeStatus: vs, }) } return volMaps, nil }
func (c *client) LocalDevices( ctx types.Context, opts *types.LocalDevicesOpts) (*types.LocalDevices, error) { if c.isController() { return nil, utils.NewUnsupportedForClientTypeError( c.clientType, "LocalDevices") } if supported, _ := c.Supported(ctx, opts.Opts); !supported { return nil, errExecutorNotSupported } ctx = context.RequireTX(ctx.Join(c.ctx)) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } si, err := c.getServiceInfo(serviceName) if err != nil { return nil, err } driverName := si.Driver.Name out, err := c.runExecutor( ctx, driverName, types.LSXCmdLocalDevices, opts.ScanType.String()) if err != nil { return nil, err } ld, err := unmarshalLocalDevices(ctx, out) if err != nil { return nil, err } ctx.Debug("xli localdevices success") return ld, nil }
func (d *driver) Volumes( ctx types.Context, opts *types.VolumesOpts) ([]*types.Volume, error) { ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } objMap, err := d.client.VolumesByService(ctx, serviceName, opts.Attachments) if err != nil { return nil, err } objs := []*types.Volume{} for _, o := range objMap { objs = append(objs, o) } return objs, nil }
func (d *driver) VolumeCreateFromSnapshot( ctx types.Context, snapshotID, volumeName string, opts *types.VolumeCreateOpts) (*types.Volume, error) { ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } req := &types.VolumeCreateRequest{ Name: volumeName, AvailabilityZone: opts.AvailabilityZone, IOPS: opts.IOPS, Size: opts.Size, Type: opts.Type, Opts: opts.Opts.Map(), } return d.client.VolumeCreateFromSnapshot(ctx, serviceName, snapshotID, req) }
func (d *driver) VolumeDetach( ctx types.Context, volumeID string, opts *types.VolumeDetachOpts) (*types.Volume, error) { if d.isController() { return nil, utils.NewUnsupportedForClientTypeError( d.clientType, "VolumeDetach") } ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } req := &types.VolumeDetachRequest{ Force: opts.Force, Opts: opts.Opts.Map(), } return d.client.VolumeDetach(ctx, serviceName, volumeID, req) }
func (d *driver) Snapshots( ctx types.Context, opts types.Store) ([]*types.Snapshot, error) { ctx = d.requireCtx(ctx) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } objMap, err := d.client.SnapshotsByService(ctx, serviceName) if err != nil { return nil, err } objs := []*types.Snapshot{} for _, o := range objMap { objs = append(objs, o) } return objs, nil }
func (c *client) InstanceID( ctx types.Context, opts types.Store) (*types.InstanceID, error) { if c.isController() { return nil, utils.NewUnsupportedForClientTypeError( c.clientType, "InstanceID") } if supported, _ := c.Supported(ctx, opts); !supported { return nil, errExecutorNotSupported } ctx = context.RequireTX(ctx.Join(c.ctx)) serviceName, ok := context.ServiceName(ctx) if !ok { return nil, goof.New("missing service name") } si, err := c.getServiceInfo(serviceName) if err != nil { return nil, err } driverName := strings.ToLower(si.Driver.Name) // check to see if the driver's instance ID is cached if iid := c.instanceIDCache.GetInstanceID(driverName); iid != nil { return iid, nil } out, err := c.runExecutor(ctx, driverName, types.LSXCmdInstanceID) if err != nil { return nil, err } iid := &types.InstanceID{} if err := iid.UnmarshalText(out); err != nil { return nil, err } ctx = ctx.WithValue(context.InstanceIDKey, iid) if iid.HasMetadata() { ctx.Debug("sending instanceID in API.InstanceInspect call") instance, err := c.InstanceInspect(ctx, serviceName) if err != nil { return nil, err } ctx.Debug("received instanceID from API.InstanceInspect call") iid.ID = instance.InstanceID.ID iid.Fields = instance.InstanceID.Fields iid.DeleteMetadata() } c.instanceIDCache.Set(driverName, iid) ctx.Debug("cached instanceID") ctx.Debug("xli instanceID success") return iid, nil }