swarmctl: interactive setup walks the first-run ceremony
swarmctl setup with no subcommand checks the setup status first, then takes the open steps one at a time: prompts for input, shows a running action as one live line, prints the store keys, root token and new password under a warning until the operator confirms, and names the deploy option for a step this host cannot do. It calls the code of bao init, bao grant-bootstrap, user add, forge make-admin, agent create, agent permissions set and agent set-state. Refuses without root or a terminal.
This commit is contained in:
parent
4fae6a7766
commit
44caa72c19
1 changed files with 2172 additions and 82 deletions
|
|
@ -57,11 +57,7 @@ pub(crate) fn create(
|
|||
})
|
||||
.transpose()?;
|
||||
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.context("starting a tokio runtime for the controller request")?;
|
||||
let resp = rt.block_on(post_create(target, &name, &hive, agents_md.as_deref()))?;
|
||||
let resp = request_create(target, &name, &hive, agents_md.as_deref())?;
|
||||
|
||||
println!("queued: job node {}", resp.node_id);
|
||||
println!(
|
||||
|
|
@ -76,6 +72,21 @@ pub(crate) fn create(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// The round trip of [`create`] for an already validated `name` and `hive`,
|
||||
/// printing nothing.
|
||||
pub(crate) fn request_create(
|
||||
target: &Target,
|
||||
name: &str,
|
||||
hive: &str,
|
||||
agents_md: Option<&str>,
|
||||
) -> Result<CreateAgentResponse> {
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.context("starting a tokio runtime for the controller request")?;
|
||||
rt.block_on(post_create(target, name, hive, agents_md))
|
||||
}
|
||||
|
||||
/// Parse a CLI-supplied name into a validated identifier, naming which
|
||||
/// argument was wrong — `invalid hive` and `invalid agent name` send the
|
||||
/// operator to different flags.
|
||||
|
|
@ -137,8 +148,23 @@ pub(crate) fn set_state(
|
|||
check_confirmed(state, yes)?;
|
||||
let agent = parse_ident(agent, "agent name")?;
|
||||
let hive = parse_ident(hive, "hive")?;
|
||||
let wire: &'static str = state.into();
|
||||
let wire = request_state(target, &agent, &hive, state)?;
|
||||
|
||||
println!(
|
||||
"declared agent {agent:?} {wire} on hive {hive:?}; the hive converges on its own clock"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The round trip of [`set_state`] for an already validated `agent` and `hive`,
|
||||
/// printing nothing. Returns the state as the wire spells it.
|
||||
pub(crate) fn request_state(
|
||||
target: &Target,
|
||||
agent: &str,
|
||||
hive: &str,
|
||||
state: swarm_wire::wanted::AgentState,
|
||||
) -> Result<&'static str> {
|
||||
let wire: &'static str = state.into();
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
|
|
@ -150,11 +176,7 @@ pub(crate) fn set_state(
|
|||
Some(&serde_json::json!({ "state": wire })),
|
||||
"set-state",
|
||||
))?;
|
||||
|
||||
println!(
|
||||
"declared agent {agent:?} {wire} on hive {hive:?}; the hive converges on its own clock"
|
||||
);
|
||||
Ok(())
|
||||
Ok(wire)
|
||||
}
|
||||
|
||||
/// One `POST /api/agents` round trip at the controller.
|
||||
|
|
|
|||
Loading…
Reference in a new issue