mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add agent timings (#14713)
* feat: begin impl of agent script timings * feat: add job_id and display_name to script timings * fix: increment migration number * fix: rename migrations from 251 to 254 * test: get tests compiling * fix: appease the linter * fix: get tests passing again * fix: drop column from correct table * test: add fixture for agent script timings * fix: typo * fix: use job id used in provisioner job timings * fix: increment migration number * test: behaviour of script runner * test: rewrite test * test: does exit 1 script break things? * test: rewrite test again * fix: revert change Not sure how this came to be, I do not recall manually changing these files. * fix: let code breathe * fix: wrap errors * fix: justify nolint * fix: swap require.Equal argument order * fix: add mutex operations * feat: add 'ran_on_start' and 'blocked_login' fields * fix: update testdata fixture * fix: refer to agent_id instead of job_id in timings * fix: JobID -> AgentID in dbauthz_test * fix: add 'id' to scripts, make timing refer to script id * fix: fix broken tests and convert bug * fix: update testdata fixtures * fix: update testdata fixtures again * feat: capture stage and if script timed out * fix: update migration number * test: add test for script api * fix: fake db query * fix: use UTC time * fix: ensure r.scriptComplete is not nil * fix: move err check to right after call * fix: uppercase sql * fix: use dbtime.Now() * fix: debug log on r.scriptCompleted being nil * fix: ensure correct rbac permissions * chore: remove DisplayName * fix: get tests passing * fix: remove space in sql up * docs: document ExecuteOption * fix: drop 'RETURNING' from sql * chore: remove 'display_name' from timing table * fix: testdata fixture * fix: put r.scriptCompleted call in goroutine * fix: track goroutine for test + use separate context for reporting * fix: appease linter, handle trackCommandGoroutine error * fix: resolve race condition * feat: replace timed_out column with status column * test: update testdata fixture * fix: apply suggestions from review * revert: linter changes
This commit is contained in:
@@ -3027,6 +3027,13 @@ func (q *querier) InsertWorkspaceAgentMetadata(ctx context.Context, arg database
|
||||
return q.db.InsertWorkspaceAgentMetadata(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.InsertWorkspaceAgentScriptTimings(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertWorkspaceAgentScripts(ctx context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return []database.WorkspaceAgentScript{}, err
|
||||
|
||||
@@ -2632,6 +2632,13 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
s.Run("InsertWorkspaceAppStats", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertWorkspaceAppStatsParams{}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertWorkspaceAgentScriptTimings", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertWorkspaceAgentScriptTimingsParams{
|
||||
ScriptID: uuid.New(),
|
||||
Stage: database.WorkspaceAgentScriptTimingStageStart,
|
||||
Status: database.WorkspaceAgentScriptTimingStatusOk,
|
||||
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertWorkspaceAgentScripts", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertWorkspaceAgentScriptsParams{}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
|
||||
}))
|
||||
|
||||
@@ -222,6 +222,7 @@ type data struct {
|
||||
workspaceAgentLogs []database.WorkspaceAgentLog
|
||||
workspaceAgentLogSources []database.WorkspaceAgentLogSource
|
||||
workspaceAgentPortShares []database.WorkspaceAgentPortShare
|
||||
workspaceAgentScriptTimings []database.WorkspaceAgentScriptTiming
|
||||
workspaceAgentScripts []database.WorkspaceAgentScript
|
||||
workspaceAgentStats []database.WorkspaceAgentStat
|
||||
workspaceApps []database.WorkspaceApp
|
||||
@@ -7826,6 +7827,30 @@ func (q *FakeQuerier) InsertWorkspaceAgentMetadata(_ context.Context, arg databa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) error {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings,
|
||||
//nolint:gosimple // Stop the linter complaining about changing the type of `arg`.
|
||||
database.WorkspaceAgentScriptTiming{
|
||||
ScriptID: arg.ScriptID,
|
||||
StartedAt: arg.StartedAt,
|
||||
EndedAt: arg.EndedAt,
|
||||
ExitCode: arg.ExitCode,
|
||||
Stage: arg.Stage,
|
||||
Status: arg.Status,
|
||||
},
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) InsertWorkspaceAgentScripts(_ context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
@@ -7840,6 +7865,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentScripts(_ context.Context, arg databas
|
||||
script := database.WorkspaceAgentScript{
|
||||
LogSourceID: source,
|
||||
WorkspaceAgentID: arg.WorkspaceAgentID,
|
||||
ID: arg.ID[index],
|
||||
LogPath: arg.LogPath[index],
|
||||
Script: arg.Script[index],
|
||||
Cron: arg.Cron[index],
|
||||
|
||||
@@ -1929,6 +1929,13 @@ func (m metricsStore) InsertWorkspaceAgentMetadata(ctx context.Context, arg data
|
||||
return err
|
||||
}
|
||||
|
||||
func (m metricsStore) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) error {
|
||||
start := time.Now()
|
||||
err := m.s.InsertWorkspaceAgentScriptTimings(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("InsertWorkspaceAgentScriptTimings").Observe(time.Since(start).Seconds())
|
||||
return err
|
||||
}
|
||||
|
||||
func (m metricsStore) InsertWorkspaceAgentScripts(ctx context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.InsertWorkspaceAgentScripts(ctx, arg)
|
||||
|
||||
@@ -4064,6 +4064,20 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceAgentMetadata(arg0, arg1 any) *g
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceAgentMetadata", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceAgentMetadata), arg0, arg1)
|
||||
}
|
||||
|
||||
// InsertWorkspaceAgentScriptTimings mocks base method.
|
||||
func (m *MockStore) InsertWorkspaceAgentScriptTimings(arg0 context.Context, arg1 database.InsertWorkspaceAgentScriptTimingsParams) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InsertWorkspaceAgentScriptTimings", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// InsertWorkspaceAgentScriptTimings indicates an expected call of InsertWorkspaceAgentScriptTimings.
|
||||
func (mr *MockStoreMockRecorder) InsertWorkspaceAgentScriptTimings(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceAgentScriptTimings", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceAgentScriptTimings), arg0, arg1)
|
||||
}
|
||||
|
||||
// InsertWorkspaceAgentScripts mocks base method.
|
||||
func (m *MockStore) InsertWorkspaceAgentScripts(arg0 context.Context, arg1 database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Generated
+37
-1
@@ -216,6 +216,23 @@ CREATE TYPE workspace_agent_lifecycle_state AS ENUM (
|
||||
'off'
|
||||
);
|
||||
|
||||
CREATE TYPE workspace_agent_script_timing_stage AS ENUM (
|
||||
'start',
|
||||
'stop',
|
||||
'cron'
|
||||
);
|
||||
|
||||
COMMENT ON TYPE workspace_agent_script_timing_stage IS 'What stage the script was ran in.';
|
||||
|
||||
CREATE TYPE workspace_agent_script_timing_status AS ENUM (
|
||||
'ok',
|
||||
'exit_failure',
|
||||
'timed_out',
|
||||
'pipes_left_open'
|
||||
);
|
||||
|
||||
COMMENT ON TYPE workspace_agent_script_timing_status IS 'What the exit status of the script is.';
|
||||
|
||||
CREATE TYPE workspace_agent_subsystem AS ENUM (
|
||||
'envbuilder',
|
||||
'envbox',
|
||||
@@ -1355,6 +1372,15 @@ CREATE TABLE workspace_agent_port_share (
|
||||
protocol port_share_protocol DEFAULT 'http'::port_share_protocol NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_agent_script_timings (
|
||||
script_id uuid NOT NULL,
|
||||
started_at timestamp with time zone NOT NULL,
|
||||
ended_at timestamp with time zone NOT NULL,
|
||||
exit_code integer NOT NULL,
|
||||
stage workspace_agent_script_timing_stage NOT NULL,
|
||||
status workspace_agent_script_timing_status NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_agent_scripts (
|
||||
workspace_agent_id uuid NOT NULL,
|
||||
log_source_id uuid NOT NULL,
|
||||
@@ -1366,7 +1392,8 @@ CREATE TABLE workspace_agent_scripts (
|
||||
run_on_start boolean NOT NULL,
|
||||
run_on_stop boolean NOT NULL,
|
||||
timeout_seconds integer NOT NULL,
|
||||
display_name text NOT NULL
|
||||
display_name text NOT NULL,
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE workspace_agent_startup_logs_id_seq
|
||||
@@ -1858,6 +1885,12 @@ ALTER TABLE ONLY workspace_agent_metadata
|
||||
ALTER TABLE ONLY workspace_agent_port_share
|
||||
ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_script_timings
|
||||
ADD CONSTRAINT workspace_agent_script_timings_script_id_started_at_key UNIQUE (script_id, started_at);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_scripts
|
||||
ADD CONSTRAINT workspace_agent_scripts_id_key UNIQUE (id);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_logs
|
||||
ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id);
|
||||
|
||||
@@ -2225,6 +2258,9 @@ ALTER TABLE ONLY workspace_agent_metadata
|
||||
ALTER TABLE ONLY workspace_agent_port_share
|
||||
ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_script_timings
|
||||
ADD CONSTRAINT workspace_agent_script_timings_script_id_fkey FOREIGN KEY (script_id) REFERENCES workspace_agent_scripts(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_scripts
|
||||
ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ const (
|
||||
ForeignKeyWorkspaceAgentLogSourcesWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_log_sources_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentMetadataWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_metadata_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentPortShareWorkspaceID ForeignKeyConstraint = "workspace_agent_port_share_workspace_id_fkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentScriptTimingsScriptID ForeignKeyConstraint = "workspace_agent_script_timings_script_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_fkey FOREIGN KEY (script_id) REFERENCES workspace_agent_scripts(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
DROP TYPE IF EXISTS workspace_agent_script_timing_status CASCADE;
|
||||
DROP TYPE IF EXISTS workspace_agent_script_timing_stage CASCADE;
|
||||
DROP TABLE IF EXISTS workspace_agent_script_timings;
|
||||
|
||||
ALTER TABLE workspace_agent_scripts DROP COLUMN id;
|
||||
@@ -0,0 +1,31 @@
|
||||
ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid UNIQUE NOT NULL DEFAULT gen_random_uuid();
|
||||
|
||||
CREATE TYPE workspace_agent_script_timing_stage AS ENUM (
|
||||
'start',
|
||||
'stop',
|
||||
'cron'
|
||||
);
|
||||
|
||||
COMMENT ON TYPE workspace_agent_script_timing_stage IS 'What stage the script was ran in.';
|
||||
|
||||
CREATE TYPE workspace_agent_script_timing_status AS ENUM (
|
||||
'ok',
|
||||
'exit_failure',
|
||||
'timed_out',
|
||||
'pipes_left_open'
|
||||
);
|
||||
|
||||
COMMENT ON TYPE workspace_agent_script_timing_status IS 'What the exit status of the script is.';
|
||||
|
||||
CREATE TABLE workspace_agent_script_timings
|
||||
(
|
||||
script_id uuid NOT NULL REFERENCES workspace_agent_scripts (id) ON DELETE CASCADE,
|
||||
started_at timestamp with time zone NOT NULL,
|
||||
ended_at timestamp with time zone NOT NULL,
|
||||
exit_code int NOT NULL,
|
||||
stage workspace_agent_script_timing_stage NOT NULL,
|
||||
status workspace_agent_script_timing_status NOT NULL,
|
||||
UNIQUE (script_id, started_at)
|
||||
);
|
||||
|
||||
COMMENT ON TYPE workspace_agent_script_timings IS 'Timing and execution information about a script run.';
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
INSERT INTO workspace_agent_script_timings (script_id, started_at, ended_at, exit_code, stage, status)
|
||||
VALUES
|
||||
((SELECT id FROM workspace_agent_scripts LIMIT 1), NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, 'start', 'ok');
|
||||
@@ -1881,6 +1881,133 @@ func AllWorkspaceAgentLifecycleStateValues() []WorkspaceAgentLifecycleState {
|
||||
}
|
||||
}
|
||||
|
||||
// What stage the script was ran in.
|
||||
type WorkspaceAgentScriptTimingStage string
|
||||
|
||||
const (
|
||||
WorkspaceAgentScriptTimingStageStart WorkspaceAgentScriptTimingStage = "start"
|
||||
WorkspaceAgentScriptTimingStageStop WorkspaceAgentScriptTimingStage = "stop"
|
||||
WorkspaceAgentScriptTimingStageCron WorkspaceAgentScriptTimingStage = "cron"
|
||||
)
|
||||
|
||||
func (e *WorkspaceAgentScriptTimingStage) Scan(src interface{}) error {
|
||||
switch s := src.(type) {
|
||||
case []byte:
|
||||
*e = WorkspaceAgentScriptTimingStage(s)
|
||||
case string:
|
||||
*e = WorkspaceAgentScriptTimingStage(s)
|
||||
default:
|
||||
return fmt.Errorf("unsupported scan type for WorkspaceAgentScriptTimingStage: %T", src)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NullWorkspaceAgentScriptTimingStage struct {
|
||||
WorkspaceAgentScriptTimingStage WorkspaceAgentScriptTimingStage `json:"workspace_agent_script_timing_stage"`
|
||||
Valid bool `json:"valid"` // Valid is true if WorkspaceAgentScriptTimingStage is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (ns *NullWorkspaceAgentScriptTimingStage) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
ns.WorkspaceAgentScriptTimingStage, ns.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
ns.Valid = true
|
||||
return ns.WorkspaceAgentScriptTimingStage.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (ns NullWorkspaceAgentScriptTimingStage) Value() (driver.Value, error) {
|
||||
if !ns.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return string(ns.WorkspaceAgentScriptTimingStage), nil
|
||||
}
|
||||
|
||||
func (e WorkspaceAgentScriptTimingStage) Valid() bool {
|
||||
switch e {
|
||||
case WorkspaceAgentScriptTimingStageStart,
|
||||
WorkspaceAgentScriptTimingStageStop,
|
||||
WorkspaceAgentScriptTimingStageCron:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func AllWorkspaceAgentScriptTimingStageValues() []WorkspaceAgentScriptTimingStage {
|
||||
return []WorkspaceAgentScriptTimingStage{
|
||||
WorkspaceAgentScriptTimingStageStart,
|
||||
WorkspaceAgentScriptTimingStageStop,
|
||||
WorkspaceAgentScriptTimingStageCron,
|
||||
}
|
||||
}
|
||||
|
||||
// What the exit status of the script is.
|
||||
type WorkspaceAgentScriptTimingStatus string
|
||||
|
||||
const (
|
||||
WorkspaceAgentScriptTimingStatusOk WorkspaceAgentScriptTimingStatus = "ok"
|
||||
WorkspaceAgentScriptTimingStatusExitFailure WorkspaceAgentScriptTimingStatus = "exit_failure"
|
||||
WorkspaceAgentScriptTimingStatusTimedOut WorkspaceAgentScriptTimingStatus = "timed_out"
|
||||
WorkspaceAgentScriptTimingStatusPipesLeftOpen WorkspaceAgentScriptTimingStatus = "pipes_left_open"
|
||||
)
|
||||
|
||||
func (e *WorkspaceAgentScriptTimingStatus) Scan(src interface{}) error {
|
||||
switch s := src.(type) {
|
||||
case []byte:
|
||||
*e = WorkspaceAgentScriptTimingStatus(s)
|
||||
case string:
|
||||
*e = WorkspaceAgentScriptTimingStatus(s)
|
||||
default:
|
||||
return fmt.Errorf("unsupported scan type for WorkspaceAgentScriptTimingStatus: %T", src)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NullWorkspaceAgentScriptTimingStatus struct {
|
||||
WorkspaceAgentScriptTimingStatus WorkspaceAgentScriptTimingStatus `json:"workspace_agent_script_timing_status"`
|
||||
Valid bool `json:"valid"` // Valid is true if WorkspaceAgentScriptTimingStatus is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (ns *NullWorkspaceAgentScriptTimingStatus) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
ns.WorkspaceAgentScriptTimingStatus, ns.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
ns.Valid = true
|
||||
return ns.WorkspaceAgentScriptTimingStatus.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (ns NullWorkspaceAgentScriptTimingStatus) Value() (driver.Value, error) {
|
||||
if !ns.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return string(ns.WorkspaceAgentScriptTimingStatus), nil
|
||||
}
|
||||
|
||||
func (e WorkspaceAgentScriptTimingStatus) Valid() bool {
|
||||
switch e {
|
||||
case WorkspaceAgentScriptTimingStatusOk,
|
||||
WorkspaceAgentScriptTimingStatusExitFailure,
|
||||
WorkspaceAgentScriptTimingStatusTimedOut,
|
||||
WorkspaceAgentScriptTimingStatusPipesLeftOpen:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func AllWorkspaceAgentScriptTimingStatusValues() []WorkspaceAgentScriptTimingStatus {
|
||||
return []WorkspaceAgentScriptTimingStatus{
|
||||
WorkspaceAgentScriptTimingStatusOk,
|
||||
WorkspaceAgentScriptTimingStatusExitFailure,
|
||||
WorkspaceAgentScriptTimingStatusTimedOut,
|
||||
WorkspaceAgentScriptTimingStatusPipesLeftOpen,
|
||||
}
|
||||
}
|
||||
|
||||
type WorkspaceAgentSubsystem string
|
||||
|
||||
const (
|
||||
@@ -2881,6 +3008,16 @@ type WorkspaceAgentScript struct {
|
||||
RunOnStop bool `db:"run_on_stop" json:"run_on_stop"`
|
||||
TimeoutSeconds int32 `db:"timeout_seconds" json:"timeout_seconds"`
|
||||
DisplayName string `db:"display_name" json:"display_name"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentScriptTiming struct {
|
||||
ScriptID uuid.UUID `db:"script_id" json:"script_id"`
|
||||
StartedAt time.Time `db:"started_at" json:"started_at"`
|
||||
EndedAt time.Time `db:"ended_at" json:"ended_at"`
|
||||
ExitCode int32 `db:"exit_code" json:"exit_code"`
|
||||
Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"`
|
||||
Status WorkspaceAgentScriptTimingStatus `db:"status" json:"status"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentStat struct {
|
||||
|
||||
@@ -394,6 +394,7 @@ type sqlcQuerier interface {
|
||||
InsertWorkspaceAgentLogSources(ctx context.Context, arg InsertWorkspaceAgentLogSourcesParams) ([]WorkspaceAgentLogSource, error)
|
||||
InsertWorkspaceAgentLogs(ctx context.Context, arg InsertWorkspaceAgentLogsParams) ([]WorkspaceAgentLog, error)
|
||||
InsertWorkspaceAgentMetadata(ctx context.Context, arg InsertWorkspaceAgentMetadataParams) error
|
||||
InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) error
|
||||
InsertWorkspaceAgentScripts(ctx context.Context, arg InsertWorkspaceAgentScriptsParams) ([]WorkspaceAgentScript, error)
|
||||
InsertWorkspaceAgentStats(ctx context.Context, arg InsertWorkspaceAgentStatsParams) error
|
||||
InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error)
|
||||
|
||||
@@ -11802,6 +11802,41 @@ func (q *sqlQuerier) InsertWorkspaceAgentMetadata(ctx context.Context, arg Inser
|
||||
return err
|
||||
}
|
||||
|
||||
const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTimings :exec
|
||||
INSERT INTO
|
||||
workspace_agent_script_timings (
|
||||
script_id,
|
||||
started_at,
|
||||
ended_at,
|
||||
exit_code,
|
||||
stage,
|
||||
status
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6)
|
||||
`
|
||||
|
||||
type InsertWorkspaceAgentScriptTimingsParams struct {
|
||||
ScriptID uuid.UUID `db:"script_id" json:"script_id"`
|
||||
StartedAt time.Time `db:"started_at" json:"started_at"`
|
||||
EndedAt time.Time `db:"ended_at" json:"ended_at"`
|
||||
ExitCode int32 `db:"exit_code" json:"exit_code"`
|
||||
Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"`
|
||||
Status WorkspaceAgentScriptTimingStatus `db:"status" json:"status"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) error {
|
||||
_, err := q.db.ExecContext(ctx, insertWorkspaceAgentScriptTimings,
|
||||
arg.ScriptID,
|
||||
arg.StartedAt,
|
||||
arg.EndedAt,
|
||||
arg.ExitCode,
|
||||
arg.Stage,
|
||||
arg.Status,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateWorkspaceAgentConnectionByID = `-- name: UpdateWorkspaceAgentConnectionByID :exec
|
||||
UPDATE
|
||||
workspace_agents
|
||||
@@ -15492,7 +15527,7 @@ func (q *sqlQuerier) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.C
|
||||
}
|
||||
|
||||
const getWorkspaceAgentScriptsByAgentIDs = `-- name: GetWorkspaceAgentScriptsByAgentIDs :many
|
||||
SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ])
|
||||
SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name, id FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ])
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgentScript, error) {
|
||||
@@ -15516,6 +15551,7 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids
|
||||
&i.RunOnStop,
|
||||
&i.TimeoutSeconds,
|
||||
&i.DisplayName,
|
||||
&i.ID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -15532,7 +15568,7 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids
|
||||
|
||||
const insertWorkspaceAgentScripts = `-- name: InsertWorkspaceAgentScripts :many
|
||||
INSERT INTO
|
||||
workspace_agent_scripts (workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name)
|
||||
workspace_agent_scripts (workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name, id)
|
||||
SELECT
|
||||
$1 :: uuid AS workspace_agent_id,
|
||||
$2 :: timestamptz AS created_at,
|
||||
@@ -15544,8 +15580,9 @@ SELECT
|
||||
unnest($8 :: boolean [ ]) AS run_on_start,
|
||||
unnest($9 :: boolean [ ]) AS run_on_stop,
|
||||
unnest($10 :: integer [ ]) AS timeout_seconds,
|
||||
unnest($11 :: text [ ]) AS display_name
|
||||
RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds, workspace_agent_scripts.display_name
|
||||
unnest($11 :: text [ ]) AS display_name,
|
||||
unnest($12 :: uuid [ ]) AS id
|
||||
RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds, workspace_agent_scripts.display_name, workspace_agent_scripts.id
|
||||
`
|
||||
|
||||
type InsertWorkspaceAgentScriptsParams struct {
|
||||
@@ -15560,6 +15597,7 @@ type InsertWorkspaceAgentScriptsParams struct {
|
||||
RunOnStop []bool `db:"run_on_stop" json:"run_on_stop"`
|
||||
TimeoutSeconds []int32 `db:"timeout_seconds" json:"timeout_seconds"`
|
||||
DisplayName []string `db:"display_name" json:"display_name"`
|
||||
ID []uuid.UUID `db:"id" json:"id"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg InsertWorkspaceAgentScriptsParams) ([]WorkspaceAgentScript, error) {
|
||||
@@ -15575,6 +15613,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert
|
||||
pq.Array(arg.RunOnStop),
|
||||
pq.Array(arg.TimeoutSeconds),
|
||||
pq.Array(arg.DisplayName),
|
||||
pq.Array(arg.ID),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -15595,6 +15634,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert
|
||||
&i.RunOnStop,
|
||||
&i.TimeoutSeconds,
|
||||
&i.DisplayName,
|
||||
&i.ID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -287,3 +287,16 @@ WHERE
|
||||
workspace_id = workspace_build_with_user.workspace_id
|
||||
)
|
||||
;
|
||||
|
||||
-- name: InsertWorkspaceAgentScriptTimings :exec
|
||||
INSERT INTO
|
||||
workspace_agent_script_timings (
|
||||
script_id,
|
||||
started_at,
|
||||
ended_at,
|
||||
exit_code,
|
||||
stage,
|
||||
status
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- name: InsertWorkspaceAgentScripts :many
|
||||
INSERT INTO
|
||||
workspace_agent_scripts (workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name)
|
||||
workspace_agent_scripts (workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name, id)
|
||||
SELECT
|
||||
@workspace_agent_id :: uuid AS workspace_agent_id,
|
||||
@created_at :: timestamptz AS created_at,
|
||||
@@ -12,7 +12,8 @@ SELECT
|
||||
unnest(@run_on_start :: boolean [ ]) AS run_on_start,
|
||||
unnest(@run_on_stop :: boolean [ ]) AS run_on_stop,
|
||||
unnest(@timeout_seconds :: integer [ ]) AS timeout_seconds,
|
||||
unnest(@display_name :: text [ ]) AS display_name
|
||||
unnest(@display_name :: text [ ]) AS display_name,
|
||||
unnest(@id :: uuid [ ]) AS id
|
||||
RETURNING workspace_agent_scripts.*;
|
||||
|
||||
-- name: GetWorkspaceAgentScriptsByAgentIDs :many
|
||||
|
||||
@@ -67,6 +67,8 @@ const (
|
||||
UniqueWorkspaceAgentLogSourcesPkey UniqueConstraint = "workspace_agent_log_sources_pkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_pkey PRIMARY KEY (workspace_agent_id, id);
|
||||
UniqueWorkspaceAgentMetadataPkey UniqueConstraint = "workspace_agent_metadata_pkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_pkey PRIMARY KEY (workspace_agent_id, key);
|
||||
UniqueWorkspaceAgentPortSharePkey UniqueConstraint = "workspace_agent_port_share_pkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port);
|
||||
UniqueWorkspaceAgentScriptTimingsScriptIDStartedAtKey UniqueConstraint = "workspace_agent_script_timings_script_id_started_at_key" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_started_at_key UNIQUE (script_id, started_at);
|
||||
UniqueWorkspaceAgentScriptsIDKey UniqueConstraint = "workspace_agent_scripts_id_key" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_id_key UNIQUE (id);
|
||||
UniqueWorkspaceAgentStartupLogsPkey UniqueConstraint = "workspace_agent_startup_logs_pkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAgentsPkey UniqueConstraint = "workspace_agents_pkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAppStatsPkey UniqueConstraint = "workspace_app_stats_pkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_pkey PRIMARY KEY (id);
|
||||
|
||||
Reference in New Issue
Block a user