swarmctl setup status shows where the setup ceremony stands
This commit is contained in:
parent
78b0451ed1
commit
61a334c847
1 changed files with 1052 additions and 3 deletions
|
|
@ -33,6 +33,7 @@ mod login;
|
|||
mod permissions;
|
||||
mod remote;
|
||||
mod schedule;
|
||||
mod setup;
|
||||
mod users;
|
||||
mod watch;
|
||||
|
||||
|
|
@ -72,7 +73,7 @@ const LOGIN_SWARM_ENVS: &[&str] = &["SWARMCTL_SWARM", "SWARMCTL_LOGIN_DEFAULT_SW
|
|||
#[derive(Args)]
|
||||
struct RemoteArgs {
|
||||
/// The swarm's domain, as `https://<domain>` or the bare domain. Given,
|
||||
/// the `agent`, `schedule` and `forge` verbs go through its gateway as the
|
||||
/// the `agent`, `schedule` and `forge` verbs, and the agent checks of `setup status`, go through its gateway as the
|
||||
/// account `swarmctl login` logged in, instead of over the controller's
|
||||
/// socket. Falls back to `SWARMCTL_SWARM`; `login` then falls back to
|
||||
/// `SWARMCTL_LOGIN_DEFAULT_SWARM`, which the swarm-controller nix module
|
||||
|
|
@ -214,6 +215,11 @@ enum Verb {
|
|||
#[command(subcommand)]
|
||||
command: ForgeVerb,
|
||||
},
|
||||
/// Show where the first-run setup ceremony stands.
|
||||
Setup {
|
||||
#[command(subcommand)]
|
||||
command: SetupVerb,
|
||||
},
|
||||
/// Log in to the swarm named by `--swarm` as your own SSO account.
|
||||
///
|
||||
/// With no `--swarm` or `SWARMCTL_SWARM`, logs in to
|
||||
|
|
@ -254,6 +260,32 @@ enum Verb {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum SetupVerb {
|
||||
/// Print each step of the first-run setup, in order, as `done`, `not done`
|
||||
/// or `unknown`, and what to do next.
|
||||
///
|
||||
/// Read-only, and needs no token. The secret store's steps come from `bao
|
||||
/// status` and systemd, so they show only on the host running swarm-bao; the
|
||||
/// SSO account comes from authelia's users file, on its host; ruth and the
|
||||
/// other agents come from the swarm-controller. When a check can't run, its
|
||||
/// steps print `unknown` with the reason, and the rest still print. Steps 7
|
||||
/// and 8, the browser login and the forge site admin, always print
|
||||
/// `unknown (not observable)`.
|
||||
///
|
||||
/// Exits 0 when every step it can see has finished, and 1 otherwise, including
|
||||
/// when a check failed to run. Step 10, another agent, is optional and never
|
||||
/// changes the exit code. The steps are those of
|
||||
/// `docs/1-getting-started/setup.md`.
|
||||
Status(SetupStatusArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
struct SetupStatusArgs {
|
||||
#[command(flatten)]
|
||||
socket: ControllerSocketArg,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum AgentVerb {
|
||||
/// Queue creation of a new agent on a hive in this swarm.
|
||||
|
|
@ -768,6 +800,20 @@ fn main() -> Result<()> {
|
|||
}
|
||||
// Same socket-resolution reasoning as `Create` above.
|
||||
Verb::Schedule { command } => schedule(&remote, command),
|
||||
// Neither the controller socket nor the users file is required: a
|
||||
// host without one reports the steps that need the other.
|
||||
Verb::Setup {
|
||||
command: SetupVerb::Status(args),
|
||||
} => {
|
||||
let target = args.socket.resolve(&remote);
|
||||
let users_file = path_from(paths.users_file, "SWARMCTL_AUTHELIA_USERS_FILE");
|
||||
let complete = setup::status(target, users_file);
|
||||
io::stdout().flush().context("writing the report")?;
|
||||
if !complete {
|
||||
std::process::exit(1);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Verb::Login => login::login(
|
||||
&remote
|
||||
.login_swarm()?
|
||||
|
|
|
|||
Loading…
Reference in a new issue