diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go
index fb5ae20e448c8..dc5724f77b020 100644
--- a/coderd/apidoc/docs.go
+++ b/coderd/apidoc/docs.go
@@ -17021,6 +17021,14 @@ const docTemplate = `{
"operating_system": {
"type": "string"
},
+ "parent_id": {
+ "format": "uuid",
+ "allOf": [
+ {
+ "$ref": "#/definitions/uuid.NullUUID"
+ }
+ ]
+ },
"ready_at": {
"type": "string",
"format": "date-time"
@@ -19033,6 +19041,18 @@ const docTemplate = `{
"url.Userinfo": {
"type": "object"
},
+ "uuid.NullUUID": {
+ "type": "object",
+ "properties": {
+ "uuid": {
+ "type": "string"
+ },
+ "valid": {
+ "description": "Valid is true if UUID is not NULL",
+ "type": "boolean"
+ }
+ }
+ },
"workspaceapps.AccessMethod": {
"type": "string",
"enum": [
diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json
index 8420c9ea0f812..1628797d85ffc 100644
--- a/coderd/apidoc/swagger.json
+++ b/coderd/apidoc/swagger.json
@@ -15538,6 +15538,14 @@
"operating_system": {
"type": "string"
},
+ "parent_id": {
+ "format": "uuid",
+ "allOf": [
+ {
+ "$ref": "#/definitions/uuid.NullUUID"
+ }
+ ]
+ },
"ready_at": {
"type": "string",
"format": "date-time"
@@ -17442,6 +17450,18 @@
"url.Userinfo": {
"type": "object"
},
+ "uuid.NullUUID": {
+ "type": "object",
+ "properties": {
+ "uuid": {
+ "type": "string"
+ },
+ "valid": {
+ "description": "Valid is true if UUID is not NULL",
+ "type": "boolean"
+ }
+ }
+ },
"workspaceapps.AccessMethod": {
"type": "string",
"enum": ["path", "subdomain", "terminal"],
diff --git a/coderd/database/dbgen/dbgen.go b/coderd/database/dbgen/dbgen.go
index f4a53815bfb50..b16faba6a8891 100644
--- a/coderd/database/dbgen/dbgen.go
+++ b/coderd/database/dbgen/dbgen.go
@@ -181,6 +181,7 @@ func WorkspaceAgentPortShare(t testing.TB, db database.Store, orig database.Work
func WorkspaceAgent(t testing.TB, db database.Store, orig database.WorkspaceAgent) database.WorkspaceAgent {
agt, err := db.InsertWorkspaceAgent(genCtx, database.InsertWorkspaceAgentParams{
ID: takeFirst(orig.ID, uuid.New()),
+ ParentID: takeFirst(orig.ParentID, uuid.NullUUID{}),
CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
Name: takeFirst(orig.Name, testutil.GetRandomName(t)),
diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go
index a46f956c02393..670587a6dfad4 100644
--- a/coderd/database/dbmem/dbmem.go
+++ b/coderd/database/dbmem/dbmem.go
@@ -9570,6 +9570,7 @@ func (q *FakeQuerier) InsertWorkspaceAgent(_ context.Context, arg database.Inser
agent := database.WorkspaceAgent{
ID: arg.ID,
+ ParentID: arg.ParentID,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
ResourceID: arg.ResourceID,
diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql
index d2be784e9424a..fa5b4b821cf0c 100644
--- a/coderd/database/dump.sql
+++ b/coderd/database/dump.sql
@@ -1833,6 +1833,7 @@ CREATE TABLE workspace_agents (
display_apps display_app[] DEFAULT '{vscode,vscode_insiders,web_terminal,ssh_helper,port_forwarding_helper}'::display_app[],
api_version text DEFAULT ''::text NOT NULL,
display_order integer DEFAULT 0 NOT NULL,
+ parent_id uuid,
CONSTRAINT max_logs_length CHECK ((logs_length <= 1048576)),
CONSTRAINT subsystems_not_none CHECK ((NOT ('none'::workspace_agent_subsystem = ANY (subsystems))))
);
@@ -2926,6 +2927,9 @@ ALTER TABLE ONLY workspace_agent_logs
ALTER TABLE ONLY workspace_agent_volume_resource_monitors
ADD CONSTRAINT workspace_agent_volume_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ALTER TABLE ONLY workspace_agents
+ ADD CONSTRAINT workspace_agents_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY workspace_agents
ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go
index 2ff04b5058b4f..d6b87ddff5376 100644
--- a/coderd/database/foreign_key_constraint.go
+++ b/coderd/database/foreign_key_constraint.go
@@ -71,6 +71,7 @@ const (
ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
ForeignKeyWorkspaceAgentVolumeResourceMonitorsAgentID ForeignKeyConstraint = "workspace_agent_volume_resource_monitors_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_volume_resource_monitors ADD CONSTRAINT workspace_agent_volume_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentsParentID ForeignKeyConstraint = "workspace_agents_parent_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
ForeignKeyWorkspaceAppAuditSessionsAgentID ForeignKeyConstraint = "workspace_app_audit_sessions_agent_id_fkey" // ALTER TABLE ONLY workspace_app_audit_sessions ADD CONSTRAINT workspace_app_audit_sessions_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
ForeignKeyWorkspaceAppStatsAgentID ForeignKeyConstraint = "workspace_app_stats_agent_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id);
diff --git a/coderd/database/migrations/000321_add_parent_id_to_workspace_agents.down.sql b/coderd/database/migrations/000321_add_parent_id_to_workspace_agents.down.sql
new file mode 100644
index 0000000000000..ab810126ad60e
--- /dev/null
+++ b/coderd/database/migrations/000321_add_parent_id_to_workspace_agents.down.sql
@@ -0,0 +1,2 @@
+ALTER TABLE workspace_agents
+DROP COLUMN IF EXISTS parent_id;
diff --git a/coderd/database/migrations/000321_add_parent_id_to_workspace_agents.up.sql b/coderd/database/migrations/000321_add_parent_id_to_workspace_agents.up.sql
new file mode 100644
index 0000000000000..f2fd7a8c1cd10
--- /dev/null
+++ b/coderd/database/migrations/000321_add_parent_id_to_workspace_agents.up.sql
@@ -0,0 +1,2 @@
+ALTER TABLE workspace_agents
+ADD COLUMN parent_id UUID REFERENCES workspace_agents (id) ON DELETE CASCADE;
diff --git a/coderd/database/models.go b/coderd/database/models.go
index af6b06464e5b1..3944d56268eaf 100644
--- a/coderd/database/models.go
+++ b/coderd/database/models.go
@@ -3402,7 +3402,8 @@ type WorkspaceAgent struct {
DisplayApps []DisplayApp `db:"display_apps" json:"display_apps"`
APIVersion string `db:"api_version" json:"api_version"`
// Specifies the order in which to display agents in user interfaces.
- DisplayOrder int32 `db:"display_order" json:"display_order"`
+ DisplayOrder int32 `db:"display_order" json:"display_order"`
+ ParentID uuid.NullUUID `db:"parent_id" json:"parent_id"`
}
// Workspace agent devcontainer configuration
diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go
index 4ab831b178e6d..e2e38c36fe10a 100644
--- a/coderd/database/queries.sql.go
+++ b/coderd/database/queries.sql.go
@@ -13926,7 +13926,7 @@ func (q *sqlQuerier) DeleteOldWorkspaceAgentLogs(ctx context.Context, threshold
const getWorkspaceAgentAndLatestBuildByAuthToken = `-- name: GetWorkspaceAgentAndLatestBuildByAuthToken :one
SELECT
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite, workspaces.next_start_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.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.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version, workspace_agents.display_order,
+ 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.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.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version, workspace_agents.display_order, workspace_agents.parent_id,
workspace_build_with_user.id, workspace_build_with_user.created_at, workspace_build_with_user.updated_at, workspace_build_with_user.workspace_id, workspace_build_with_user.template_version_id, workspace_build_with_user.build_number, workspace_build_with_user.transition, workspace_build_with_user.initiator_id, workspace_build_with_user.provisioner_state, workspace_build_with_user.job_id, workspace_build_with_user.deadline, workspace_build_with_user.reason, workspace_build_with_user.daily_cost, workspace_build_with_user.max_deadline, workspace_build_with_user.template_version_preset_id, workspace_build_with_user.initiator_by_avatar_url, workspace_build_with_user.initiator_by_username
FROM
workspace_agents
@@ -14016,6 +14016,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndLatestBuildByAuthToken(ctx context.Cont
pq.Array(&i.WorkspaceAgent.DisplayApps),
&i.WorkspaceAgent.APIVersion,
&i.WorkspaceAgent.DisplayOrder,
+ &i.WorkspaceAgent.ParentID,
&i.WorkspaceBuild.ID,
&i.WorkspaceBuild.CreatedAt,
&i.WorkspaceBuild.UpdatedAt,
@@ -14039,7 +14040,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndLatestBuildByAuthToken(ctx context.Cont
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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order
+ 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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order, parent_id
FROM
workspace_agents
WHERE
@@ -14081,13 +14082,14 @@ func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (W
pq.Array(&i.DisplayApps),
&i.APIVersion,
&i.DisplayOrder,
+ &i.ParentID,
)
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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order
+ 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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order, parent_id
FROM
workspace_agents
WHERE
@@ -14131,6 +14133,7 @@ func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInst
pq.Array(&i.DisplayApps),
&i.APIVersion,
&i.DisplayOrder,
+ &i.ParentID,
)
return i, err
}
@@ -14350,7 +14353,7 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptTimingsByBuildID(ctx context.Context
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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order
+ 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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order, parent_id
FROM
workspace_agents
WHERE
@@ -14398,6 +14401,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []
pq.Array(&i.DisplayApps),
&i.APIVersion,
&i.DisplayOrder,
+ &i.ParentID,
); err != nil {
return nil, err
}
@@ -14413,7 +14417,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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order 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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order, parent_id FROM workspace_agents WHERE created_at > $1
`
func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) {
@@ -14457,6 +14461,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created
pq.Array(&i.DisplayApps),
&i.APIVersion,
&i.DisplayOrder,
+ &i.ParentID,
); err != nil {
return nil, err
}
@@ -14473,7 +14478,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.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.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version, workspace_agents.display_order
+ 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.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.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version, workspace_agents.display_order, workspace_agents.parent_id
FROM
workspace_agents
JOIN
@@ -14533,6 +14538,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx context.Co
pq.Array(&i.DisplayApps),
&i.APIVersion,
&i.DisplayOrder,
+ &i.ParentID,
); err != nil {
return nil, err
}
@@ -14551,6 +14557,7 @@ const insertWorkspaceAgent = `-- name: InsertWorkspaceAgent :one
INSERT INTO
workspace_agents (
id,
+ parent_id,
created_at,
updated_at,
name,
@@ -14570,11 +14577,12 @@ INSERT INTO
display_order
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) 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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19) 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, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version, display_order, parent_id
`
type InsertWorkspaceAgentParams struct {
ID uuid.UUID `db:"id" json:"id"`
+ ParentID uuid.NullUUID `db:"parent_id" json:"parent_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
@@ -14597,6 +14605,7 @@ type InsertWorkspaceAgentParams struct {
func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error) {
row := q.db.QueryRowContext(ctx, insertWorkspaceAgent,
arg.ID,
+ arg.ParentID,
arg.CreatedAt,
arg.UpdatedAt,
arg.Name,
@@ -14648,6 +14657,7 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa
pq.Array(&i.DisplayApps),
&i.APIVersion,
&i.DisplayOrder,
+ &i.ParentID,
)
return i, err
}
diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql
index 52d8b5275fc97..2e186461931b2 100644
--- a/coderd/database/queries/workspaceagents.sql
+++ b/coderd/database/queries/workspaceagents.sql
@@ -31,6 +31,7 @@ SELECT * FROM workspace_agents WHERE created_at > $1;
INSERT INTO
workspace_agents (
id,
+ parent_id,
created_at,
updated_at,
name,
@@ -50,7 +51,7 @@ INSERT INTO
display_order
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) RETURNING *;
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19) RETURNING *;
-- name: UpdateWorkspaceAgentConnectionByID :exec
UPDATE
diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go
index e630533c55bee..1206d81025d7a 100644
--- a/coderd/provisionerdserver/provisionerdserver.go
+++ b/coderd/provisionerdserver/provisionerdserver.go
@@ -2085,6 +2085,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
agentID := uuid.New()
dbAgent, err := db.InsertWorkspaceAgent(ctx, database.InsertWorkspaceAgentParams{
ID: agentID,
+ ParentID: uuid.NullUUID{},
CreatedAt: dbtime.Now(),
UpdatedAt: dbtime.Now(),
ResourceID: resource.ID,
diff --git a/coderd/provisionerdserver/provisionerdserver_test.go b/coderd/provisionerdserver/provisionerdserver_test.go
index 488ef4bbdfd97..9cfb3449ea522 100644
--- a/coderd/provisionerdserver/provisionerdserver_test.go
+++ b/coderd/provisionerdserver/provisionerdserver_test.go
@@ -2158,6 +2158,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
require.NoError(t, err)
require.Len(t, agents, 1)
agent := agents[0]
+ require.Equal(t, uuid.NullUUID{}, agent.ParentID)
require.Equal(t, "amd64", agent.Architecture)
require.Equal(t, "linux", agent.OperatingSystem)
want, err := json.Marshal(map[string]string{
diff --git a/codersdk/workspaceagents.go b/codersdk/workspaceagents.go
index 5c7171f70a627..f58338a209901 100644
--- a/codersdk/workspaceagents.go
+++ b/codersdk/workspaceagents.go
@@ -139,6 +139,7 @@ const (
type WorkspaceAgent struct {
ID uuid.UUID `json:"id" format:"uuid"`
+ ParentID uuid.NullUUID `json:"parent_id" format:"uuid"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
FirstConnectedAt *time.Time `json:"first_connected_at,omitempty" format:"date-time"`
diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md
index c9124efa14bf0..2ab7d454ca71b 100644
--- a/docs/admin/security/audit-logs.md
+++ b/docs/admin/security/audit-logs.md
@@ -29,7 +29,7 @@ We track the following resources:
| Template
write, delete |
Field | Tracked |
| active_version_id | true |
activity_bump | true |
allow_user_autostart | true |
allow_user_autostop | true |
allow_user_cancel_workspace_jobs | true |
autostart_block_days_of_week | true |
autostop_requirement_days_of_week | true |
autostop_requirement_weeks | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_username | false |
default_ttl | true |
deleted | false |
deprecated | true |
description | true |
display_name | true |
failure_ttl | true |
group_acl | true |
icon | true |
id | true |
max_port_sharing_level | true |
name | true |
organization_display_name | false |
organization_icon | false |
organization_id | false |
organization_name | false |
provisioner | true |
require_active_version | true |
time_til_dormant | true |
time_til_dormant_autodelete | true |
updated_at | false |
user_acl | true |
|
| TemplateVersion
create, write | Field | Tracked |
| archived | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_username | false |
external_auth_providers | false |
id | true |
job_id | false |
message | false |
name | true |
organization_id | false |
readme | true |
source_example_id | false |
template_id | true |
updated_at | false |
|
| User
create, write, delete | Field | Tracked |
| avatar_url | false |
created_at | false |
deleted | true |
email | true |
github_com_user_id | false |
hashed_one_time_passcode | false |
hashed_password | true |
id | true |
is_system | true |
last_seen_at | false |
login_type | true |
name | true |
one_time_passcode_expires_at | true |
quiet_hours_schedule | true |
rbac_roles | true |
status | true |
updated_at | false |
username | true |
|
-| WorkspaceAgent
connect, disconnect | Field | Tracked |
| api_version | false |
architecture | false |
auth_instance_id | false |
auth_token | false |
connection_timeout_seconds | false |
created_at | false |
directory | false |
disconnected_at | false |
display_apps | false |
display_order | false |
environment_variables | false |
expanded_directory | false |
first_connected_at | false |
id | false |
instance_metadata | false |
last_connected_at | false |
last_connected_replica_id | false |
lifecycle_state | false |
logs_length | false |
logs_overflowed | false |
motd_file | false |
name | false |
operating_system | false |
ready_at | false |
resource_id | false |
resource_metadata | false |
started_at | false |
subsystems | false |
troubleshooting_url | false |
updated_at | false |
version | false |
|
+| WorkspaceAgent
connect, disconnect | Field | Tracked |
| api_version | false |
architecture | false |
auth_instance_id | false |
auth_token | false |
connection_timeout_seconds | false |
created_at | false |
directory | false |
disconnected_at | false |
display_apps | false |
display_order | false |
environment_variables | false |
expanded_directory | false |
first_connected_at | false |
id | false |
instance_metadata | false |
last_connected_at | false |
last_connected_replica_id | false |
lifecycle_state | false |
logs_length | false |
logs_overflowed | false |
motd_file | false |
name | false |
operating_system | false |
parent_id | false |
ready_at | false |
resource_id | false |
resource_metadata | false |
started_at | false |
subsystems | false |
troubleshooting_url | false |
updated_at | false |
version | false |
|
| WorkspaceApp
open, close | Field | Tracked |
| agent_id | false |
command | false |
created_at | false |
display_name | false |
display_order | false |
external | false |
health | false |
healthcheck_interval | false |
healthcheck_threshold | false |
healthcheck_url | false |
hidden | false |
icon | false |
id | false |
open_in | false |
sharing_level | false |
slug | false |
subdomain | false |
url | false |
|
| WorkspaceBuild
start, stop | Field | Tracked |
| build_number | false |
created_at | false |
daily_cost | false |
deadline | false |
id | false |
initiator_by_avatar_url | false |
initiator_by_username | false |
initiator_id | false |
job_id | false |
max_deadline | false |
provisioner_state | false |
reason | false |
template_version_id | true |
template_version_preset_id | false |
transition | false |
updated_at | false |
workspace_id | false |
|
| WorkspaceProxy
| Field | Tracked |
| created_at | true |
deleted | false |
derp_enabled | true |
derp_only | true |
display_name | true |
icon | true |
id | true |
name | true |
region_id | true |
token_hashed_secret | true |
updated_at | false |
url | true |
version | true |
wildcard_hostname | true |
|
diff --git a/docs/reference/api/agents.md b/docs/reference/api/agents.md
index 853cb67e38bfd..c0ddd79cd2052 100644
--- a/docs/reference/api/agents.md
+++ b/docs/reference/api/agents.md
@@ -577,6 +577,10 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
diff --git a/docs/reference/api/builds.md b/docs/reference/api/builds.md
index 1f795c3d7d313..8e88df96c1d29 100644
--- a/docs/reference/api/builds.md
+++ b/docs/reference/api/builds.md
@@ -164,6 +164,10 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -393,6 +397,10 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -737,6 +745,10 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -859,6 +871,9 @@ Status Code **200**
| `»» logs_overflowed` | boolean | false | | |
| `»» name` | string | false | | |
| `»» operating_system` | string | false | | |
+| `»» parent_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | |
+| `»»» uuid` | string | false | | |
+| `»»» valid` | boolean | false | | Valid is true if UUID is not NULL |
| `»» ready_at` | string(date-time) | false | | |
| `»» resource_id` | string(uuid) | false | | |
| `»» scripts` | array | false | | |
@@ -1092,6 +1107,10 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -1394,6 +1413,10 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -1573,6 +1596,9 @@ Status Code **200**
| `»»» logs_overflowed` | boolean | false | | |
| `»»» name` | string | false | | |
| `»»» operating_system` | string | false | | |
+| `»»» parent_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | |
+| `»»»» uuid` | string | false | | |
+| `»»»» valid` | boolean | false | | Valid is true if UUID is not NULL |
| `»»» ready_at` | string(date-time) | false | | |
| `»»» resource_id` | string(uuid) | false | | |
| `»»» scripts` | array | false | | |
@@ -1867,6 +1893,10 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md
index 6ca005b4ec69c..8c1c86167b9d4 100644
--- a/docs/reference/api/schemas.md
+++ b/docs/reference/api/schemas.md
@@ -8304,6 +8304,10 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -8508,6 +8512,10 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -8564,6 +8572,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `logs_overflowed` | boolean | false | | |
| `name` | string | false | | |
| `operating_system` | string | false | | |
+| `parent_id` | [uuid.NullUUID](#uuidnulluuid) | false | | |
| `ready_at` | string | false | | |
| `resource_id` | string | false | | |
| `scripts` | array of [codersdk.WorkspaceAgentScript](#codersdkworkspaceagentscript) | false | | |
@@ -9256,6 +9265,10 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -9672,6 +9685,10 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -9954,6 +9971,10 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -11941,6 +11962,22 @@ RegionIDs in range 900-999 are reserved for end users to run their own DERP node
None
+## uuid.NullUUID
+
+```json
+{
+ "uuid": "string",
+ "valid": true
+}
+```
+
+### Properties
+
+| Name | Type | Required | Restrictions | Description |
+|---------|---------|----------|--------------|-----------------------------------|
+| `uuid` | string | false | | |
+| `valid` | boolean | false | | Valid is true if UUID is not NULL |
+
## workspaceapps.AccessMethod
```json
diff --git a/docs/reference/api/templates.md b/docs/reference/api/templates.md
index ef136764bf2c5..b1beeb64a7116 100644
--- a/docs/reference/api/templates.md
+++ b/docs/reference/api/templates.md
@@ -2348,6 +2348,10 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -2470,6 +2474,9 @@ Status Code **200**
| `»» logs_overflowed` | boolean | false | | |
| `»» name` | string | false | | |
| `»» operating_system` | string | false | | |
+| `»» parent_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | |
+| `»»» uuid` | string | false | | |
+| `»»» valid` | boolean | false | | Valid is true if UUID is not NULL |
| `»» ready_at` | string(date-time) | false | | |
| `»» resource_id` | string(uuid) | false | | |
| `»» scripts` | array | false | | |
@@ -2869,6 +2876,10 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -2991,6 +3002,9 @@ Status Code **200**
| `»» logs_overflowed` | boolean | false | | |
| `»» name` | string | false | | |
| `»» operating_system` | string | false | | |
+| `»» parent_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | |
+| `»»» uuid` | string | false | | |
+| `»»» valid` | boolean | false | | Valid is true if UUID is not NULL |
| `»» ready_at` | string(date-time) | false | | |
| `»» resource_id` | string(uuid) | false | | |
| `»» scripts` | array | false | | |
diff --git a/docs/reference/api/workspaces.md b/docs/reference/api/workspaces.md
index 5d09c46a01d30..8e25cd0bd58e6 100644
--- a/docs/reference/api/workspaces.md
+++ b/docs/reference/api/workspaces.md
@@ -219,6 +219,10 @@ of the template will be used.
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -496,6 +500,10 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -799,6 +807,10 @@ of the template will be used.
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -1062,6 +1074,10 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -1340,6 +1356,10 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
@@ -1733,6 +1753,10 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \
"logs_overflowed": true,
"name": "string",
"operating_system": "string",
+ "parent_id": {
+ "uuid": "string",
+ "valid": true
+ },
"ready_at": "2019-08-24T14:15:22Z",
"resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"scripts": [
diff --git a/enterprise/audit/table.go b/enterprise/audit/table.go
index 84cc7d451b4f1..d5bf22df9ff5e 100644
--- a/enterprise/audit/table.go
+++ b/enterprise/audit/table.go
@@ -342,6 +342,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
"display_apps": ActionIgnore,
"api_version": ActionIgnore,
"display_order": ActionIgnore,
+ "parent_id": ActionIgnore,
},
&database.WorkspaceApp{}: {
"id": ActionIgnore,
diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts
index e471e12b240b6..63dabab5bd793 100644
--- a/site/src/api/typesGenerated.ts
+++ b/site/src/api/typesGenerated.ts
@@ -3254,6 +3254,7 @@ export interface Workspace {
// From codersdk/workspaceagents.go
export interface WorkspaceAgent {
readonly id: string;
+ readonly parent_id: string | null;
readonly created_at: string;
readonly updated_at: string;
readonly first_connected_at?: string;
diff --git a/site/src/pages/WorkspacePage/Workspace.stories.tsx b/site/src/pages/WorkspacePage/Workspace.stories.tsx
index 957a651788d2c..ca782d73b68a0 100644
--- a/site/src/pages/WorkspacePage/Workspace.stories.tsx
+++ b/site/src/pages/WorkspacePage/Workspace.stories.tsx
@@ -103,6 +103,33 @@ export const Running: Story = {
},
};
+export const RunningWithChildAgent: Story = {
+ args: {
+ ...Running.args,
+ workspace: {
+ ...Mocks.MockWorkspace,
+ latest_build: {
+ ...Mocks.MockWorkspace.latest_build,
+ resources: [
+ {
+ ...Mocks.MockWorkspaceResource,
+ agents: [
+ {
+ ...Mocks.MockWorkspaceAgent,
+ lifecycle_state: "ready",
+ },
+ {
+ ...Mocks.MockWorkspaceChildAgent,
+ lifecycle_state: "ready",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ },
+};
+
export const RunningWithAppStatuses: Story = {
args: {
workspace: {
diff --git a/site/src/pages/WorkspacePage/Workspace.tsx b/site/src/pages/WorkspacePage/Workspace.tsx
index 69ce29ed0e7d1..1c60b8b86b50b 100644
--- a/site/src/pages/WorkspacePage/Workspace.tsx
+++ b/site/src/pages/WorkspacePage/Workspace.tsx
@@ -269,22 +269,28 @@ export const Workspace: FC = ({
minWidth: 0 /* Prevent overflow */,
}}
>
- {selectedResource.agents?.map((agent) => (
-
- ))}
+ {selectedResource.agents
+ // If an agent has a `parent_id`, that means it is
+ // child of another agent. We do not want these agents
+ // to be displayed at the top-level on this page. We
+ // want them to display _as children_ of their parents.
+ ?.filter((agent) => agent.parent_id === null)
+ .map((agent) => (
+
+ ))}
{(!selectedResource.agents ||
selectedResource.agents?.length === 0) && (
diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts
index a8db5f55879c4..7fa69c006b8e7 100644
--- a/site/src/testHelpers/entities.ts
+++ b/site/src/testHelpers/entities.ts
@@ -932,6 +932,7 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
created_at: "",
environment_variables: {},
id: "test-workspace-agent",
+ parent_id: null,
name: "a-workspace-agent",
operating_system: "linux",
resource_id: "",
@@ -966,6 +967,47 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
],
};
+export const MockWorkspaceChildAgent: TypesGen.WorkspaceAgent = {
+ apps: [],
+ architecture: "amd64",
+ created_at: "",
+ environment_variables: {},
+ id: "test-workspace-child-agent",
+ parent_id: "test-workspace-agent",
+ name: "a-workspace-child-agent",
+ operating_system: "linux",
+ resource_id: "",
+ status: "connected",
+ updated_at: "",
+ version: MockBuildInfo.version,
+ api_version: MockBuildInfo.agent_api_version,
+ latency: {
+ "Coder Embedded DERP": {
+ latency_ms: 32.55,
+ preferred: true,
+ },
+ },
+ connection_timeout_seconds: 120,
+ troubleshooting_url: "https://coder.com/troubleshoot",
+ lifecycle_state: "starting",
+ logs_length: 0,
+ logs_overflowed: false,
+ log_sources: [MockWorkspaceAgentLogSource],
+ scripts: [],
+ startup_script_behavior: "non-blocking",
+ subsystems: ["envbox", "exectrace"],
+ health: {
+ healthy: true,
+ },
+ display_apps: [
+ "ssh_helper",
+ "port_forwarding_helper",
+ "vscode",
+ "vscode_insiders",
+ "web_terminal",
+ ],
+};
+
export const MockWorkspaceAppStatus: TypesGen.WorkspaceAppStatus = {
id: "test-app-status",
created_at: "2022-05-17T17:39:01.382927298Z",
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy