diff --git a/pkg/daemon/ceph/osd/daemon.go b/pkg/daemon/ceph/osd/daemon.go index 8bf087203..99a85b744 100644 --- a/pkg/daemon/ceph/osd/daemon.go +++ b/pkg/daemon/ceph/osd/daemon.go @@ -531,19 +531,7 @@ func getAvailableDevices(context *clusterd.Context, agent *OsdAgent) (*DeviceOsd if matched { matchedDevice = desiredDevice - if matchedDevice.DeviceClass == "" { - classNotSet := true - if agent.pvcBacked { - crushDeviceClass := os.Getenv(oposd.CrushDeviceClassVarName) - if crushDeviceClass != "" { - matchedDevice.DeviceClass = crushDeviceClass - classNotSet = false - } - } - if classNotSet { - matchedDevice.DeviceClass = sys.GetDiskDeviceClass(device) - } - } + matchedDevice.UpdateDeviceClass(agent, device) break } } diff --git a/pkg/daemon/ceph/osd/device.go b/pkg/daemon/ceph/osd/device.go index 152666502..3c4676762 100644 --- a/pkg/daemon/ceph/osd/device.go +++ b/pkg/daemon/ceph/osd/device.go @@ -18,7 +18,9 @@ package osd import ( "encoding/json" + "os" + oposd "github.com/rook/rook/pkg/operator/ceph/cluster/osd" "github.com/rook/rook/pkg/util/sys" ) @@ -67,3 +69,29 @@ func (m *DeviceOsdMapping) String() string { b, _ := json.Marshal(m) return string(b) } + +func (d *DesiredDevice) UpdateDeviceClass(agent *OsdAgent, device *sys.LocalDisk) { + // Rook sets the storage class of a device with the following priority. + // + // 1. the device-level configuration + // 2. the global or node-local configuration + // 3. the default value estimated from sysfs. + if d.DeviceClass != "" { + return + } + + if agent.pvcBacked { + crushDeviceClass := os.Getenv(oposd.CrushDeviceClassVarName) + if crushDeviceClass != "" { + d.DeviceClass = crushDeviceClass + return + } + } else { + if agent.storeConfig.DeviceClass != "" { + d.DeviceClass = agent.storeConfig.DeviceClass + return + } + } + + d.DeviceClass = sys.GetDiskDeviceClass(device) +} diff --git a/pkg/daemon/ceph/osd/device_test.go b/pkg/daemon/ceph/osd/device_test.go index 312d7245e..bf445904d 100644 --- a/pkg/daemon/ceph/osd/device_test.go +++ b/pkg/daemon/ceph/osd/device_test.go @@ -23,7 +23,9 @@ import ( "github.com/rook/rook/pkg/clusterd" "github.com/rook/rook/pkg/daemon/ceph/client" + "github.com/rook/rook/pkg/operator/ceph/cluster/osd" exectest "github.com/rook/rook/pkg/util/exec/test" + "github.com/rook/rook/pkg/util/sys" "github.com/stretchr/testify/assert" ) @@ -47,3 +49,36 @@ func TestOSDBootstrap(t *testing.T) { assert.NotEqual(t, -1, strings.Index(string(contents), "key = mysecurekey")) assert.NotEqual(t, -1, strings.Index(string(contents), "caps mon = \"allow profile bootstrap-osd\"")) } + +func TestUpdateDeviceClass(t *testing.T) { + d := &DesiredDevice{} + agent := &OsdAgent{} + disk := &sys.LocalDisk{} + + d.DeviceClass = "test" + d.UpdateDeviceClass(agent, disk) + assert.Equal(t, "test", d.DeviceClass) + + d.DeviceClass = "" + agent.pvcBacked = true + t.Setenv(osd.CrushDeviceClassVarName, "test") + d.UpdateDeviceClass(agent, disk) + assert.Equal(t, "test", d.DeviceClass) + + d.DeviceClass = "" + t.Setenv(osd.CrushDeviceClassVarName, "") + d.UpdateDeviceClass(agent, disk) + t.Log(d) + t.Log(disk) + assert.Equal(t, "ssd", d.DeviceClass) + + d.DeviceClass = "" + agent.pvcBacked = false + d.UpdateDeviceClass(agent, disk) + assert.Equal(t, "ssd", d.DeviceClass) + + d.DeviceClass = "" + agent.storeConfig.DeviceClass = "test" + d.UpdateDeviceClass(agent, disk) + assert.Equal(t, "test", d.DeviceClass) +} diff --git a/pkg/util/sys/device_test.go b/pkg/util/sys/device_test.go index 10342f857..01023c0ff 100644 --- a/pkg/util/sys/device_test.go +++ b/pkg/util/sys/device_test.go @@ -196,3 +196,13 @@ func TestListDevicesChildListDevicesChild(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 3, len(child)) } + +func TestGetDiskDeviceClass(t *testing.T) { + d := &LocalDisk{} + assert.Equal(t, "ssd", GetDiskDeviceClass(d)) + d.Rotational = true + assert.Equal(t, "hdd", GetDiskDeviceClass(d)) + d.Rotational = false + d.RealPath = "nvme" + assert.Equal(t, "nvme", GetDiskDeviceClass(d)) +}