@@ -19,10 +19,12 @@ import (
19
19
"github.com/spf13/afero"
20
20
"golang.org/x/sync/errgroup"
21
21
"golang.org/x/xerrors"
22
+ "google.golang.org/protobuf/types/known/timestamppb"
22
23
23
24
"cdr.dev/slog"
24
25
25
26
"github.com/coder/coder/v2/agent/agentssh"
27
+ "github.com/coder/coder/v2/agent/proto"
26
28
"github.com/coder/coder/v2/codersdk"
27
29
"github.com/coder/coder/v2/codersdk/agentsdk"
28
30
)
@@ -66,7 +68,6 @@ func New(opts Options) *Runner {
66
68
cronCtxCancel :cronCtxCancel ,
67
69
cron :cron .New (cron .WithParser (parser )),
68
70
closed :make (chan struct {}),
69
- scriptTimings :make (chan TimingSpan ),
70
71
dataDir :filepath .Join (opts .DataDirBase ,"coder-script-data" ),
71
72
scriptsExecuted :prometheus .NewCounterVec (prometheus.CounterOpts {
72
73
Namespace :"agent" ,
@@ -76,30 +77,28 @@ func New(opts Options) *Runner {
76
77
}
77
78
}
78
79
80
+ type ScriptCompletedFunc func (context.Context ,* proto.WorkspaceAgentScriptCompletedRequest ) (* proto.WorkspaceAgentScriptCompletedResponse ,error )
81
+
79
82
type Runner struct {
80
83
Options
81
84
82
- cronCtx context.Context
83
- cronCtxCancel context.CancelFunc
84
- cmdCloseWait sync.WaitGroup
85
- closed chan struct {}
86
- closeMutex sync.Mutex
87
- cron * cron.Cron
88
- initialized atomic.Bool
89
- scripts []codersdk.WorkspaceAgentScript
90
- scriptTimings chan TimingSpan
91
- dataDir string
85
+ cronCtx context.Context
86
+ cronCtxCancel context.CancelFunc
87
+ cmdCloseWait sync.WaitGroup
88
+ closed chan struct {}
89
+ closeMutex sync.Mutex
90
+ cron * cron.Cron
91
+ initialized atomic.Bool
92
+ scripts []codersdk.WorkspaceAgentScript
93
+ dataDir string
94
+ scriptCompleted ScriptCompletedFunc
92
95
93
96
// scriptsExecuted includes all scripts executed by the workspace agent. Agents
94
97
// execute startup scripts, and scripts on a cron schedule. Both will increment
95
98
// this counter.
96
99
scriptsExecuted * prometheus.CounterVec
97
100
}
98
101
99
- func (r * Runner )ScriptTimings ()* chan TimingSpan {
100
- return & r .scriptTimings
101
- }
102
-
103
102
// DataDir returns the directory where scripts data is stored.
104
103
func (r * Runner )DataDir ()string {
105
104
return r .dataDir
@@ -122,12 +121,13 @@ func (r *Runner) RegisterMetrics(reg prometheus.Registerer) {
122
121
// Init initializes the runner with the provided scripts.
123
122
// It also schedules any scripts that have a schedule.
124
123
// This function must be called before Execute.
125
- func (r * Runner )Init (scripts []codersdk.WorkspaceAgentScript )error {
124
+ func (r * Runner )Init (scripts []codersdk.WorkspaceAgentScript , scriptCompleted ScriptCompletedFunc )error {
126
125
if r .initialized .Load () {
127
126
return xerrors .New ("init: already initialized" )
128
127
}
129
128
r .initialized .Store (true )
130
129
r .scripts = scripts
130
+ r .scriptCompleted = scriptCompleted
131
131
r .Logger .Info (r .cronCtx ,"initializing agent scripts" ,slog .F ("script_count" ,len (scripts )),slog .F ("log_dir" ,r .LogDir ))
132
132
133
133
err := r .Filesystem .MkdirAll (r .ScriptBinDir (),0o700 )
@@ -321,12 +321,14 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript)
321
321
logger .Info (ctx ,fmt .Sprintf ("%s script completed" ,logPath ),slog .F ("execution_time" ,execTime ),slog .F ("exit_code" ,exitCode ))
322
322
}
323
323
324
- r .scriptTimings <- TimingSpan {
325
- displayName :script .DisplayName ,
326
- start :start ,
327
- end :end ,
328
- exitCode :int32 (exitCode ),
329
- }
324
+ _ ,err = r .scriptCompleted (ctx ,& proto.WorkspaceAgentScriptCompletedRequest {
325
+ Timing :& proto.Timing {
326
+ DisplayName :script .DisplayName ,
327
+ Start :timestamppb .New (start ),
328
+ End :timestamppb .New (end ),
329
+ ExitCode :int32 (exitCode ),
330
+ },
331
+ })
330
332
}()
331
333
332
334
err = cmd .Start ()