From b37dfe030a252dadf224b3e4512292b97d057f38 Mon Sep 17 00:00:00 2001 From: Blaise Dias Date: Tue, 12 Nov 2024 12:13:31 +0000 Subject: [PATCH] chore: add support for the openebs plugin the openebs plugin supercedes the mayastor plugin. However it is not a dropin replacement. It is functional for all openebs IO engines, and stem commands needs to further qualify which IO engine the command is for. At present invocations of the plugin in the code base only exist for mayastor. Refactor by adding functions - GetMayastorPluginCmd returns and exec cmds with the correct argument list - GetMayastorPluginCmdString - needed for invocation of support shell scripts using the plugin For the argument list is determined by name. The assumption is that if the plugin name is not kubectl-mayastor then it is the new plugin. Refactor to replace most uses of GetPluginPath, the execptions being - upgrade - plugin version check commands Also add support to create a config map for mayastor diskpools. Compatibilty with kubectl-mayastor is maintained Signed-off-by: Blaise Dias --- common/controlplane/v1/cordon.go | 10 +- common/controlplane/v1/drain.go | 11 +- common/controlplane/v1/msn_cp.go | 12 +- common/controlplane/v1/msp_cp.go | 9 +- common/controlplane/v1/msv_cp.go | 21 +-- common/controlplane/v1/plugin.go | 21 +++ common/controlplane/v1/snapshot.go | 25 +--- common/e2e_config/e2e_config.go | 2 +- common/k8stest/util.go | 6 +- common/k8stest/util_pool.go | 140 +++++++++++++++++- .../mayastor/supportability/supportability.go | 4 +- 11 files changed, 188 insertions(+), 73 deletions(-) diff --git a/common/controlplane/v1/cordon.go b/common/controlplane/v1/cordon.go index 1ff534c..8323286 100644 --- a/common/controlplane/v1/cordon.go +++ b/common/controlplane/v1/cordon.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "os/exec" "strings" "github.com/openebs/openebs-e2e/common" @@ -49,8 +48,7 @@ type NodeCordonState struct { func (cp CPv1) CordonNode(nodeName string, cordonLabel string) error { logf.Log.Info("Executing cordon node command", "node", nodeName, "cordon label", cordonLabel) - kubectlPlugin := GetPluginPath() - cmd := exec.Command(kubectlPlugin, "-n", common.NSMayastor(), "cordon", "node", nodeName, cordonLabel) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "cordon", "node", nodeName, cordonLabel) var out bytes.Buffer cmd.Stdout = &out err := cmd.Run() @@ -64,8 +62,7 @@ func (cp CPv1) CordonNode(nodeName string, cordonLabel string) error { func (cp CPv1) GetCordonNodeLabels(nodeName string) ([]string, error) { logf.Log.Info("Executing command to get cordon node labels", "node", nodeName) - pluginPath := GetPluginPath() - cmd := exec.Command(pluginPath, "-n", common.NSMayastor(), "get", "node", nodeName, "-ojson") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "get", "node", nodeName, "-ojson") var out bytes.Buffer cmd.Stdout = &out err := cmd.Run() @@ -97,8 +94,7 @@ func (cp CPv1) GetCordonNodeLabels(nodeName string) ([]string, error) { func (cp CPv1) UnCordonNode(nodeName string, cordonLabel string) error { logf.Log.Info("Executing uncordon node command", "node", nodeName, "cordon label", cordonLabel) - kubectlPlugin := GetPluginPath() - cmd := exec.Command(kubectlPlugin, "-n", common.NSMayastor(), "uncordon", "node", nodeName, cordonLabel) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "uncordon", "node", nodeName, cordonLabel) var out bytes.Buffer cmd.Stdout = &out err := cmd.Run() diff --git a/common/controlplane/v1/drain.go b/common/controlplane/v1/drain.go index 68868b5..22b43d2 100644 --- a/common/controlplane/v1/drain.go +++ b/common/controlplane/v1/drain.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "os/exec" "strings" "github.com/openebs/openebs-e2e/common" @@ -15,14 +14,13 @@ import ( // DrainNode drain the given node with label func (cp CPv1) DrainNode(nodeName string, drainLabel string, drainTimeOut int) error { logf.Log.Info("Executing drain node command", "node", nodeName, "drain label", drainLabel, "timeout", drainTimeOut) - kubectlPlugin := GetPluginPath() // #FIXME remove drain timeout drain command is fuctional - cmd := exec.Command(kubectlPlugin, "-n", common.NSMayastor(), "drain", "node", nodeName, drainLabel, "--drain-timeout", fmt.Sprintf("%ds", drainTimeOut)) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "drain", "node", nodeName, drainLabel, "--drain-timeout", fmt.Sprintf("%ds", drainTimeOut)) var out bytes.Buffer cmd.Stdout = &out err := cmd.Run() if err != nil { - return fmt.Errorf("%s plugin failed to drain node %s with drain label %s , error %v", kubectlPlugin, nodeName, drainLabel, err) + return fmt.Errorf("%s plugin failed to drain node %s with drain label %s , error %v", GetPluginPath(), nodeName, drainLabel, err) } else if strings.Contains(out.String(), ErrorResponse) { return fmt.Errorf("REST api error, failed to drain node %s with label %s, error %v", nodeName, drainLabel, out.String()) } @@ -32,13 +30,12 @@ func (cp CPv1) DrainNode(nodeName string, drainLabel string, drainTimeOut int) e // GetDrainNodeLabels returns draining, drained labels and error func (cp CPv1) GetDrainNodeLabels(nodeName string) ([]string, []string, error) { logf.Log.Info("Executing command to get drain node labels", "node", nodeName) - pluginPath := GetPluginPath() - cmd := exec.Command(pluginPath, "-n", common.NSMayastor(), "get", "node", nodeName, "-ojson") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "get", "node", nodeName, "-ojson") var out bytes.Buffer cmd.Stdout = &out err := cmd.Run() if err != nil { - return nil, nil, fmt.Errorf("%s failed to get cordon labels for node %s, error %v", pluginPath, nodeName, err) + return nil, nil, fmt.Errorf("%s failed to get cordon labels for node %s, error %v", GetPluginPath(), nodeName, err) } outputString := out.String() var cordonLabelsInfo NodeCordonLabelsInfo diff --git a/common/controlplane/v1/msn_cp.go b/common/controlplane/v1/msn_cp.go index 08c7e76..b44b47d 100644 --- a/common/controlplane/v1/msn_cp.go +++ b/common/controlplane/v1/msn_cp.go @@ -4,7 +4,6 @@ package v1 import ( "encoding/json" "fmt" - "os/exec" "strings" "github.com/openebs/openebs-e2e/common" @@ -31,11 +30,9 @@ type msnState struct { } func GetMayastorCpNode(nodeName string) (*MayastorCpNode, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "node", nodeName) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "node", nodeName) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -54,11 +51,9 @@ func GetMayastorCpNode(nodeName string) (*MayastorCpNode, error) { } func ListMayastorCpNodes() ([]MayastorCpNode, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "nodes") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "nodes") jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -137,7 +132,6 @@ func (cp CPv1) GetMsNodeStatus(nodeName string) (string, error) { // UpdateNodeLabel adds or remove labels from nodes func (cp CPv1) UpdateNodeLabel(nodeName string, labelKey, labelValue string) error { - pluginPath := GetPluginPath() args := []string{"label", "node", nodeName} // Check if a label value is provided @@ -149,7 +143,7 @@ func (cp CPv1) UpdateNodeLabel(nodeName string, labelKey, labelValue string) err args = append(args, fmt.Sprintf("%s-", labelKey)) } - cmd := exec.Command(pluginPath, args...) + cmd := GetMayastorPluginCmd(args...) // Print the command that will be executed logf.Log.Info("Executing", "command", strings.Join(cmd.Args, " ")) diff --git a/common/controlplane/v1/msp_cp.go b/common/controlplane/v1/msp_cp.go index 7b3067c..a4df9e1 100644 --- a/common/controlplane/v1/msp_cp.go +++ b/common/controlplane/v1/msp_cp.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "os" - "os/exec" "github.com/openebs/openebs-e2e/common" @@ -41,11 +40,9 @@ func (cp CPv1) CreatePoolOnInstall() bool { } func GetMayastorCpPool(name string) (*MayastorCpPool, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "pool", name) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "pool", name) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -65,11 +62,9 @@ func GetMayastorCpPool(name string) (*MayastorCpPool, error) { } func ListMayastorCpPools() ([]MayastorCpPool, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "pools") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "pools") jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { diff --git a/common/controlplane/v1/msv_cp.go b/common/controlplane/v1/msv_cp.go index 99fe265..51c8754 100644 --- a/common/controlplane/v1/msv_cp.go +++ b/common/controlplane/v1/msv_cp.go @@ -4,7 +4,6 @@ package v1 import ( "encoding/json" "fmt" - "os/exec" "regexp" "strconv" "strings" @@ -23,11 +22,9 @@ func HasNotFoundRestJsonError(str string) bool { } func getMayastorCpVolume(uuid string) (*common.MayastorVolume, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volume", uuid) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volume", uuid) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -46,11 +43,9 @@ func getMayastorCpVolume(uuid string) (*common.MayastorVolume, error) { } func listMayastorCpVolumes() ([]common.MayastorVolume, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volumes") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volumes") jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -67,11 +62,9 @@ func listMayastorCpVolumes() ([]common.MayastorVolume, error) { } func scaleMayastorVolume(uuid string, replicaCount int) error { - pluginpath := GetPluginPath() - var err error var jsonInput []byte - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "scale", "volume", uuid, strconv.Itoa(replicaCount)) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "scale", "volume", uuid, strconv.Itoa(replicaCount)) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -237,11 +230,9 @@ func (cp CPv1) ListMsvs() ([]common.MayastorVolume, error) { } func (cp CPv1) ListRestoredMsvs() ([]common.MayastorVolume, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volumes", "--source", "snapshot") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volumes", "--source", "snapshot") jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -361,11 +352,9 @@ func (cp CPv1) GetMsvDeviceUri(volName string) (string, error) { } func (cp CPv1) SetVolumeMaxSnapshotCount(uuid string, maxSnapshotCount int32) error { - pluginpath := GetPluginPath() - var err error var jsonInput []byte - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "set", "volume", uuid, "max-snapshots", strconv.Itoa(int(maxSnapshotCount))) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "set", "volume", uuid, "max-snapshots", strconv.Itoa(int(maxSnapshotCount))) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { diff --git a/common/controlplane/v1/plugin.go b/common/controlplane/v1/plugin.go index 40279aa..a34a797 100644 --- a/common/controlplane/v1/plugin.go +++ b/common/controlplane/v1/plugin.go @@ -60,3 +60,24 @@ func CheckPluginError(jsonInput []byte, err error) error { } return err } + +// GetMayastorPluginCmd return an exec cmd object setup to invoke the plugin +// for the mayastor IOEngine +func GetMayastorPluginCmd(arg ...string) *exec.Cmd { + binPath := GetPluginPath() + if e2e_config.GetConfig().Product.KubectlPluginName != "kubectl-mayastor" { + return exec.Command(binPath, append([]string{"mayastor"}, arg...)...) + } + return exec.Command(binPath, arg...) +} + +// GetMayastorPluginCmdString return a string which can be supplied to +// shell commands to invoke the plugin for the mayastor IOEngine +// deprecated: use GetMayastorPluginCmd in preference +func GetMayastorPluginCmdString() string { + binPath := GetPluginPath() + if e2e_config.GetConfig().Product.KubectlPluginName != "kubectl-mayastor" { + return binPath + " " + "mayastor " + } + return binPath +} diff --git a/common/controlplane/v1/snapshot.go b/common/controlplane/v1/snapshot.go index aef17e1..e28a9d2 100644 --- a/common/controlplane/v1/snapshot.go +++ b/common/controlplane/v1/snapshot.go @@ -3,17 +3,14 @@ package v1 import ( "encoding/json" "fmt" - "os/exec" "github.com/openebs/openebs-e2e/common" ) func (cp CPv1) GetSnapshots() ([]common.SnapshotSchema, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots") jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -30,12 +27,10 @@ func (cp CPv1) GetSnapshots() ([]common.SnapshotSchema, error) { } func (cp CPv1) GetSnapshot(snapshotId string) (common.SnapshotSchema, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error var response []common.SnapshotSchema - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots", "--snapshot", snapshotId) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots", "--snapshot", snapshotId) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -57,12 +52,10 @@ func (cp CPv1) GetSnapshot(snapshotId string) (common.SnapshotSchema, error) { } func (cp CPv1) GetVolumeSnapshot(volUuid string, snapshotId string) (common.SnapshotSchema, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error var response []common.SnapshotSchema - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots", "--volume", volUuid, "--snapshot", snapshotId) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots", "--volume", volUuid, "--snapshot", snapshotId) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -83,11 +76,9 @@ func (cp CPv1) GetVolumeSnapshot(volUuid string, snapshotId string) (common.Snap } func (cp CPv1) GetVolumeSnapshots(volUuid string) ([]common.SnapshotSchema, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots", "--volume", volUuid) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volume-snapshots", "--volume", volUuid) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -104,11 +95,9 @@ func (cp CPv1) GetVolumeSnapshots(volUuid string) ([]common.SnapshotSchema, erro } func (cp CPv1) GetVolumeSnapshotTopology() ([]common.SnapshotSchema, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volume-snapshot-topology") + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volume-snapshot-topology") jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { @@ -125,12 +114,10 @@ func (cp CPv1) GetVolumeSnapshotTopology() ([]common.SnapshotSchema, error) { } func (cp CPv1) GetPerSnapshotVolumeSnapshotTopology(snapshotId string) (common.SnapshotSchema, error) { - pluginpath := GetPluginPath() - var jsonInput []byte var err error var response []common.SnapshotSchema - cmd := exec.Command(pluginpath, "-n", common.NSMayastor(), "-ojson", "get", "volume-snapshot-topology", "--snapshot", snapshotId) + cmd := GetMayastorPluginCmd("-n", common.NSMayastor(), "-ojson", "get", "volume-snapshot-topology", "--snapshot", snapshotId) jsonInput, err = cmd.CombinedOutput() err = CheckPluginError(jsonInput, err) if err != nil { diff --git a/common/e2e_config/e2e_config.go b/common/e2e_config/e2e_config.go index 0a03171..d2fdf73 100644 --- a/common/e2e_config/e2e_config.go +++ b/common/e2e_config/e2e_config.go @@ -62,7 +62,7 @@ type ProductSpec struct { IOEnginePodLabelValue string `yaml:"ioEnginePodLabelValue" env-default:"io-engine"` IOEnginePodName string `yaml:"ioEnginePodName"` JaegersCrdName string `yaml:"jaegersCrdName" env-default:"jaegers.jaegertracing.io"` - KubectlPluginName string `yaml:"kubectlPluginName" env-default:"kubectl-mayastor"` + KubectlPluginName string `yaml:"kubectlPluginName" env-default:"kubectl-mayastor" env:"e2e_kc_plugin"` KubectlPluginPort int `yaml:"kubectlPluginPort" env-default:"30011"` LogConfigResources []string `yaml:"logConfigResources"` LogDumpCsiAttacherName string `yaml:"logDumpCsiAttacherName" env-default:"csi-attacher"` diff --git a/common/k8stest/util.go b/common/k8stest/util.go index 7b7a934..a3cef88 100644 --- a/common/k8stest/util.go +++ b/common/k8stest/util.go @@ -1001,7 +1001,7 @@ func GenerateSupportBundle(testLogDir string) { bashCmd := fmt.Sprintf("%s/e2e-cluster-dump.sh --destdir '%s' --plugin '%s'", locations.GetE2EScriptsPath(), testLogDir, - mcpV1.GetPluginPath(), + mcpV1.GetMayastorPluginCmdString(), ) logf.Log.Info("About to execute", "command", bashCmd) cmd := exec.Command("bash", "-c", bashCmd) @@ -1013,7 +1013,7 @@ func GenerateSupportBundle(testLogDir string) { logf.Log.Info(out.String()) } bashCmd = fmt.Sprintf("%s -n %s get volume-replica-topologies -o json > %s/%s", - mcpV1.GetPluginPath(), + mcpV1.GetMayastorPluginCmdString(), common.NSMayastor(), testLogDir, "replica-topologies.json") @@ -1024,7 +1024,7 @@ func GenerateSupportBundle(testLogDir string) { logf.Log.Info("command failed", "error", err) logf.Log.Info(out.String()) } - cmd = exec.Command(mcpV1.GetPluginPath(), "dump", "system", "-n", common.NSMayastor(), "-d", testLogDir) + cmd = mcpV1.GetMayastorPluginCmd("dump", "system", "-n", common.NSMayastor(), "-d", testLogDir) logf.Log.Info("About to execute", "command", cmd) err = cmd.Run() if err != nil { diff --git a/common/k8stest/util_pool.go b/common/k8stest/util_pool.go index e81d0e4..1c04225 100644 --- a/common/k8stest/util_pool.go +++ b/common/k8stest/util_pool.go @@ -1,21 +1,30 @@ package k8stest import ( + "bytes" "context" + "encoding/json" "fmt" + "sort" + "strings" "github.com/openebs/openebs-e2e/common" + mcpV1 "github.com/openebs/openebs-e2e/common/controlplane/v1" "github.com/openebs/openebs-e2e/common/custom_resources" "gopkg.in/yaml.v3" + coreV1 "k8s.io/api/core/v1" metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/log" ) +const configMapName = "e2e-diskpools-fqn" + // GetConfiguredClusterNodePoolDevices read the diskpool configmap // and return the contents as a map of pool device lists keyed on the node name. func GetConfiguredClusterNodePoolDevices() (map[string][]string, error) { - configMap, err := gTestEnv.KubeInt.CoreV1().ConfigMaps(common.NSDefault).Get(context.TODO(), "e2e-diskpools-fqn", metaV1.GetOptions{}) + configMap, err := gTestEnv.KubeInt.CoreV1().ConfigMaps(common.NSDefault).Get(context.TODO(), configMapName, metaV1.GetOptions{}) nodesPoolDevices := make(map[string][]string) if err == nil { for k, v := range configMap.Data { @@ -29,6 +38,7 @@ func GetConfiguredClusterNodePoolDevices() (map[string][]string, error) { } } } + log.Log.Info("#############", "nodePoolDevices", nodesPoolDevices) return nodesPoolDevices, err } @@ -121,3 +131,131 @@ func GetCapacityAndAllocatedAllSnapshotsAllReplicasOnPool(poolName string) (int6 } return totalCapacity, err } + +// CreateDiskPoolsConfiguration query mayastor for available devices and create configmap +// e2e-diskpools-fqn with a map of nodes and pool devices +// This function is a NOP if the config map is already present +// to allow external agents to determine the set of pool devices +// by creating the configmap before this function is invoked +func CreateDiskPoolsConfiguration() error { + // weights for sorting device links in order of preference + var devLinkWeights = map[string]int{ + "by-uuid": 0, + "by-id": 1, + "by-partuuid": 2, + "by-path": 3, + } + // struct to de-serialise plugin output for block devices + type msBlockDev struct { + Available bool `json:"available"` + DevLinks []string `json:"devlinks"` + DevName string `json:"devname"` + DevPath string `json:"devpath"` + } + configMapApi := gTestEnv.KubeInt.CoreV1().ConfigMaps(common.NSDefault) + cmLst, err := configMapApi.List(context.TODO(), metaV1.ListOptions{}) + + if err == nil { + // if the configmap already exists the use it as is + for _, cm := range cmLst.Items { + if cm.Name == configMapName { + log.Log.Info("CreateDiskPoolsConfiguration: using existing config map", "name", cm.Name) + return nil + } + } + // compile a list of devices on each node. + nodes, err := GetMayastorNodeNames() + if err != nil { + log.Log.Info("CreateDiskPoolsConfiguration: GetMayastorNodeName", "error", err) + return err + } + cmapData := make(map[string]string) + for _, node := range nodes { + // retrieve block devices on a node in json format + cmd := mcpV1.GetMayastorPluginCmd("-n", common.NSMayastor(), "get", "block-devices", node, "-o", "json") + var out bytes.Buffer + log.Log.Info("About to execute:", "cmd", cmd) + cmd.Stdout = &out + err = cmd.Run() + if err != nil { + log.Log.Info("CreateDiskPoolsConfiguration:", "cmd", cmd, "error", err) + return err + } + log.Log.Info("CreateDiskPoolsConfiguration:", "raw data", out.String()) + // de-serialise the json data + var data []msBlockDev + err = json.Unmarshal(out.Bytes(), &data) + if err != nil { + log.Log.Info("CreateDiskPoolsConfiguration: json Unmarshal", "error", err) + return err + } + var disks []string + for _, bd := range data { + if !bd.Available { + // disk is not available for use by mayastor + continue + } + // ignore loop devices + if strings.HasPrefix(bd.DevName, "/dev/loop") { + continue + } + // default to device name + device := bd.DevName + if len(bd.DevLinks) != 0 { + // if a list device links exists then use that as the device + // sort in order of preference and use the first one. + sort.Slice(bd.DevLinks, func(i int, j int) bool { + keyI := strings.Split(bd.DevLinks[i], "/")[3] + keyJ := strings.Split(bd.DevLinks[j], "/")[3] + weightI := 10 + if val, ok := devLinkWeights[keyI]; ok { + weightI = val + } + weightJ := 10 + if val, ok := devLinkWeights[keyJ]; ok { + weightJ = val + } + if weightI == weightJ { + // if weights are the same sort alphabetically for consitent + // results + return bd.DevLinks[i] < bd.DevLinks[j] + } + return weightI < weightJ + }) + device = bd.DevLinks[0] + } + disks = append(disks, device) + } + if len(disks) > 0 { + var yamlBytes []byte + yamlBytes, err = yaml.Marshal(disks) + if err != nil { + log.Log.Info("CreateDiskPoolsConfiguration: yaml Marshal", "error", err) + return err + } + cmapData[node] = string(yamlBytes) + } + } + + cmap := coreV1.ConfigMap{ + TypeMeta: metaV1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metaV1.ObjectMeta{ + Name: configMapName, + Namespace: common.NSDefault, + }, + Immutable: nil, + Data: cmapData, + BinaryData: nil, + } + _, err = configMapApi.Create(context.TODO(), &cmap, metaV1.CreateOptions{}) + if err == nil { + log.Log.Info("Created config map", "name", cmap.ObjectMeta.Name) + } else { + log.Log.Info("failed to create config map", "name", cmap.ObjectMeta.Name, "error", err) + } + } + return err +} diff --git a/common/mayastor/supportability/supportability.go b/common/mayastor/supportability/supportability.go index 3a41491..43c31a0 100644 --- a/common/mayastor/supportability/supportability.go +++ b/common/mayastor/supportability/supportability.go @@ -9,7 +9,6 @@ import ( "io/fs" "math/rand" "os" - "os/exec" "path/filepath" "regexp" "sort" @@ -164,8 +163,7 @@ func GetPodsWithLoggingLabel() ([]coreV1.Pod, error) { } func SystemDump() (string, error) { - bp := v1.GetPluginPath() - cmd := exec.Command(bp, "dump", "system", "-n", common.NSMayastor(), "-d", TmpDir) + cmd := v1.GetMayastorPluginCmd("dump", "system", "-n", common.NSMayastor(), "-d", TmpDir) start := time.Now() logf.Log.Info("Collecting system log dump starts", "namespace", common.NSMayastor(), "start_time", start) err := cmd.Run()