fix: exclude prebuilt workspaces from template-level lifecycle updates (#19265)

## Description

This PR ensures that lifecycle-related changes made via template
schedule updates do **not affect prebuilt workspaces**. Since prebuilds
are managed by the reconciliation loop and do not participate in the
regular lifecycle executor flow, they must be excluded from any updates
triggered by template configuration changes.

This includes changes to TTL, dormant-deletion scheduling, deadline and
autostart scheduling.

## Changes

- Updated SQL query `UpdateWorkspacesTTLByTemplateID` to exclude
prebuilt workspaces
- Updated SQL query `UpdateWorkspacesDormantDeletingAtByTemplateID` to
exclude prebuilt workspaces
- Updated application-layer logic to skip any updates to lifecycle
parameters if a workspace is a prebuild
- Preserved all existing update behavior for regular user workspaces

This change guarantees that only lifecycle-managed workspaces are
affected when template-level configurations are modified, preserving
strict boundaries between prebuild and user workspace lifecycles.

Related with: 
* Issue: https://github.com/coder/coder/issues/18898
* PR: https://github.com/coder/coder/pull/19252
This commit is contained in:
Susana Ferreira
2025-08-19 13:08:01 +01:00
committed by GitHub
parent e8795269e4
commit d79a7797c2
4 changed files with 282 additions and 8 deletions
+11 -4
View File
@@ -579,7 +579,11 @@ UPDATE
SET
ttl = $2
WHERE
template_id = $1;
template_id = $1
-- Prebuilt workspaces (identified by having the prebuilds system user as owner_id)
-- should not have their TTL updated, as they are handled by the prebuilds
-- reconciliation loop.
AND workspaces.owner_id != 'c42fdf75-3097-471c-8c33-fb52454d81c0'::UUID;
-- name: UpdateWorkspaceLastUsedAt :exec
UPDATE
@@ -824,14 +828,17 @@ UPDATE workspaces
SET
deleting_at = CASE
WHEN @time_til_dormant_autodelete_ms::bigint = 0 THEN NULL
WHEN @dormant_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN (@dormant_at::timestamptz) + interval '1 milliseconds' * @time_til_dormant_autodelete_ms::bigint
WHEN @dormant_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN (@dormant_at::timestamptz) + interval '1 milliseconds' * @time_til_dormant_autodelete_ms::bigint
ELSE dormant_at + interval '1 milliseconds' * @time_til_dormant_autodelete_ms::bigint
END,
dormant_at = CASE WHEN @dormant_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN @dormant_at::timestamptz ELSE dormant_at END
WHERE
template_id = @template_id
AND
dormant_at IS NOT NULL
AND dormant_at IS NOT NULL
-- Prebuilt workspaces (identified by having the prebuilds system user as owner_id)
-- should not have their dormant or deleting at set, as these are handled by the
-- prebuilds reconciliation loop.
AND workspaces.owner_id != 'c42fdf75-3097-471c-8c33-fb52454d81c0'::UUID
RETURNING *;
-- name: UpdateTemplateWorkspacesLastUsedAt :exec