diff --git a/plugins/host_agent/routes.py b/plugins/host_agent/routes.py index ab88034..0519873 100644 --- a/plugins/host_agent/routes.py +++ b/plugins/host_agent/routes.py @@ -731,17 +731,19 @@ async def deploy_via_ansible(): targets = await fetch_scope_targets(db, scope) if not targets: return _error(400, "no_targets", "No Ansible targets in that scope") + # The read above autobegins the session transaction (SQLAlchemy 2.0), so + # mint into it directly and commit — a nested db.begin() would double-begin. tokens: dict[str, str] = {} - async with db.begin(): - for t in targets: - host = await _ensure_host_for_target(db, t) - tokens[t.name] = await _mint_registration_token(db, host) - inv = generate_inventory(targets) + for t in targets: + host = await _ensure_host_for_target(db, t) + tokens[t.name] = await _mint_registration_token(db, host) + inv = generate_inventory(targets) # built while ORM objects are still live for name, tok in tokens.items(): hv = inv["_meta"]["hostvars"].setdefault(name, {}) hv["steward_url"] = url hv["steward_token"] = tok inventory_content = _json.dumps(inv) + await db.commit() actor_role = UserRole(session.get("user_role", "viewer")) run, _source, err = await invoke_capability( @@ -805,12 +807,13 @@ async def provision_via_ansible(): targets = await fetch_scope_targets(db, scope) if not targets: return _error(400, "no_targets", "No Ansible targets in that scope") + # The read above autobegins the session transaction (SQLAlchemy 2.0), so + # mint into it directly and commit — a nested db.begin() would double-begin. tokens: dict[str, str] = {} - async with db.begin(): - for t in targets: - host = await _ensure_host_for_target(db, t) - tokens[t.name] = await _mint_registration_token(db, host) - inv = generate_inventory(targets) + for t in targets: + host = await _ensure_host_for_target(db, t) + tokens[t.name] = await _mint_registration_token(db, host) + inv = generate_inventory(targets) # built while ORM objects are still live for name, tok in tokens.items(): hv = inv["_meta"]["hostvars"].setdefault(name, {}) hv["steward_url"] = url @@ -821,6 +824,7 @@ async def provision_via_ansible(): hv["steward_pubkey"] = pubkey hv["steward_user"] = steward_user inventory_content = _json.dumps(inv) + await db.commit() actor_role = UserRole(session.get("user_role", "viewer")) run, _source, err = await invoke_capability(