tenseleyflow/shithub / feb5cd7

Browse files

actions/runners: add pool ops schema and queries (S41j-4)

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
feb5cd7180fa3fc709d1d0bed0a0e82773abcb79
Parents
fbd1091
Tree
1442e55

22 changed files

StatusFile+-
M internal/actions/queries/workflow_jobs.sql 2 0
M internal/actions/queries/workflow_runners.sql 76 9
M internal/actions/sqlc/models.go 6 0
M internal/actions/sqlc/querier.go 9 5
M internal/actions/sqlc/workflow_jobs.sql.go 2 0
M internal/actions/sqlc/workflow_runners.sql.go 427 19
M internal/admin/sqlc/models.go 6 0
M internal/auth/policy/sqlc/models.go 6 0
M internal/billing/sqlc/models.go 6 0
M internal/checks/sqlc/models.go 6 0
M internal/issues/sqlc/models.go 6 0
M internal/meta/sqlc/models.go 6 0
A internal/migrationsfs/migrations/0067_runner_pool_ops.sql 50 0
M internal/notif/sqlc/models.go 6 0
M internal/orgs/sqlc/models.go 6 0
M internal/pulls/sqlc/models.go 6 0
M internal/ratelimit/sqlc/models.go 6 0
M internal/repos/sqlc/models.go 6 0
M internal/social/sqlc/models.go 6 0
M internal/users/sqlc/models.go 6 0
M internal/webhook/sqlc/models.go 6 0
M internal/worker/sqlc/models.go 6 0
internal/actions/queries/workflow_jobs.sqlmodified
@@ -213,6 +213,8 @@ FROM workflow_jobs j
213213
 LEFT JOIN workflow_runners wr
214214
   ON (j.runs_on = '' OR j.runs_on = ANY(wr.labels))
215215
  AND wr.status IN ('idle', 'busy')
216
+ AND wr.draining_at IS NULL
217
+ AND wr.revoked_at IS NULL
216218
 WHERE j.status = 'queued'
217219
   AND j.cancel_requested = false
218220
   AND j.runner_id IS NULL
internal/actions/queries/workflow_runners.sqlmodified
@@ -4,28 +4,40 @@
44
 INSERT INTO workflow_runners (name, labels, capacity, registered_by_user_id)
55
 VALUES ($1, $2, $3, $4)
66
 RETURNING id, name, labels, capacity, status, last_heartbeat_at,
7
-          registered_by_user_id, created_at, updated_at;
7
+          host_name, version, draining_at, drain_reason, revoked_at,
8
+          revoked_reason, registered_by_user_id, created_at, updated_at;
89
 
910
 -- name: GetRunnerByID :one
1011
 SELECT id, name, labels, capacity, status, last_heartbeat_at,
11
-       registered_by_user_id, created_at, updated_at
12
+       host_name, version, draining_at, drain_reason, revoked_at,
13
+       revoked_reason, registered_by_user_id, created_at, updated_at
1214
 FROM workflow_runners
1315
 WHERE id = $1;
1416
 
1517
 -- name: GetRunnerByName :one
1618
 SELECT id, name, labels, capacity, status, last_heartbeat_at,
17
-       registered_by_user_id, created_at, updated_at
19
+       host_name, version, draining_at, drain_reason, revoked_at,
20
+       revoked_reason, registered_by_user_id, created_at, updated_at
1821
 FROM workflow_runners
1922
 WHERE name = $1;
2023
 
2124
 -- name: ListRunners :many
22
-SELECT id, name, labels, capacity, status, last_heartbeat_at, created_at
23
-FROM workflow_runners
24
-ORDER BY name ASC;
25
+SELECT r.id, r.name, r.labels, r.capacity, r.status, r.last_heartbeat_at,
26
+       r.host_name, r.version, r.draining_at, r.drain_reason, r.revoked_at,
27
+       r.revoked_reason, r.created_at, COUNT(j.id)::integer AS active_job_count
28
+FROM workflow_runners r
29
+LEFT JOIN workflow_jobs j
30
+       ON j.runner_id = r.id
31
+      AND j.status = 'running'
32
+GROUP BY r.id, r.name, r.labels, r.capacity, r.status, r.last_heartbeat_at,
33
+         r.host_name, r.version, r.draining_at, r.drain_reason, r.revoked_at,
34
+         r.revoked_reason, r.created_at
35
+ORDER BY r.name ASC;
2536
 
2637
 -- name: LockRunnerByID :one
2738
 SELECT id, name, labels, capacity, status, last_heartbeat_at,
28
-       registered_by_user_id, created_at, updated_at
39
+       host_name, version, draining_at, drain_reason, revoked_at,
40
+       revoked_reason, registered_by_user_id, created_at, updated_at
2941
 FROM workflow_runners
3042
 WHERE id = $1
3143
 FOR UPDATE;
@@ -36,10 +48,13 @@ SET labels = $2,
3648
     capacity = $3,
3749
     last_heartbeat_at = now(),
3850
     status = $4,
51
+    host_name = $5,
52
+    version = $6,
3953
     updated_at = now()
4054
 WHERE id = $1
4155
 RETURNING id, name, labels, capacity, status, last_heartbeat_at,
42
-          registered_by_user_id, created_at, updated_at;
56
+          host_name, version, draining_at, drain_reason, revoked_at,
57
+          revoked_reason, registered_by_user_id, created_at, updated_at;
4358
 
4459
 -- name: TouchRunnerHeartbeat :exec
4560
 UPDATE workflow_runners
@@ -55,14 +70,66 @@ RETURNING id, runner_id, token_hash, expires_at, revoked_at, created_at;
5570
 
5671
 -- name: GetRunnerByTokenHash :one
5772
 SELECT r.id, r.name, r.labels, r.capacity, r.status,
58
-       r.last_heartbeat_at, r.created_at
73
+       r.last_heartbeat_at, r.host_name, r.version, r.draining_at,
74
+       r.drain_reason, r.revoked_at, r.revoked_reason, r.created_at
5975
 FROM workflow_runners r
