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:
Danielle Maywood
2024-09-24 10:51:49 +01:00
committed by GitHub
parent b8944074c4
commit ae522c558d
43 changed files with 1367 additions and 232 deletions
+7
View File
@@ -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
+7
View File
@@ -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)
}))
+26
View File
@@ -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],
+7
View File
@@ -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)
+14
View File
@@ -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()
+37 -1
View File
@@ -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.';
@@ -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');
+137
View File
@@ -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 {
+1
View File
@@ -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)
+44 -4
View File
@@ -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);
+3 -2
View File
@@ -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
+2
View File
@@ -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);