Add graceful flag for storcon

This commit is contained in:
Aleksandr Sarantsev
2025-06-02 15:17:12 +04:00
parent 24e627e44c
commit 61a3258e5d
3 changed files with 26 additions and 3 deletions

View File

@@ -920,7 +920,7 @@ async fn main() -> anyhow::Result<()> {
storcon_client
.dispatch::<(), ()>(
Method::PUT,
format!("control/v1/node/{node_id}/drain"),
format!("control/v1/node/{node_id}/drain?graceful=true"),
None,
)
.await?;

View File

@@ -47,7 +47,9 @@ use crate::metrics::{
};
use crate::persistence::SafekeeperUpsert;
use crate::reconciler::ReconcileError;
use crate::service::{LeadershipStatus, RECONCILE_TIMEOUT, STARTUP_RECONCILE_TIMEOUT, Service};
use crate::service::{
LeadershipStatus, NodeDrainMode, RECONCILE_TIMEOUT, STARTUP_RECONCILE_TIMEOUT, Service,
};
/// State available to HTTP request handlers
pub struct HttpState {
@@ -1000,8 +1002,18 @@ async fn handle_node_drain(req: Request<Body>) -> Result<Response<Body>, ApiErro
let state = get_state(&req);
let node_id: NodeId = parse_request_param(&req, "node_id")?;
let graceful: bool = parse_query_param(&req, "graceful")?.unwrap_or(false);
state.service.start_node_drain(node_id).await?;
let node_drain_mode = if graceful {
NodeDrainMode::FullWithReprovisioning
} else {
NodeDrainMode::AttachedOnly
};
state
.service
.start_node_drain(node_id, node_drain_mode)
.await?;
json_response(StatusCode::ACCEPTED, ())
}

View File

@@ -687,6 +687,16 @@ struct ShardMutationLocations {
#[derive(Default, Clone)]
struct TenantMutationLocations(BTreeMap<TenantShardId, ShardMutationLocations>);
#[allow(dead_code)]
pub(crate) enum NodeDrainMode {
/// Drain only attached locations (primary node itself)
AttachedOnly,
/// Drain attached and secondary locations (but don't create new secondaries)
AttachedAndSecondaries,
/// Drain everything and also provision new secondaries for the newly promoted primaries
FullWithReprovisioning,
}
impl Service {
pub fn get_config(&self) -> &Config {
&self.config
@@ -7548,6 +7558,7 @@ impl Service {
pub(crate) async fn start_node_drain(
self: &Arc<Self>,
node_id: NodeId,
_mode: NodeDrainMode,
) -> Result<(), ApiError> {
let (ongoing_op, node_available, node_policy, schedulable_nodes_count) = {
let locked = self.inner.read().unwrap();