mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 18:00:08 +00:00
ScaleIO - Specify SDC GUID value via node label
The commit allow ScaleIO volume plugin to read SDC GUID value as a node label. If binary drv_cfg is not installed, the plugin will still work properly. If node label not found, it defaults to drv_cfg if installed.
This commit is contained in:
parent
424819888a
commit
314859538e
@ -74,6 +74,7 @@ type sioClient struct {
|
|||||||
spClient *sio.StoragePool
|
spClient *sio.StoragePool
|
||||||
provisionMode string
|
provisionMode string
|
||||||
sdcPath string
|
sdcPath string
|
||||||
|
sdcGuid string
|
||||||
instanceID string
|
instanceID string
|
||||||
inited bool
|
inited bool
|
||||||
diskRegex *regexp.Regexp
|
diskRegex *regexp.Regexp
|
||||||
@ -292,28 +293,43 @@ func (c *sioClient) DeleteVolume(id sioVolumeID) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IID returns the scaleio instance id for node
|
||||||
func (c *sioClient) IID() (string, error) {
|
func (c *sioClient) IID() (string, error) {
|
||||||
if err := c.init(); err != nil {
|
if err := c.init(); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if instanceID not set, retrieve it
|
||||||
if c.instanceID == "" {
|
if c.instanceID == "" {
|
||||||
|
guid, err := c.getGuid()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
sdc, err := c.sysClient.FindSdc("SdcGuid", guid)
|
||||||
|
if err != nil {
|
||||||
|
glog.Error(log("failed to retrieve sdc info %s", err))
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
c.instanceID = sdc.Sdc.ID
|
||||||
|
glog.V(4).Info(log("retrieved instanceID %s", c.instanceID))
|
||||||
|
}
|
||||||
|
return c.instanceID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getGuid returns instance GUID, if not set using resource labels
|
||||||
|
// it attemps to fallback to using drv_cfg binary
|
||||||
|
func (c *sioClient) getGuid() (string, error) {
|
||||||
|
if c.sdcGuid == "" {
|
||||||
|
glog.V(4).Info(log("sdc guid label not set, falling back to using drv_cfg"))
|
||||||
cmd := c.getSdcCmd()
|
cmd := c.getSdcCmd()
|
||||||
output, err := c.exec.Run(cmd, "--query_guid")
|
output, err := c.exec.Run(cmd, "--query_guid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(log("drv_cfg --query_guid failed: %v", err))
|
glog.Error(log("drv_cfg --query_guid failed: %v", err))
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
guid := strings.TrimSpace(string(output))
|
c.sdcGuid = strings.TrimSpace(string(output))
|
||||||
sdc, err := c.sysClient.FindSdc("SdcGuid", guid)
|
|
||||||
if err != nil {
|
|
||||||
glog.Error(log("failed to get sdc info %s", err))
|
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
c.instanceID = sdc.Sdc.ID
|
return c.sdcGuid, nil
|
||||||
glog.V(4).Info(log("got instanceID %s", c.instanceID))
|
|
||||||
}
|
|
||||||
return c.instanceID, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSioDiskPaths traverse local disk devices to retrieve device path
|
// getSioDiskPaths traverse local disk devices to retrieve device path
|
||||||
|
@ -81,6 +81,7 @@ func (m *sioMgr) getClient() (sioInterface, error) {
|
|||||||
client.spName = configs[confKey.storagePool]
|
client.spName = configs[confKey.storagePool]
|
||||||
client.sdcPath = configs[confKey.sdcRootPath]
|
client.sdcPath = configs[confKey.sdcRootPath]
|
||||||
client.provisionMode = configs[confKey.storageMode]
|
client.provisionMode = configs[confKey.storageMode]
|
||||||
|
client.sdcGuid = configs[confKey.sdcGuid]
|
||||||
|
|
||||||
m.client = client
|
m.client = client
|
||||||
|
|
||||||
@ -215,23 +216,12 @@ func (m *sioMgr) DeleteVolume(volName string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iid, err := client.IID()
|
|
||||||
if err != nil {
|
|
||||||
glog.Error(log("failed to get instanceID: %v", err))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vol, err := client.FindVolume(volName)
|
vol, err := client.FindVolume(volName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// if still attached, stop
|
|
||||||
if m.isSdcMappedToVol(iid, vol) {
|
|
||||||
glog.Error(log("volume %s still attached, unable to delete", volName))
|
|
||||||
return errors.New("volume still attached")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := client.DeleteVolume(sioVolumeID(vol.ID)); err != nil {
|
if err := client.DeleteVolume(sioVolumeID(vol.ID)); err != nil {
|
||||||
glog.Error(log("failed to delete volume %s: %v", volName, err))
|
glog.Error(log("failed to delete volume %s: %v", volName, err))
|
||||||
return err
|
return err
|
||||||
@ -242,10 +232,6 @@ func (m *sioMgr) DeleteVolume(volName string) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************
|
|
||||||
// Helpers
|
|
||||||
//*****************************************************************
|
|
||||||
|
|
||||||
// isSdcMappedToVol returns true if the sdc is mapped to the volume
|
// isSdcMappedToVol returns true if the sdc is mapped to the volume
|
||||||
func (m *sioMgr) isSdcMappedToVol(sdcID string, vol *siotypes.Volume) bool {
|
func (m *sioMgr) isSdcMappedToVol(sdcID string, vol *siotypes.Volume) bool {
|
||||||
if len(vol.MappedSdcInfo) == 0 {
|
if len(vol.MappedSdcInfo) == 0 {
|
||||||
|
@ -47,7 +47,8 @@ var (
|
|||||||
readOnly,
|
readOnly,
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
namespace string
|
namespace,
|
||||||
|
sdcGuid string
|
||||||
}{
|
}{
|
||||||
gateway: "gateway",
|
gateway: "gateway",
|
||||||
sslEnabled: "sslEnabled",
|
sslEnabled: "sslEnabled",
|
||||||
@ -64,8 +65,9 @@ var (
|
|||||||
username: "username",
|
username: "username",
|
||||||
password: "password",
|
password: "password",
|
||||||
namespace: "namespace",
|
namespace: "namespace",
|
||||||
|
sdcGuid: "sdcGuid",
|
||||||
}
|
}
|
||||||
nsSep = "%"
|
sdcGuidLabelName = "scaleio.sdcGuid"
|
||||||
sdcRootPath = "/opt/emc/scaleio/sdc/bin"
|
sdcRootPath = "/opt/emc/scaleio/sdc/bin"
|
||||||
|
|
||||||
secretNotFoundErr = errors.New("secret not found")
|
secretNotFoundErr = errors.New("secret not found")
|
||||||
@ -215,6 +217,33 @@ func attachSecret(plug *sioPlugin, namespace string, configData map[string]strin
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attachSdcGuid injects the sdc guid node label value into config
|
||||||
|
func attachSdcGuid(plug *sioPlugin, conf map[string]string) error {
|
||||||
|
guid, err := getSdcGuidLabel(plug)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
conf[confKey.sdcGuid] = guid
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSdcGuidLabel fetches the scaleio.sdcGuid node label
|
||||||
|
// associated with the node executing this code.
|
||||||
|
func getSdcGuidLabel(plug *sioPlugin) (string, error) {
|
||||||
|
nodeLabels, err := plug.host.GetNodeLabels()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
label, ok := nodeLabels[sdcGuidLabelName]
|
||||||
|
if !ok {
|
||||||
|
glog.V(4).Info(log("node label %s not found", sdcGuidLabelName))
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
glog.V(4).Info(log("found node label %s=%s", sdcGuidLabelName, label))
|
||||||
|
return label, nil
|
||||||
|
}
|
||||||
|
|
||||||
// getVolumeSourceFromSpec safely extracts ScaleIOVolumeSource from spec
|
// getVolumeSourceFromSpec safely extracts ScaleIOVolumeSource from spec
|
||||||
func getVolumeSourceFromSpec(spec *volume.Spec) (*api.ScaleIOVolumeSource, error) {
|
func getVolumeSourceFromSpec(spec *volume.Spec) (*api.ScaleIOVolumeSource, error) {
|
||||||
if spec.Volume != nil && spec.Volume.ScaleIO != nil {
|
if spec.Volume != nil && spec.Volume.ScaleIO != nil {
|
||||||
|
@ -386,7 +386,13 @@ func (v *sioVolume) setSioMgr() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merge in Sdc Guid label value
|
||||||
|
if err := attachSdcGuid(v.plugin, configData); err != nil {
|
||||||
|
glog.Error(log("failed to retrieve sdc guid: %v", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
mgr, err := newSioMgr(configData, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
mgr, err := newSioMgr(configData, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(log("failed to reset sio manager: %v", err))
|
glog.Error(log("failed to reset sio manager: %v", err))
|
||||||
return err
|
return err
|
||||||
@ -418,7 +424,14 @@ func (v *sioVolume) resetSioMgr() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merge in Sdc Guid label value
|
||||||
|
if err := attachSdcGuid(v.plugin, configData); err != nil {
|
||||||
|
glog.Error(log("failed to retrieve sdc guid: %v", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
mgr, err := newSioMgr(configData, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
mgr, err := newSioMgr(configData, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(log("failed to reset scaleio mgr: %v", err))
|
glog.Error(log("failed to reset scaleio mgr: %v", err))
|
||||||
return err
|
return err
|
||||||
@ -453,6 +466,7 @@ func (v *sioVolume) setSioMgrFromConfig() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mgr, err := newSioMgr(data, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
mgr, err := newSioMgr(data, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(log("failed while setting scaleio mgr from config: %v", err))
|
glog.Error(log("failed while setting scaleio mgr from config: %v", err))
|
||||||
return err
|
return err
|
||||||
@ -462,6 +476,8 @@ func (v *sioVolume) setSioMgrFromConfig() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setSioMgrFromSpec sets the scaleio manager from a spec object.
|
||||||
|
// The spec may be complete or incomplete depending on lifecycle phase.
|
||||||
func (v *sioVolume) setSioMgrFromSpec() error {
|
func (v *sioVolume) setSioMgrFromSpec() error {
|
||||||
glog.V(4).Info(log("setting sio manager from spec"))
|
glog.V(4).Info(log("setting sio manager from spec"))
|
||||||
if v.sioMgr == nil {
|
if v.sioMgr == nil {
|
||||||
@ -482,6 +498,7 @@ func (v *sioVolume) setSioMgrFromSpec() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mgr, err := newSioMgr(configData, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
mgr, err := newSioMgr(configData, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(log("failed to reset sio manager: %v", err))
|
glog.Error(log("failed to reset sio manager: %v", err))
|
||||||
return err
|
return err
|
||||||
|
@ -60,8 +60,14 @@ func newPluginMgr(t *testing.T) (*volume.VolumePluginMgr, string) {
|
|||||||
"password": []byte("password"),
|
"password": []byte("password"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fakeClient := fakeclient.NewSimpleClientset(config)
|
fakeClient := fakeclient.NewSimpleClientset(config)
|
||||||
host := volumetest.NewFakeVolumeHost(tmpDir, fakeClient, nil)
|
host := volumetest.NewFakeVolumeHostWithNodeLabels(
|
||||||
|
tmpDir,
|
||||||
|
fakeClient,
|
||||||
|
nil,
|
||||||
|
map[string]string{sdcGuidLabelName: "abc-123"},
|
||||||
|
)
|
||||||
plugMgr := &volume.VolumePluginMgr{}
|
plugMgr := &volume.VolumePluginMgr{}
|
||||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host)
|
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host)
|
||||||
|
|
||||||
@ -195,6 +201,11 @@ func TestVolumeMounterUnmounter(t *testing.T) {
|
|||||||
t.Errorf("SetUp() - expecting multiple volume disabled by default")
|
t.Errorf("SetUp() - expecting multiple volume disabled by default")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// did we read sdcGuid label
|
||||||
|
if _, ok := sioVol.sioMgr.configData[confKey.sdcGuid]; !ok {
|
||||||
|
t.Errorf("Expected to find node label scaleio.sdcGuid, but did not find it")
|
||||||
|
}
|
||||||
|
|
||||||
// rebuild spec
|
// rebuild spec
|
||||||
builtSpec, err := sioPlug.ConstructVolumeSpec(volume.NewSpecFromVolume(vol).Name(), path)
|
builtSpec, err := sioPlug.ConstructVolumeSpec(volume.NewSpecFromVolume(vol).Name(), path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -322,6 +333,11 @@ func TestVolumeProvisioner(t *testing.T) {
|
|||||||
t.Fatalf("Expected success, got: %v", err)
|
t.Fatalf("Expected success, got: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// did we read sdcGuid label
|
||||||
|
if _, ok := sioVol.sioMgr.configData[confKey.sdcGuid]; !ok {
|
||||||
|
t.Errorf("Expected to find node label scaleio.sdcGuid, but did not find it")
|
||||||
|
}
|
||||||
|
|
||||||
// isMultiMap applied
|
// isMultiMap applied
|
||||||
if !sio.isMultiMap {
|
if !sio.isMultiMap {
|
||||||
t.Errorf("SetUp() expecting attached volume with multi-mapping")
|
t.Errorf("SetUp() expecting attached volume with multi-mapping")
|
||||||
|
Loading…
Reference in New Issue
Block a user