mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 15:25:57 +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
|
||||
provisionMode string
|
||||
sdcPath string
|
||||
sdcGuid string
|
||||
instanceID string
|
||||
inited bool
|
||||
diskRegex *regexp.Regexp
|
||||
@ -292,28 +293,43 @@ func (c *sioClient) DeleteVolume(id sioVolumeID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IID returns the scaleio instance id for node
|
||||
func (c *sioClient) IID() (string, error) {
|
||||
if err := c.init(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// if instanceID not set, retrieve it
|
||||
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()
|
||||
output, err := c.exec.Run(cmd, "--query_guid")
|
||||
if err != nil {
|
||||
glog.Error(log("drv_cfg --query_guid failed: %v", err))
|
||||
return "", err
|
||||
}
|
||||
guid := 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
|
||||
glog.V(4).Info(log("got instanceID %s", c.instanceID))
|
||||
c.sdcGuid = strings.TrimSpace(string(output))
|
||||
}
|
||||
return c.instanceID, nil
|
||||
return c.sdcGuid, nil
|
||||
}
|
||||
|
||||
// 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.sdcPath = configs[confKey.sdcRootPath]
|
||||
client.provisionMode = configs[confKey.storageMode]
|
||||
client.sdcGuid = configs[confKey.sdcGuid]
|
||||
|
||||
m.client = client
|
||||
|
||||
@ -215,23 +216,12 @@ func (m *sioMgr) DeleteVolume(volName string) error {
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
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 {
|
||||
glog.Error(log("failed to delete volume %s: %v", volName, 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
|
||||
func (m *sioMgr) isSdcMappedToVol(sdcID string, vol *siotypes.Volume) bool {
|
||||
if len(vol.MappedSdcInfo) == 0 {
|
||||
|
@ -47,7 +47,8 @@ var (
|
||||
readOnly,
|
||||
username,
|
||||
password,
|
||||
namespace string
|
||||
namespace,
|
||||
sdcGuid string
|
||||
}{
|
||||
gateway: "gateway",
|
||||
sslEnabled: "sslEnabled",
|
||||
@ -64,9 +65,10 @@ var (
|
||||
username: "username",
|
||||
password: "password",
|
||||
namespace: "namespace",
|
||||
sdcGuid: "sdcGuid",
|
||||
}
|
||||
nsSep = "%"
|
||||
sdcRootPath = "/opt/emc/scaleio/sdc/bin"
|
||||
sdcGuidLabelName = "scaleio.sdcGuid"
|
||||
sdcRootPath = "/opt/emc/scaleio/sdc/bin"
|
||||
|
||||
secretNotFoundErr = errors.New("secret not found")
|
||||
configMapNotFoundErr = errors.New("configMap not found")
|
||||
@ -215,6 +217,33 @@ func attachSecret(plug *sioPlugin, namespace string, configData map[string]strin
|
||||
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
|
||||
func getVolumeSourceFromSpec(spec *volume.Spec) (*api.ScaleIOVolumeSource, error) {
|
||||
if spec.Volume != nil && spec.Volume.ScaleIO != nil {
|
||||
|
@ -386,7 +386,13 @@ func (v *sioVolume) setSioMgr() error {
|
||||
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()))
|
||||
|
||||
if err != nil {
|
||||
glog.Error(log("failed to reset sio manager: %v", err))
|
||||
return err
|
||||
@ -418,7 +424,14 @@ func (v *sioVolume) resetSioMgr() error {
|
||||
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()))
|
||||
|
||||
if err != nil {
|
||||
glog.Error(log("failed to reset scaleio mgr: %v", err))
|
||||
return err
|
||||
@ -453,6 +466,7 @@ func (v *sioVolume) setSioMgrFromConfig() error {
|
||||
}
|
||||
|
||||
mgr, err := newSioMgr(data, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
||||
|
||||
if err != nil {
|
||||
glog.Error(log("failed while setting scaleio mgr from config: %v", err))
|
||||
return err
|
||||
@ -462,6 +476,8 @@ func (v *sioVolume) setSioMgrFromConfig() error {
|
||||
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 {
|
||||
glog.V(4).Info(log("setting sio manager from spec"))
|
||||
if v.sioMgr == nil {
|
||||
@ -482,6 +498,7 @@ func (v *sioVolume) setSioMgrFromSpec() error {
|
||||
}
|
||||
|
||||
mgr, err := newSioMgr(configData, v.plugin.host.GetExec(v.plugin.GetPluginName()))
|
||||
|
||||
if err != nil {
|
||||
glog.Error(log("failed to reset sio manager: %v", err))
|
||||
return err
|
||||
|
@ -60,8 +60,14 @@ func newPluginMgr(t *testing.T) (*volume.VolumePluginMgr, string) {
|
||||
"password": []byte("password"),
|
||||
},
|
||||
}
|
||||
|
||||
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.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host)
|
||||
|
||||
@ -195,6 +201,11 @@ func TestVolumeMounterUnmounter(t *testing.T) {
|
||||
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
|
||||
builtSpec, err := sioPlug.ConstructVolumeSpec(volume.NewSpecFromVolume(vol).Name(), path)
|
||||
if err != nil {
|
||||
@ -322,6 +333,11 @@ func TestVolumeProvisioner(t *testing.T) {
|
||||
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
|
||||
if !sio.isMultiMap {
|
||||
t.Errorf("SetUp() expecting attached volume with multi-mapping")
|
||||
|
Loading…
Reference in New Issue
Block a user