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"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"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).
|
||||
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"`
|
||||
RadosNamespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
Device string `json:"device"`
|
||||
}
|
||||
|
||||
// nbdDeviceInfo strongly typed JSON spec for rbd-nbd device list output (of type nbd)
|
||||
// NOTE: There is a bug in rbd output that returns id as number for nbd, and string for krbd, thus
|
||||
// requiring 2 different JSON structures to unmarshal the output.
|
||||
// NOTE: image key is "name" in krbd output and "image" in nbd output, which is another difference.
|
||||
type nbdDeviceInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
Pool string `json:"pool"`
|
||||
RadosNamespace string `json:"namespace"`
|
||||
Name string `json:"image"`
|
||||
Device string `json:"device"`
|
||||
func (rdi *rbdDeviceInfo) GetName() string {
|
||||
if rdi.Name != "" {
|
||||
return rdi.Name
|
||||
}
|
||||
|
||||
return rdi.Image
|
||||
}
|
||||
|
||||
func (rdi *rbdDeviceInfo) GetPool() string {
|
||||
return rdi.Pool
|
||||
}
|
||||
|
||||
func (rdi *rbdDeviceInfo) GetRadosNamespace() string {
|
||||
return rdi.RadosNamespace
|
||||
}
|
||||
|
||||
func (rdi *rbdDeviceInfo) GetDevice() string {
|
||||
return rdi.Device
|
||||
}
|
||||
|
||||
type detachRBDImageArgs struct {
|
||||
@ -123,25 +140,17 @@ type detachRBDImageArgs struct {
|
||||
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.
|
||||
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]
|
||||
var (
|
||||
rbdDeviceList []rbdDeviceInfo
|
||||
nbdDeviceList []nbdDeviceInfo
|
||||
)
|
||||
|
||||
stdout, _, err := util.ExecCommand(ctx, rbd, "device", "list", "--format="+"json", "--device-type", accessType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting device list from rbd for devices of type (%s): %w", accessType, err)
|
||||
}
|
||||
|
||||
if accessType == accessTypeKRbd {
|
||||
err = json.Unmarshal([]byte(stdout), &rbdDeviceList)
|
||||
} else {
|
||||
err = json.Unmarshal([]byte(stdout), &nbdDeviceList)
|
||||
}
|
||||
var devices []*rbdDeviceInfo
|
||||
err = json.Unmarshal([]byte(stdout), &devices)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"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)
|
||||
}
|
||||
|
||||
// convert output to a rbdDeviceInfo list for consumers
|
||||
if accessType == accessTypeNbd {
|
||||
for _, device := range nbdDeviceList {
|
||||
rbdDeviceList = append(
|
||||
rbdDeviceList,
|
||||
rbdDeviceInfo{
|
||||
ID: strconv.FormatInt(device.ID, 10),
|
||||
Pool: device.Pool,
|
||||
RadosNamespace: device.RadosNamespace,
|
||||
Name: device.Name,
|
||||
Device: device.Device,
|
||||
})
|
||||
}
|
||||
// convert []rbdDeviceInfo to []deviceInfo
|
||||
deviceList := make([]deviceInfo, len(devices))
|
||||
for i := range devices {
|
||||
deviceList[i] = devices[i]
|
||||
}
|
||||
|
||||
return rbdDeviceList, nil
|
||||
return deviceList, nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
rbdDeviceList, err := rbdGetDeviceList(ctx, accessType)
|
||||
deviceList, err := getDeviceList(ctx, accessType)
|
||||
if err != nil {
|
||||
log.WarningLog(ctx, "failed to determine if image (%s) is mapped to a device (%v)", imageSpec, err)
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
for _, device := range rbdDeviceList {
|
||||
if device.Name == image && device.Pool == pool && device.RadosNamespace == namespace {
|
||||
return device.Device, true
|
||||
for _, device := range deviceList {
|
||||
if device.GetName() == image && device.GetPool() == pool && device.GetRadosNamespace() == namespace {
|
||||
return device.GetDevice(), true
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user