Skip to content

Commit d9ae3a3

Browse files
committed
fix: allow deleting orphans while retaining the data
check for DeleteCustomResourceOnly label in orphan if label is set to true, skip data cleaning ref#11286 Signed-off-by: Nina Zhan <[email protected]>
1 parent eb0bc95 commit d9ae3a3

File tree

4 files changed

+70
-5
lines changed

4 files changed

+70
-5
lines changed

controller/node_controller.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ func (nc *NodeController) syncOrphans(node *longhorn.Node, collectedDataInfo map
13221322
return nil
13231323
}
13241324

1325-
func (nc *NodeController) getNewAndMissingOrphanedReplicaDataStores(diskName, diskUUID, diskPath string, replicaDataStores map[string]string) (map[string]string, map[string]string) {
1325+
func (nc *NodeController) getNewAndMissingOrphanedReplicaDataStores(diskName, diskUUID, diskPath string, orphanedReplicaDataStores map[string]string) (map[string]string, map[string]string) {
13261326
newOrphanedReplicaDataStores := map[string]string{}
13271327
missingOrphanedReplicaDataStores := map[string]string{}
13281328

@@ -1339,13 +1339,19 @@ func (nc *NodeController) getNewAndMissingOrphanedReplicaDataStores(diskName, di
13391339
}
13401340
}
13411341

1342-
for dataStore := range replicaDataStores {
1342+
for dataStore := range orphanedReplicaDataStores {
13431343
orphanName := types.GetOrphanChecksumNameForOrphanedDataStore(nc.controllerID, diskName, diskPath, diskUUID, dataStore)
13441344
if _, ok := orphanMap[orphanName]; !ok {
13451345
newOrphanedReplicaDataStores[dataStore] = ""
13461346
}
13471347
}
13481348

1349+
replicas, err := nc.ds.ListReplicasByDiskUUIDRO(diskUUID)
1350+
if err != nil {
1351+
nc.logger.WithError(err).Warnf("Failed to list replicas for disk %v", diskUUID)
1352+
return map[string]string{}, map[string]string{}
1353+
}
1354+
13491355
for _, orphan := range orphanMap {
13501356
if orphan.Spec.Parameters[longhorn.OrphanDiskName] != diskName ||
13511357
orphan.Spec.Parameters[longhorn.OrphanDiskUUID] != diskUUID ||
@@ -1354,9 +1360,25 @@ func (nc *NodeController) getNewAndMissingOrphanedReplicaDataStores(diskName, di
13541360
}
13551361

13561362
dataStore := orphan.Spec.Parameters[longhorn.OrphanDataName]
1357-
if _, ok := replicaDataStores[dataStore]; !ok {
1363+
reused := false
1364+
for _, r := range replicas {
1365+
if r.Spec.DataDirectoryName == dataStore {
1366+
reused = true
1367+
break
1368+
}
1369+
}
1370+
_, ok := orphanedReplicaDataStores[dataStore]
1371+
1372+
if !ok {
1373+
if reused {
1374+
if err := datastore.AddOrphanDeleteCustomResourceOnlyLabel(nc.ds, orphan.Name); err != nil {
1375+
nc.logger.Infof("failed to add label delete-custom-resource-only to orphan %v ", orphan.Name)
1376+
return map[string]string{}, map[string]string{}
1377+
}
1378+
}
13581379
missingOrphanedReplicaDataStores[dataStore] = ""
13591380
}
1381+
13601382
}
13611383

13621384
return newOrphanedReplicaDataStores, missingOrphanedReplicaDataStores
@@ -1437,7 +1459,12 @@ func (nc *NodeController) canDeleteOrphan(orphan *longhorn.Orphan, autoDeleteEna
14371459

14381460
// When dataCleanableCondition is false, it means the associated node is not ready, missing or evicted (check updateDataCleanableCondition()).
14391461
// In this case, we can delete the orphan directly because the data is not reachable and no need to keep the orphan resource.
1440-
canDelete := autoDeleteAllowed || dataCleanableCondition.Status == longhorn.ConditionStatusFalse
1462+
isReasonNodeOrDisk := (dataCleanableCondition.Reason == longhorn.OrphanConditionTypeDataCleanableReasonNodeUnavailable) ||
1463+
(dataCleanableCondition.Reason == longhorn.OrphanConditionTypeDataCleanableReasonNodeEvicted) ||
1464+
(dataCleanableCondition.Reason == longhorn.OrphanConditionTypeDataCleanableReasonDiskInvalid) ||
1465+
(dataCleanableCondition.Reason == longhorn.OrphanConditionTypeDataCleanableReasonDiskEvicted) ||
1466+
(dataCleanableCondition.Reason == longhorn.OrphanConditionTypeDataCleanableReasonDiskChanged)
1467+
canDelete := autoDeleteAllowed || ((dataCleanableCondition.Status == longhorn.ConditionStatusFalse) && isReasonNodeOrDisk)
14411468
if !canDelete {
14421469
nc.logger.Debugf("Orphan %v is not ready to be deleted, autoDeleteAllowed: %v, dataCleanableCondition: %v", orphan.Name, autoDeleteAllowed, dataCleanableCondition.Status)
14431470
}

controller/orphan_controller.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,6 @@ func (oc *OrphanController) updateDataCleanableCondition(orphan *longhorn.Orphan
622622
if orphan.Spec.Type == longhorn.OrphanTypeReplicaData {
623623
reason = oc.checkOrphanedReplicaDataCleanable(node, orphan)
624624
}
625-
626625
return nil
627626
}
628627

@@ -647,6 +646,11 @@ func (oc *OrphanController) checkOrphanedReplicaDataCleanable(node *longhorn.Nod
647646
return longhorn.OrphanConditionTypeDataCleanableReasonDiskEvicted
648647
}
649648

649+
exists, _ := datastore.IsLabelLonghornDeleteCustomResourceOnlyExisting(orphan)
650+
if exists {
651+
return longhorn.OrphanConditionTypeDataCleanableReasonSkipped
652+
}
653+
650654
return ""
651655
}
652656

datastore/longhorn.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,6 +3213,18 @@ func (s *DataStore) ListReplicasByDiskUUID(uuid string) (map[string]*longhorn.Re
32133213
return s.listReplicas(diskSelector)
32143214
}
32153215

3216+
func (s *DataStore) ListReplicasByDiskUUIDRO(uuid string) ([]*longhorn.Replica, error) {
3217+
diskSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
3218+
MatchLabels: map[string]string{
3219+
types.LonghornDiskUUIDKey: uuid,
3220+
},
3221+
})
3222+
if err != nil {
3223+
return nil, err
3224+
}
3225+
return s.replicaLister.Replicas(s.namespace).List(diskSelector)
3226+
}
3227+
32163228
func getBackingImageSelector(backingImageName, diskUUID string) (labels.Selector, error) {
32173229
matchLabels := map[string]string{
32183230
types.GetLonghornLabelKey(types.LonghornLabelBackingImage): backingImageName,
@@ -3461,6 +3473,27 @@ func AddSystemBackupDeleteCustomResourceOnlyLabel(ds *DataStore, systemBackupNam
34613473
return nil
34623474
}
34633475

3476+
// AddOrphanDeleteCustomResourceOnlyLabel adds the label `longhorn.io/delete-custom-resource-only: true` to the Orphan
3477+
func AddOrphanDeleteCustomResourceOnlyLabel(ds *DataStore, OrphanName string) error {
3478+
orphan, err := ds.GetOrphan(OrphanName)
3479+
if err != nil {
3480+
return err
3481+
}
3482+
if exists, err := IsLabelLonghornDeleteCustomResourceOnlyExisting(orphan); err != nil {
3483+
return err
3484+
} else if exists {
3485+
return nil
3486+
}
3487+
if err := labelLonghornDeleteCustomResourceOnly(orphan); err != nil {
3488+
return err
3489+
}
3490+
if _, err = ds.UpdateOrphan(orphan); err != nil {
3491+
return err
3492+
}
3493+
3494+
return nil
3495+
}
3496+
34643497
func FixupRecurringJob(v *longhorn.Volume) error {
34653498
if err := labelRecurringJobDefault(v); err != nil {
34663499
return err

k8s/pkg/apis/longhorn/v1beta2/orphan.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const (
2020
OrphanConditionTypeDataCleanableReasonDiskInvalid = "DiskInvalid"
2121
OrphanConditionTypeDataCleanableReasonDiskEvicted = "DiskEvicted"
2222
OrphanConditionTypeDataCleanableReasonDiskChanged = "DiskChanged"
23+
OrphanConditionTypeDataCleanableReasonSkipped = "Skipped"
2324
)
2425

2526
const (

0 commit comments

Comments
 (0)