From 496c63830635288e7672e2dc126b934c58399d60 Mon Sep 17 00:00:00 2001 From: Michael Vollman Date: Mon, 26 Aug 2019 09:56:25 -0400 Subject: [PATCH 1/2] ceph: add db-devices flag and fix DatabaseSizeMB Adding support for the db-devices flag for ceph versions 14.2.1 and newer. This flag will allow for explictly setting the db device for bluestore configurations to the device specified as metadataDevice. Fixing the databaseSizeMB config parameter to ensure it is used to set the size of the db-device partition when specified at either the global or individual device level. (#3652) Signed-off-by: Michael Vollman --- cmd/rook/ceph/osd.go | 15 ++-- cmd/rook/ceph/osd_test.go | 6 +- pkg/daemon/ceph/osd/device.go | 1 + pkg/daemon/ceph/osd/volume.go | 79 +++++++++++++++------- pkg/daemon/ceph/osd/volume_test.go | 5 ++ pkg/operator/ceph/cluster/osd/spec.go | 9 +++ pkg/operator/ceph/cluster/osd/spec_test.go | 2 +- 7 files changed, 87 insertions(+), 30 deletions(-) diff --git a/cmd/rook/ceph/osd.go b/cmd/rook/ceph/osd.go index 9795d9ce6..e5fade095 100644 --- a/cmd/rook/ceph/osd.go +++ b/cmd/rook/ceph/osd.go @@ -275,9 +275,9 @@ func commonOSDInit(cmd *cobra.Command) { // Parse the devices, which are comma separated. A colon indicates a non-default number of osds per device // or a non collocated metadata device. // For example, one osd will be created on each of sda and sdb, with 5 osds on the nvme01 device. -// sda:1,sdb:1,nvme01:5 +// sda:1::,sdb:1::,nvme01:5:: // For example, 3 osds will use sdb SSD for db and 3 osds will use sdc SSD for db. -// sdd:1:sdb,sde:1:sdb,sdf:1:sdb,sdg:1:sdc,sdh:1:sdc,sdi:1:sdc +// sdd:1::sdb,sde:1::sdb,sdf:1::sdb,sdg:1::sdc,sdh:1::sdc,sdi:1::sdc func parseDevices(devices string) ([]osddaemon.DesiredDevice, error) { var result []osddaemon.DesiredDevice parsed := strings.Split(devices, ",") @@ -294,8 +294,15 @@ func parseDevices(devices string) ([]osddaemon.DesiredDevice, error) { } d.OSDsPerDevice = count } - if len(parts) > 2 { - d.MetadataDevice = parts[2] + if len(parts) > 2 && parts[2] != "" { + size, err := strconv.Atoi(parts[2]) + if err != nil { + return nil, fmt.Errorf("error DatabaseSizeMB (%s) to int. %+v", parts[2], err) + } + d.DatabaseSizeMB = size + } + if len(parts) > 3 { + d.MetadataDevice = parts[3] } result = append(result, d) } diff --git a/cmd/rook/ceph/osd_test.go b/cmd/rook/ceph/osd_test.go index 3188a1748..28ba634e6 100644 --- a/cmd/rook/ceph/osd_test.go +++ b/cmd/rook/ceph/osd_test.go @@ -50,7 +50,7 @@ func TestParseDesiredDevices(t *testing.T) { assert.NotNil(t, err) // metadataDevice and OSDsPerDevice - devices = "sdd:1:sdb,sde:1:sdb,sdf:1:sdc,sdg:1:sdc" + devices = "sdd:1:2048:sdb,sde:1::sdb,sdf:1::sdc,sdg:1::sdc" result, err = parseDevices(devices) assert.Equal(t, "sdd", result[0].Name) assert.Equal(t, "sde", result[1].Name) @@ -60,6 +60,10 @@ func TestParseDesiredDevices(t *testing.T) { assert.Equal(t, 1, result[1].OSDsPerDevice) assert.Equal(t, 1, result[2].OSDsPerDevice) assert.Equal(t, 1, result[3].OSDsPerDevice) + assert.Equal(t, 2048, result[0].DatabaseSizeMB) + assert.Equal(t, 0, result[1].DatabaseSizeMB) + assert.Equal(t, 0, result[2].DatabaseSizeMB) + assert.Equal(t, 0, result[3].DatabaseSizeMB) assert.Equal(t, "sdb", result[0].MetadataDevice) assert.Equal(t, "sdb", result[1].MetadataDevice) assert.Equal(t, "sdc", result[2].MetadataDevice) diff --git a/pkg/daemon/ceph/osd/device.go b/pkg/daemon/ceph/osd/device.go index 9eda86b72..5e3740300 100644 --- a/pkg/daemon/ceph/osd/device.go +++ b/pkg/daemon/ceph/osd/device.go @@ -76,6 +76,7 @@ type DesiredDevice struct { Name string OSDsPerDevice int MetadataDevice string + DatabaseSizeMB int IsFilter bool } diff --git a/pkg/daemon/ceph/osd/volume.go b/pkg/daemon/ceph/osd/volume.go index b84491a75..3d3f427f8 100644 --- a/pkg/daemon/ceph/osd/volume.go +++ b/pkg/daemon/ceph/osd/volume.go @@ -29,6 +29,7 @@ import ( "github.com/rook/rook/pkg/clusterd" oposd "github.com/rook/rook/pkg/operator/ceph/cluster/osd" "github.com/rook/rook/pkg/operator/ceph/cluster/osd/config" + cephver "github.com/rook/rook/pkg/operator/ceph/version" "github.com/rook/rook/pkg/util/display" "github.com/rook/rook/pkg/util/exec" "github.com/rook/rook/pkg/util/sys" @@ -40,6 +41,7 @@ const ( osdsPerDeviceFlag = "--osds-per-device" encryptedFlag = "--dmcrypt" databaseSizeFlag = "--block-db-size" + dbDeviceFlag = "--db-devices" cephVolumeCmd = "ceph-volume" cephVolumeMinDBSize = 1024 // 1GB lvmConfPath = "/etc/lvm/lvm.conf" @@ -167,20 +169,7 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO osdsPerDeviceCount := sanitizeOSDsPerDevice(a.storeConfig.OSDsPerDevice) batchArgs := baseArgs - if a.storeConfig.StoreType == config.Bluestore && a.storeConfig.DatabaseSizeMB > 0 { - if a.storeConfig.DatabaseSizeMB < cephVolumeMinDBSize { - // ceph-volume will convert this value to ?G. It needs to be > 1G to invoke lvcreate. - logger.Infof("skipping databaseSizeMB setting. For it should be larger than %dMB.", cephVolumeMinDBSize) - } else { - batchArgs = append(batchArgs, []string{ - databaseSizeFlag, - // ceph-volume takes in this value in bytes - strconv.FormatUint(display.MbTob(uint64(a.storeConfig.DatabaseSizeMB)), 10), - }...) - } - } - - metadataDevices := make(map[string][]string) + metadataDevices := make(map[string]map[string]string) for name, device := range devices.Entries { if device.LegacyPartitionsFound { logger.Infof("skipping device %s configured with legacy rook osd", name) @@ -203,18 +192,33 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO } logger.Infof("using %s as metadataDevice for device %s and let ceph-volume lvm batch decide how to create volumes", md, deviceArg) if _, ok := metadataDevices[md]; ok { - metadataDevices[md] = append(metadataDevices[md], deviceArg) // Fail when two devices using the same metadata device have different values for osdsPerDevice - if deviceOSDCount != metadataDevices[md][1] { - return fmt.Errorf("metadataDevice (%s) has more than 1 osdsPerDevice value set: %s != %s", md, deviceOSDCount, metadataDevices[md][1]) + metadataDevices[md]["devices"] += " " + deviceArg + if deviceOSDCount != metadataDevices[md]["osdsperdevice"] { + return fmt.Errorf("metadataDevice (%s) has more than 1 osdsPerDevice value set: %s != %s", md, deviceOSDCount, metadataDevices[md]["osdsperdevice"]) } } else { - metadataDevices[md] = []string{ - osdsPerDeviceFlag, - deviceOSDCount, - deviceArg, + metadataDevices[md] = make(map[string]string) + metadataDevices[md]["osdsperdevice"] = deviceOSDCount + metadataDevices[md]["devices"] = deviceArg + } + deviceDBSizeMB := getDatabaseSize(a.storeConfig.DatabaseSizeMB, device.Config.DatabaseSizeMB) + if storeFlag == "--bluestore" && deviceDBSizeMB > 0 { + if deviceDBSizeMB < cephVolumeMinDBSize { + // ceph-volume will convert this value to ?G. It needs to be > 1G to invoke lvcreate. + logger.Infof("skipping databaseSizeMB setting (%d). For it should be larger than %dMB.", deviceDBSizeMB, cephVolumeMinDBSize) + } else { + dbSizeString := strconv.FormatUint(display.MbTob(uint64(deviceDBSizeMB)), 10) + if _, ok := metadataDevices[md]["databasesizemb"]; ok { + if metadataDevices[md]["databasesizemb"] != dbSizeString { + return fmt.Errorf("metadataDevice (%s) has more than 1 databaseSizeMB value set: %s != %s", md, metadataDevices[md]["databasesizemb"], dbSizeString) + } + } else { + metadataDevices[md]["databasesizemb"] = dbSizeString + } } } + } else { immediateExecuteArgs := append(baseArgs, []string{ osdsPerDeviceFlag, @@ -245,10 +249,30 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO } } - for md, devs := range metadataDevices { + for md, conf := range metadataDevices { - mdArgs := append(batchArgs, devs...) - mdArgs = append(mdArgs, path.Join("/dev", md)) + if _, ok := conf["osdsperdevice"]; ok { + batchArgs = append(batchArgs, []string{ + osdsPerDeviceFlag, + conf["osdsperdevice"], + }...) + } + if _, ok := conf["databasesizemb"]; ok { + batchArgs = append(batchArgs, []string{ + databaseSizeFlag, + conf["databasesizemb"], + }...) + } + mdArgs := append(batchArgs, strings.Split(conf["devices"], " ")...) + + if a.cluster.CephVersion.IsAtLeast(cephver.CephVersion{Major: 14, Minor: 2, Extra: 1}) { + mdArgs = append(mdArgs, []string{ + dbDeviceFlag, + path.Join("/dev", md), + }...) + } else { + mdArgs = append(mdArgs, path.Join("/dev", md)) + } // Reporting reportArgs := append(mdArgs, []string{ @@ -289,6 +313,13 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO return nil } +func getDatabaseSize(globalSize int, deviceSize int) int { + if deviceSize > 0 { + globalSize = deviceSize + } + return globalSize +} + func sanitizeOSDsPerDevice(count int) string { if count < 1 { count = 1 diff --git a/pkg/daemon/ceph/osd/volume_test.go b/pkg/daemon/ceph/osd/volume_test.go index 5de99401e..ac08a2041 100644 --- a/pkg/daemon/ceph/osd/volume_test.go +++ b/pkg/daemon/ceph/osd/volume_test.go @@ -306,3 +306,8 @@ func TestSanitizeOSDsPerDevice(t *testing.T) { assert.Equal(t, "1", sanitizeOSDsPerDevice(1)) assert.Equal(t, "2", sanitizeOSDsPerDevice(2)) } + +func TestGetDatabaseSize(t *testing.T) { + assert.Equal(t, 0, getDatabaseSize(0, 0)) + assert.Equal(t, 2048, getDatabaseSize(4096, 2048)) +} diff --git a/pkg/operator/ceph/cluster/osd/spec.go b/pkg/operator/ceph/cluster/osd/spec.go index 689a5d22e..df06c8795 100644 --- a/pkg/operator/ceph/cluster/osd/spec.go +++ b/pkg/operator/ceph/cluster/osd/spec.go @@ -553,9 +553,17 @@ func (c *Cluster) provisionOSDContainer(osdProps osdProperties, copyBinariesMoun } else { devSuffix += ":1" } + if databaseSizeMB, ok := device.Config[config.DatabaseSizeMBKey]; ok { + logger.Infof("osd %s requested with DB size %sMB (node %s)", device.Name, databaseSizeMB, osdProps.crushHostname) + devSuffix += ":" + databaseSizeMB + } else { + devSuffix += ":" + } if md, ok := device.Config[config.MetadataDeviceKey]; ok { logger.Infof("osd %s requested with metadataDevice %s (node %s)", device.Name, md, osdProps.crushHostname) devSuffix += ":" + md + } else { + devSuffix += ":" } deviceNames[i] = device.Name + devSuffix } @@ -568,6 +576,7 @@ func (c *Cluster) provisionOSDContainer(osdProps osdProperties, copyBinariesMoun envVars = append(envVars, deviceFilterEnvVar("all")) devMountNeeded = true } + envVars = append(envVars, v1.EnvVar{Name: "ROOK_CEPH_VERSION", Value: c.clusterInfo.CephVersion.CephVersionFormatted()}) if osdProps.metadataDevice != "" { envVars = append(envVars, metadataDeviceEnvVar(osdProps.metadataDevice)) diff --git a/pkg/operator/ceph/cluster/osd/spec_test.go b/pkg/operator/ceph/cluster/osd/spec_test.go index 87ce377ef..5f6f085bf 100644 --- a/pkg/operator/ceph/cluster/osd/spec_test.go +++ b/pkg/operator/ceph/cluster/osd/spec_test.go @@ -38,7 +38,7 @@ import ( ) func TestPodContainer(t *testing.T) { - cluster := &Cluster{Namespace: "myosd", rookVersion: "23", cephVersion: cephv1.CephVersionSpec{}} + cluster := &Cluster{Namespace: "myosd", rookVersion: "23", cephVersion: cephv1.CephVersionSpec{}, clusterInfo: &cephconfig.ClusterInfo{}} osdProps := osdProperties{ crushHostname: "node", devices: []rookalpha.Device{}, From ed9519953a205160671e772836f40dbcadb73367 Mon Sep 17 00:00:00 2001 From: Michael Vollman Date: Wed, 7 Aug 2019 11:17:16 -0400 Subject: [PATCH 2/2] ceph: add per OSD custom deviceClass support Add deviceClass as a per OSD config option under storage/nodes/devices/config for setting a custom crush device class per OSD. Signed-off-by: Michael Vollman --- PendingReleaseNotes.md | 2 + cmd/rook/ceph/osd.go | 11 +++-- cmd/rook/ceph/osd_test.go | 8 +++- pkg/daemon/ceph/osd/device.go | 1 + pkg/daemon/ceph/osd/volume.go | 41 ++++++++++++++----- .../ceph/cluster/osd/config/config.go | 4 ++ pkg/operator/ceph/cluster/osd/spec.go | 6 +++ 7 files changed, 56 insertions(+), 17 deletions(-) diff --git a/PendingReleaseNotes.md b/PendingReleaseNotes.md index 11a0c72f3..442100324 100644 --- a/PendingReleaseNotes.md +++ b/PendingReleaseNotes.md @@ -14,6 +14,8 @@ an example usage - Allow `metadataDevice` to be set per OSD device in the device specific `config` section. - [YugabyteDB](https://www.yugabyte.com/) is now supported by Rook with a new operator. You can deploy, configure and manage instances of this high-performance distributed SQL database. Create an instance of the new `ybcluster.yugabytedb.rook.io` custom resource to easily deploy a cluster of YugabyteDB Database. Checkout its [user guide](Documentation/yugabytedb.md) to get started with YugabyteDB. - Git tags can be added for alpha, beta, or rc releases. For example: v1.1.0-alpha.0 +- Added `deviceClass` to the per OSD device specific `config` section for setting custom crush device class per OSD. +- Use `--db-devices` with Ceph 14.2.1 and newer clusters to explicitly set `metadataDevice` per OSD. ### Ceph diff --git a/cmd/rook/ceph/osd.go b/cmd/rook/ceph/osd.go index e5fade095..3bd132950 100644 --- a/cmd/rook/ceph/osd.go +++ b/cmd/rook/ceph/osd.go @@ -275,9 +275,9 @@ func commonOSDInit(cmd *cobra.Command) { // Parse the devices, which are comma separated. A colon indicates a non-default number of osds per device // or a non collocated metadata device. // For example, one osd will be created on each of sda and sdb, with 5 osds on the nvme01 device. -// sda:1::,sdb:1::,nvme01:5:: +// sda:1:::,sdb:1:::,nvme01:5::: // For example, 3 osds will use sdb SSD for db and 3 osds will use sdc SSD for db. -// sdd:1::sdb,sde:1::sdb,sdf:1::sdb,sdg:1::sdc,sdh:1::sdc,sdi:1::sdc +// sdd:1:::sdb,sde:1:::sdb,sdf:1:::sdb,sdg:1:::sdc,sdh:1:::sdc,sdi:1:::sdc func parseDevices(devices string) ([]osddaemon.DesiredDevice, error) { var result []osddaemon.DesiredDevice parsed := strings.Split(devices, ",") @@ -301,8 +301,11 @@ func parseDevices(devices string) ([]osddaemon.DesiredDevice, error) { } d.DatabaseSizeMB = size } - if len(parts) > 3 { - d.MetadataDevice = parts[3] + if len(parts) > 3 && parts[3] != "" { + d.DeviceClass = parts[3] + } + if len(parts) > 4 { + d.MetadataDevice = parts[4] } result = append(result, d) } diff --git a/cmd/rook/ceph/osd_test.go b/cmd/rook/ceph/osd_test.go index 28ba634e6..16433425c 100644 --- a/cmd/rook/ceph/osd_test.go +++ b/cmd/rook/ceph/osd_test.go @@ -49,8 +49,8 @@ func TestParseDesiredDevices(t *testing.T) { assert.Nil(t, result) assert.NotNil(t, err) - // metadataDevice and OSDsPerDevice - devices = "sdd:1:2048:sdb,sde:1::sdb,sdf:1::sdc,sdg:1::sdc" + // OSDsPerDevice, metadataDevice, databaseSizeMB and deviceClass + devices = "sdd:1:2048::sdb,sde:1:::sdb,sdf:1:::sdc,sdg:1::tst:sdc" result, err = parseDevices(devices) assert.Equal(t, "sdd", result[0].Name) assert.Equal(t, "sde", result[1].Name) @@ -64,6 +64,10 @@ func TestParseDesiredDevices(t *testing.T) { assert.Equal(t, 0, result[1].DatabaseSizeMB) assert.Equal(t, 0, result[2].DatabaseSizeMB) assert.Equal(t, 0, result[3].DatabaseSizeMB) + assert.Equal(t, "", result[0].DeviceClass) + assert.Equal(t, "", result[1].DeviceClass) + assert.Equal(t, "", result[2].DeviceClass) + assert.Equal(t, "tst", result[3].DeviceClass) assert.Equal(t, "sdb", result[0].MetadataDevice) assert.Equal(t, "sdb", result[1].MetadataDevice) assert.Equal(t, "sdc", result[2].MetadataDevice) diff --git a/pkg/daemon/ceph/osd/device.go b/pkg/daemon/ceph/osd/device.go index 5e3740300..7380f9853 100644 --- a/pkg/daemon/ceph/osd/device.go +++ b/pkg/daemon/ceph/osd/device.go @@ -77,6 +77,7 @@ type DesiredDevice struct { OSDsPerDevice int MetadataDevice string DatabaseSizeMB int + DeviceClass string IsFilter bool } diff --git a/pkg/daemon/ceph/osd/volume.go b/pkg/daemon/ceph/osd/volume.go index 3d3f427f8..af6e419e3 100644 --- a/pkg/daemon/ceph/osd/volume.go +++ b/pkg/daemon/ceph/osd/volume.go @@ -38,13 +38,14 @@ import ( var cephConfigDir = "/var/lib/ceph" const ( - osdsPerDeviceFlag = "--osds-per-device" - encryptedFlag = "--dmcrypt" - databaseSizeFlag = "--block-db-size" - dbDeviceFlag = "--db-devices" - cephVolumeCmd = "ceph-volume" - cephVolumeMinDBSize = 1024 // 1GB - lvmConfPath = "/etc/lvm/lvm.conf" + osdsPerDeviceFlag = "--osds-per-device" + crushDeviceClassFlag = "--crush-device-class" + encryptedFlag = "--dmcrypt" + databaseSizeFlag = "--block-db-size" + dbDeviceFlag = "--db-devices" + cephVolumeCmd = "ceph-volume" + cephVolumeMinDBSize = 1024 // 1GB + lvmConfPath = "/etc/lvm/lvm.conf" ) func (a *OsdAgent) configureCVDevices(context *clusterd.Context, devices *DeviceOsdMapping) ([]oposd.OSDInfo, error) { @@ -179,10 +180,12 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO if device.Data == -1 { logger.Infof("configuring new device %s", name) deviceArg := path.Join("/dev", name) + deviceOSDCount := osdsPerDeviceCount if device.Config.OSDsPerDevice > 1 { deviceOSDCount = sanitizeOSDsPerDevice(device.Config.OSDsPerDevice) } + if a.metadataDevice != "" || device.Config.MetadataDevice != "" { // When mixed hdd/ssd devices are given, ceph-volume configures db lv on the ssd. // the device will be configured as a batch at the end of the method @@ -200,6 +203,9 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO } else { metadataDevices[md] = make(map[string]string) metadataDevices[md]["osdsperdevice"] = deviceOSDCount + if device.Config.DeviceClass != "" { + metadataDevices[md]["deviceclass"] = device.Config.DeviceClass + } metadataDevices[md]["devices"] = deviceArg } deviceDBSizeMB := getDatabaseSize(a.storeConfig.DatabaseSizeMB, device.Config.DatabaseSizeMB) @@ -218,7 +224,6 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO } } } - } else { immediateExecuteArgs := append(baseArgs, []string{ osdsPerDeviceFlag, @@ -226,6 +231,13 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO deviceArg, }...) + if device.Config.DeviceClass != "" { + immediateExecuteArgs = append(immediateExecuteArgs, []string{ + crushDeviceClassFlag, + device.Config.DeviceClass, + }...) + } + // Reporting immediateReportArgs := append(immediateExecuteArgs, []string{ "--report", @@ -251,19 +263,26 @@ func (a *OsdAgent) initializeDevices(context *clusterd.Context, devices *DeviceO for md, conf := range metadataDevices { + mdArgs := batchArgs if _, ok := conf["osdsperdevice"]; ok { - batchArgs = append(batchArgs, []string{ + mdArgs = append(mdArgs, []string{ osdsPerDeviceFlag, conf["osdsperdevice"], }...) } + if _, ok := conf["deviceclass"]; ok { + mdArgs = append(mdArgs, []string{ + crushDeviceClassFlag, + conf["deviceclass"], + }...) + } if _, ok := conf["databasesizemb"]; ok { - batchArgs = append(batchArgs, []string{ + mdArgs = append(mdArgs, []string{ databaseSizeFlag, conf["databasesizemb"], }...) } - mdArgs := append(batchArgs, strings.Split(conf["devices"], " ")...) + mdArgs = append(mdArgs, strings.Split(conf["devices"], " ")...) if a.cluster.CephVersion.IsAtLeast(cephver.CephVersion{Major: 14, Minor: 2, Extra: 1}) { mdArgs = append(mdArgs, []string{ diff --git a/pkg/operator/ceph/cluster/osd/config/config.go b/pkg/operator/ceph/cluster/osd/config/config.go index 5495a8360..47c1e20b3 100644 --- a/pkg/operator/ceph/cluster/osd/config/config.go +++ b/pkg/operator/ceph/cluster/osd/config/config.go @@ -44,6 +44,7 @@ const ( OSDsPerDeviceKey = "osdsPerDevice" EncryptedDeviceKey = "encryptedDevice" MetadataDeviceKey = "metadataDevice" + DeviceClassKey = "deviceClass" ) type StoreConfig struct { @@ -53,6 +54,7 @@ type StoreConfig struct { JournalSizeMB int `json:"journalSizeMB,omitempty"` OSDsPerDevice int `json:"osdsPerDevice,omitempty"` EncryptedDevice bool `json:"encryptedDevice,omitempty"` + DeviceClass string `json:"deviceClass,omitempty"` } func ToStoreConfig(config map[string]string) StoreConfig { @@ -71,6 +73,8 @@ func ToStoreConfig(config map[string]string) StoreConfig { storeConfig.OSDsPerDevice = convertToIntIgnoreErr(v) case EncryptedDeviceKey: storeConfig.EncryptedDevice = (v == "true") + case DeviceClassKey: + storeConfig.DeviceClass = v } } diff --git a/pkg/operator/ceph/cluster/osd/spec.go b/pkg/operator/ceph/cluster/osd/spec.go index df06c8795..f1157dc6a 100644 --- a/pkg/operator/ceph/cluster/osd/spec.go +++ b/pkg/operator/ceph/cluster/osd/spec.go @@ -559,6 +559,12 @@ func (c *Cluster) provisionOSDContainer(osdProps osdProperties, copyBinariesMoun } else { devSuffix += ":" } + if deviceClass, ok := device.Config[config.DeviceClassKey]; ok { + logger.Infof("osd %s requested with deviceClass %s (node %s)", device.Name, deviceClass, osdProps.crushHostname) + devSuffix += ":" + deviceClass + } else { + devSuffix += ":" + } if md, ok := device.Config[config.MetadataDeviceKey]; ok { logger.Infof("osd %s requested with metadataDevice %s (node %s)", device.Name, md, osdProps.crushHostname) devSuffix += ":" + md