(release) Add explicit incomplete snapshot cleanup
Add a dedicated cleanup path for incomplete snapshots instead of letting retention prune them implicitly. The retention plan now exposes a guarded form that requires host and delete-count confirmation before removing .incomplete snapshot directories and their SQL records. Keep scheduled/manual retention behavior unchanged, add path safety checks, and cover cleanup success, confirmation failures, max-delete limits, and unexpected paths in tests. Refs #10
This commit is contained in:
@@ -274,6 +274,36 @@ class RetentionApplyForm(forms.Form):
|
||||
return value
|
||||
|
||||
|
||||
class IncompleteCleanupForm(forms.Form):
|
||||
max_delete = forms.IntegerField(min_value=0, initial=0)
|
||||
confirm_delete_count = forms.IntegerField(min_value=0)
|
||||
confirm_host = forms.CharField()
|
||||
|
||||
def __init__(self, *args, host_name: str, expected_delete_count: int, **kwargs) -> None:
|
||||
self.host_name = host_name
|
||||
self.expected_delete_count = expected_delete_count
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["confirm_host"].help_text = f"Type {host_name} to confirm incomplete snapshot cleanup."
|
||||
self.fields["confirm_delete_count"].help_text = (
|
||||
f"Type {expected_delete_count} to confirm the current number of incomplete snapshots."
|
||||
)
|
||||
self.fields["max_delete"].help_text = (
|
||||
f"Must be at least {expected_delete_count} for the incomplete snapshots shown here."
|
||||
)
|
||||
|
||||
def clean_confirm_host(self) -> str:
|
||||
value = self.cleaned_data["confirm_host"].strip()
|
||||
if value != self.host_name:
|
||||
raise forms.ValidationError(f"Type {self.host_name} to confirm.")
|
||||
return value
|
||||
|
||||
def clean_confirm_delete_count(self) -> int:
|
||||
value = self.cleaned_data["confirm_delete_count"]
|
||||
if value != self.expected_delete_count:
|
||||
raise forms.ValidationError(f"Type {self.expected_delete_count} to confirm the incomplete count.")
|
||||
return value
|
||||
|
||||
|
||||
class ScheduleConfigForm(forms.ModelForm):
|
||||
cron_expr = forms.CharField(
|
||||
label="Schedule expression",
|
||||
|
||||
Reference in New Issue
Block a user