6076
 JOIN runner_tokens t ON t.runner_id = r.id
6177
 WHERE t.token_hash = $1
6278
   AND t.revoked_at IS NULL
79
+  AND r.revoked_at IS NULL
6380
   AND (t.expires_at IS NULL OR t.expires_at > now());
6481
 
82
+-- name: SetRunnerDraining :one
83
+UPDATE workflow_runners
84
+SET draining_at = COALESCE(draining_at, now()),
85
+    drain_reason = $2,
86
+    updated_at = now()
87
+WHERE id = $1
88
+  AND revoked_at IS NULL
89
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
90
+          host_name, version, draining_at, drain_reason, revoked_at,
91
+          revoked_reason, registered_by_user_id, created_at, updated_at;
92
+
93
+-- name: ClearRunnerDraining :one
94
+UPDATE workflow_runners
95
+SET draining_at = NULL,
96
+    drain_reason = '',
97
+    updated_at = now()
98
+WHERE id = $1
99
+  AND revoked_at IS NULL
100
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
101
+          host_name, version, draining_at, drain_reason, revoked_at,
102
+          revoked_reason, registered_by_user_id, created_at, updated_at;
103
+
104
+-- name: RevokeRunner :one
105
+UPDATE workflow_runners
106
+SET revoked_at = COALESCE(revoked_at, now()),
107
+    revoked_reason = CASE WHEN revoked_at IS NULL THEN $2 ELSE revoked_reason END,
108
+    draining_at = COALESCE(draining_at, now()),
109
+    drain_reason = CASE
110
+        WHEN draining_at IS NULL THEN $2
111
+        ELSE drain_reason
112
+    END,
113
+    status = 'offline',
114
+    updated_at = now()
115
+WHERE id = $1
116
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
117
+          host_name, version, draining_at, drain_reason, revoked_at,
118
+          revoked_reason, registered_by_user_id, created_at, updated_at;
119
+
65120
 -- name: RevokeAllTokensForRunner :exec
66121
 UPDATE runner_tokens
67122
 SET revoked_at = now()
68123
 WHERE runner_id = $1 AND revoked_at IS NULL;
