diff --git a/pkg/operator/ceph/cluster/mon/health.go b/pkg/operator/ceph/cluster/mon/health.go index 4afdfc93a..6727dd62d 100644 --- a/pkg/operator/ceph/cluster/mon/health.go +++ b/pkg/operator/ceph/cluster/mon/health.go @@ -366,9 +366,32 @@ func (c *Cluster) checkHealth(ctx context.Context) error { } } + // failover mons running on host path to use persistent volumes if VolumeClaimTemplate is set and vice versa + for _, mon := range c.ClusterInfo.Monitors { + if c.HasMonPathChanged(mon.Name) { + logger.Infof("fail over mon %q due to change in mon path", mon.Name) + c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon.Name) + return nil + } + } + return nil } +// HasMonPathChanged checks if the mon storage path has changed from host path to persistent volume or vice versa +func (c *Cluster) HasMonPathChanged(mon string) bool { + var monPathChanged bool + if c.mapping.Schedule[mon] != nil && c.spec.Mon.VolumeClaimTemplate != nil { + logger.Infof("mon %q path has changed from host path to persistent volumes", mon) + monPathChanged = true + } else if c.mapping.Schedule[mon] == nil && c.spec.Mon.VolumeClaimTemplate == nil { + logger.Infof("mon %q path has changed from persistent volumes to host path", mon) + monPathChanged = true + } + + return monPathChanged +} + func (c *Cluster) trackMonInOrOutOfQuorum(monName string, inQuorum bool) (bool, error) { updateNeeded := false var monsOutOfQuorum []string diff --git a/pkg/operator/ceph/cluster/mon/health_test.go b/pkg/operator/ceph/cluster/mon/health_test.go index bc0b7297a..bef7fda8d 100644 --- a/pkg/operator/ceph/cluster/mon/health_test.go +++ b/pkg/operator/ceph/cluster/mon/health_test.go @@ -645,3 +645,37 @@ func TestUpdateMonInterval(t *testing.T) { assert.Equal(t, time.Minute, h.interval) }) } + +func TestHasMonPathChanged(t *testing.T) { + t.Run("mon path changed from pv to hostpath", func(t *testing.T) { + c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil) + c.mapping.Schedule["a"] = nil + result := c.HasMonPathChanged("a") + assert.True(t, result) + }) + + t.Run("mon path has not changed from pv to hostpath", func(t *testing.T) { + c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil) + c.spec.Mon.VolumeClaimTemplate = &v1.PersistentVolumeClaim{Spec: v1.PersistentVolumeClaimSpec{}} + c.mapping.Schedule["b"] = nil + result := c.HasMonPathChanged("b") + c.spec.Mon.VolumeClaimTemplate = nil + assert.False(t, result) + }) + + t.Run("mon path changed from hostpath to pv", func(t *testing.T) { + c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil) + c.mapping.Schedule["c"] = &opcontroller.MonScheduleInfo{} + c.spec.Mon.VolumeClaimTemplate = &v1.PersistentVolumeClaim{Spec: v1.PersistentVolumeClaimSpec{}} + result := c.HasMonPathChanged("c") + assert.True(t, result) + }) + + t.Run("mon path has not changed from host path to pv", func(t *testing.T) { + c := New(context.TODO(), &clusterd.Context{}, "ns", cephv1.ClusterSpec{}, nil) + c.mapping.Schedule["d"] = &opcontroller.MonScheduleInfo{} + result := c.HasMonPathChanged("d") + c.spec.Mon.VolumeClaimTemplate = nil + assert.False(t, result) + }) +} diff --git a/pkg/operator/ceph/cluster/mon/mon.go b/pkg/operator/ceph/cluster/mon/mon.go index c08d04e14..1e2201ec0 100644 --- a/pkg/operator/ceph/cluster/mon/mon.go +++ b/pkg/operator/ceph/cluster/mon/mon.go @@ -1229,6 +1229,12 @@ func (c *Cluster) commitMaxMonIDRequireIncrementing(desiredMaxMonID int, require var updateDeploymentAndWait = UpdateCephDeploymentAndWait func (c *Cluster) updateMon(m *monConfig, d *apps.Deployment) error { + + if c.HasMonPathChanged(m.DaemonName) { + logger.Infof("path has changed for mon %q. Skip updating mon deployment %q in order to failover the mon", m.DaemonName, d.Name) + return nil + } + // Expand mon PVC if storage request for mon has increased in cephcluster crd if c.monVolumeClaimTemplate(m) != nil { desiredPvc, err := c.makeDeploymentPVC(m, false)