Archiving a node pool must unpin it from action constraints, and say so

An action pinned to a node pool keeps being placed on that pool after it is archived. Found while writing the 26.10.0 upgrade steps for GPU pools that must be archived and recreated (#1483 (closed), point 6).

Decided behaviour: archiving a pool unpins it from every action's constraints. An action pinned only to that pool becomes unconstrained, which is intended. Archiving must say so up front instead of doing it silently.

Steps to reproduce

  1. Create two node pools on a site, A and B.
  2. In the Studio, pin an action to A (Constraints › Sites and Node Pools) and deploy the workflow.
  3. Archive A (POST /api/runner/node-pools/<A>/archive).
  4. Trigger the workflow: the execution is placed on A.
  5. Redeploy the workflow without touching the constraint: the pin to A is dropped with only a warning in the runner log, and the Studio still shows the action as pinned to A.

What is the current bug behavior and the expected correct behavior?

Current:

  • A deployed action's constraints hold the NodePool rows through a plain relationship (node_pool_list, no archived filter). The placement services use to_schedule.node_pool_list as the candidate list as is, so an archived pool is still a valid target.
  • The Studio keeps its own copy of the constraint, so it still shows and sends the archived pool. The runner drops it at deploy time without telling the user.

Expected:

  • An archived pool is never a placement target. It no longer counts in any action's constraints, whether the workflow was deployed before or after the archive. An action whose only pinned pool was archived can run on any pool that fits its request.
  • The Studio no longer shows or sends an archived pool as a constraint.
  • The archive confirmation lists the actions pinned to the pool that will lose their pin, so the admin can re-pin them first. It sits next to the rewording in #1483 (closed) point 8.

Relevant logs and/or screenshots

Node Pool %s from node pool constraints list not found. This might come from a deleted site, ignoring...

(The %s is never filled in: the call passes no argument.)

Found by reading the code on ryax-core master (5bc17e49), not on a live instance.

Possible fixes

  • Runner: add a loader criteria NodePool.archived == False on the node_pool_list relationship. Every placement policy then stops seeing archived pools: v0 (the default, also used by v1) and the fallback. Filtering rather than deleting keeps the constraint rows as history.
  • Runner: pass node_pool_id to the warning in workflow_deployment_handlers.py:118.
  • Studio: drop the archived pool from the workflow actions' constraints. Either the runner publishes an event when a pool is archived, or the Studio filters against the active pools when it shows and sends constraints.
  • Front: in the archive confirmation, list the actions pinned to the pool, from a runner query on nodepool_constraints_association joined to deployed workflow actions.
Edited by Michael Mercier