124
+
125
+-- name: MarkStaleRunnersOffline :many
126
+UPDATE workflow_runners
127
+SET status = 'offline',
128
+    updated_at = now()
129
+WHERE revoked_at IS NULL
130
+  AND status <> 'offline'
131
+  AND last_heartbeat_at IS NOT NULL
132
+  AND last_heartbeat_at < $1
133
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
134
+          host_name, version, draining_at, drain_reason, revoked_at,
135
+          revoked_reason, registered_by_user_id, created_at, updated_at;
internal/actions/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/actions/sqlc/querier.gomodified
@@ -16,6 +16,7 @@ type Querier interface {
1616
 	ApproveWorkflowRun(ctx context.Context, db DBTX, arg ApproveWorkflowRunParams) (ApproveWorkflowRunRow, error)
1717
 	CancelOpenWorkflowStepsForJob(ctx context.Context, db DBTX, jobID int64) ([]WorkflowStep, error)
1818
 	ClaimQueuedWorkflowJob(ctx context.Context, db DBTX, arg ClaimQueuedWorkflowJobParams) (ClaimQueuedWorkflowJobRow, error)
19
+	ClearRunnerDraining(ctx context.Context, db DBTX, id int64) (ClearRunnerDrainingRow, error)
1920
 	CompleteWorkflowRun(ctx context.Context, db DBTX, arg CompleteWorkflowRunParams) (WorkflowRun, error)
2021
 	CountQueuedWorkflowRunsForRepo(ctx context.Context, db DBTX, repoID int64) (int64, error)
2122
 	CountRecentWorkflowRunsForActor(ctx context.Context, db DBTX, arg CountRecentWorkflowRunsForActorParams) (int64, error)
@@ -69,8 +70,8 @@ type Querier interface {
6970
 	GetOrgVariable(ctx context.Context, db DBTX, arg GetOrgVariableParams) (GetOrgVariableRow, error)
7071
 	GetRepoSecret(ctx context.Context, db DBTX, arg GetRepoSecretParams) (GetRepoSecretRow, error)
7172
 	GetRepoVariable(ctx context.Context, db DBTX, arg GetRepoVariableParams) (GetRepoVariableRow, error)
72
-	GetRunnerByID(ctx context.Context, db DBTX, id int64) (WorkflowRunner, error)
73
-	GetRunnerByName(ctx context.Context, db DBTX, name string) (WorkflowRunner, error)
73
+	GetRunnerByID(ctx context.Context, db DBTX, id int64) (GetRunnerByIDRow, error)
74
+	GetRunnerByName(ctx context.Context, db DBTX, name string) (GetRunnerByNameRow, error)
7475
 	GetRunnerByTokenHash(ctx context.Context, db DBTX, tokenHash []byte) (GetRunnerByTokenHashRow, error)
7576
 	GetStepLogChunkBefore(ctx context.Context, db DBTX, arg GetStepLogChunkBeforeParams) (WorkflowStepLogChunk, error)
7677
 	GetStepLogChunkByStepSeq(ctx context.Context, db DBTX, arg GetStepLogChunkByStepSeqParams) (WorkflowStepLogChunk, error)
@@ -81,11 +82,11 @@ type Querier interface {
8182
 	GetWorkflowRunByID(ctx context.Context, db DBTX, id int64) (WorkflowRun, error)
8283
 	GetWorkflowRunForRepoByIndex(ctx context.Context, db DBTX, arg GetWorkflowRunForRepoByIndexParams) (GetWorkflowRunForRepoByIndexRow, error)
8384
 	GetWorkflowStepByID(ctx context.Context, db DBTX, id int64) (WorkflowStep, error)
84
-	HeartbeatRunner(ctx context.Context, db DBTX, arg HeartbeatRunnerParams) (WorkflowRunner, error)
85
+	HeartbeatRunner(ctx context.Context, db DBTX, arg HeartbeatRunnerParams) (HeartbeatRunnerRow, error)
8586
 	// SPDX-License-Identifier: AGPL-3.0-or-later
8687
 	InsertArtifact(ctx context.Context, db DBTX, arg InsertArtifactParams) (WorkflowArtifact, error)
8788
 	// SPDX-License-Identifier: AGPL-3.0-or-later
88
-	InsertRunner(ctx context.Context, db DBTX, arg InsertRunnerParams) (WorkflowRunner, error)
89
+	InsertRunner(ctx context.Context, db DBTX, arg InsertRunnerParams) (InsertRunnerRow, error)
8990
 	InsertRunnerToken(ctx context.Context, db DBTX, arg InsertRunnerTokenParams) (RunnerToken, error)
9091
 	// SPDX-License-Identifier: AGPL-3.0-or-later
9192
 	// Called by the future runner-side upload handler when an
@@ -136,7 +137,7 @@ type Querier interface {
136137
 	ListWorkflowCachesForRepo(ctx context.Context, db DBTX, arg ListWorkflowCachesForRepoParams) ([]WorkflowCache, error)
137138
 	ListWorkflowRunWorkflowsForRepo(ctx context.Context, db DBTX, repoID int64) ([]ListWorkflowRunWorkflowsForRepoRow, error)
138139
 	ListWorkflowRunsForRepo(ctx context.Context, db DBTX, arg ListWorkflowRunsForRepoParams) ([]ListWorkflowRunsForRepoRow, error)
139
-	LockRunnerByID(ctx context.Context, db DBTX, id int64) (WorkflowRunner, error)
140
+	LockRunnerByID(ctx context.Context, db DBTX, id int64) (LockRunnerByIDRow, error)
140141
 	// Companion to EnqueueWorkflowRun for the conflict path: when an
141142
 	// INSERT ... ON CONFLICT DO NOTHING returns no rows, the trigger
142143
 	// handler uses this to find the existing row so it can surface a
@@ -144,6 +145,7 @@ type Querier interface {
144145
 	LookupWorkflowRunByTriggerEvent(ctx context.Context, db DBTX, arg LookupWorkflowRunByTriggerEventParams) (WorkflowRun, error)
145146
 	// SPDX-License-Identifier: AGPL-3.0-or-later
146147
 	MarkRunnerJWTUsed(ctx context.Context, db DBTX, arg MarkRunnerJWTUsedParams) (RunnerJwtUsed, error)
148
+	MarkStaleRunnersOffline(ctx context.Context, db DBTX, lastHeartbeatAt pgtype.Timestamptz) ([]MarkStaleRunnersOfflineRow, error)
147149
 	MarkWorkflowJobsRejected(ctx context.Context, db DBTX, runID int64) ([]WorkflowJob, error)
148150
 	MarkWorkflowRunRejected(ctx context.Context, db DBTX, id int64) (WorkflowRun, error)
149151
 	MarkWorkflowRunRunning(ctx context.Context, db DBTX, id int64) error
@@ -157,6 +159,8 @@ type Querier interface {
157159
 	RequestWorkflowJobCancel(ctx context.Context, db DBTX, id int64) (WorkflowJob, error)
158160
 	RequestWorkflowRunCancel(ctx context.Context, db DBTX, runID int64) ([]WorkflowJob, error)
159161
 	RevokeAllTokensForRunner(ctx context.Context, db DBTX, runnerID int64) error
162
+	RevokeRunner(ctx context.Context, db DBTX, arg RevokeRunnerParams) (RevokeRunnerRow, error)
163
+	SetRunnerDraining(ctx context.Context, db DBTX, arg SetRunnerDrainingParams) (SetRunnerDrainingRow, error)
160164
 	StartWorkflowRun(ctx context.Context, db DBTX, id int64) (WorkflowRun, error)
161165
 	TouchRunnerHeartbeat(ctx context.Context, db DBTX, arg TouchRunnerHeartbeatParams) error
162166
 	// Bumps last_accessed_at on cache hit. Called by the future
internal/actions/sqlc/workflow_jobs.sql.gomodified
@@ -374,6 +374,8 @@ FROM workflow_jobs j
374374
 LEFT JOIN workflow_runners wr
375375
   ON (j.runs_on = '' OR j.runs_on = ANY(wr.labels))
376376
  AND wr.status IN ('idle', 'busy')
377
+ AND wr.draining_at IS NULL
378
+ AND wr.revoked_at IS NULL
377379
 WHERE j.status = 'queued'
378380
   AND j.cancel_requested = false
379381
   AND j.runner_id IS NULL
internal/actions/sqlc/workflow_runners.sql.gomodified
@@ -11,16 +11,88 @@ import (
1111
 	"github.com/jackc/pgx/v5/pgtype"
1212
 )
1313
 
14
+const clearRunnerDraining = `-- name: ClearRunnerDraining :one
15
+UPDATE workflow_runners
16
+SET draining_at = NULL,
17
+    drain_reason = '',
18
+    updated_at = now()
19
+WHERE id = $1
20
+  AND revoked_at IS NULL
21
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
22
+          host_name, version, draining_at, drain_reason, revoked_at,
23
+          revoked_reason, registered_by_user_id, created_at, updated_at
24
+`
25
+
26
+type ClearRunnerDrainingRow struct {
27
+	ID                 int64
28
+	Name               string
29
+	Labels             []string
30
+	Capacity           int32
31
+	Status             WorkflowRunnerStatus
32
+	LastHeartbeatAt    pgtype.Timestamptz
33
+	HostName           string
34
+	Version            string
35
+	DrainingAt         pgtype.Timestamptz
36
+	DrainReason        string
37
+	RevokedAt          pgtype.Timestamptz
38
+	RevokedReason      string
39
+	RegisteredByUserID pgtype.Int8
40
+	CreatedAt          pgtype.Timestamptz
41
+	UpdatedAt          pgtype.Timestamptz
42
+}
43
+
44
+func (q *Queries) ClearRunnerDraining(ctx context.Context, db DBTX, id int64) (ClearRunnerDrainingRow, error) {
45
+	row := db.QueryRow(ctx, clearRunnerDraining, id)
46
+	var i ClearRunnerDrainingRow
47
+	err := row.Scan(
48
+		&i.ID,
49
+		&i.Name,
50
+		&i.Labels,
51
+		&i.Capacity,
52
+		&i.Status,
53
+		&i.LastHeartbeatAt,
54
+		&i.HostName,
55
+		&i.Version,
56
+		&i.DrainingAt,
57
+		&i.DrainReason,
58
+		&i.RevokedAt,
59
+		&i.RevokedReason,
60
+		&i.RegisteredByUserID,
61
+		&i.CreatedAt,
62
+		&i.UpdatedAt,
63
+	)
64
+	return i, err
65
+}
66
+
1467
 const getRunnerByID = `-- name: GetRunnerByID :one
1568
 SELECT id, name, labels, capacity, status, last_heartbeat_at,
16
-       registered_by_user_id, created_at, updated_at
69
+       host_name, version, draining_at, drain_reason, revoked_at,
70
+       revoked_reason, registered_by_user_id, created_at, updated_at
1771
 FROM workflow_runners
1872
 WHERE id = $1
1973
 `
2074
 
21
-func (q *Queries) GetRunnerByID(ctx context.Context, db DBTX, id int64) (WorkflowRunner, error) {
75
+type GetRunnerByIDRow struct {
76
+	ID                 int64
77
+	Name               string
78
+	Labels             []string
79
+	Capacity           int32
80
+	Status             WorkflowRunnerStatus
81
+	LastHeartbeatAt    pgtype.Timestamptz
82
+	HostName           string
83
+	Version            string
84
+	DrainingAt         pgtype.Timestamptz
85
+	DrainReason        string
86
+	RevokedAt          pgtype.Timestamptz
87
+	RevokedReason      string
88
+	RegisteredByUserID pgtype.Int8
89
+	CreatedAt          pgtype.Timestamptz
90
+	UpdatedAt          pgtype.Timestamptz
91
+}
92
+
93
+func (q *Queries) GetRunnerByID(ctx context.Context, db DBTX, id int64) (GetRunnerByIDRow, error) {
2294
 	row := db.QueryRow(ctx, getRunnerByID, id)
23
-	var i WorkflowRunner
95
+	var i GetRunnerByIDRow
2496
 	err := row.Scan(
2597
 		&i.ID,
2698
 		&i.Name,
@@ -28,6 +100,12 @@ func (q *Queries) GetRunnerByID(ctx context.Context, db DBTX, id int64) (Workflo
28100
 		&i.Capacity,
29101
 		&i.Status,
30102
 		&i.LastHeartbeatAt,
103
+		&i.HostName,
104
+		&i.Version,
105
+		&i.DrainingAt,
106
+		&i.DrainReason,
107
+		&i.RevokedAt,
108
+		&i.RevokedReason,
31109
 		&i.RegisteredByUserID,
32110
 		&i.CreatedAt,
33111
 		&i.UpdatedAt,
@@ -37,14 +115,33 @@ func (q *Queries) GetRunnerByID(ctx context.Context, db DBTX, id int64) (Workflo
37115
 
38116
 const getRunnerByName = `-- name: GetRunnerByName :one
39117
 SELECT id, name, labels, capacity, status, last_heartbeat_at,
40
-       registered_by_user_id, created_at, updated_at
118
+       host_name, version, draining_at, drain_reason, revoked_at,
119
+       revoked_reason, registered_by_user_id, created_at, updated_at
41120
 FROM workflow_runners
42121
 WHERE name = $1
43122
 `
44123
 
45
-func (q *Queries) GetRunnerByName(ctx context.Context, db DBTX, name string) (WorkflowRunner, error) {
124
+type GetRunnerByNameRow struct {
125
+	ID                 int64
126
+	Name               string
127
+	Labels             []string
128
+	Capacity           int32
129
+	Status             WorkflowRunnerStatus
130
+	LastHeartbeatAt    pgtype.Timestamptz
131
+	HostName           string
132
+	Version            string
133
+	DrainingAt         pgtype.Timestamptz
134
+	DrainReason        string
135
+	RevokedAt          pgtype.Timestamptz
136
+	RevokedReason      string
137
+	RegisteredByUserID pgtype.Int8
138
+	CreatedAt          pgtype.Timestamptz
139
+	UpdatedAt          pgtype.Timestamptz
140
+}
141
+
142
+func (q *Queries) GetRunnerByName(ctx context.Context, db DBTX, name string) (GetRunnerByNameRow, error) {
46143
 	row := db.QueryRow(ctx, getRunnerByName, name)
47
-	var i WorkflowRunner
144
+	var i GetRunnerByNameRow
48145
 	err := row.Scan(
49146
 		&i.ID,
50147
 		&i.Name,
@@ -52,6 +149,12 @@ func (q *Queries) GetRunnerByName(ctx context.Context, db DBTX, name string) (Wo
52149
 		&i.Capacity,
53150
 		&i.Status,
54151
 		&i.LastHeartbeatAt,
152
+		&i.HostName,
153
+		&i.Version,
154
+		&i.DrainingAt,
155
+		&i.DrainReason,
156
+		&i.RevokedAt,
157
+		&i.RevokedReason,
55158
 		&i.RegisteredByUserID,
56159
 		&i.CreatedAt,
57160
 		&i.UpdatedAt,
@@ -61,11 +164,13 @@ func (q *Queries) GetRunnerByName(ctx context.Context, db DBTX, name string) (Wo
61164
 
62165
 const getRunnerByTokenHash = `-- name: GetRunnerByTokenHash :one
63166
 SELECT r.id, r.name, r.labels, r.capacity, r.status,
64
-       r.last_heartbeat_at, r.created_at
167
+       r.last_heartbeat_at, r.host_name, r.version, r.draining_at,
168
+       r.drain_reason, r.revoked_at, r.revoked_reason, r.created_at
65169
 FROM workflow_runners r
66170
 JOIN runner_tokens t ON t.runner_id = r.id
67171
 WHERE t.token_hash = $1
68172
   AND t.revoked_at IS NULL
173
+  AND r.revoked_at IS NULL
69174
   AND (t.expires_at IS NULL OR t.expires_at > now())
70175
 `
71176
 
@@ -76,6 +181,12 @@ type GetRunnerByTokenHashRow struct {
76181
 	Capacity        int32
77182
 	Status          WorkflowRunnerStatus
78183
 	LastHeartbeatAt pgtype.Timestamptz
184
+	HostName        string
185
+	Version         string
186
+	DrainingAt      pgtype.Timestamptz
187
+	DrainReason     string
188
+	RevokedAt       pgtype.Timestamptz
189
+	RevokedReason   string
79190
 	CreatedAt       pgtype.Timestamptz
80191
 }
81192
 
@@ -89,6 +200,12 @@ func (q *Queries) GetRunnerByTokenHash(ctx context.Context, db DBTX, tokenHash [
89200
 		&i.Capacity,
90201
 		&i.Status,
91202
 		&i.LastHeartbeatAt,
203
+		&i.HostName,
204
+		&i.Version,
205
+		&i.DrainingAt,
206
+		&i.DrainReason,
207
+		&i.RevokedAt,
208
+		&i.RevokedReason,
92209
 		&i.CreatedAt,
93210
 	)
94211
 	return i, err
@@ -100,10 +217,13 @@ SET labels = $2,
100217
     capacity = $3,
101218
     last_heartbeat_at = now(),
102219
     status = $4,
220
+    host_name = $5,
221
+    version = $6,
103222
     updated_at = now()
104223
 WHERE id = $1
105224
 RETURNING id, name, labels, capacity, status, last_heartbeat_at,
106
-          registered_by_user_id, created_at, updated_at
225
+          host_name, version, draining_at, drain_reason, revoked_at,
226
+          revoked_reason, registered_by_user_id, created_at, updated_at
107227
 `
108228
 
109229
 type HeartbeatRunnerParams struct {
@@ -111,16 +231,38 @@ type HeartbeatRunnerParams struct {
111231
 	Labels   []string
112232
 	Capacity int32
113233
 	Status   WorkflowRunnerStatus
234
+	HostName string
235
+	Version  string
114236
 }
115237
 
116
-func (q *Queries) HeartbeatRunner(ctx context.Context, db DBTX, arg HeartbeatRunnerParams) (WorkflowRunner, error) {
238
+type HeartbeatRunnerRow struct {
239
+	ID                 int64
240
+	Name               string
241
+	Labels             []string
242
+	Capacity           int32
243
+	Status             WorkflowRunnerStatus
244
+	LastHeartbeatAt    pgtype.Timestamptz
245
+	HostName           string
246
+	Version            string
247
+	DrainingAt         pgtype.Timestamptz
248
+	DrainReason        string
249
+	RevokedAt          pgtype.Timestamptz
250
+	RevokedReason      string
251
+	RegisteredByUserID pgtype.Int8
252
+	CreatedAt          pgtype.Timestamptz
253
+	UpdatedAt          pgtype.Timestamptz
254
+}
255
+
256
+func (q *Queries) HeartbeatRunner(ctx context.Context, db DBTX, arg HeartbeatRunnerParams) (HeartbeatRunnerRow, error) {
117257
 	row := db.QueryRow(ctx, heartbeatRunner,
118258
 		arg.ID,
119259
 		arg.Labels,
120260
 		arg.Capacity,
121261
 		arg.Status,
262
+		arg.HostName,
263
+		arg.Version,
122264
 	)
123
-	var i WorkflowRunner
265
+	var i HeartbeatRunnerRow
124266
 	err := row.Scan(
125267
 		&i.ID,
126268
 		&i.Name,
@@ -128,6 +270,12 @@ func (q *Queries) HeartbeatRunner(ctx context.Context, db DBTX, arg HeartbeatRun
128270
 		&i.Capacity,
129271
 		&i.Status,
130272
 		&i.LastHeartbeatAt,
273
+		&i.HostName,
274
+		&i.Version,
275
+		&i.DrainingAt,
276
+		&i.DrainReason,
277
+		&i.RevokedAt,
278
+		&i.RevokedReason,
131279
 		&i.RegisteredByUserID,
132280
 		&i.CreatedAt,
133281
 		&i.UpdatedAt,
@@ -140,7 +288,8 @@ const insertRunner = `-- name: InsertRunner :one
140288
 INSERT INTO workflow_runners (name, labels, capacity, registered_by_user_id)
141289
 VALUES ($1, $2, $3, $4)
142290
 RETURNING id, name, labels, capacity, status, last_heartbeat_at,
143
-          registered_by_user_id, created_at, updated_at
291
+          host_name, version, draining_at, drain_reason, revoked_at,
292
+          revoked_reason, registered_by_user_id, created_at, updated_at
144293
 `
145294
 
146295
 type InsertRunnerParams struct {
@@ -150,15 +299,33 @@ type InsertRunnerParams struct {
150299
 	RegisteredByUserID pgtype.Int8
151300
 }
152301
 
302
+type InsertRunnerRow struct {
303
+	ID                 int64
304
+	Name               string
305
+	Labels             []string
306
+	Capacity           int32
307
+	Status             WorkflowRunnerStatus
308
+	LastHeartbeatAt    pgtype.Timestamptz
309
+	HostName           string
310
+	Version            string
311
+	DrainingAt         pgtype.Timestamptz
312
+	DrainReason        string
313
+	RevokedAt          pgtype.Timestamptz
314
+	RevokedReason      string
315
+	RegisteredByUserID pgtype.Int8
316
+	CreatedAt          pgtype.Timestamptz
317
+	UpdatedAt          pgtype.Timestamptz
318
+}
319
+
153320
 // SPDX-License-Identifier: AGPL-3.0-or-later
154
-func (q *Queries) InsertRunner(ctx context.Context, db DBTX, arg InsertRunnerParams) (WorkflowRunner, error) {
321
+func (q *Queries) InsertRunner(ctx context.Context, db DBTX, arg InsertRunnerParams) (InsertRunnerRow, error) {
155322
 	row := db.QueryRow(ctx, insertRunner,
156323
 		arg.Name,
157324
 		arg.Labels,
158325
 		arg.Capacity,
159326
 		arg.RegisteredByUserID,
160327
 	)
161
-	var i WorkflowRunner
328
+	var i InsertRunnerRow
162329
 	err := row.Scan(
163330
 		&i.ID,
164331
 		&i.Name,
@@ -166,6 +333,12 @@ func (q *Queries) InsertRunner(ctx context.Context, db DBTX, arg InsertRunnerPar
166333
 		&i.Capacity,
167334
 		&i.Status,
168335
 		&i.LastHeartbeatAt,
336
+		&i.HostName,
337
+		&i.Version,
338
+		&i.DrainingAt,
339
+		&i.DrainReason,
340
+		&i.RevokedAt,
341
+		&i.RevokedReason,
169342
 		&i.RegisteredByUserID,
170343
 		&i.CreatedAt,
171344
 		&i.UpdatedAt,
@@ -200,9 +373,17 @@ func (q *Queries) InsertRunnerToken(ctx context.Context, db DBTX, arg InsertRunn
200373
 }
201374
 
202375
 const listRunners = `-- name: ListRunners :many
203
-SELECT id, name, labels, capacity, status, last_heartbeat_at, created_at
204
-FROM workflow_runners
205
-ORDER BY name ASC
376
+SELECT r.id, r.name, r.labels, r.capacity, r.status, r.last_heartbeat_at,
377
+       r.host_name, r.version, r.draining_at, r.drain_reason, r.revoked_at,
378
+       r.revoked_reason, r.created_at, COUNT(j.id)::integer AS active_job_count
379
+FROM workflow_runners r
380
+LEFT JOIN workflow_jobs j
381
+       ON j.runner_id = r.id
382
+      AND j.status = 'running'
383
+GROUP BY r.id, r.name, r.labels, r.capacity, r.status, r.last_heartbeat_at,
384
+         r.host_name, r.version, r.draining_at, r.drain_reason, r.revoked_at,
385
+         r.revoked_reason, r.created_at
386
+ORDER BY r.name ASC
206387
 `
207388
 
208389
 type ListRunnersRow struct {
@@ -212,7 +393,14 @@ type ListRunnersRow struct {
212393
 	Capacity        int32
213394
 	Status          WorkflowRunnerStatus
214395
 	LastHeartbeatAt pgtype.Timestamptz
396
+	HostName        string
397
+	Version         string
398
+	DrainingAt      pgtype.Timestamptz
399
+	DrainReason     string
400
+	RevokedAt       pgtype.Timestamptz
401
+	RevokedReason   string
215402
 	CreatedAt       pgtype.Timestamptz
403
+	ActiveJobCount  int32
216404
 }
217405
 
218406
 func (q *Queries) ListRunners(ctx context.Context, db DBTX) ([]ListRunnersRow, error) {
@@ -231,7 +419,14 @@ func (q *Queries) ListRunners(ctx context.Context, db DBTX) ([]ListRunnersRow, e
231419
 			&i.Capacity,
232420
 			&i.Status,
233421
 			&i.LastHeartbeatAt,
422
+			&i.HostName,
423
+			&i.Version,
424
+			&i.DrainingAt,
425
+			&i.DrainReason,
426
+			&i.RevokedAt,
427
+			&i.RevokedReason,
234428
 			&i.CreatedAt,
429
+			&i.ActiveJobCount,
235430
 		); err != nil {
236431
 			return nil, err
237432
 		}
@@ -245,15 +440,34 @@ func (q *Queries) ListRunners(ctx context.Context, db DBTX) ([]ListRunnersRow, e
245440
 
246441
 const lockRunnerByID = `-- name: LockRunnerByID :one
247442
 SELECT id, name, labels, capacity, status, last_heartbeat_at,
248
-       registered_by_user_id, created_at, updated_at
443
+       host_name, version, draining_at, drain_reason, revoked_at,
444
+       revoked_reason, registered_by_user_id, created_at, updated_at
249445
 FROM workflow_runners
250446
 WHERE id = $1
251447
 FOR UPDATE
252448
 `
253449
 
254
-func (q *Queries) LockRunnerByID(ctx context.Context, db DBTX, id int64) (WorkflowRunner, error) {
450
+type LockRunnerByIDRow struct {
451
+	ID                 int64
452
+	Name               string
453
+	Labels             []string
454
+	Capacity           int32
455
+	Status             WorkflowRunnerStatus
456
+	LastHeartbeatAt    pgtype.Timestamptz
457
+	HostName           string
458
+	Version            string
459
+	DrainingAt         pgtype.Timestamptz
460
+	DrainReason        string
461
+	RevokedAt          pgtype.Timestamptz
462
+	RevokedReason      string
463
+	RegisteredByUserID pgtype.Int8
464
+	CreatedAt          pgtype.Timestamptz
465
+	UpdatedAt          pgtype.Timestamptz
466
+}
467
+
468
+func (q *Queries) LockRunnerByID(ctx context.Context, db DBTX, id int64) (LockRunnerByIDRow, error) {
255469
 	row := db.QueryRow(ctx, lockRunnerByID, id)
256
-	var i WorkflowRunner
470
+	var i LockRunnerByIDRow
257471
 	err := row.Scan(
258472
 		&i.ID,
259473
 		&i.Name,
@@ -261,6 +475,12 @@ func (q *Queries) LockRunnerByID(ctx context.Context, db DBTX, id int64) (Workfl
261475
 		&i.Capacity,
262476
 		&i.Status,
263477
 		&i.LastHeartbeatAt,
478
+		&i.HostName,
479
+		&i.Version,
480
+		&i.DrainingAt,
481
+		&i.DrainReason,
482
+		&i.RevokedAt,
483
+		&i.RevokedReason,
264484
 		&i.RegisteredByUserID,
265485
 		&i.CreatedAt,
266486
 		&i.UpdatedAt,
@@ -268,6 +488,73 @@ func (q *Queries) LockRunnerByID(ctx context.Context, db DBTX, id int64) (Workfl
268488
 	return i, err
269489
 }
270490
 
491
+const markStaleRunnersOffline = `-- name: MarkStaleRunnersOffline :many
492
+UPDATE workflow_runners
493
+SET status = 'offline',
494
+    updated_at = now()
495
+WHERE revoked_at IS NULL
496
+  AND status <> 'offline'
497
+  AND last_heartbeat_at IS NOT NULL
498
+  AND last_heartbeat_at < $1
499
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
500
+          host_name, version, draining_at, drain_reason, revoked_at,
501
+          revoked_reason, registered_by_user_id, created_at, updated_at
502
+`
503
+
504
+type MarkStaleRunnersOfflineRow struct {
505
+	ID                 int64
506
+	Name               string
507
+	Labels             []string
508
+	Capacity           int32
509
+	Status             WorkflowRunnerStatus
510
+	LastHeartbeatAt    pgtype.Timestamptz
511
+	HostName           string
512
+	Version            string
513
+	DrainingAt         pgtype.Timestamptz
514
+	DrainReason        string
515
+	RevokedAt          pgtype.Timestamptz
516
+	RevokedReason      string
517
+	RegisteredByUserID pgtype.Int8
518
+	CreatedAt          pgtype.Timestamptz
519
+	UpdatedAt          pgtype.Timestamptz
520
+}
521
+
522
+func (q *Queries) MarkStaleRunnersOffline(ctx context.Context, db DBTX, lastHeartbeatAt pgtype.Timestamptz) ([]MarkStaleRunnersOfflineRow, error) {
523
+	rows, err := db.Query(ctx, markStaleRunnersOffline, lastHeartbeatAt)
524
+	if err != nil {
525
+		return nil, err
526
+	}
527
+	defer rows.Close()
528
+	items := []MarkStaleRunnersOfflineRow{}
529
+	for rows.Next() {
530
+		var i MarkStaleRunnersOfflineRow
531
+		if err := rows.Scan(
532
+			&i.ID,
533
+			&i.Name,
534
+			&i.Labels,
535
+			&i.Capacity,
536
+			&i.Status,
537
+			&i.LastHeartbeatAt,
538
+			&i.HostName,
539
+			&i.Version,
540
+			&i.DrainingAt,
541
+			&i.DrainReason,
542
+			&i.RevokedAt,
543
+			&i.RevokedReason,
544
+			&i.RegisteredByUserID,
545
+			&i.CreatedAt,
546
+			&i.UpdatedAt,
547
+		); err != nil {
548
+			return nil, err
549
+		}
550
+		items = append(items, i)
551
+	}
552
+	if err := rows.Err(); err != nil {
553
+		return nil, err
554
+	}
555
+	return items, nil
556
+}
557
+
271558
 const revokeAllTokensForRunner = `-- name: RevokeAllTokensForRunner :exec
272559
 UPDATE runner_tokens
273560
 SET revoked_at = now()
@@ -279,6 +566,127 @@ func (q *Queries) RevokeAllTokensForRunner(ctx context.Context, db DBTX, runnerI
279566
 	return err
280567
 }
281568
 
569
+const revokeRunner = `-- name: RevokeRunner :one
570
+UPDATE workflow_runners
571
+SET revoked_at = COALESCE(revoked_at, now()),
572
+    revoked_reason = CASE WHEN revoked_at IS NULL THEN $2 ELSE revoked_reason END,
573
+    draining_at = COALESCE(draining_at, now()),
574
+    drain_reason = CASE
575
+        WHEN draining_at IS NULL THEN $2
576
+        ELSE drain_reason
577
+    END,
578
+    status = 'offline',
579
+    updated_at = now()
580
+WHERE id = $1
581
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
582
+          host_name, version, draining_at, drain_reason, revoked_at,
583
+          revoked_reason, registered_by_user_id, created_at, updated_at
584
+`
585
+
586
+type RevokeRunnerParams struct {
587
+	ID            int64
588
+	RevokedReason string
589
+}
590
+
591
+type RevokeRunnerRow struct {
592
+	ID                 int64
593
+	Name               string
594
+	Labels             []string
595
+	Capacity           int32
596
+	Status             WorkflowRunnerStatus
597
+	LastHeartbeatAt    pgtype.Timestamptz
598
+	HostName           string
599
+	Version            string
600
+	DrainingAt         pgtype.Timestamptz
601
+	DrainReason        string
602
+	RevokedAt          pgtype.Timestamptz
603
+	RevokedReason      string
604
+	RegisteredByUserID pgtype.Int8
605
+	CreatedAt          pgtype.Timestamptz
606
+	UpdatedAt          pgtype.Timestamptz
607
+}
608
+
609
+func (q *Queries) RevokeRunner(ctx context.Context, db DBTX, arg RevokeRunnerParams) (RevokeRunnerRow, error) {
610
+	row := db.QueryRow(ctx, revokeRunner, arg.ID, arg.RevokedReason)
611
+	var i RevokeRunnerRow
612
+	err := row.Scan(
613
+		&i.ID,
614
+		&i.Name,
615
+		&i.Labels,
616
+		&i.Capacity,
617
+		&i.Status,
618
+		&i.LastHeartbeatAt,
619
+		&i.HostName,
620
+		&i.Version,
621
+		&i.DrainingAt,
622
+		&i.DrainReason,
623
+		&i.RevokedAt,
624
+		&i.RevokedReason,
625
+		&i.RegisteredByUserID,
626
+		&i.CreatedAt,
627
+		&i.UpdatedAt,
628
+	)
629
+	return i, err
630
+}
631
+
632
+const setRunnerDraining = `-- name: SetRunnerDraining :one
633
+UPDATE workflow_runners
634
+SET draining_at = COALESCE(draining_at, now()),
635
+    drain_reason = $2,
636
+    updated_at = now()
637
+WHERE id = $1
638
+  AND revoked_at IS NULL
639
+RETURNING id, name, labels, capacity, status, last_heartbeat_at,
640
+          host_name, version, draining_at, drain_reason, revoked_at,
641
+          revoked_reason, registered_by_user_id, created_at, updated_at
642
+`
643
+
644
+type SetRunnerDrainingParams struct {
645
+	ID          int64
646
+	DrainReason string
647
+}
648
+
649
+type SetRunnerDrainingRow struct {
650
+	ID                 int64
651
+	Name               string
652
+	Labels             []string
653
+	Capacity           int32
654
+	Status             WorkflowRunnerStatus
655
+	LastHeartbeatAt    pgtype.Timestamptz
656
+	HostName           string
657
+	Version            string
658
+	DrainingAt         pgtype.Timestamptz
659
+	DrainReason        string
660
+	RevokedAt          pgtype.Timestamptz
661
+	RevokedReason      string
662
+	RegisteredByUserID pgtype.Int8
663
+	CreatedAt          pgtype.Timestamptz
664
+	UpdatedAt          pgtype.Timestamptz
665
+}
666
+
667
+func (q *Queries) SetRunnerDraining(ctx context.Context, db DBTX, arg SetRunnerDrainingParams) (SetRunnerDrainingRow, error) {
668
+	row := db.QueryRow(ctx, setRunnerDraining, arg.ID, arg.DrainReason)
669
+	var i SetRunnerDrainingRow
670
+	err := row.Scan(
671
+		&i.ID,
672
+		&i.Name,
673
+		&i.Labels,
674
+		&i.Capacity,
675
+		&i.Status,
676
+		&i.LastHeartbeatAt,
677
+		&i.HostName,
678
+		&i.Version,
679
+		&i.DrainingAt,
680
+		&i.DrainReason,
681
+		&i.RevokedAt,
682
+		&i.RevokedReason,
683
+		&i.RegisteredByUserID,
684
+		&i.CreatedAt,
685
+		&i.UpdatedAt,
686
+	)
687
+	return i, err
688
+}
689
+
282690
 const touchRunnerHeartbeat = `-- name: TouchRunnerHeartbeat :exec
283691
 UPDATE workflow_runners
284692
 SET last_heartbeat_at = now(),
internal/admin/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/auth/policy/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/billing/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/checks/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/issues/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/meta/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/migrationsfs/migrations/0067_runner_pool_ops.sqladded
@@ -0,0 +1,50 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+--
3
+-- S41j runner pool operations: runner metadata plus explicit drain/revoke
4
+-- state. Draining prevents new claims while allowing in-flight jobs to finish.
5
+-- Revocation is a hard operator control: registration tokens no longer
6
+-- authenticate and job API JWTs minted for that runner are rejected.
7
+
8
+-- +goose Up
9
+
10
+ALTER TABLE workflow_runners
11
+    ADD COLUMN host_name text NOT NULL DEFAULT '',
12
+    ADD COLUMN version text NOT NULL DEFAULT '',
13
+    ADD COLUMN draining_at timestamptz,
14
+    ADD COLUMN drain_reason text NOT NULL DEFAULT '',
15
+    ADD COLUMN revoked_at timestamptz,
16
+    ADD COLUMN revoked_reason text NOT NULL DEFAULT '',
17
+    ADD CONSTRAINT workflow_runners_host_name_length CHECK (char_length(host_name) <= 255),
18
+    ADD CONSTRAINT workflow_runners_version_length CHECK (char_length(version) <= 255),
19
+    ADD CONSTRAINT workflow_runners_drain_reason_length CHECK (char_length(drain_reason) <= 1000),
20
+    ADD CONSTRAINT workflow_runners_revoked_reason_length CHECK (char_length(revoked_reason) <= 1000);
21
+
22
+CREATE INDEX workflow_runners_draining_idx
23
+    ON workflow_runners (draining_at)
24
+    WHERE draining_at IS NOT NULL AND revoked_at IS NULL;
25
+
26
+CREATE INDEX workflow_runners_revoked_idx
27
+    ON workflow_runners (revoked_at)
28
+    WHERE revoked_at IS NOT NULL;
29
+
30
+CREATE INDEX workflow_runners_claimable_idx
31
+    ON workflow_runners (status)
32
+    WHERE revoked_at IS NULL AND draining_at IS NULL;
33
+
34
+-- +goose Down
35
+
36
+DROP INDEX IF EXISTS workflow_runners_claimable_idx;
37
+DROP INDEX IF EXISTS workflow_runners_revoked_idx;
38
+DROP INDEX IF EXISTS workflow_runners_draining_idx;
39
+
40
+ALTER TABLE workflow_runners
41
+    DROP CONSTRAINT IF EXISTS workflow_runners_revoked_reason_length,
42
+    DROP CONSTRAINT IF EXISTS workflow_runners_drain_reason_length,
43
+    DROP CONSTRAINT IF EXISTS workflow_runners_version_length,
44
+    DROP CONSTRAINT IF EXISTS workflow_runners_host_name_length,
45
+    DROP COLUMN IF EXISTS revoked_reason,
46
+    DROP COLUMN IF EXISTS revoked_at,
47
+    DROP COLUMN IF EXISTS drain_reason,
48
+    DROP COLUMN IF EXISTS draining_at,
49
+    DROP COLUMN IF EXISTS version,
50
+    DROP COLUMN IF EXISTS host_name;
internal/notif/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/orgs/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/pulls/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/ratelimit/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/repos/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/social/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/users/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/webhook/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {
internal/worker/sqlc/models.gomodified
@@ -2861,6 +2861,12 @@ type WorkflowRunner struct {
28612861
 	RegisteredByUserID pgtype.Int8
28622862
 	CreatedAt          pgtype.Timestamptz
28632863
 	UpdatedAt          pgtype.Timestamptz
2864
+	HostName           string
2865
+	Version            string
2866
+	DrainingAt         pgtype.Timestamptz
2867
+	DrainReason        string
2868
+	RevokedAt          pgtype.Timestamptz
2869
+	RevokedReason      string
28642870
 }
28652871
 
28662872
 type WorkflowSecret struct {