Skip to content

Pool scale-down deletes the ConfigMaps of a claimed instance, 403ing a live session #143

Description

@Mtze

Found by CodeRabbit reviewing #142, verified in the code. Pre-existing in reconcile; filed separately because fixing it properly is a design change rather than a one-liner.

The gap

ResourceLifecycleManager.reconcile deletes a resource whose instance id exceeds targetCount, guarded by sole ownership (ResourceLifecycleManager.java:281-282):

// Case A: Resource ID > target count → should be deleted
if (id > ctx.targetCount) {
    if (OwnershipManager.isOwnedSolelyBy(resource, ctx.owner)) {

For a claimed instance that guard protects the Deployment and the Services, because claiming adds a Session owner reference (PrewarmedResourcePool.java:1079-1080) and isOwnedSolelyBy is then false.

It does not protect the instance-N-proxy-… and instance-N-email-… ConfigMaps. Those stay owned by the AppDefinition alone for the life of the claim - AGENTS.md states this outright under "The pool's email ConfigMaps carry live session state". So on a scale-down they are deleted while the session, its Deployment and its Services survive.

restoreEmailConfigsOfClaimedInstances does not cover it. It looks the ConfigMap up and, when it is gone, only warns (PrewarmedResourcePool.java:724-726):

if (emailConfigMap == null) {
    LOGGER.warn(formatLogMessage(correlationId, "Email config " + emailConfigName ...

It rewrites the allow-list of ConfigMaps that still exist; it never recreates a deleted one.

Consequence

A live session whose instance id is above the new minInstances keeps running with its oauth2-proxy ConfigMap deleted. The proxy then has no allow-list to admit anyone, which is the 403-for-everyone failure AGENTS.md already warns about, reached by a different route than the one restoreEmailConfigsOfClaimedInstances was written for.

Reaching it needs minInstances lowered below the id of a currently-claimed instance. reserveInstance hands out the lowest free id, so claimed ids cluster low and this is uncommon - but the admin scaling API can lower minInstances at any time, and the pool runs at 10 in production.

Two ways to fix it

  1. Give the claim's ConfigMaps a Session owner reference, like the Deployment and Services already get, and drop it on release. isOwnedSolelyBy then protects them for free and no call site changes. Needs matching cleanup in the release path.
  2. Teach the ConfigMap phase about claims - pass the claimed ids into the reconcile context and skip deletion for them. Narrower, but it puts the same rule in a second place.

(1) matches the design that is already there, and is what the review suggested.

Relation to #142

#142 does not introduce this, but it widens when it can fire: reconcile now also runs at operator startup, so a scale-down that previously sat harmlessly until the next MODIFIED event is acted on at the next operator restart - and every helm upgrade restarts the operator. An argument for fixing this soon, not for holding #142, which is what stops students being served a stale image.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions