@@ -26,6 +26,7 @@ import (
26
26
"github.com/coder/coder/v2/coderd/database/dbauthz"
27
27
"github.com/coder/coder/v2/coderd/database/dbtime"
28
28
"github.com/coder/coder/v2/coderd/database/provisionerjobs"
29
+ "github.com/coder/coder/v2/coderd/provisionerdserver"
29
30
"github.com/coder/coder/v2/coderd/database/pubsub"
30
31
"github.com/coder/coder/v2/coderd/notifications"
31
32
"github.com/coder/coder/v2/coderd/schedule"
@@ -131,6 +132,30 @@ func (e *Executor) Run() {
131
132
}()
132
133
}
133
134
135
+ // Add this function to check for available provisioners
136
+ func (e * Executor ) hasAvailableProvisioners (ctx context.Context , tx database.Store , ws database.Workspace , templateVersionJob database.ProvisionerJob ) (bool , error ) {
137
+ // Get eligible provisioner daemons for this workspace's template
138
+ provisionerDaemons , err := tx .GetProvisionerDaemonsByOrganization (ctx , database.GetProvisionerDaemonsByOrganizationParams {
139
+ OrganizationID : ws .OrganizationID ,
140
+ WantTags : templateVersionJob .Tags ,
141
+ })
142
+ if err != nil {
143
+ return false , xerrors .Errorf ("get provisioner daemons: %w" , err )
144
+ }
145
+
146
+ // Check if any provisioners are active (not stale)
147
+ now := dbtime .Now ()
148
+ for _ , pd := range provisionerDaemons {
149
+ if pd .LastSeenAt .Valid {
150
+ age := now .Sub (pd .LastSeenAt .Time )
151
+ if age <= provisionerdserver .StaleInterval {
152
+ return true , nil
153
+ }
154
+ }
155
+ }
156
+ return false , nil
157
+ }
158
+
134
159
func (e * Executor ) runOnce (t time.Time ) Stats {
135
160
stats := Stats {
136
161
Transitions : make (map [uuid.UUID ]database.WorkspaceTransition ),
@@ -280,6 +305,22 @@ func (e *Executor) runOnce(t time.Time) Stats {
280
305
return nil
281
306
}
282
307
308
+ // Get the template version job to access tags
309
+ templateVersionJob , err := tx .GetProvisionerJobByID (e .ctx , activeTemplateVersion .JobID )
310
+ if err != nil {
311
+ return xerrors .Errorf ("get template version job: %w" , err )
312
+ }
313
+
314
+ // Before creating the workspace build, check for available provisioners
315
+ hasProvisioners , err := e .hasAvailableProvisioners (e .ctx , tx , ws , templateVersionJob )
316
+ if err != nil {
317
+ return xerrors .Errorf ("check provisioner availability: %w" , err )
318
+ }
319
+ if ! hasProvisioners {
320
+ log .Warn (e .ctx , "skipping autostart - no available provisioners" )
321
+ return nil // Skip this workspace
322
+ }
323
+
283
324
if nextTransition != "" {
284
325
builder := wsbuilder .New (ws , nextTransition , * e .buildUsageChecker .Load ()).
285
326
SetLastWorkspaceBuildInTx (& latestBuild ).
0 commit comments