Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: Update Terraform provider to support "dir" in "coder_agent"
This allows users to specify a starting directory for shell sessions.
  • Loading branch information
kylecarbs committed Apr 29, 2022
commit 24f99e637bfe102fc38b48d492e6d0fb573c0ff4
8 changes: 8 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Metadata struct {
OwnerUsername string `json:"owner_username"`
EnvironmentVariables map[string]string `json:"environment_variables"`
StartupScript string `json:"startup_script"`
Directory string `json:"directory"`
}

type Dialer func(ctx context.Context, logger slog.Logger) (Metadata, *peerbroker.Listener, error)
Expand Down Expand Up @@ -66,6 +67,7 @@ type agent struct {
// Environment variables sent by Coder to inject for shell sessions.
// These are atomic because values can change after reconnect.
envVars atomic.Value
directory atomic.String
ownerEmail atomic.String
ownerUsername atomic.String
startupScript atomic.Bool
Expand Down Expand Up @@ -98,6 +100,7 @@ func (a *agent) run(ctx context.Context) {
return
default:
}
a.directory.Store(options.Directory)
a.envVars.Store(options.EnvironmentVariables)
a.ownerEmail.Store(options.OwnerEmail)
a.ownerUsername.Store(options.OwnerUsername)
Expand Down Expand Up @@ -308,6 +311,11 @@ func (a *agent) handleSSHSession(session ssh.Session) error {
caller = "/c"
}
cmd := exec.CommandContext(session.Context(), shell, caller, command)
cmd.Dir = a.directory.Load()
if cmd.Dir == "" {
// Default to $HOME if a directory is not set!
cmd.Dir = os.Getenv("HOME")
}
cmd.Env = append(os.Environ(), session.Environ()...)
executablePath, err := os.Executable()
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion coderd/database/dump.sql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions coderd/database/migrations/000009_agent_directory.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE ONLY workspace_agents
DROP COLUMN IF EXISTS directory;
3 changes: 3 additions & 0 deletions coderd/database/migrations/000009_agent_directory.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE ONLY workspace_agents
-- UNIX paths are a maximum length of 4096.
ADD COLUMN IF NOT EXISTS directory varchar(4096) DEFAULT '' NOT NULL;
1 change: 1 addition & 0 deletions coderd/database/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions coderd/provisionerdaemons.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
WorkspaceTransition: transition,
WorkspaceName: workspace.Name,
WorkspaceOwner: owner.Username,
WorkspaceId: workspace.ID.String(),
WorkspaceOwnerId: owner.ID.String(),
},
},
}
Expand Down
2 changes: 2 additions & 0 deletions coderd/workspaceagents.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func (api *api) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request)
OwnerUsername: owner.Username,
EnvironmentVariables: apiAgent.EnvironmentVariables,
StartupScript: apiAgent.StartupScript,
Directory: apiAgent.Directory,
})
}

Expand Down Expand Up @@ -339,6 +340,7 @@ func convertWorkspaceAgent(dbAgent database.WorkspaceAgent, agentUpdateFrequency
OperatingSystem: dbAgent.OperatingSystem,
StartupScript: dbAgent.StartupScript.String,
EnvironmentVariables: envs,
Directory: dbAgent.Directory,
}
if dbAgent.FirstConnectedAt.Valid {
workspaceAgent.FirstConnectedAt = &dbAgent.FirstConnectedAt.Time
Expand Down
1 change: 1 addition & 0 deletions codersdk/workspaceresources.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type WorkspaceAgent struct {
EnvironmentVariables map[string]string `json:"environment_variables"`
OperatingSystem string `json:"operating_system"`
StartupScript string `json:"startup_script,omitempty"`
Directory string `json:"directory,omitempty"`
}

type WorkspaceAgentResourceMetadata struct {
Expand Down
10 changes: 10 additions & 0 deletions provisioner/terraform/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ func (t *terraform) Provision(stream proto.DRPCProvisioner_ProvisionStream) erro
"CODER_WORKSPACE_TRANSITION="+strings.ToLower(start.Metadata.WorkspaceTransition.String()),
"CODER_WORKSPACE_NAME="+start.Metadata.WorkspaceName,
"CODER_WORKSPACE_OWNER="+start.Metadata.WorkspaceOwner,
"CODER_WORKSPACE_ID="+start.Metadata.WorkspaceId,
"CODER_WORKSPACE_OWNER_ID="+start.Metadata.WorkspaceOwnerId,
)
for key, value := range provisionersdk.AgentScriptEnv() {
env = append(env, key+"="+value)
Expand Down Expand Up @@ -330,6 +332,12 @@ func parseTerraformPlan(ctx context.Context, terraform *tfexec.Terraform, planfi
agent.StartupScript = startupScript
}
}
if directoryRaw, has := resource.Expressions["dir"]; has {
dir, ok := directoryRaw.ConstantValue.(string)
if ok {
agent.Directory = dir
}
}

agents[resource.Address] = agent
}
Expand Down Expand Up @@ -381,6 +389,7 @@ func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform, state
Auth string `mapstructure:"auth"`
OperatingSystem string `mapstructure:"os"`
Architecture string `mapstructure:"arch"`
Directory string `mapstructure:"dir"`
ID string `mapstructure:"id"`
Token string `mapstructure:"token"`
Env map[string]string `mapstructure:"env"`
Expand All @@ -405,6 +414,7 @@ func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform, state
StartupScript: attrs.StartupScript,
OperatingSystem: attrs.OperatingSystem,
Architecture: attrs.Architecture,
Directory: attrs.Directory,
}
switch attrs.Auth {
case "token":
Expand Down
4 changes: 3 additions & 1 deletion provisioner/terraform/provision_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.3.1"
version = "0.3.3"
}
}
}
Expand Down Expand Up @@ -160,6 +160,7 @@ provider "coder" {
resource "coder_agent" "A" {
os = "windows"
arch = "arm64"
dir = "C:\\System32"
}
resource "null_resource" "A" {
depends_on = [
Expand All @@ -184,6 +185,7 @@ provider "coder" {
Name: "A",
OperatingSystem: "windows",
Architecture: "arm64",
Directory: "C:\\System32",
Auth: &proto.Agent_Token{
Token: "",
},
Expand Down
Loading