diff --git a/agent/agent.go b/agent/agent.go index ea22069fd08fe..9846a7a31433c 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -62,6 +62,7 @@ type Options struct { IgnorePorts map[int]string SSHMaxTimeout time.Duration TailnetListenPort uint16 + Subsystem codersdk.AgentSubsystem } type Client interface { @@ -119,6 +120,7 @@ func New(options Options) Agent { ignorePorts: options.IgnorePorts, connStatsChan: make(chan *agentsdk.Stats, 1), sshMaxTimeout: options.SSHMaxTimeout, + subsystem: options.Subsystem, } a.init(ctx) return a @@ -136,6 +138,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 reconnectingPTYs sync.Map reconnectingPTYTimeout time.Duration @@ -488,6 +491,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, }) if err != nil { return xerrors.Errorf("update workspace agent version: %w", err) @@ -1455,3 +1459,8 @@ func expandDirectory(dir string) (string, error) { } return dir, nil } + +// EnvAgentSubsystem is the environment variable used to denote the +// specialized environment in which the agent is running +// (e.g. envbox, envbuilder). +const EnvAgentSubsystem = "CODER_AGENT_SUBSYSTEM" diff --git a/cli/agent.go b/cli/agent.go index 04626d2d4e42a..c96836c92df0b 100644 --- a/cli/agent.go +++ b/cli/agent.go @@ -26,6 +26,7 @@ import ( "github.com/coder/coder/agent/reaper" "github.com/coder/coder/buildinfo" "github.com/coder/coder/cli/clibase" + "github.com/coder/coder/codersdk" "github.com/coder/coder/codersdk/agentsdk" ) @@ -197,6 +198,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd { return xerrors.Errorf("add executable to $PATH: %w", err) } + subsystem := inv.Environ.Get(agent.EnvAgentSubsystem) agnt := agent.New(agent.Options{ Client: client, Logger: logger, @@ -218,6 +220,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd { }, IgnorePorts: ignorePorts, SSHMaxTimeout: sshMaxTimeout, + Subsystem: codersdk.AgentSubsystem(subsystem), }) debugSrvClose := ServeHandler(ctx, logger, agnt.HTTPDebug(), debugAddress, "debug") diff --git a/cli/agent_test.go b/cli/agent_test.go index 3911258cc19d6..6850e077f8820 100644 --- a/cli/agent_test.go +++ b/cli/agent_test.go @@ -12,8 +12,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/coder/coder/agent" "github.com/coder/coder/cli/clitest" "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/codersdk" "github.com/coder/coder/provisioner/echo" "github.com/coder/coder/provisionersdk/proto" "github.com/coder/coder/pty/ptytest" @@ -235,4 +237,43 @@ func TestWorkspaceAgent(t *testing.T) { _, err = uuid.Parse(strings.TrimSpace(string(token))) require.NoError(t, err) }) + + t.Run("PostStartup", func(t *testing.T) { + t.Parallel() + + authToken := uuid.NewString() + client := coderdtest.New(t, &coderdtest.Options{ + IncludeProvisionerDaemon: true, + }) + user := coderdtest.CreateFirstUser(t, client) + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionApply: echo.ProvisionApplyWithAgent(authToken), + }) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) + + logDir := t.TempDir() + inv, _ := clitest.New(t, + "agent", + "--auth", "token", + "--agent-token", authToken, + "--agent-url", client.URL.String(), + "--log-dir", logDir, + ) + // Set the subsystem for the agent. + inv.Environ.Set(agent.EnvAgentSubsystem, string(codersdk.AgentSubsystemEnvbox)) + + pty := ptytest.New(t).Attach(inv) + + clitest.Start(t, inv) + pty.ExpectMatch("starting agent") + + 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) + }) } diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 424ebfbab8b40..d58afadd533d9 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -5966,6 +5966,9 @@ const docTemplate = `{ "expanded_directory": { "type": "string" }, + "subsystem": { + "$ref": "#/definitions/codersdk.AgentSubsystem" + }, "version": { "type": "string" } @@ -6406,6 +6409,15 @@ const docTemplate = `{ } } }, + "codersdk.AgentSubsystem": { + "type": "string", + "enum": [ + "envbox" + ], + "x-enum-varnames": [ + "AgentSubsystemEnvbox" + ] + }, "codersdk.AppHostResponse": { "type": "object", "properties": { @@ -9627,6 +9639,9 @@ const docTemplate = `{ "status": { "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" }, + "subsystem": { + "$ref": "#/definitions/codersdk.AgentSubsystem" + }, "troubleshooting_url": { "type": "string" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 89d3226f68eeb..dd75cdec2f03d 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -5258,6 +5258,9 @@ "expanded_directory": { "type": "string" }, + "subsystem": { + "$ref": "#/definitions/codersdk.AgentSubsystem" + }, "version": { "type": "string" } @@ -5676,6 +5679,11 @@ } } }, + "codersdk.AgentSubsystem": { + "type": "string", + "enum": ["envbox"], + "x-enum-varnames": ["AgentSubsystemEnvbox"] + }, "codersdk.AppHostResponse": { "type": "object", "properties": { @@ -8665,6 +8673,9 @@ "status": { "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" }, + "subsystem": { + "$ref": "#/definitions/codersdk.AgentSubsystem" + }, "troubleshooting_url": { "type": "string" }, diff --git a/coderd/database/dbauthz/querier_test.go b/coderd/database/dbauthz/querier_test.go index c84aa3bffc373..907fec4060d95 100644 --- a/coderd/database/dbauthz/querier_test.go +++ b/coderd/database/dbauthz/querier_test.go @@ -1029,7 +1029,8 @@ 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, + ID: agt.ID, + Subsystem: database.WorkspaceAgentSubsystemNone, }).Asserts(ws, rbac.ActionUpdate).Returns() })) s.Run("GetWorkspaceAgentStartupLogsAfter", s.Subtest(func(db database.Store, check *expects) { diff --git a/coderd/database/dbfake/databasefake.go b/coderd/database/dbfake/databasefake.go index 52d0684cecbb6..41800dbcd9e74 100644 --- a/coderd/database/dbfake/databasefake.go +++ b/coderd/database/dbfake/databasefake.go @@ -3702,6 +3702,7 @@ func (q *fakeQuerier) UpdateWorkspaceAgentStartupByID(_ context.Context, arg dat agent.Version = arg.Version agent.ExpandedDirectory = arg.ExpandedDirectory + agent.Subsystem = arg.Subsystem q.workspaceAgents[index] = agent return nil } diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 6fd8b76ae156c..3520008680968 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -116,6 +116,12 @@ CREATE TYPE workspace_agent_lifecycle_state AS ENUM ( 'off' ); +CREATE TYPE workspace_agent_subsystem AS ENUM ( + 'envbuilder', + 'envbox', + 'none' +); + CREATE TYPE workspace_app_health AS ENUM ( 'disabled', 'initializing', @@ -597,6 +603,7 @@ CREATE TABLE workspace_agents ( shutdown_script_timeout_seconds integer DEFAULT 0 NOT NULL, startup_logs_length integer DEFAULT 0 NOT NULL, startup_logs_overflowed boolean DEFAULT false NOT NULL, + subsystem workspace_agent_subsystem DEFAULT 'none'::workspace_agent_subsystem NOT NULL, CONSTRAINT max_startup_logs_length CHECK ((startup_logs_length <= 1048576)) ); diff --git a/coderd/database/migrations/000123_workspace_agent_subsystem.down.sql b/coderd/database/migrations/000123_workspace_agent_subsystem.down.sql new file mode 100644 index 0000000000000..ec1fc4aa26c7f --- /dev/null +++ b/coderd/database/migrations/000123_workspace_agent_subsystem.down.sql @@ -0,0 +1,4 @@ +BEGIN; +ALTER TABLE workspace_agents DROP COLUMN subsystem; +DROP TYPE workspace_agent_subsystem; +COMMIT; diff --git a/coderd/database/migrations/000123_workspace_agent_subsystem.up.sql b/coderd/database/migrations/000123_workspace_agent_subsystem.up.sql new file mode 100644 index 0000000000000..747c5d362fe5d --- /dev/null +++ b/coderd/database/migrations/000123_workspace_agent_subsystem.up.sql @@ -0,0 +1,4 @@ +BEGIN; +CREATE TYPE workspace_agent_subsystem AS ENUM ('envbuilder', 'envbox', 'none'); +ALTER TABLE workspace_agents ADD COLUMN subsystem workspace_agent_subsystem NOT NULL default 'none'; +COMMIT; diff --git a/coderd/database/models.go b/coderd/database/models.go index 82a1a0ca806b6..4cef35e644a4c 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -1096,6 +1096,67 @@ func AllWorkspaceAgentLifecycleStateValues() []WorkspaceAgentLifecycleState { } } +type WorkspaceAgentSubsystem string + +const ( + WorkspaceAgentSubsystemEnvbuilder WorkspaceAgentSubsystem = "envbuilder" + WorkspaceAgentSubsystemEnvbox WorkspaceAgentSubsystem = "envbox" + WorkspaceAgentSubsystemNone WorkspaceAgentSubsystem = "none" +) + +func (e *WorkspaceAgentSubsystem) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = WorkspaceAgentSubsystem(s) + case string: + *e = WorkspaceAgentSubsystem(s) + default: + return fmt.Errorf("unsupported scan type for WorkspaceAgentSubsystem: %T", src) + } + return nil +} + +type NullWorkspaceAgentSubsystem struct { + WorkspaceAgentSubsystem WorkspaceAgentSubsystem + Valid bool // Valid is true if WorkspaceAgentSubsystem is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullWorkspaceAgentSubsystem) Scan(value interface{}) error { + if value == nil { + ns.WorkspaceAgentSubsystem, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.WorkspaceAgentSubsystem.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullWorkspaceAgentSubsystem) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.WorkspaceAgentSubsystem), nil +} + +func (e WorkspaceAgentSubsystem) Valid() bool { + switch e { + case WorkspaceAgentSubsystemEnvbuilder, + WorkspaceAgentSubsystemEnvbox, + WorkspaceAgentSubsystemNone: + return true + } + return false +} + +func AllWorkspaceAgentSubsystemValues() []WorkspaceAgentSubsystem { + return []WorkspaceAgentSubsystem{ + WorkspaceAgentSubsystemEnvbuilder, + WorkspaceAgentSubsystemEnvbox, + WorkspaceAgentSubsystemNone, + } +} + type WorkspaceAppHealth string const ( @@ -1587,7 +1648,8 @@ type WorkspaceAgent struct { // Total length of startup logs StartupLogsLength int32 `db:"startup_logs_length" json:"startup_logs_length"` // Whether the startup logs overflowed in length - StartupLogsOverflowed bool `db:"startup_logs_overflowed" json:"startup_logs_overflowed"` + StartupLogsOverflowed bool `db:"startup_logs_overflowed" json:"startup_logs_overflowed"` + Subsystem WorkspaceAgentSubsystem `db:"subsystem" json:"subsystem"` } type WorkspaceAgentMetadatum struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 23524b4386cc2..9955deb439ffd 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -5553,7 +5553,7 @@ func (q *sqlQuerier) DeleteOldWorkspaceAgentStartupLogs(ctx context.Context) err 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed + 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed, subsystem FROM workspace_agents WHERE @@ -5596,13 +5596,14 @@ func (q *sqlQuerier) GetWorkspaceAgentByAuthToken(ctx context.Context, authToken &i.ShutdownScriptTimeoutSeconds, &i.StartupLogsLength, &i.StartupLogsOverflowed, + &i.Subsystem, ) 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed + 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed, subsystem FROM workspace_agents WHERE @@ -5643,13 +5644,14 @@ func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (W &i.ShutdownScriptTimeoutSeconds, &i.StartupLogsLength, &i.StartupLogsOverflowed, + &i.Subsystem, ) 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed + 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed, subsystem FROM workspace_agents WHERE @@ -5692,6 +5694,7 @@ func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInst &i.ShutdownScriptTimeoutSeconds, &i.StartupLogsLength, &i.StartupLogsOverflowed, + &i.Subsystem, ) return i, err } @@ -5786,7 +5789,7 @@ func (q *sqlQuerier) GetWorkspaceAgentStartupLogsAfter(ctx context.Context, arg 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed + 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed, subsystem FROM workspace_agents WHERE @@ -5833,6 +5836,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids [] &i.ShutdownScriptTimeoutSeconds, &i.StartupLogsLength, &i.StartupLogsOverflowed, + &i.Subsystem, ); err != nil { return nil, err } @@ -5848,7 +5852,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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed 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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed, subsystem FROM workspace_agents WHERE created_at > $1 ` func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) { @@ -5891,6 +5895,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created &i.ShutdownScriptTimeoutSeconds, &i.StartupLogsLength, &i.StartupLogsOverflowed, + &i.Subsystem, ); err != nil { return nil, err } @@ -5907,7 +5912,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.login_before_ready, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.startup_logs_length, workspace_agents.startup_logs_overflowed + 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.login_before_ready, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.startup_logs_length, workspace_agents.startup_logs_overflowed, workspace_agents.subsystem FROM workspace_agents JOIN @@ -5966,6 +5971,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx context.Co &i.ShutdownScriptTimeoutSeconds, &i.StartupLogsLength, &i.StartupLogsOverflowed, + &i.Subsystem, ); err != nil { return nil, err } @@ -6006,7 +6012,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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed + ($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, login_before_ready, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, startup_logs_length, startup_logs_overflowed, subsystem ` type InsertWorkspaceAgentParams struct { @@ -6089,6 +6095,7 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa &i.ShutdownScriptTimeoutSeconds, &i.StartupLogsLength, &i.StartupLogsOverflowed, + &i.Subsystem, ) return i, err } @@ -6275,19 +6282,26 @@ UPDATE workspace_agents SET version = $2, - expanded_directory = $3 + expanded_directory = $3, + subsystem = $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"` + 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"` } func (q *sqlQuerier) UpdateWorkspaceAgentStartupByID(ctx context.Context, arg UpdateWorkspaceAgentStartupByIDParams) error { - _, err := q.db.ExecContext(ctx, updateWorkspaceAgentStartupByID, arg.ID, arg.Version, arg.ExpandedDirectory) + _, err := q.db.ExecContext(ctx, updateWorkspaceAgentStartupByID, + arg.ID, + arg.Version, + arg.ExpandedDirectory, + arg.Subsystem, + ) return err } diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index f8fd756c7d888..3ceb2c70c264a 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -82,7 +82,8 @@ UPDATE workspace_agents SET version = $2, - expanded_directory = $3 + expanded_directory = $3, + subsystem = $4 WHERE id = $1; diff --git a/coderd/telemetry/telemetry.go b/coderd/telemetry/telemetry.go index 9e53e5b63506d..ba027cef63e81 100644 --- a/coderd/telemetry/telemetry.go +++ b/coderd/telemetry/telemetry.go @@ -562,6 +562,7 @@ func ConvertWorkspaceAgent(agent database.WorkspaceAgent) WorkspaceAgent { Directory: agent.Directory != "", ConnectionTimeoutSeconds: agent.ConnectionTimeoutSeconds, ShutdownScript: agent.ShutdownScript.Valid, + Subsystem: string(agent.Subsystem), } if agent.FirstConnectedAt.Valid { snapAgent.FirstConnectedAt = &agent.FirstConnectedAt.Time @@ -783,6 +784,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"` } type WorkspaceAgentStat struct { diff --git a/coderd/telemetry/telemetry_test.go b/coderd/telemetry/telemetry_test.go index 5d55bd4f013e8..9e911a83a84c1 100644 --- a/coderd/telemetry/telemetry_test.go +++ b/coderd/telemetry/telemetry_test.go @@ -1,7 +1,6 @@ package telemetry_test import ( - "context" "encoding/json" "net/http" "net/http/httptest" @@ -22,6 +21,7 @@ import ( "github.com/coder/coder/coderd/database/dbfake" "github.com/coder/coder/coderd/database/dbgen" "github.com/coder/coder/coderd/telemetry" + "github.com/coder/coder/testutil" ) func TestMain(m *testing.M) { @@ -37,7 +37,7 @@ func TestTelemetry(t *testing.T) { db := dbfake.New() - ctx := context.Background() + ctx := testutil.Context(t, testutil.WaitMedium) _, _ = dbgen.APIKey(t, db, database.APIKey{}) _ = dbgen.ParameterSchema(t, db, database.ParameterSchema{ DefaultSourceScheme: database.ParameterSourceSchemeNone, @@ -59,7 +59,18 @@ func TestTelemetry(t *testing.T) { SharingLevel: database.AppSharingLevelOwner, Health: database.WorkspaceAppHealthDisabled, }) - _ = dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{}) + wsagent := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{ + Subsystem: database.WorkspaceAgentSubsystemEnvbox, + }) + // 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, + }) + require.NoError(t, err) + _ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{ Transition: database.WorkspaceTransitionStart, Reason: database.BuildReasonAutostart, @@ -88,6 +99,9 @@ func TestTelemetry(t *testing.T) { require.Len(t, snapshot.WorkspaceBuilds, 1) require.Len(t, snapshot.WorkspaceResources, 1) require.Len(t, snapshot.WorkspaceAgentStats, 1) + + wsa := snapshot.WorkspaceAgents[0] + require.Equal(t, string(database.WorkspaceAgentSubsystemEnvbox), wsa.Subsystem) }) t.Run("HashedEmail", func(t *testing.T) { t.Parallel() diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 6028336892864..6d9e1ffb3f144 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -220,6 +220,7 @@ func (api *API) postWorkspaceAgentStartup(rw http.ResponseWriter, r *http.Reques ID: apiAgent.ID, Version: req.Version, ExpandedDirectory: req.ExpandedDirectory, + Subsystem: convertWorkspaceAgentSubsystem(req.Subsystem), }); err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ Message: "Error setting agent version", @@ -1129,6 +1130,7 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin StartupScriptTimeoutSeconds: dbAgent.StartupScriptTimeoutSeconds, ShutdownScript: dbAgent.ShutdownScript.String, ShutdownScriptTimeoutSeconds: dbAgent.ShutdownScriptTimeoutSeconds, + Subsystem: codersdk.AgentSubsystem(dbAgent.Subsystem), } node := coordinator.Node(dbAgent.ID) if node != nil { @@ -1983,3 +1985,12 @@ func convertWorkspaceAgentStartupLog(logEntry database.WorkspaceAgentStartupLog) Level: codersdk.LogLevel(logEntry.Level), } } + +func convertWorkspaceAgentSubsystem(ss codersdk.AgentSubsystem) database.WorkspaceAgentSubsystem { + switch ss { + case codersdk.AgentSubsystemEnvbox: + return database.WorkspaceAgentSubsystemEnvbox + default: + return database.WorkspaceAgentSubsystemNone + } +} diff --git a/coderd/workspaceagents_test.go b/coderd/workspaceagents_test.go index d5ba9d2ddad1e..73b540ea5ac68 100644 --- a/coderd/workspaceagents_test.go +++ b/coderd/workspaceagents_test.go @@ -1326,3 +1326,85 @@ func TestWorkspaceAgent_Metadata(t *testing.T) { err = agentClient.PostMetadata(ctx, "unknown", unknownKeyMetadata) require.NoError(t, err) } + +func TestWorkspaceAgent_Startup(t *testing.T) { + t.Parallel() + + t.Run("OK", func(t *testing.T) { + t.Parallel() + + client := coderdtest.New(t, &coderdtest.Options{ + IncludeProvisionerDaemon: true, + }) + user := coderdtest.CreateFirstUser(t, client) + authToken := uuid.NewString() + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionPlan: echo.ProvisionComplete, + ProvisionApply: echo.ProvisionApplyWithAgent(authToken), + }) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) + + agentClient := agentsdk.New(client.URL) + agentClient.SetSessionToken(authToken) + + ctx := testutil.Context(t, testutil.WaitMedium) + + const ( + expectedVersion = "v1.2.3" + expectedDir = "/home/coder" + expectedSubsystem = codersdk.AgentSubsystemEnvbox + ) + + err := agentClient.PostStartup(ctx, agentsdk.PostStartupRequest{ + Version: expectedVersion, + ExpandedDirectory: expectedDir, + Subsystem: expectedSubsystem, + }) + require.NoError(t, err) + + workspace, err = client.Workspace(ctx, workspace.ID) + require.NoError(t, err) + + wsagent, err := client.WorkspaceAgent(ctx, workspace.LatestBuild.Resources[0].Agents[0].ID) + require.NoError(t, err) + require.Equal(t, expectedVersion, wsagent.Version) + require.Equal(t, expectedDir, wsagent.ExpandedDirectory) + require.Equal(t, expectedSubsystem, wsagent.Subsystem) + }) + + t.Run("InvalidSemver", func(t *testing.T) { + t.Parallel() + + client := coderdtest.New(t, &coderdtest.Options{ + IncludeProvisionerDaemon: true, + }) + user := coderdtest.CreateFirstUser(t, client) + authToken := uuid.NewString() + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionPlan: echo.ProvisionComplete, + ProvisionApply: echo.ProvisionApplyWithAgent(authToken), + }) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) + + agentClient := agentsdk.New(client.URL) + agentClient.SetSessionToken(authToken) + + ctx := testutil.Context(t, testutil.WaitMedium) + + err := agentClient.PostStartup(ctx, agentsdk.PostStartupRequest{ + Version: "1.2.3", + }) + require.Error(t, err) + cerr, ok := codersdk.AsError(err) + require.True(t, ok) + require.Equal(t, http.StatusBadRequest, cerr.StatusCode()) + }) +} diff --git a/codersdk/agentsdk/agentsdk.go b/codersdk/agentsdk/agentsdk.go index 12d651e3f0412..0a5d30c0f1d9a 100644 --- a/codersdk/agentsdk/agentsdk.go +++ b/codersdk/agentsdk/agentsdk.go @@ -544,8 +544,9 @@ func (c *Client) PostLifecycle(ctx context.Context, req PostLifecycleRequest) er } type PostStartupRequest struct { - Version string `json:"version"` - ExpandedDirectory string `json:"expanded_directory"` + Version string `json:"version"` + ExpandedDirectory string `json:"expanded_directory"` + Subsystem codersdk.AgentSubsystem `json:"subsystem"` } func (c *Client) PostStartup(ctx context.Context, req PostStartupRequest) error { diff --git a/codersdk/workspaceagents.go b/codersdk/workspaceagents.go index 8f418eebf29ff..c633d5f0744ad 100644 --- a/codersdk/workspaceagents.go +++ b/codersdk/workspaceagents.go @@ -130,9 +130,10 @@ type WorkspaceAgent struct { // LoginBeforeReady if true, the agent will delay logins until it is ready (e.g. executing startup script has ended). LoginBeforeReady bool `json:"login_before_ready"` // StartupScriptTimeoutSeconds 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. - StartupScriptTimeoutSeconds int32 `json:"startup_script_timeout_seconds"` - ShutdownScript string `json:"shutdown_script,omitempty"` - ShutdownScriptTimeoutSeconds int32 `json:"shutdown_script_timeout_seconds"` + StartupScriptTimeoutSeconds int32 `json:"startup_script_timeout_seconds"` + ShutdownScript string `json:"shutdown_script,omitempty"` + ShutdownScriptTimeoutSeconds int32 `json:"shutdown_script_timeout_seconds"` + Subsystem AgentSubsystem `json:"subsystem"` } type DERPRegion struct { @@ -553,3 +554,9 @@ type WorkspaceAgentStartupLog struct { Output string `json:"output"` Level LogLevel `json:"level"` } + +type AgentSubsystem string + +const ( + AgentSubsystemEnvbox AgentSubsystem = "envbox" +) diff --git a/docs/api/agents.md b/docs/api/agents.md index cfdb087c30b8b..835d95e0497a6 100644 --- a/docs/api/agents.md +++ b/docs/api/agents.md @@ -474,6 +474,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \ "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" diff --git a/docs/api/builds.md b/docs/api/builds.md index 9e05671efb003..1b6664204e23f 100644 --- a/docs/api/builds.md +++ b/docs/api/builds.md @@ -111,6 +111,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -263,6 +264,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -556,6 +558,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -638,6 +641,7 @@ Status Code **200** | `»» startup_script` | string | 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 | | | | `»» troubleshooting_url` | string | false | | | | `»» updated_at` | string(date-time) | false | | | | `»» version` | string | false | | | @@ -679,6 +683,7 @@ Status Code **200** | `status` | `connected` | | `status` | `disconnected` | | `status` | `timeout` | +| `subsystem` | `envbox` | | `workspace_transition` | `start` | | `workspace_transition` | `stop` | | `workspace_transition` | `delete` | @@ -794,6 +799,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -951,6 +957,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -1067,6 +1074,7 @@ Status Code **200** | `»»» startup_script` | string | 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 | | | | `»»» troubleshooting_url` | string | false | | | | `»»» updated_at` | string(date-time) | false | | | | `»»» version` | string | false | | | @@ -1128,6 +1136,7 @@ Status Code **200** | `status` | `connected` | | `status` | `disconnected` | | `status` | `timeout` | +| `subsystem` | `envbox` | | `workspace_transition` | `start` | | `workspace_transition` | `stop` | | `workspace_transition` | `delete` | @@ -1286,6 +1295,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" diff --git a/docs/api/schemas.md b/docs/api/schemas.md index cb66df84adcb5..307b83544a449 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -327,16 +327,18 @@ ```json { "expanded_directory": "string", + "subsystem": "envbox", "version": "string" } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| -------------------- | ------ | -------- | ------------ | ----------- | -| `expanded_directory` | string | false | | | -| `version` | string | false | | | +| Name | Type | Required | Restrictions | Description | +| -------------------- | -------------------------------------------------- | -------- | ------------ | ----------- | +| `expanded_directory` | string | false | | | +| `subsystem` | [codersdk.AgentSubsystem](#codersdkagentsubsystem) | false | | | +| `version` | string | false | | | ## agentsdk.StartupLog @@ -783,6 +785,20 @@ | --------- | ------ | -------- | ------------ | ----------- | | `license` | string | true | | | +## codersdk.AgentSubsystem + +```json +"envbox" +``` + +### Properties + +#### Enumerated Values + +| Value | +| -------- | +| `envbox` | + ## codersdk.AppHostResponse ```json @@ -4698,6 +4714,7 @@ Parameter represents a set value for the scope. "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -4828,6 +4845,7 @@ Parameter represents a set value for the scope. "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -4865,6 +4883,7 @@ Parameter represents a set value for the scope. | `startup_script` | string | 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 | | | | `troubleshooting_url` | string | false | | | | `updated_at` | string | false | | | | `version` | string | false | | | @@ -5219,6 +5238,7 @@ Parameter represents a set value for the scope. "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -5500,6 +5520,7 @@ Parameter represents a set value for the scope. "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -5698,6 +5719,7 @@ Parameter represents a set value for the scope. "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" diff --git a/docs/api/templates.md b/docs/api/templates.md index 6364e4b8e0279..829f43f410216 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -1680,6 +1680,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -1762,6 +1763,7 @@ Status Code **200** | `»» startup_script` | string | 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 | | | | `»» troubleshooting_url` | string | false | | | | `»» updated_at` | string(date-time) | false | | | | `»» version` | string | false | | | @@ -1803,6 +1805,7 @@ Status Code **200** | `status` | `connected` | | `status` | `disconnected` | | `status` | `timeout` | +| `subsystem` | `envbox` | | `workspace_transition` | `start` | | `workspace_transition` | `stop` | | `workspace_transition` | `delete` | @@ -2109,6 +2112,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -2191,6 +2195,7 @@ Status Code **200** | `»» startup_script` | string | 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 | | | | `»» troubleshooting_url` | string | false | | | | `»» updated_at` | string(date-time) | false | | | | `»» version` | string | false | | | @@ -2232,6 +2237,7 @@ Status Code **200** | `status` | `connected` | | `status` | `disconnected` | | `status` | `timeout` | +| `subsystem` | `envbox` | | `workspace_transition` | `start` | | `workspace_transition` | `stop` | | `workspace_transition` | `delete` | diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index fff7d2d640695..de27221b8060f 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -144,6 +144,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -317,6 +318,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -509,6 +511,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" @@ -683,6 +686,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \ "startup_script": "string", "startup_script_timeout_seconds": 0, "status": "connecting", + "subsystem": "envbox", "troubleshooting_url": "string", "updated_at": "2019-08-24T14:15:22Z", "version": "string" diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index d8ef384a4c406..fbd8b6da08356 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1147,6 +1147,7 @@ export interface WorkspaceAgent { readonly startup_script_timeout_seconds: number readonly shutdown_script?: string readonly shutdown_script_timeout_seconds: number + readonly subsystem: AgentSubsystem } // From codersdk/workspaceagentconn.go @@ -1341,6 +1342,10 @@ export interface WorkspacesResponse { 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"] + // From codersdk/audit.go export type AuditAction = | "create" diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index a4a68aa78682f..b0bb2a4f7fe0f 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -501,6 +501,7 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = { startup_logs_overflowed: false, startup_script_timeout_seconds: 120, shutdown_script_timeout_seconds: 120, + subsystem: "envbox", } export const MockWorkspaceAgentDisconnected: TypesGen.WorkspaceAgent = {