Skip to content

Commit 24f99e6

Browse files
committed
feat: Update Terraform provider to support "dir" in "coder_agent"
This allows users to specify a starting directory for shell sessions.
1 parent 35211e2 commit 24f99e6

File tree

14 files changed

+186
-114
lines changed

14 files changed

+186
-114
lines changed

agent/agent.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type Metadata struct {
3838
OwnerUsername string `json:"owner_username"`
3939
EnvironmentVariables map[string]string `json:"environment_variables"`
4040
StartupScript string `json:"startup_script"`
41+
Directory string `json:"directory"`
4142
}
4243

4344
type Dialer func(ctx context.Context, logger slog.Logger) (Metadata, *peerbroker.Listener, error)
@@ -66,6 +67,7 @@ type agent struct {
6667
// Environment variables sent by Coder to inject for shell sessions.
6768
// These are atomic because values can change after reconnect.
6869
envVars atomic.Value
70+
directory atomic.String
6971
ownerEmail atomic.String
7072
ownerUsername atomic.String
7173
startupScript atomic.Bool
@@ -98,6 +100,7 @@ func (a *agent) run(ctx context.Context) {
98100
return
99101
default:
100102
}
103+
a.directory.Store(options.Directory)
101104
a.envVars.Store(options.EnvironmentVariables)
102105
a.ownerEmail.Store(options.OwnerEmail)
103106
a.ownerUsername.Store(options.OwnerUsername)
@@ -308,6 +311,11 @@ func (a *agent) handleSSHSession(session ssh.Session) error {
308311
caller = "/c"
309312
}
310313
cmd := exec.CommandContext(session.Context(), shell, caller, command)
314+
cmd.Dir = a.directory.Load()
315+
if cmd.Dir == "" {
316+
// Default to $HOME if a directory is not set!
317+
cmd.Dir = os.Getenv("HOME")
318+
}
311319
cmd.Env = append(os.Environ(), session.Environ()...)
312320
executablePath, err := os.Executable()
313321
if err != nil {

coderd/database/dump.sql

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE ONLY workspace_agents
2+
DROP COLUMN IF EXISTS directory;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ALTER TABLE ONLY workspace_agents
2+
-- UNIX paths are a maximum length of 4096.
3+
ADD COLUMN IF NOT EXISTS directory varchar(4096) DEFAULT '' NOT NULL;

coderd/database/models.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

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

coderd/provisionerdaemons.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
243243
WorkspaceTransition: transition,
244244
WorkspaceName: workspace.Name,
245245
WorkspaceOwner: owner.Username,
246+
WorkspaceId: workspace.ID.String(),
247+
WorkspaceOwnerId: owner.ID.String(),
246248
},
247249
},
248250
}

coderd/workspaceagents.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ func (api *api) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request)
131131
OwnerUsername: owner.Username,
132132
EnvironmentVariables: apiAgent.EnvironmentVariables,
133133
StartupScript: apiAgent.StartupScript,
134+
Directory: apiAgent.Directory,
134135
})
135136
}
136137

@@ -339,6 +340,7 @@ func convertWorkspaceAgent(dbAgent database.WorkspaceAgent, agentUpdateFrequency
339340
OperatingSystem: dbAgent.OperatingSystem,
340341
StartupScript: dbAgent.StartupScript.String,
341342
EnvironmentVariables: envs,
343+
Directory: dbAgent.Directory,
342344
}
343345
if dbAgent.FirstConnectedAt.Valid {
344346
workspaceAgent.FirstConnectedAt = &dbAgent.FirstConnectedAt.Time

codersdk/workspaceresources.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type WorkspaceAgent struct {
4545
EnvironmentVariables map[string]string `json:"environment_variables"`
4646
OperatingSystem string `json:"operating_system"`
4747
StartupScript string `json:"startup_script,omitempty"`
48+
Directory string `json:"directory,omitempty"`
4849
}
4950

5051
type WorkspaceAgentResourceMetadata struct {

provisioner/terraform/provision.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ func (t *terraform) Provision(stream proto.DRPCProvisioner_ProvisionStream) erro
124124
"CODER_WORKSPACE_TRANSITION="+strings.ToLower(start.Metadata.WorkspaceTransition.String()),
125125
"CODER_WORKSPACE_NAME="+start.Metadata.WorkspaceName,
126126
"CODER_WORKSPACE_OWNER="+start.Metadata.WorkspaceOwner,
127+
"CODER_WORKSPACE_ID="+start.Metadata.WorkspaceId,
128+
"CODER_WORKSPACE_OWNER_ID="+start.Metadata.WorkspaceOwnerId,
127129
)
128130
for key, value := range provisionersdk.AgentScriptEnv() {
129131
env = append(env, key+"="+value)
@@ -330,6 +332,12 @@ func parseTerraformPlan(ctx context.Context, terraform *tfexec.Terraform, planfi
330332
agent.StartupScript = startupScript
331333
}
332334
}
335+
if directoryRaw, has := resource.Expressions["dir"]; has {
336+
dir, ok := directoryRaw.ConstantValue.(string)
337+
if ok {
338+
agent.Directory = dir
339+
}
340+
}
333341

334342
agents[resource.Address] = agent
335343
}
@@ -381,6 +389,7 @@ func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform, state
381389
Auth string `mapstructure:"auth"`
382390
OperatingSystem string `mapstructure:"os"`
383391
Architecture string `mapstructure:"arch"`
392+
Directory string `mapstructure:"dir"`
384393
ID string `mapstructure:"id"`
385394
Token string `mapstructure:"token"`
386395
Env map[string]string `mapstructure:"env"`
@@ -405,6 +414,7 @@ func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform, state
405414
StartupScript: attrs.StartupScript,
406415
OperatingSystem: attrs.OperatingSystem,
407416
Architecture: attrs.Architecture,
417+
Directory: attrs.Directory,
408418
}
409419
switch attrs.Auth {
410420
case "token":

provisioner/terraform/provision_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ terraform {
2828
required_providers {
2929
coder = {
3030
source = "coder/coder"
31-
version = "0.3.1"
31+
version = "0.3.3"
3232
}
3333
}
3434
}
@@ -160,6 +160,7 @@ provider "coder" {
160160
resource "coder_agent" "A" {
161161
os = "windows"
162162
arch = "arm64"
163+
dir = "C:\\System32"
163164
}
164165
resource "null_resource" "A" {
165166
depends_on = [
@@ -184,6 +185,7 @@ provider "coder" {
184185
Name: "A",
185186
OperatingSystem: "windows",
186187
Architecture: "arm64",
188+
Directory: "C:\\System32",
187189
Auth: &proto.Agent_Token{
188190
Token: "",
189191
},

0 commit comments

Comments
 (0)