hive-c0re: drop the spawn-time forge user-email, repo-creation and config-repo passes
sync_agent no longer runs ensure_user_email, ensure_repo_creation_disabled or ensure_config_repo. swarm-controller does all three before any deploy: CreateForgeUser sets the account email and max_repo_creation = 0 (and the agent_token backfill re-runs CreateForgeUser), CreateRepo creates and protects agent-configs/<agent>, AddRepoMember grants the agent write on it, and InitAgentConfigRepo seeds it. What goes with them: the email-aligned and repo-creation-disabled marker paths and the legacy email-marker relocate, sparse_edit_user_option, is_forbidden and its tests, and ensure_org_repo. A config repo deleted by hand is no longer recreated on the next spawn; the operator recreates the agent at swarm level. Comments in swarm-controller that described the removed hive passes now state only the current behaviour. Closes #4848
This commit is contained in:
parent
d2c6f1a967
commit
1de8a01936
6 changed files with 44 additions and 351 deletions
|
|
@ -397,8 +397,8 @@ impl Client {
|
|||
/// Then locks the account out of creating repos
|
||||
/// ([`Self::disable_repo_creation`]), whether it was just created or
|
||||
/// already existed. Nothing else does that for a swarm-created agent, so
|
||||
/// a failure fails the node. Does not align the account's email the way
|
||||
/// `hive-c0re`'s `ensure_user_email` does — cosmetic, not a guard.
|
||||
/// a failure fails the node. Leaves an existing account's email as it
|
||||
/// finds it.
|
||||
pub async fn ensure_agent_user(&self, agent: &str) -> Result<()> {
|
||||
self.create_agent_user(agent).await?;
|
||||
self.disable_repo_creation(agent).await
|
||||
|
|
@ -421,13 +421,8 @@ impl Client {
|
|||
/// account once and checks the one thing that *is* comparable: the
|
||||
/// email. A match against either [`agent_email`] (what
|
||||
/// `create_agent_user` itself sets) or [`legacy_agent_email`] (what
|
||||
/// `hive-c0re::forge::users::ensure_user_exists` used before its own
|
||||
/// `ensure_user_email` alignment pass runs) counts as this agent's
|
||||
/// account — the legacy value has to be accepted too, not just the
|
||||
/// aligned one, because `ensure_user_email` only runs on the forge-host
|
||||
/// hive and only once it has a core token and has ticked at least once,
|
||||
/// so a real, existing legacy agent can still carry the old email when
|
||||
/// this node reads it mid-rollout. A mismatch against both means the
|
||||
/// older hive-created agent accounts carry) counts as this agent's
|
||||
/// account. A mismatch against both means the
|
||||
/// name collided with an account this node didn't create, so it fails
|
||||
/// the node rather than sending the PATCH (or silently skipping) to an
|
||||
/// account nobody verified is agent-controlled.
|
||||
|
|
@ -1139,30 +1134,23 @@ fn initial_flake_nix() -> &'static str {
|
|||
/// [`Client::disable_repo_creation`] before it sends the account's PATCH. Same
|
||||
/// format string as `hive-c0re::forge::users::agent_email` — not called
|
||||
/// across the crate boundary (see this module's doc comment), but both
|
||||
/// creators (and `hive-c0re`'s `ensure_user_email`, which aligns older
|
||||
/// accounts to it) converge on this exact value, so it doubles as the
|
||||
/// creators use this exact value, so it doubles as the
|
||||
/// marker that distinguishes an agent's own account from an unrelated one
|
||||
/// that happens to share its username.
|
||||
fn agent_email(agent: &str) -> String {
|
||||
format!("{agent}@hyperhive.local")
|
||||
}
|
||||
|
||||
/// The pre-alignment email `hive-c0re::forge::users::ensure_user_exists`
|
||||
/// gave an agent account before that crate's own `ensure_user_email`
|
||||
/// existed — see that function's doc comment ("Existing agents were
|
||||
/// created with `{name}@hive.local`; this corrects that"). Accepted by
|
||||
/// [`Client::disable_repo_creation`]'s guard alongside [`agent_email`]
|
||||
/// because `ensure_user_email`'s alignment PATCH only runs on the
|
||||
/// forge-host hive, and only after it has a core token and has ticked at
|
||||
/// least once, so a real legacy agent can still carry this value when this
|
||||
/// node reads it.
|
||||
/// The email older hive-created agent accounts carry, and keep: nothing
|
||||
/// rewrites it to [`agent_email`]. Accepted by
|
||||
/// [`Client::disable_repo_creation`]'s guard alongside [`agent_email`] so
|
||||
/// such an account is still recognised as the agent's own.
|
||||
fn legacy_agent_email(agent: &str) -> String {
|
||||
format!("{agent}@hive.local")
|
||||
}
|
||||
|
||||
/// The `admin_edit_user` body that sets `max_repo_creation = 0` on `agent`
|
||||
/// and nothing else. Same shape as `hive-c0re::forge::users`'
|
||||
/// `sparse_edit_user_option`: `login_name` + `source_id = 0` (local auth,
|
||||
/// and nothing else. `login_name` + `source_id = 0` (local auth,
|
||||
/// which is what [`Client::create_agent_user`] creates) ride along because
|
||||
/// Forgejo resets `use_custom_avatar` on an admin edit that omits
|
||||
/// `login_name`; every other field is left unset so nothing else is touched.
|
||||
|
|
@ -1548,9 +1536,9 @@ mod tests {
|
|||
}
|
||||
|
||||
/// A refused lockdown fails the node with Forgejo's own message, rather
|
||||
/// than warning and reporting the account as provisioned — that is
|
||||
/// `hive-c0re`'s `ensure_repo_creation_disabled` shape, which leaves an
|
||||
/// agent able to create and self-merge with nothing marked failed.
|
||||
/// than warning and reporting the account as provisioned, which would
|
||||
/// leave an agent able to create and self-merge with nothing marked
|
||||
/// failed.
|
||||
#[tokio::test]
|
||||
async fn a_refused_lockdown_fails_the_node() {
|
||||
let (client, _seen) = stub_forge(
|
||||
|
|
@ -1598,10 +1586,9 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
/// A legacy account `hive-c0re::forge::users::ensure_user_exists` (or
|
||||
/// its `ensure_user_email` alignment pass) created carries the same
|
||||
/// `{agent}@hyperhive.local` marker, plus the `login_name`/`source_id`
|
||||
/// fields its own `sparse_edit_user_option` sets — this node must still
|
||||
/// A legacy hive-created account can carry the same
|
||||
/// `{agent}@hyperhive.local` marker, plus `login_name`/`source_id` from
|
||||
/// a hive admin edit — this node must still
|
||||
/// lock such an account down, not just ones it created itself.
|
||||
#[tokio::test]
|
||||
async fn a_legacy_hive_created_agent_account_still_gets_locked_down() {
|
||||
|
|
@ -1621,14 +1608,9 @@ mod tests {
|
|||
assert_eq!(body["max_repo_creation"], 0);
|
||||
}
|
||||
|
||||
/// argus's round-2 🟡: `hive-c0re`'s `ensure_user_email` alignment pass
|
||||
/// (the thing that rewrites a legacy `{name}@hive.local` account to
|
||||
/// `{name}@hyperhive.local`) only runs on the forge-host hive, and only
|
||||
/// once it has a core token and has ticked — so a real, pre-existing
|
||||
/// agent can still be sitting on the pre-alignment `@hive.local` email
|
||||
/// when this node reads it. The guard must accept that value too, not
|
||||
/// just the aligned one, or a real agent would fail with "not this
|
||||
/// agent's" during the rollout window.
|
||||
/// A real, pre-existing agent account can carry the legacy
|
||||
/// `@hive.local` email, and nothing rewrites it. The guard must accept
|
||||
/// that value too, or such an agent would fail with "not this agent's".
|
||||
#[tokio::test]
|
||||
async fn a_pre_alignment_legacy_email_still_gets_locked_down() {
|
||||
let (client, seen) = stub_forge(
|
||||
|
|
|
|||
Loading…
Reference in a new issue