mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-28 07:57:01 +00:00
fix(scanner): preserve restore expiry semantics
This commit is contained in:
@@ -249,6 +249,10 @@ fn resolve_sizes(object_infos: &[ObjectInfo]) -> Vec<SizeResolution> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lifecycle_rule_has_size_filter(lifecycle: &BucketLifecycleConfiguration, rule_id: &str) -> bool {
|
fn lifecycle_rule_has_size_filter(lifecycle: &BucketLifecycleConfiguration, rule_id: &str) -> bool {
|
||||||
|
if rule_id.is_empty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let filter_has_size = |filter: &s3s::dto::LifecycleRuleFilter| {
|
let filter_has_size = |filter: &s3s::dto::LifecycleRuleFilter| {
|
||||||
filter.object_size_greater_than.is_some()
|
filter.object_size_greater_than.is_some()
|
||||||
|| filter.object_size_less_than.is_some()
|
|| filter.object_size_less_than.is_some()
|
||||||
@@ -260,21 +264,19 @@ fn lifecycle_rule_has_size_filter(lifecycle: &BucketLifecycleConfiguration, rule
|
|||||||
lifecycle
|
lifecycle
|
||||||
.rules
|
.rules
|
||||||
.iter()
|
.iter()
|
||||||
.find(|rule| rule.id.as_deref().unwrap_or_default() == rule_id)
|
.find(|rule| rule.id.as_deref() == Some(rule_id))
|
||||||
.and_then(|rule| rule.filter.as_ref())
|
.and_then(|rule| rule.filter.as_ref())
|
||||||
.is_some_and(filter_has_size)
|
.is_some_and(filter_has_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lifecycle_event_allowed(resolution: &SizeResolution, event: &Event, lifecycle: &BucketLifecycleConfiguration) -> bool {
|
fn lifecycle_event_allowed(resolution: &SizeResolution, event: &Event, lifecycle: &BucketLifecycleConfiguration) -> bool {
|
||||||
match resolution {
|
match resolution {
|
||||||
// Corrupt metadata cannot safely authorize a destructive action, even
|
// Missing or invalid logical size only defers actions whose selected
|
||||||
// when the evaluator happened to produce a time-only event.
|
// rule actually depends on that size. Time/version-only actions retain
|
||||||
SizeResolution::Corrupt { .. } => false,
|
// their existing semantics, including intrinsic events without a rule ID.
|
||||||
// A valid-but-unknown logical size may still execute lifecycle
|
SizeResolution::Unknown { .. } | SizeResolution::Corrupt { .. } => {
|
||||||
// actions whose rule is independent of object-size predicates. The
|
!lifecycle_rule_has_size_filter(lifecycle, &event.rule_id)
|
||||||
// evaluator has already selected the rule; only that rule's filter
|
}
|
||||||
// can make the missing logical value action-critical.
|
|
||||||
SizeResolution::Unknown { .. } => !lifecycle_rule_has_size_filter(lifecycle, &event.rule_id),
|
|
||||||
SizeResolution::Known { .. } => true,
|
SizeResolution::Known { .. } => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1571,7 +1573,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
&BucketLifecycleConfiguration::default()
|
&BucketLifecycleConfiguration::default()
|
||||||
));
|
));
|
||||||
assert!(!lifecycle_event_allowed(
|
assert!(lifecycle_event_allowed(
|
||||||
&SizeResolution::Corrupt {
|
&SizeResolution::Corrupt {
|
||||||
physical: 12,
|
physical: 12,
|
||||||
reason: SizeResolutionReason::InvalidDeclaredSize,
|
reason: SizeResolutionReason::InvalidDeclaredSize,
|
||||||
@@ -1582,6 +1584,39 @@ mod tests {
|
|||||||
},
|
},
|
||||||
&BucketLifecycleConfiguration::default()
|
&BucketLifecycleConfiguration::default()
|
||||||
));
|
));
|
||||||
|
assert!(!lifecycle_event_allowed(
|
||||||
|
&SizeResolution::Corrupt {
|
||||||
|
physical: 12,
|
||||||
|
reason: SizeResolutionReason::InvalidDeclaredSize,
|
||||||
|
},
|
||||||
|
&Event {
|
||||||
|
action: IlmAction::DeleteAction,
|
||||||
|
rule_id: "size".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&size_filtered
|
||||||
|
));
|
||||||
|
assert!(!lifecycle_rule_has_size_filter(
|
||||||
|
&BucketLifecycleConfiguration {
|
||||||
|
rules: vec![s3s::dto::LifecycleRule {
|
||||||
|
status: s3s::dto::ExpirationStatus::from_static(s3s::dto::ExpirationStatus::ENABLED),
|
||||||
|
expiration: None,
|
||||||
|
abort_incomplete_multipart_upload: None,
|
||||||
|
del_marker_expiration: None,
|
||||||
|
id: None,
|
||||||
|
filter: Some(s3s::dto::LifecycleRuleFilter {
|
||||||
|
object_size_greater_than: Some(1),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
noncurrent_version_expiration: None,
|
||||||
|
noncurrent_version_transitions: None,
|
||||||
|
prefix: None,
|
||||||
|
transitions: None,
|
||||||
|
}],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
""
|
||||||
|
));
|
||||||
assert!(lifecycle_event_allowed(
|
assert!(lifecycle_event_allowed(
|
||||||
&SizeResolution::Known {
|
&SizeResolution::Known {
|
||||||
logical: 10,
|
logical: 10,
|
||||||
|
|||||||
Reference in New Issue
Block a user