chore: allow multiple agent subsystems, add exectrace (#8933)

This commit is contained in:
Dean Sheather 2023-08-08 22:10:28 -07:00 committed by GitHub
parent 70bd23a40a
commit 07fd73c4a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 285 additions and 119 deletions

View File

@ -64,7 +64,7 @@ type Options struct {
IgnorePorts map[int]string
SSHMaxTimeout time.Duration
TailnetListenPort uint16
Subsystem codersdk.AgentSubsystem
Subsystems []codersdk.AgentSubsystem
Addresses []netip.Prefix
PrometheusRegistry *prometheus.Registry
ReportMetadataInterval time.Duration
@ -145,7 +145,7 @@ func New(options Options) Agent {
reportMetadataInterval: options.ReportMetadataInterval,
serviceBannerRefreshInterval: options.ServiceBannerRefreshInterval,
sshMaxTimeout: options.SSHMaxTimeout,
subsystem: options.Subsystem,
subsystems: options.Subsystems,
addresses: options.Addresses,
prometheusRegistry: prometheusRegistry,
@ -167,7 +167,7 @@ type agent struct {
// listing all listening ports. This is helpful to hide ports that
// are used by the agent, that the user does not care about.
ignorePorts map[int]string
subsystem codersdk.AgentSubsystem
subsystems []codersdk.AgentSubsystem
reconnectingPTYs sync.Map
reconnectingPTYTimeout time.Duration
@ -609,7 +609,7 @@ func (a *agent) run(ctx context.Context) error {
err = a.client.PostStartup(ctx, agentsdk.PostStartupRequest{
Version: buildinfo.Version(),
ExpandedDirectory: manifest.Directory,
Subsystem: a.subsystem,
Subsystems: a.subsystems,
})
if err != nil {
return xerrors.Errorf("update workspace agent version: %w", err)

View File

@ -12,6 +12,7 @@ import (
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
"time"
@ -253,7 +254,19 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
}
prometheusRegistry := prometheus.NewRegistry()
subsystem := inv.Environ.Get(agent.EnvAgentSubsystem)
subsystemsRaw := inv.Environ.Get(agent.EnvAgentSubsystem)
subsystems := []codersdk.AgentSubsystem{}
for _, s := range strings.Split(subsystemsRaw, ",") {
subsystem := codersdk.AgentSubsystem(strings.TrimSpace(s))
if subsystem == "" {
continue
}
if !subsystem.Valid() {
return xerrors.Errorf("invalid subsystem %q", subsystem)
}
subsystems = append(subsystems, subsystem)
}
agnt := agent.New(agent.Options{
Client: client,
Logger: logger,
@ -275,7 +288,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
},
IgnorePorts: ignorePorts,
SSHMaxTimeout: sshMaxTimeout,
Subsystem: codersdk.AgentSubsystem(subsystem),
Subsystems: subsystems,
PrometheusRegistry: prometheusRegistry,
})

View File

@ -2,6 +2,7 @@ package cli_test
import (
"context"
"fmt"
"os"
"path/filepath"
"runtime"
@ -264,8 +265,8 @@ func TestWorkspaceAgent(t *testing.T) {
"--agent-url", client.URL.String(),
"--log-dir", logDir,
)
// Set the subsystem for the agent.
inv.Environ.Set(agent.EnvAgentSubsystem, string(codersdk.AgentSubsystemEnvbox))
// Set the subsystems for the agent.
inv.Environ.Set(agent.EnvAgentSubsystem, fmt.Sprintf("%s,%s", codersdk.AgentSubsystemExectrace, codersdk.AgentSubsystemEnvbox))
pty := ptytest.New(t).Attach(inv)
@ -275,6 +276,9 @@ func TestWorkspaceAgent(t *testing.T) {
resources := coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
require.Len(t, resources, 1)
require.Len(t, resources[0].Agents, 1)
require.Equal(t, codersdk.AgentSubsystemEnvbox, resources[0].Agents[0].Subsystem)
require.Len(t, resources[0].Agents[0].Subsystems, 2)
// Sorted
require.Equal(t, codersdk.AgentSubsystemEnvbox, resources[0].Agents[0].Subsystems[0])
require.Equal(t, codersdk.AgentSubsystemExectrace, resources[0].Agents[0].Subsystems[1])
})
}

22
coderd/apidoc/docs.go generated
View File

@ -6447,8 +6447,11 @@ const docTemplate = `{
"expanded_directory": {
"type": "string"
},
"subsystem": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
"subsystems": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
}
},
"version": {
"type": "string"
@ -6903,10 +6906,14 @@ const docTemplate = `{
"codersdk.AgentSubsystem": {
"type": "string",
"enum": [
"envbox"
"envbox",
"envbuilder",
"exectrace"
],
"x-enum-varnames": [
"AgentSubsystemEnvbox"
"AgentSubsystemEnvbox",
"AgentSubsystemEnvbuilder",
"AgentSubsystemExectrace"
]
},
"codersdk.AppHostResponse": {
@ -10556,8 +10563,11 @@ const docTemplate = `{
"status": {
"$ref": "#/definitions/codersdk.WorkspaceAgentStatus"
},
"subsystem": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
"subsystems": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
}
},
"troubleshooting_url": {
"type": "string"

View File

@ -5697,8 +5697,11 @@
"expanded_directory": {
"type": "string"
},
"subsystem": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
"subsystems": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
}
},
"version": {
"type": "string"
@ -6130,8 +6133,12 @@
},
"codersdk.AgentSubsystem": {
"type": "string",
"enum": ["envbox"],
"x-enum-varnames": ["AgentSubsystemEnvbox"]
"enum": ["envbox", "envbuilder", "exectrace"],
"x-enum-varnames": [
"AgentSubsystemEnvbox",
"AgentSubsystemEnvbuilder",
"AgentSubsystemExectrace"
]
},
"codersdk.AppHostResponse": {
"type": "object",
@ -9571,8 +9578,11 @@
"status": {
"$ref": "#/definitions/codersdk.WorkspaceAgentStatus"
},
"subsystem": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
"subsystems": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.AgentSubsystem"
}
},
"troubleshooting_url": {
"type": "string"

View File

@ -1064,8 +1064,10 @@ func (s *MethodTestSuite) TestWorkspace() {
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
check.Args(database.UpdateWorkspaceAgentStartupByIDParams{
ID: agt.ID,
Subsystem: database.WorkspaceAgentSubsystemNone,
ID: agt.ID,
Subsystems: []database.WorkspaceAgentSubsystem{
database.WorkspaceAgentSubsystemEnvbox,
},
}).Asserts(ws, rbac.ActionUpdate).Returns()
}))
s.Run("GetWorkspaceAgentLogsAfter", s.Subtest(func(db database.Store, check *expects) {

View File

@ -5203,6 +5203,23 @@ func (q *FakeQuerier) UpdateWorkspaceAgentStartupByID(_ context.Context, arg dat
return err
}
if len(arg.Subsystems) > 0 {
seen := map[database.WorkspaceAgentSubsystem]struct{}{
arg.Subsystems[0]: {},
}
for i := 1; i < len(arg.Subsystems); i++ {
s := arg.Subsystems[i]
if _, ok := seen[s]; ok {
return xerrors.Errorf("duplicate subsystem %q", s)
}
seen[s] = struct{}{}
if arg.Subsystems[i-1] > arg.Subsystems[i] {
return xerrors.Errorf("subsystems not sorted: %q > %q", arg.Subsystems[i-1], arg.Subsystems[i])
}
}
}
q.mutex.Lock()
defer q.mutex.Unlock()
@ -5213,7 +5230,7 @@ func (q *FakeQuerier) UpdateWorkspaceAgentStartupByID(_ context.Context, arg dat
agent.Version = arg.Version
agent.ExpandedDirectory = arg.ExpandedDirectory
agent.Subsystem = arg.Subsystem
agent.Subsystems = arg.Subsystems
q.workspaceAgents[index] = agent
return nil
}

View File

@ -148,7 +148,8 @@ CREATE TYPE workspace_agent_log_source AS ENUM (
CREATE TYPE workspace_agent_subsystem AS ENUM (
'envbuilder',
'envbox',
'none'
'none',
'exectrace'
);
CREATE TYPE workspace_app_health AS ENUM (
@ -775,11 +776,12 @@ CREATE TABLE workspace_agents (
shutdown_script_timeout_seconds integer DEFAULT 0 NOT NULL,
logs_length integer DEFAULT 0 NOT NULL,
logs_overflowed boolean DEFAULT false NOT NULL,
subsystem workspace_agent_subsystem DEFAULT 'none'::workspace_agent_subsystem NOT NULL,
startup_script_behavior startup_script_behavior DEFAULT 'non-blocking'::startup_script_behavior NOT NULL,
started_at timestamp with time zone,
ready_at timestamp with time zone,
CONSTRAINT max_logs_length CHECK ((logs_length <= 1048576))
subsystems workspace_agent_subsystem[] DEFAULT '{}'::workspace_agent_subsystem[],
CONSTRAINT max_logs_length CHECK ((logs_length <= 1048576)),
CONSTRAINT subsystems_not_none CHECK ((NOT ('none'::workspace_agent_subsystem = ANY (subsystems))))
);
COMMENT ON COLUMN workspace_agents.version IS 'Version tracks the version of the currently running workspace agent. Workspace agents register their version upon start.';

View File

@ -0,0 +1,17 @@
BEGIN;
-- Bring back the subsystem column.
ALTER TABLE workspace_agents ADD COLUMN subsystem workspace_agent_subsystem NOT NULL DEFAULT 'none';
-- Update all existing workspace_agents to have subsystem = subsystems[0] unless
-- subsystems is empty.
UPDATE workspace_agents SET subsystem = subsystems[1] WHERE cardinality(subsystems) > 0;
-- Drop the subsystems column from workspace_agents.
ALTER TABLE workspace_agents DROP COLUMN subsystems;
-- We cannot drop the "exectrace" value from the workspace_agent_subsystem type
-- because you cannot drop values from an enum type.
UPDATE workspace_agents SET subsystem = 'none' WHERE subsystem = 'exectrace';
COMMIT;

View File

@ -0,0 +1,21 @@
BEGIN;
-- Add "exectrace" to workspace_agent_subsystem type.
ALTER TYPE workspace_agent_subsystem ADD VALUE 'exectrace';
-- Create column subsystems in workspace_agents table, with default value being
-- an empty array.
ALTER TABLE workspace_agents ADD COLUMN subsystems workspace_agent_subsystem[] DEFAULT '{}';
-- Add a constraint that the subsystems cannot contain the deprecated value
-- 'none'.
ALTER TABLE workspace_agents ADD CONSTRAINT subsystems_not_none CHECK (NOT ('none' = ANY (subsystems)));
-- Update all existing workspace_agents to have subsystems = [subsystem] unless
-- the subsystem is 'none'.
UPDATE workspace_agents SET subsystems = ARRAY[subsystem] WHERE subsystem != 'none';
-- Drop the subsystem column from workspace_agents.
ALTER TABLE workspace_agents DROP COLUMN subsystem;
COMMIT;

View File

@ -1307,6 +1307,7 @@ const (
WorkspaceAgentSubsystemEnvbuilder WorkspaceAgentSubsystem = "envbuilder"
WorkspaceAgentSubsystemEnvbox WorkspaceAgentSubsystem = "envbox"
WorkspaceAgentSubsystemNone WorkspaceAgentSubsystem = "none"
WorkspaceAgentSubsystemExectrace WorkspaceAgentSubsystem = "exectrace"
)
func (e *WorkspaceAgentSubsystem) Scan(src interface{}) error {
@ -1348,7 +1349,8 @@ func (e WorkspaceAgentSubsystem) Valid() bool {
switch e {
case WorkspaceAgentSubsystemEnvbuilder,
WorkspaceAgentSubsystemEnvbox,
WorkspaceAgentSubsystemNone:
WorkspaceAgentSubsystemNone,
WorkspaceAgentSubsystemExectrace:
return true
}
return false
@ -1359,6 +1361,7 @@ func AllWorkspaceAgentSubsystemValues() []WorkspaceAgentSubsystem {
WorkspaceAgentSubsystemEnvbuilder,
WorkspaceAgentSubsystemEnvbox,
WorkspaceAgentSubsystemNone,
WorkspaceAgentSubsystemExectrace,
}
}
@ -1944,14 +1947,14 @@ type WorkspaceAgent struct {
// Total length of startup logs
LogsLength int32 `db:"logs_length" json:"logs_length"`
// Whether the startup logs overflowed in length
LogsOverflowed bool `db:"logs_overflowed" json:"logs_overflowed"`
Subsystem WorkspaceAgentSubsystem `db:"subsystem" json:"subsystem"`
LogsOverflowed bool `db:"logs_overflowed" json:"logs_overflowed"`
// When startup script behavior is non-blocking, the workspace will be ready and accessible upon agent connection, when it is blocking, workspace will wait for the startup script to complete before becoming ready and accessible.
StartupScriptBehavior StartupScriptBehavior `db:"startup_script_behavior" json:"startup_script_behavior"`
// The time the agent entered the starting lifecycle state
StartedAt sql.NullTime `db:"started_at" json:"started_at"`
// The time the agent entered the ready or start_error lifecycle state
ReadyAt sql.NullTime `db:"ready_at" json:"ready_at"`
ReadyAt sql.NullTime `db:"ready_at" json:"ready_at"`
Subsystems []WorkspaceAgentSubsystem `db:"subsystems" json:"subsystems"`
}
type WorkspaceAgentLog struct {

View File

@ -6239,7 +6239,7 @@ func (q *sqlQuerier) DeleteOldWorkspaceAgentLogs(ctx context.Context) error {
const getWorkspaceAgentByAuthToken = `-- name: GetWorkspaceAgentByAuthToken :one
SELECT
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, subsystem, startup_script_behavior, started_at, ready_at
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
FROM
workspace_agents
WHERE
@ -6281,17 +6281,17 @@ func (q *sqlQuerier) GetWorkspaceAgentByAuthToken(ctx context.Context, authToken
&i.ShutdownScriptTimeoutSeconds,
&i.LogsLength,
&i.LogsOverflowed,
&i.Subsystem,
&i.StartupScriptBehavior,
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
)
return i, err
}
const getWorkspaceAgentByID = `-- name: GetWorkspaceAgentByID :one
SELECT
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, subsystem, startup_script_behavior, started_at, ready_at
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
FROM
workspace_agents
WHERE
@ -6331,17 +6331,17 @@ func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (W
&i.ShutdownScriptTimeoutSeconds,
&i.LogsLength,
&i.LogsOverflowed,
&i.Subsystem,
&i.StartupScriptBehavior,
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
)
return i, err
}
const getWorkspaceAgentByInstanceID = `-- name: GetWorkspaceAgentByInstanceID :one
SELECT
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, subsystem, startup_script_behavior, started_at, ready_at
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
FROM
workspace_agents
WHERE
@ -6383,10 +6383,10 @@ func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInst
&i.ShutdownScriptTimeoutSeconds,
&i.LogsLength,
&i.LogsOverflowed,
&i.Subsystem,
&i.StartupScriptBehavior,
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
)
return i, err
}
@ -6506,7 +6506,7 @@ func (q *sqlQuerier) GetWorkspaceAgentMetadata(ctx context.Context, workspaceAge
const getWorkspaceAgentsByResourceIDs = `-- name: GetWorkspaceAgentsByResourceIDs :many
SELECT
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, subsystem, startup_script_behavior, started_at, ready_at
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
FROM
workspace_agents
WHERE
@ -6552,10 +6552,10 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []
&i.ShutdownScriptTimeoutSeconds,
&i.LogsLength,
&i.LogsOverflowed,
&i.Subsystem,
&i.StartupScriptBehavior,
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
); err != nil {
return nil, err
}
@ -6571,7 +6571,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []
}
const getWorkspaceAgentsCreatedAfter = `-- name: GetWorkspaceAgentsCreatedAfter :many
SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, subsystem, startup_script_behavior, started_at, ready_at FROM workspace_agents WHERE created_at > $1
SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems FROM workspace_agents WHERE created_at > $1
`
func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) {
@ -6613,10 +6613,10 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created
&i.ShutdownScriptTimeoutSeconds,
&i.LogsLength,
&i.LogsOverflowed,
&i.Subsystem,
&i.StartupScriptBehavior,
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
); err != nil {
return nil, err
}
@ -6633,7 +6633,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created
const getWorkspaceAgentsInLatestBuildByWorkspaceID = `-- name: GetWorkspaceAgentsInLatestBuildByWorkspaceID :many
SELECT
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.startup_script, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.subsystem, workspace_agents.startup_script_behavior, workspace_agents.started_at, workspace_agents.ready_at
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.startup_script, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.startup_script_behavior, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems
FROM
workspace_agents
JOIN
@ -6691,10 +6691,10 @@ func (q *sqlQuerier) GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx context.Co
&i.ShutdownScriptTimeoutSeconds,
&i.LogsLength,
&i.LogsOverflowed,
&i.Subsystem,
&i.StartupScriptBehavior,
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
); err != nil {
return nil, err
}
@ -6735,7 +6735,7 @@ INSERT INTO
shutdown_script_timeout_seconds
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, subsystem, startup_script_behavior, started_at, ready_at
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
`
type InsertWorkspaceAgentParams struct {
@ -6817,10 +6817,10 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa
&i.ShutdownScriptTimeoutSeconds,
&i.LogsLength,
&i.LogsOverflowed,
&i.Subsystem,
&i.StartupScriptBehavior,
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
)
return i, err
}
@ -7040,16 +7040,16 @@ UPDATE
SET
version = $2,
expanded_directory = $3,
subsystem = $4
subsystems = $4
WHERE
id = $1
`
type UpdateWorkspaceAgentStartupByIDParams struct {
ID uuid.UUID `db:"id" json:"id"`
Version string `db:"version" json:"version"`
ExpandedDirectory string `db:"expanded_directory" json:"expanded_directory"`
Subsystem WorkspaceAgentSubsystem `db:"subsystem" json:"subsystem"`
ID uuid.UUID `db:"id" json:"id"`
Version string `db:"version" json:"version"`
ExpandedDirectory string `db:"expanded_directory" json:"expanded_directory"`
Subsystems []WorkspaceAgentSubsystem `db:"subsystems" json:"subsystems"`
}
func (q *sqlQuerier) UpdateWorkspaceAgentStartupByID(ctx context.Context, arg UpdateWorkspaceAgentStartupByIDParams) error {
@ -7057,7 +7057,7 @@ func (q *sqlQuerier) UpdateWorkspaceAgentStartupByID(ctx context.Context, arg Up
arg.ID,
arg.Version,
arg.ExpandedDirectory,
arg.Subsystem,
pq.Array(arg.Subsystems),
)
return err
}

View File

@ -83,7 +83,7 @@ UPDATE
SET
version = $2,
expanded_directory = $3,
subsystem = $4
subsystems = $4
WHERE
id = $1;

View File

@ -544,6 +544,11 @@ func ConvertProvisionerJob(job database.ProvisionerJob) ProvisionerJob {
// ConvertWorkspaceAgent anonymizes a workspace agent.
func ConvertWorkspaceAgent(agent database.WorkspaceAgent) WorkspaceAgent {
subsystems := []string{}
for _, subsystem := range agent.Subsystems {
subsystems = append(subsystems, string(subsystem))
}
snapAgent := WorkspaceAgent{
ID: agent.ID,
CreatedAt: agent.CreatedAt,
@ -556,7 +561,7 @@ func ConvertWorkspaceAgent(agent database.WorkspaceAgent) WorkspaceAgent {
Directory: agent.Directory != "",
ConnectionTimeoutSeconds: agent.ConnectionTimeoutSeconds,
ShutdownScript: agent.ShutdownScript.Valid,
Subsystem: string(agent.Subsystem),
Subsystems: subsystems,
}
if agent.FirstConnectedAt.Valid {
snapAgent.FirstConnectedAt = &agent.FirstConnectedAt.Time
@ -792,7 +797,7 @@ type WorkspaceAgent struct {
DisconnectedAt *time.Time `json:"disconnected_at"`
ConnectionTimeoutSeconds int32 `json:"connection_timeout_seconds"`
ShutdownScript bool `json:"shutdown_script"`
Subsystem string `json:"subsystem"`
Subsystems []string `json:"subsystems"`
}
type WorkspaceAgentStat struct {

View File

@ -54,15 +54,16 @@ func TestTelemetry(t *testing.T) {
SharingLevel: database.AppSharingLevelOwner,
Health: database.WorkspaceAppHealthDisabled,
})
wsagent := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{
Subsystem: database.WorkspaceAgentSubsystemEnvbox,
})
wsagent := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{})
// Update the workspace agent to have a valid subsystem.
err = db.UpdateWorkspaceAgentStartupByID(ctx, database.UpdateWorkspaceAgentStartupByIDParams{
ID: wsagent.ID,
Version: wsagent.Version,
ExpandedDirectory: wsagent.ExpandedDirectory,
Subsystem: database.WorkspaceAgentSubsystemEnvbox,
Subsystems: []database.WorkspaceAgentSubsystem{
database.WorkspaceAgentSubsystemEnvbox,
database.WorkspaceAgentSubsystemExectrace,
},
})
require.NoError(t, err)
@ -98,7 +99,9 @@ func TestTelemetry(t *testing.T) {
require.Len(t, snapshot.WorkspaceProxies, 1)
wsa := snapshot.WorkspaceAgents[0]
require.Equal(t, string(database.WorkspaceAgentSubsystemEnvbox), wsa.Subsystem)
require.Len(t, wsa.Subsystems, 2)
require.Equal(t, string(database.WorkspaceAgentSubsystemEnvbox), wsa.Subsystems[0])
require.Equal(t, string(database.WorkspaceAgentSubsystemExectrace), wsa.Subsystems[1])
})
t.Run("HashedEmail", func(t *testing.T) {
t.Parallel()

View File

@ -14,6 +14,7 @@ import (
"net/netip"
"net/url"
"runtime/pprof"
"sort"
"strconv"
"strings"
"sync"
@ -219,11 +220,31 @@ func (api *API) postWorkspaceAgentStartup(rw http.ResponseWriter, r *http.Reques
return
}
// Validate subsystems.
seen := make(map[codersdk.AgentSubsystem]bool)
for _, s := range req.Subsystems {
if !s.Valid() {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Invalid workspace agent subsystem provided.",
Detail: fmt.Sprintf("invalid subsystem: %q", s),
})
return
}
if seen[s] {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Invalid workspace agent subsystem provided.",
Detail: fmt.Sprintf("duplicate subsystem: %q", s),
})
return
}
seen[s] = true
}
if err := api.Database.UpdateWorkspaceAgentStartupByID(ctx, database.UpdateWorkspaceAgentStartupByIDParams{
ID: apiAgent.ID,
Version: req.Version,
ExpandedDirectory: req.ExpandedDirectory,
Subsystem: convertWorkspaceAgentSubsystem(req.Subsystem),
Subsystems: convertWorkspaceAgentSubsystems(req.Subsystems),
}); err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Error setting agent version",
@ -1277,6 +1298,11 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin
if dbAgent.TroubleshootingURL != "" {
troubleshootingURL = dbAgent.TroubleshootingURL
}
subsystems := make([]codersdk.AgentSubsystem, len(dbAgent.Subsystems))
for i, subsystem := range dbAgent.Subsystems {
subsystems[i] = codersdk.AgentSubsystem(subsystem)
}
workspaceAgent := codersdk.WorkspaceAgent{
ID: dbAgent.ID,
CreatedAt: dbAgent.CreatedAt,
@ -1302,7 +1328,7 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin
LoginBeforeReady: dbAgent.StartupScriptBehavior != database.StartupScriptBehaviorBlocking,
ShutdownScript: dbAgent.ShutdownScript.String,
ShutdownScriptTimeoutSeconds: dbAgent.ShutdownScriptTimeoutSeconds,
Subsystem: codersdk.AgentSubsystem(dbAgent.Subsystem),
Subsystems: subsystems,
}
node := coordinator.Node(dbAgent.ID)
if node != nil {
@ -2114,11 +2140,23 @@ func convertWorkspaceAgentLog(logEntry database.WorkspaceAgentLog) codersdk.Work
}
}
func convertWorkspaceAgentSubsystem(ss codersdk.AgentSubsystem) database.WorkspaceAgentSubsystem {
switch ss {
case codersdk.AgentSubsystemEnvbox:
return database.WorkspaceAgentSubsystemEnvbox
default:
return database.WorkspaceAgentSubsystemNone
func convertWorkspaceAgentSubsystems(ss []codersdk.AgentSubsystem) []database.WorkspaceAgentSubsystem {
out := make([]database.WorkspaceAgentSubsystem, 0, len(ss))
for _, s := range ss {
switch s {
case codersdk.AgentSubsystemEnvbox:
out = append(out, database.WorkspaceAgentSubsystemEnvbox)
case codersdk.AgentSubsystemEnvbuilder:
out = append(out, database.WorkspaceAgentSubsystemEnvbuilder)
case codersdk.AgentSubsystemExectrace:
out = append(out, database.WorkspaceAgentSubsystemExectrace)
default:
// Invalid, drop it.
}
}
sort.Slice(out, func(i, j int) bool {
return out[i] < out[j]
})
return out
}

View File

@ -1195,16 +1195,23 @@ func TestWorkspaceAgent_Startup(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitMedium)
const (
expectedVersion = "v1.2.3"
expectedDir = "/home/coder"
expectedSubsystem = codersdk.AgentSubsystemEnvbox
var (
expectedVersion = "v1.2.3"
expectedDir = "/home/coder"
expectedSubsystems = []codersdk.AgentSubsystem{
codersdk.AgentSubsystemEnvbox,
codersdk.AgentSubsystemExectrace,
}
)
err := agentClient.PostStartup(ctx, agentsdk.PostStartupRequest{
Version: expectedVersion,
ExpandedDirectory: expectedDir,
Subsystem: expectedSubsystem,
Subsystems: []codersdk.AgentSubsystem{
// Not sorted.
expectedSubsystems[1],
expectedSubsystems[0],
},
})
require.NoError(t, err)
@ -1215,7 +1222,8 @@ func TestWorkspaceAgent_Startup(t *testing.T) {
require.NoError(t, err)
require.Equal(t, expectedVersion, wsagent.Version)
require.Equal(t, expectedDir, wsagent.ExpandedDirectory)
require.Equal(t, expectedSubsystem, wsagent.Subsystem)
// Sorted
require.Equal(t, expectedSubsystems, wsagent.Subsystems)
})
t.Run("InvalidSemver", func(t *testing.T) {

View File

@ -612,9 +612,9 @@ func (c *Client) PostLifecycle(ctx context.Context, req PostLifecycleRequest) er
}
type PostStartupRequest struct {
Version string `json:"version"`
ExpandedDirectory string `json:"expanded_directory"`
Subsystem codersdk.AgentSubsystem `json:"subsystem"`
Version string `json:"version"`
ExpandedDirectory string `json:"expanded_directory"`
Subsystems []codersdk.AgentSubsystem `json:"subsystems"`
}
func (c *Client) PostStartup(ctx context.Context, req PostStartupRequest) error {

View File

@ -167,7 +167,7 @@ type WorkspaceAgent struct {
LoginBeforeReady bool `json:"login_before_ready"`
ShutdownScript string `json:"shutdown_script,omitempty"`
ShutdownScriptTimeoutSeconds int32 `json:"shutdown_script_timeout_seconds"`
Subsystem AgentSubsystem `json:"subsystem"`
Subsystems []AgentSubsystem `json:"subsystems"`
Health WorkspaceAgentHealth `json:"health"` // Health reports the health of the agent.
}
@ -754,9 +754,20 @@ type WorkspaceAgentLog struct {
type AgentSubsystem string
const (
AgentSubsystemEnvbox AgentSubsystem = "envbox"
AgentSubsystemEnvbox AgentSubsystem = "envbox"
AgentSubsystemEnvbuilder AgentSubsystem = "envbuilder"
AgentSubsystemExectrace AgentSubsystem = "exectrace"
)
func (s AgentSubsystem) Valid() bool {
switch s {
case AgentSubsystemEnvbox, AgentSubsystemEnvbuilder, AgentSubsystemExectrace:
return true
default:
return false
}
}
type WorkspaceAgentLogSource string
const (

2
docs/api/agents.md generated
View File

@ -695,7 +695,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"

18
docs/api/builds.md generated
View File

@ -120,7 +120,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -282,7 +282,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -583,7 +583,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -672,7 +672,7 @@ Status Code **200**
| `»» startup_script_behavior` | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false | | |
| `»» startup_script_timeout_seconds` | integer | false | | »startup script timeout seconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout. |
| `»» status` | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus) | false | | |
| `»» subsystem` | [codersdk.AgentSubsystem](schemas.md#codersdkagentsubsystem) | false | | |
| `»» subsystems` | array | false | | |
| `»» troubleshooting_url` | string | false | | |
| `»» updated_at` | string(date-time) | false | | |
| `»» version` | string | false | | |
@ -716,7 +716,6 @@ Status Code **200**
| `status` | `connected` |
| `status` | `disconnected` |
| `status` | `timeout` |
| `subsystem` | `envbox` |
| `workspace_transition` | `start` |
| `workspace_transition` | `stop` |
| `workspace_transition` | `delete` |
@ -841,7 +840,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -1008,7 +1007,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -1133,7 +1132,7 @@ Status Code **200**
| `»»» startup_script_behavior` | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false | | |
| `»»» startup_script_timeout_seconds` | integer | false | | »»startup script timeout seconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout. |
| `»»» status` | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus) | false | | |
| `»»» subsystem` | [codersdk.AgentSubsystem](schemas.md#codersdkagentsubsystem) | false | | |
| `»»» subsystems` | array | false | | |
| `»»» troubleshooting_url` | string | false | | |
| `»»» updated_at` | string(date-time) | false | | |
| `»»» version` | string | false | | |
@ -1197,7 +1196,6 @@ Status Code **200**
| `status` | `connected` |
| `status` | `disconnected` |
| `status` | `timeout` |
| `subsystem` | `envbox` |
| `workspace_transition` | `start` |
| `workspace_transition` | `stop` |
| `workspace_transition` | `delete` |
@ -1356,7 +1354,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"

32
docs/api/schemas.md generated
View File

@ -377,18 +377,18 @@
```json
{
"expanded_directory": "string",
"subsystem": "envbox",
"subsystems": ["envbox"],
"version": "string"
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| -------------------- | -------------------------------------------------- | -------- | ------------ | ----------- |
| `expanded_directory` | string | false | | |
| `subsystem` | [codersdk.AgentSubsystem](#codersdkagentsubsystem) | false | | |
| `version` | string | false | | |
| Name | Type | Required | Restrictions | Description |
| -------------------- | ----------------------------------------------------------- | -------- | ------------ | ----------- |
| `expanded_directory` | string | false | | |
| `subsystems` | array of [codersdk.AgentSubsystem](#codersdkagentsubsystem) | false | | |
| `version` | string | false | | |
## agentsdk.Stats
@ -913,9 +913,11 @@ _None_
#### Enumerated Values
| Value |
| -------- |
| `envbox` |
| Value |
| ------------ |
| `envbox` |
| `envbuilder` |
| `exectrace` |
## codersdk.AppHostResponse
@ -5402,7 +5404,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -5543,7 +5545,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -5585,7 +5587,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `startup_script_behavior` | [codersdk.WorkspaceAgentStartupScriptBehavior](#codersdkworkspaceagentstartupscriptbehavior) | false | | |
| `startup_script_timeout_seconds` | integer | false | | Startup script timeout seconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout. |
| `status` | [codersdk.WorkspaceAgentStatus](#codersdkworkspaceagentstatus) | false | | |
| `subsystem` | [codersdk.AgentSubsystem](#codersdkagentsubsystem) | false | | |
| `subsystems` | array of [codersdk.AgentSubsystem](#codersdkagentsubsystem) | false | | |
| `troubleshooting_url` | string | false | | |
| `updated_at` | string | false | | |
| `version` | string | false | | |
@ -6001,7 +6003,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -6312,7 +6314,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -6524,7 +6526,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"

10
docs/api/templates.md generated
View File

@ -1633,7 +1633,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -1722,7 +1722,7 @@ Status Code **200**
| `»» startup_script_behavior` | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false | | |
| `»» startup_script_timeout_seconds` | integer | false | | »startup script timeout seconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout. |
| `»» status` | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus) | false | | |
| `»» subsystem` | [codersdk.AgentSubsystem](schemas.md#codersdkagentsubsystem) | false | | |
| `»» subsystems` | array | false | | |
| `»» troubleshooting_url` | string | false | | |
| `»» updated_at` | string(date-time) | false | | |
| `»» version` | string | false | | |
@ -1766,7 +1766,6 @@ Status Code **200**
| `status` | `connected` |
| `status` | `disconnected` |
| `status` | `timeout` |
| `subsystem` | `envbox` |
| `workspace_transition` | `start` |
| `workspace_transition` | `stop` |
| `workspace_transition` | `delete` |
@ -2025,7 +2024,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -2114,7 +2113,7 @@ Status Code **200**
| `»» startup_script_behavior` | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false | | |
| `»» startup_script_timeout_seconds` | integer | false | | »startup script timeout seconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout. |
| `»» status` | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus) | false | | |
| `»» subsystem` | [codersdk.AgentSubsystem](schemas.md#codersdkagentsubsystem) | false | | |
| `»» subsystems` | array | false | | |
| `»» troubleshooting_url` | string | false | | |
| `»» updated_at` | string(date-time) | false | | |
| `»» version` | string | false | | |
@ -2158,7 +2157,6 @@ Status Code **200**
| `status` | `connected` |
| `status` | `disconnected` |
| `status` | `timeout` |
| `subsystem` | `envbox` |
| `workspace_transition` | `start` |
| `workspace_transition` | `stop` |
| `workspace_transition` | `delete` |

10
docs/api/workspaces.md generated
View File

@ -148,7 +148,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -336,7 +336,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -523,7 +523,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -712,7 +712,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"
@ -1034,7 +1034,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/lock \
"startup_script_behavior": "blocking",
"startup_script_timeout_seconds": 0,
"status": "connecting",
"subsystem": "envbox",
"subsystems": ["envbox"],
"troubleshooting_url": "string",
"updated_at": "2019-08-24T14:15:22Z",
"version": "string"

View File

@ -1340,7 +1340,7 @@ export interface WorkspaceAgent {
readonly login_before_ready: boolean
readonly shutdown_script?: string
readonly shutdown_script_timeout_seconds: number
readonly subsystem: AgentSubsystem
readonly subsystems: AgentSubsystem[]
readonly health: WorkspaceAgentHealth
}
@ -1545,8 +1545,12 @@ export type APIKeyScope = "all" | "application_connect"
export const APIKeyScopes: APIKeyScope[] = ["all", "application_connect"]
// From codersdk/workspaceagents.go
export type AgentSubsystem = "envbox"
export const AgentSubsystems: AgentSubsystem[] = ["envbox"]
export type AgentSubsystem = "envbox" | "envbuilder" | "exectrace"
export const AgentSubsystems: AgentSubsystem[] = [
"envbox",
"envbuilder",
"exectrace",
]
// From codersdk/audit.go
export type AuditAction =

View File

@ -563,7 +563,7 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
logs_overflowed: false,
startup_script_timeout_seconds: 120,
shutdown_script_timeout_seconds: 120,
subsystem: "envbox",
subsystems: ["envbox", "exectrace"],
health: {
healthy: true,
},