Skip to content

Commit 07fd73c

Browse files
authored
chore: allow multiple agent subsystems, add exectrace (coder#8933)
1 parent 70bd23a commit 07fd73c

26 files changed

+285
-119
lines changed

agent/agent.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ type Options struct {
6464
IgnorePorts map[int]string
6565
SSHMaxTimeout time.Duration
6666
TailnetListenPort uint16
67-
Subsystem codersdk.AgentSubsystem
67+
Subsystems []codersdk.AgentSubsystem
6868
Addresses []netip.Prefix
6969
PrometheusRegistry *prometheus.Registry
7070
ReportMetadataInterval time.Duration
@@ -145,7 +145,7 @@ func New(options Options) Agent {
145145
reportMetadataInterval: options.ReportMetadataInterval,
146146
serviceBannerRefreshInterval: options.ServiceBannerRefreshInterval,
147147
sshMaxTimeout: options.SSHMaxTimeout,
148-
subsystem: options.Subsystem,
148+
subsystems: options.Subsystems,
149149
addresses: options.Addresses,
150150

151151
prometheusRegistry: prometheusRegistry,
@@ -167,7 +167,7 @@ type agent struct {
167167
// listing all listening ports. This is helpful to hide ports that
168168
// are used by the agent, that the user does not care about.
169169
ignorePorts map[int]string
170-
subsystem codersdk.AgentSubsystem
170+
subsystems []codersdk.AgentSubsystem
171171

172172
reconnectingPTYs sync.Map
173173
reconnectingPTYTimeout time.Duration
@@ -609,7 +609,7 @@ func (a *agent) run(ctx context.Context) error {
609609
err = a.client.PostStartup(ctx, agentsdk.PostStartupRequest{
610610
Version: buildinfo.Version(),
611611
ExpandedDirectory: manifest.Directory,
612-
Subsystem: a.subsystem,
612+
Subsystems: a.subsystems,
613613
})
614614
if err != nil {
615615
return xerrors.Errorf("update workspace agent version: %w", err)

cli/agent.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"path/filepath"
1313
"runtime"
1414
"strconv"
15+
"strings"
1516
"sync"
1617
"time"
1718

@@ -253,7 +254,19 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
253254
}
254255

255256
prometheusRegistry := prometheus.NewRegistry()
256-
subsystem := inv.Environ.Get(agent.EnvAgentSubsystem)
257+
subsystemsRaw := inv.Environ.Get(agent.EnvAgentSubsystem)
258+
subsystems := []codersdk.AgentSubsystem{}
259+
for _, s := range strings.Split(subsystemsRaw, ",") {
260+
subsystem := codersdk.AgentSubsystem(strings.TrimSpace(s))
261+
if subsystem == "" {
262+
continue
263+
}
264+
if !subsystem.Valid() {
265+
return xerrors.Errorf("invalid subsystem %q", subsystem)
266+
}
267+
subsystems = append(subsystems, subsystem)
268+
}
269+
257270
agnt := agent.New(agent.Options{
258271
Client: client,
259272
Logger: logger,
@@ -275,7 +288,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
275288
},
276289
IgnorePorts: ignorePorts,
277290
SSHMaxTimeout: sshMaxTimeout,
278-
Subsystem: codersdk.AgentSubsystem(subsystem),
291+
Subsystems: subsystems,
279292

280293
PrometheusRegistry: prometheusRegistry,
281294
})

cli/agent_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli_test
22

33
import (
44
"context"
5+
"fmt"
56
"os"
67
"path/filepath"
78
"runtime"
@@ -264,8 +265,8 @@ func TestWorkspaceAgent(t *testing.T) {
264265
"--agent-url", client.URL.String(),
265266
"--log-dir", logDir,
266267
)
267-
// Set the subsystem for the agent.
268-
inv.Environ.Set(agent.EnvAgentSubsystem, string(codersdk.AgentSubsystemEnvbox))
268+
// Set the subsystems for the agent.
269+
inv.Environ.Set(agent.EnvAgentSubsystem, fmt.Sprintf("%s,%s", codersdk.AgentSubsystemExectrace, codersdk.AgentSubsystemEnvbox))
269270

270271
pty := ptytest.New(t).Attach(inv)
271272

@@ -275,6 +276,9 @@ func TestWorkspaceAgent(t *testing.T) {
275276
resources := coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
276277
require.Len(t, resources, 1)
277278
require.Len(t, resources[0].Agents, 1)
278-
require.Equal(t, codersdk.AgentSubsystemEnvbox, resources[0].Agents[0].Subsystem)
279+
require.Len(t, resources[0].Agents[0].Subsystems, 2)
280+
// Sorted
281+
require.Equal(t, codersdk.AgentSubsystemEnvbox, resources[0].Agents[0].Subsystems[0])
282+
require.Equal(t, codersdk.AgentSubsystemExectrace, resources[0].Agents[0].Subsystems[1])
279283
})
280284
}

coderd/apidoc/docs.go

Lines changed: 16 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 16 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,8 +1064,10 @@ func (s *MethodTestSuite) TestWorkspace() {
10641064
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
10651065
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
10661066
check.Args(database.UpdateWorkspaceAgentStartupByIDParams{
1067-
ID: agt.ID,
1068-
Subsystem: database.WorkspaceAgentSubsystemNone,
1067+
ID: agt.ID,
1068+
Subsystems: []database.WorkspaceAgentSubsystem{
1069+
database.WorkspaceAgentSubsystemEnvbox,
1070+
},
10691071
}).Asserts(ws, rbac.ActionUpdate).Returns()
10701072
}))
10711073
s.Run("GetWorkspaceAgentLogsAfter", s.Subtest(func(db database.Store, check *expects) {

coderd/database/dbfake/dbfake.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5203,6 +5203,23 @@ func (q *FakeQuerier) UpdateWorkspaceAgentStartupByID(_ context.Context, arg dat
52035203
return err
52045204
}
52055205

5206+
if len(arg.Subsystems) > 0 {
5207+
seen := map[database.WorkspaceAgentSubsystem]struct{}{
5208+
arg.Subsystems[0]: {},
5209+
}
5210+
for i := 1; i < len(arg.Subsystems); i++ {
5211+
s := arg.Subsystems[i]
5212+
if _, ok := seen[s]; ok {
5213+
return xerrors.Errorf("duplicate subsystem %q", s)
5214+
}
5215+
seen[s] = struct{}{}
5216+
5217+
if arg.Subsystems[i-1] > arg.Subsystems[i] {
5218+
return xerrors.Errorf("subsystems not sorted: %q > %q", arg.Subsystems[i-1], arg.Subsystems[i])
5219+
}
5220+
}
5221+
}
5222+
52065223
q.mutex.Lock()
52075224
defer q.mutex.Unlock()
52085225

@@ -5213,7 +5230,7 @@ func (q *FakeQuerier) UpdateWorkspaceAgentStartupByID(_ context.Context, arg dat
52135230

52145231
agent.Version = arg.Version
52155232
agent.ExpandedDirectory = arg.ExpandedDirectory
5216-
agent.Subsystem = arg.Subsystem
5233+
agent.Subsystems = arg.Subsystems
52175234
q.workspaceAgents[index] = agent
52185235
return nil
52195236
}

coderd/database/dump.sql

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
BEGIN;
2+
3+
-- Bring back the subsystem column.
4+
ALTER TABLE workspace_agents ADD COLUMN subsystem workspace_agent_subsystem NOT NULL DEFAULT 'none';
5+
6+
-- Update all existing workspace_agents to have subsystem = subsystems[0] unless
7+
-- subsystems is empty.
8+
UPDATE workspace_agents SET subsystem = subsystems[1] WHERE cardinality(subsystems) > 0;
9+
10+
-- Drop the subsystems column from workspace_agents.
11+
ALTER TABLE workspace_agents DROP COLUMN subsystems;
12+
13+
-- We cannot drop the "exectrace" value from the workspace_agent_subsystem type
14+
-- because you cannot drop values from an enum type.
15+
UPDATE workspace_agents SET subsystem = 'none' WHERE subsystem = 'exectrace';
16+
17+
COMMIT;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
BEGIN;
2+
3+
-- Add "exectrace" to workspace_agent_subsystem type.
4+
ALTER TYPE workspace_agent_subsystem ADD VALUE 'exectrace';
5+
6+
-- Create column subsystems in workspace_agents table, with default value being
7+
-- an empty array.
8+
ALTER TABLE workspace_agents ADD COLUMN subsystems workspace_agent_subsystem[] DEFAULT '{}';
9+
10+
-- Add a constraint that the subsystems cannot contain the deprecated value
11+
-- 'none'.
12+
ALTER TABLE workspace_agents ADD CONSTRAINT subsystems_not_none CHECK (NOT ('none' = ANY (subsystems)));
13+
14+
-- Update all existing workspace_agents to have subsystems = [subsystem] unless
15+
-- the subsystem is 'none'.
16+
UPDATE workspace_agents SET subsystems = ARRAY[subsystem] WHERE subsystem != 'none';
17+
18+
-- Drop the subsystem column from workspace_agents.
19+
ALTER TABLE workspace_agents DROP COLUMN subsystem;
20+
21+
COMMIT;

coderd/database/models.go

Lines changed: 7 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)