mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 11:00:25 +00:00
cleanup: simplify rbdGetDeviceList()
The `rbdGetDeviceList()` function uses two very similar types for converting krbd and NBD device information from JSON. There is no need to use this distinction, and callers of `rbdGetDeviceList()` should not need to care about it either. By introducing a `deviceInfo` interface with Get-functions, the `rbdGetDeviceList()` function becomes a little simpler, with a clearly defined API for the returned list. Signed-off-by: Niels de Vos <ndevos@ibm.com>
This commit is contained in:
parent
2dab8f2b74
commit
3bf5c0e478
@ -21,7 +21,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -91,25 +90,43 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type deviceInfo interface {
|
||||||
|
GetName() string
|
||||||
|
GetPool() string
|
||||||
|
GetRadosNamespace() string
|
||||||
|
GetDevice() string
|
||||||
|
}
|
||||||
|
|
||||||
// rbdDeviceInfo strongly typed JSON spec for rbd device list output (of type krbd).
|
// rbdDeviceInfo strongly typed JSON spec for rbd device list output (of type krbd).
|
||||||
type rbdDeviceInfo struct {
|
type rbdDeviceInfo struct {
|
||||||
ID string `json:"id"`
|
// Name will only be set for krbd devices (NBD uses Image)
|
||||||
|
Name string `json:"name"`
|
||||||
|
// Image will only be set for NBD devices (krbd uses Name)
|
||||||
|
Image string `json:"image"`
|
||||||
|
|
||||||
Pool string `json:"pool"`
|
Pool string `json:"pool"`
|
||||||
RadosNamespace string `json:"namespace"`
|
RadosNamespace string `json:"namespace"`
|
||||||
Name string `json:"name"`
|
|
||||||
Device string `json:"device"`
|
Device string `json:"device"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// nbdDeviceInfo strongly typed JSON spec for rbd-nbd device list output (of type nbd)
|
func (rdi *rbdDeviceInfo) GetName() string {
|
||||||
// NOTE: There is a bug in rbd output that returns id as number for nbd, and string for krbd, thus
|
if rdi.Name != "" {
|
||||||
// requiring 2 different JSON structures to unmarshal the output.
|
return rdi.Name
|
||||||
// NOTE: image key is "name" in krbd output and "image" in nbd output, which is another difference.
|
}
|
||||||
type nbdDeviceInfo struct {
|
|
||||||
ID int64 `json:"id"`
|
return rdi.Image
|
||||||
Pool string `json:"pool"`
|
}
|
||||||
RadosNamespace string `json:"namespace"`
|
|
||||||
Name string `json:"image"`
|
func (rdi *rbdDeviceInfo) GetPool() string {
|
||||||
Device string `json:"device"`
|
return rdi.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rdi *rbdDeviceInfo) GetRadosNamespace() string {
|
||||||
|
return rdi.RadosNamespace
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rdi *rbdDeviceInfo) GetDevice() string {
|
||||||
|
return rdi.Device
|
||||||
}
|
}
|
||||||
|
|
||||||
type detachRBDImageArgs struct {
|
type detachRBDImageArgs struct {
|
||||||
@ -123,25 +140,17 @@ type detachRBDImageArgs struct {
|
|||||||
logStrategy string
|
logStrategy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// rbdGetDeviceList queries rbd about mapped devices and returns a list of rbdDeviceInfo
|
// getDeviceList queries rbd about mapped devices and returns a list of deviceInfo
|
||||||
// It will selectively list devices mapped using krbd or nbd as specified by accessType.
|
// It will selectively list devices mapped using krbd or nbd as specified by accessType.
|
||||||
func rbdGetDeviceList(ctx context.Context, accessType string) ([]rbdDeviceInfo, error) {
|
func getDeviceList(ctx context.Context, accessType string) ([]deviceInfo, error) {
|
||||||
// rbd device list --format json --device-type [krbd|nbd]
|
// rbd device list --format json --device-type [krbd|nbd]
|
||||||
var (
|
|
||||||
rbdDeviceList []rbdDeviceInfo
|
|
||||||
nbdDeviceList []nbdDeviceInfo
|
|
||||||
)
|
|
||||||
|
|
||||||
stdout, _, err := util.ExecCommand(ctx, rbd, "device", "list", "--format="+"json", "--device-type", accessType)
|
stdout, _, err := util.ExecCommand(ctx, rbd, "device", "list", "--format="+"json", "--device-type", accessType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error getting device list from rbd for devices of type (%s): %w", accessType, err)
|
return nil, fmt.Errorf("error getting device list from rbd for devices of type (%s): %w", accessType, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if accessType == accessTypeKRbd {
|
var devices []*rbdDeviceInfo
|
||||||
err = json.Unmarshal([]byte(stdout), &rbdDeviceList)
|
err = json.Unmarshal([]byte(stdout), &devices)
|
||||||
} else {
|
|
||||||
err = json.Unmarshal([]byte(stdout), &nbdDeviceList)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf(
|
return nil, fmt.Errorf(
|
||||||
"error to parse JSON output of device list for devices of type (%s): %w",
|
"error to parse JSON output of device list for devices of type (%s): %w",
|
||||||
@ -149,22 +158,13 @@ func rbdGetDeviceList(ctx context.Context, accessType string) ([]rbdDeviceInfo,
|
|||||||
err)
|
err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert output to a rbdDeviceInfo list for consumers
|
// convert []rbdDeviceInfo to []deviceInfo
|
||||||
if accessType == accessTypeNbd {
|
deviceList := make([]deviceInfo, len(devices))
|
||||||
for _, device := range nbdDeviceList {
|
for i := range devices {
|
||||||
rbdDeviceList = append(
|
deviceList[i] = devices[i]
|
||||||
rbdDeviceList,
|
|
||||||
rbdDeviceInfo{
|
|
||||||
ID: strconv.FormatInt(device.ID, 10),
|
|
||||||
Pool: device.Pool,
|
|
||||||
RadosNamespace: device.RadosNamespace,
|
|
||||||
Name: device.Name,
|
|
||||||
Device: device.Device,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rbdDeviceList, nil
|
return deviceList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// findDeviceMappingImage finds a devicePath, if available, based on image spec (pool/{namespace/}image) on the node.
|
// findDeviceMappingImage finds a devicePath, if available, based on image spec (pool/{namespace/}image) on the node.
|
||||||
@ -179,16 +179,16 @@ func findDeviceMappingImage(ctx context.Context, pool, namespace, image string,
|
|||||||
imageSpec = fmt.Sprintf("%s/%s/%s", pool, namespace, image)
|
imageSpec = fmt.Sprintf("%s/%s/%s", pool, namespace, image)
|
||||||
}
|
}
|
||||||
|
|
||||||
rbdDeviceList, err := rbdGetDeviceList(ctx, accessType)
|
deviceList, err := getDeviceList(ctx, accessType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WarningLog(ctx, "failed to determine if image (%s) is mapped to a device (%v)", imageSpec, err)
|
log.WarningLog(ctx, "failed to determine if image (%s) is mapped to a device (%v)", imageSpec, err)
|
||||||
|
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, device := range rbdDeviceList {
|
for _, device := range deviceList {
|
||||||
if device.Name == image && device.Pool == pool && device.RadosNamespace == namespace {
|
if device.GetName() == image && device.GetPool() == pool && device.GetRadosNamespace() == namespace {
|
||||||
return device.Device, true
|
return device.GetDevice(), true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user