mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-25 21:46:50 +00:00
fix(admin): clear removed site resync status (#2803)
This commit is contained in:
@@ -1594,8 +1594,27 @@ fn remove_sites(mut state: SiteReplicationState, req: SRRemoveReq) -> SiteReplic
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
let names: Vec<String> = req.site_names.into_iter().collect();
|
let names: HashSet<String> = req.site_names.into_iter().collect();
|
||||||
state.peers.retain(|_, peer| !names.iter().any(|name| name == &peer.name));
|
if names.contains(&state.name) {
|
||||||
|
state.peers.clear();
|
||||||
|
state.resync_status.clear();
|
||||||
|
state.updated_at = Some(OffsetDateTime::now_utc());
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
let removed_deployment_ids: Vec<String> = state
|
||||||
|
.peers
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, peer)| names.contains(&peer.name))
|
||||||
|
.map(|(deployment_id, _)| deployment_id.clone())
|
||||||
|
.collect();
|
||||||
|
for deployment_id in removed_deployment_ids {
|
||||||
|
state.peers.remove(&deployment_id);
|
||||||
|
state.resync_status.remove(&deployment_id);
|
||||||
|
}
|
||||||
|
state
|
||||||
|
.resync_status
|
||||||
|
.retain(|deployment_id, _| state.peers.contains_key(deployment_id));
|
||||||
state.updated_at = Some(OffsetDateTime::now_utc());
|
state.updated_at = Some(OffsetDateTime::now_utc());
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
@@ -3295,6 +3314,122 @@ mod tests {
|
|||||||
assert!(status.err_detail.contains("403 Forbidden"));
|
assert!(status.err_detail.contains("403 Forbidden"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_remove_sites_drops_resync_status_for_removed_peer() {
|
||||||
|
let mut state = SiteReplicationState {
|
||||||
|
name: "local".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
state.peers.insert(
|
||||||
|
"local-deployment".to_string(),
|
||||||
|
PeerInfo {
|
||||||
|
deployment_id: "local-deployment".to_string(),
|
||||||
|
..peer("local", "https://local.example.com")
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.peers.insert(
|
||||||
|
"remote-a-deployment".to_string(),
|
||||||
|
PeerInfo {
|
||||||
|
deployment_id: "remote-a-deployment".to_string(),
|
||||||
|
..peer("remote-a", "https://remote-a.example.com")
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.peers.insert(
|
||||||
|
"remote-b-deployment".to_string(),
|
||||||
|
PeerInfo {
|
||||||
|
deployment_id: "remote-b-deployment".to_string(),
|
||||||
|
..peer("remote-b", "https://remote-b.example.com")
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.resync_status.insert(
|
||||||
|
"remote-a-deployment".to_string(),
|
||||||
|
SRResyncOpStatus {
|
||||||
|
resync_id: "stale-a".to_string(),
|
||||||
|
status: "success".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.resync_status.insert(
|
||||||
|
"remote-a-legacy-key".to_string(),
|
||||||
|
SRResyncOpStatus {
|
||||||
|
resync_id: "stale-a-legacy".to_string(),
|
||||||
|
status: "success".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.resync_status.insert(
|
||||||
|
"remote-b-deployment".to_string(),
|
||||||
|
SRResyncOpStatus {
|
||||||
|
resync_id: "active-b".to_string(),
|
||||||
|
status: "success".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let state = remove_sites(
|
||||||
|
state,
|
||||||
|
SRRemoveReq {
|
||||||
|
site_names: vec!["remote-a".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(state.peers.contains_key("local-deployment"));
|
||||||
|
assert!(!state.peers.contains_key("remote-a-deployment"));
|
||||||
|
assert!(state.peers.contains_key("remote-b-deployment"));
|
||||||
|
assert!(!state.resync_status.contains_key("remote-a-deployment"));
|
||||||
|
assert!(!state.resync_status.contains_key("remote-a-legacy-key"));
|
||||||
|
assert!(state.resync_status.contains_key("remote-b-deployment"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_remove_sites_clears_state_when_local_site_is_removed() {
|
||||||
|
let mut state = SiteReplicationState {
|
||||||
|
name: "local".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
state.peers.insert(
|
||||||
|
"local-deployment".to_string(),
|
||||||
|
PeerInfo {
|
||||||
|
deployment_id: "local-deployment".to_string(),
|
||||||
|
..peer("local", "https://local.example.com")
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.peers.insert(
|
||||||
|
"remote-a-deployment".to_string(),
|
||||||
|
PeerInfo {
|
||||||
|
deployment_id: "remote-a-deployment".to_string(),
|
||||||
|
..peer("remote-a", "https://remote-a.example.com")
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.peers.insert(
|
||||||
|
"remote-b-deployment".to_string(),
|
||||||
|
PeerInfo {
|
||||||
|
deployment_id: "remote-b-deployment".to_string(),
|
||||||
|
..peer("remote-b", "https://remote-b.example.com")
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state.resync_status.insert(
|
||||||
|
"remote-a-deployment".to_string(),
|
||||||
|
SRResyncOpStatus {
|
||||||
|
resync_id: "active-a".to_string(),
|
||||||
|
status: "success".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let state = remove_sites(
|
||||||
|
state,
|
||||||
|
SRRemoveReq {
|
||||||
|
site_names: vec!["local".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(state.peers.is_empty());
|
||||||
|
assert!(state.resync_status.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_site_replication_remove_status_truncates_peer_error_detail() {
|
fn test_site_replication_remove_status_truncates_peer_error_detail() {
|
||||||
let long_peer_body = "peer response body ".repeat(40);
|
let long_peer_body = "peer response body ".repeat(40);
|
||||||
|
|||||||
Reference in New Issue
Block a user