Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0f2394a

Browse files
committed
Merge branch 'main' into optional-external-auth-frontend
2 parents1dc0874 +475c365 commit0f2394a

File tree

177 files changed

+7760
-2033
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+7760
-2033
lines changed

‎.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ coderd/apidoc/swagger.json linguist-generated=true
66
coderd/database/dump.sqllinguist-generated=true
77
peerbroker/proto/*.golinguist-generated=true
88
provisionerd/proto/*.golinguist-generated=true
9+
provisionerd/proto/version.golinguist-generated=false
910
provisionersdk/proto/*.golinguist-generated=true
1011
*.tfplan.jsonlinguist-generated=true
1112
*.tfstate.jsonlinguist-generated=true

‎.github/workflows/dogfood.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ jobs:
109109
-name:"Push template"
110110
if:github.ref == 'refs/heads/main'
111111
run:|
112-
./coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION --message="$CODER_TEMPLATE_MESSAGE" --variable jfrog_url=${{ secrets.JFROG_URL }}
112+
./coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION --message="$CODER_TEMPLATE_MESSAGE"
113113
env:
114114
# Consumed by Coder CLI
115115
CODER_URL:https://dev.coder.com

‎.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
"Signup",
115115
"slogtest",
116116
"sourcemapped",
117+
"spinbutton",
117118
"Srcs",
118119
"stdbuf",
119120
"stretchr",

‎agent/agent.go

Lines changed: 115 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ type Options struct {
6666
Filesystem afero.Fs
6767
LogDirstring
6868
TempDirstring
69+
ScriptDataDirstring
6970
ExchangeTokenfunc(ctx context.Context) (string,error)
7071
ClientClient
7172
ReconnectingPTYTimeout time.Duration
@@ -112,9 +113,19 @@ func New(options Options) Agent {
112113
ifoptions.LogDir=="" {
113114
ifoptions.TempDir!=os.TempDir() {
114115
options.Logger.Debug(context.Background(),"log dir not set, using temp dir",slog.F("temp_dir",options.TempDir))
116+
}else {
117+
options.Logger.Debug(context.Background(),"using log dir",slog.F("log_dir",options.LogDir))
115118
}
116119
options.LogDir=options.TempDir
117120
}
121+
ifoptions.ScriptDataDir=="" {
122+
ifoptions.TempDir!=os.TempDir() {
123+
options.Logger.Debug(context.Background(),"script data dir not set, using temp dir",slog.F("temp_dir",options.TempDir))
124+
}else {
125+
options.Logger.Debug(context.Background(),"using script data dir",slog.F("script_data_dir",options.ScriptDataDir))
126+
}
127+
options.ScriptDataDir=options.TempDir
128+
}
118129
ifoptions.ExchangeToken==nil {
119130
options.ExchangeToken=func(ctx context.Context) (string,error) {
120131
return"",nil
@@ -146,12 +157,13 @@ func New(options Options) Agent {
146157
logger:options.Logger,
147158
closeCancel:cancelFunc,
148159
closed:make(chanstruct{}),
149-
envVars:options.EnvironmentVariables,
160+
environmentVariables:options.EnvironmentVariables,
150161
client:options.Client,
151162
exchangeToken:options.ExchangeToken,
152163
filesystem:options.Filesystem,
153164
logDir:options.LogDir,
154165
tempDir:options.TempDir,
166+
scriptDataDir:options.ScriptDataDir,
155167
lifecycleUpdate:make(chanstruct{},1),
156168
lifecycleReported:make(chan codersdk.WorkspaceAgentLifecycle,1),
157169
lifecycleStates: []agentsdk.PostLifecycleRequest{{State:codersdk.WorkspaceAgentLifecycleCreated}},
@@ -169,6 +181,8 @@ func New(options Options) Agent {
169181
prometheusRegistry:prometheusRegistry,
170182
metrics:newAgentMetrics(prometheusRegistry),
171183
}
184+
a.serviceBanner.Store(new(codersdk.ServiceBannerConfig))
185+
a.sessionToken.Store(new(string))
172186
a.init(ctx)
173187
returna
174188
}
@@ -181,6 +195,7 @@ type agent struct {
181195
filesystem afero.Fs
182196
logDirstring
183197
tempDirstring
198+
scriptDataDirstring
184199
// ignorePorts tells the api handler which ports to ignore when
185200
// listing all listening ports. This is helpful to hide ports that
186201
// are used by the agent, that the user does not care about.
@@ -196,7 +211,7 @@ type agent struct {
196211
closeMutex sync.Mutex
197212
closedchanstruct{}
198213

199-
envVarsmap[string]string
214+
environmentVariablesmap[string]string
200215

201216
manifest atomic.Pointer[agentsdk.Manifest]// manifest is atomic because values can change after reconnection.
202217
reportMetadataInterval time.Duration
@@ -235,21 +250,24 @@ func (a *agent) TailnetConn() *tailnet.Conn {
235250
}
236251

237252
func (a*agent)init(ctx context.Context) {
238-
sshSrv,err:=agentssh.NewServer(ctx,a.logger.Named("ssh-server"),a.prometheusRegistry,a.filesystem,a.sshMaxTimeout,"")
253+
sshSrv,err:=agentssh.NewServer(ctx,a.logger.Named("ssh-server"),a.prometheusRegistry,a.filesystem,&agentssh.Config{
254+
MaxTimeout:a.sshMaxTimeout,
255+
MOTDFile:func()string {returna.manifest.Load().MOTDFile },
256+
ServiceBanner:func()*codersdk.ServiceBannerConfig {returna.serviceBanner.Load() },
257+
UpdateEnv:a.updateCommandEnv,
258+
WorkingDirectory:func()string {returna.manifest.Load().Directory },
259+
})
239260
iferr!=nil {
240261
panic(err)
241262
}
242-
sshSrv.Env=a.envVars
243-
sshSrv.AgentToken=func()string {return*a.sessionToken.Load() }
244-
sshSrv.Manifest=&a.manifest
245-
sshSrv.ServiceBanner=&a.serviceBanner
246263
a.sshServer=sshSrv
247264
a.scriptRunner=agentscripts.New(agentscripts.Options{
248-
LogDir:a.logDir,
249-
Logger:a.logger,
250-
SSHServer:sshSrv,
251-
Filesystem:a.filesystem,
252-
PatchLogs:a.client.PatchLogs,
265+
LogDir:a.logDir,
266+
DataDirBase:a.scriptDataDir,
267+
Logger:a.logger,
268+
SSHServer:sshSrv,
269+
Filesystem:a.filesystem,
270+
PatchLogs:a.client.PatchLogs,
253271
})
254272
// Register runner metrics. If the prom registry is nil, the metrics
255273
// will not report anywhere.
@@ -879,6 +897,90 @@ func (a *agent) run(ctx context.Context) error {
879897
returneg.Wait()
880898
}
881899

900+
// updateCommandEnv updates the provided command environment with the
901+
// following set of environment variables:
902+
// - Predefined workspace environment variables
903+
// - Environment variables currently set (overriding predefined)
904+
// - Environment variables passed via the agent manifest (overriding predefined and current)
905+
// - Agent-level environment variables (overriding all)
906+
func (a*agent)updateCommandEnv(current []string) (updated []string,errerror) {
907+
manifest:=a.manifest.Load()
908+
ifmanifest==nil {
909+
returnnil,xerrors.Errorf("no manifest")
910+
}
911+
912+
executablePath,err:=os.Executable()
913+
iferr!=nil {
914+
returnnil,xerrors.Errorf("getting os executable: %w",err)
915+
}
916+
unixExecutablePath:=strings.ReplaceAll(executablePath,"\\","/")
917+
918+
// Define environment variables that should be set for all commands,
919+
// and then merge them with the current environment.
920+
envs:=map[string]string{
921+
// Set env vars indicating we're inside a Coder workspace.
922+
"CODER":"true",
923+
"CODER_WORKSPACE_NAME":manifest.WorkspaceName,
924+
"CODER_WORKSPACE_AGENT_NAME":manifest.AgentName,
925+
926+
// Specific Coder subcommands require the agent token exposed!
927+
"CODER_AGENT_TOKEN":*a.sessionToken.Load(),
928+
929+
// Git on Windows resolves with UNIX-style paths.
930+
// If using backslashes, it's unable to find the executable.
931+
"GIT_SSH_COMMAND":fmt.Sprintf("%s gitssh --",unixExecutablePath),
932+
// Hide Coder message on code-server's "Getting Started" page
933+
"CS_DISABLE_GETTING_STARTED_OVERRIDE":"true",
934+
}
935+
936+
// This adds the ports dialog to code-server that enables
937+
// proxying a port dynamically.
938+
// If this is empty string, do not set anything. Code-server auto defaults
939+
// using its basepath to construct a path based port proxy.
940+
ifmanifest.VSCodePortProxyURI!="" {
941+
envs["VSCODE_PROXY_URI"]=manifest.VSCodePortProxyURI
942+
}
943+
944+
// Allow any of the current env to override what we defined above.
945+
for_,env:=rangecurrent {
946+
parts:=strings.SplitN(env,"=",2)
947+
iflen(parts)!=2 {
948+
continue
949+
}
950+
if_,ok:=envs[parts[0]];!ok {
951+
envs[parts[0]]=parts[1]
952+
}
953+
}
954+
955+
// Load environment variables passed via the agent manifest.
956+
// These override all variables we manually specify.
957+
fork,v:=rangemanifest.EnvironmentVariables {
958+
// Expanding environment variables allows for customization
959+
// of the $PATH, among other variables. Customers can prepend
960+
// or append to the $PATH, so allowing expand is required!
961+
envs[k]=os.ExpandEnv(v)
962+
}
963+
964+
// Agent-level environment variables should take over all. This is
965+
// used for setting agent-specific variables like CODER_AGENT_TOKEN
966+
// and GIT_ASKPASS.
967+
fork,v:=rangea.environmentVariables {
968+
envs[k]=v
969+
}
970+
971+
// Prepend the agent script bin directory to the PATH
972+
// (this is where Coder modules place their binaries).
973+
if_,ok:=envs["PATH"];!ok {
974+
envs["PATH"]=os.Getenv("PATH")
975+
}
976+
envs["PATH"]=fmt.Sprintf("%s%c%s",a.scriptRunner.ScriptBinDir(),filepath.ListSeparator,envs["PATH"])
977+
978+
fork,v:=rangeenvs {
979+
updated=append(updated,fmt.Sprintf("%s=%s",k,v))
980+
}
981+
returnupdated,nil
982+
}
983+
882984
func (a*agent)wireguardAddresses(agentID uuid.UUID) []netip.Prefix {
883985
iflen(a.addresses)==0 {
884986
return []netip.Prefix{
@@ -1314,7 +1416,7 @@ func (a *agent) manageProcessPriorityLoop(ctx context.Context) {
13141416
}
13151417
}()
13161418

1317-
ifval:=a.envVars[EnvProcPrioMgmt];val==""||runtime.GOOS!="linux" {
1419+
ifval:=a.environmentVariables[EnvProcPrioMgmt];val==""||runtime.GOOS!="linux" {
13181420
a.logger.Debug(ctx,"process priority not enabled, agent will not manage process niceness/oom_score_adj ",
13191421
slog.F("env_var",EnvProcPrioMgmt),
13201422
slog.F("value",val),

‎agent/agent_test.go

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"bytes"
66
"context"
77
"encoding/json"
8+
"errors"
89
"fmt"
910
"io"
1011
"math/rand"
@@ -281,6 +282,91 @@ func TestAgent_SessionExec(t *testing.T) {
281282
require.Equal(t,"test",strings.TrimSpace(string(output)))
282283
}
283284

285+
//nolint:tparallel // Sub tests need to run sequentially.
286+
funcTestAgent_Session_EnvironmentVariables(t*testing.T) {
287+
t.Parallel()
288+
289+
tmpdir:=t.TempDir()
290+
291+
// Defined by the coder script runner, hardcoded here since we don't
292+
// have a reference to it.
293+
scriptBinDir:=filepath.Join(tmpdir,"coder-script-data","bin")
294+
295+
manifest:= agentsdk.Manifest{
296+
EnvironmentVariables:map[string]string{
297+
"MY_MANIFEST":"true",
298+
"MY_OVERRIDE":"false",
299+
"MY_SESSION_MANIFEST":"false",
300+
},
301+
}
302+
banner:= codersdk.ServiceBannerConfig{}
303+
session:=setupSSHSession(t,manifest,banner,nil,func(_*agenttest.Client,opts*agent.Options) {
304+
opts.ScriptDataDir=tmpdir
305+
opts.EnvironmentVariables["MY_OVERRIDE"]="true"
306+
})
307+
308+
err:=session.Setenv("MY_SESSION_MANIFEST","true")
309+
require.NoError(t,err)
310+
err=session.Setenv("MY_SESSION","true")
311+
require.NoError(t,err)
312+
313+
command:="sh"
314+
echoEnv:=func(t*testing.T,w io.Writer,envstring) {
315+
ifruntime.GOOS=="windows" {
316+
_,err:=fmt.Fprintf(w,"echo %%%s%%\r\n",env)
317+
require.NoError(t,err)
318+
}else {
319+
_,err:=fmt.Fprintf(w,"echo $%s\n",env)
320+
require.NoError(t,err)
321+
}
322+
}
323+
ifruntime.GOOS=="windows" {
324+
command="cmd.exe"
325+
}
326+
stdin,err:=session.StdinPipe()
327+
require.NoError(t,err)
328+
deferstdin.Close()
329+
stdout,err:=session.StdoutPipe()
330+
require.NoError(t,err)
331+
332+
err=session.Start(command)
333+
require.NoError(t,err)
334+
335+
// Context is fine here since we're not doing a parallel subtest.
336+
ctx:=testutil.Context(t,testutil.WaitLong)
337+
gofunc() {
338+
<-ctx.Done()
339+
_=session.Close()
340+
}()
341+
342+
s:=bufio.NewScanner(stdout)
343+
344+
//nolint:paralleltest // These tests need to run sequentially.
345+
fork,partialV:=rangemap[string]string{
346+
"CODER":"true",// From the agent.
347+
"MY_MANIFEST":"true",// From the manifest.
348+
"MY_OVERRIDE":"true",// From the agent environment variables option, overrides manifest.
349+
"MY_SESSION_MANIFEST":"false",// From the manifest, overrides session env.
350+
"MY_SESSION":"true",// From the session.
351+
"PATH":scriptBinDir+string(filepath.ListSeparator),
352+
} {
353+
t.Run(k,func(t*testing.T) {
354+
echoEnv(t,stdin,k)
355+
// Windows is unreliable, so keep scanning until we find a match.
356+
fors.Scan() {
357+
got:=strings.TrimSpace(s.Text())
358+
t.Logf("%s=%s",k,got)
359+
ifstrings.Contains(got,partialV) {
360+
break
361+
}
362+
}
363+
iferr:=s.Err();!errors.Is(err,io.EOF) {
364+
require.NoError(t,err)
365+
}
366+
})
367+
}
368+
}
369+
284370
funcTestAgent_GitSSH(t*testing.T) {
285371
t.Parallel()
286372
session:=setupSSHSession(t, agentsdk.Manifest{}, codersdk.ServiceBannerConfig{},nil)
@@ -1991,15 +2077,17 @@ func setupSSHSession(
19912077
manifest agentsdk.Manifest,
19922078
serviceBanner codersdk.ServiceBannerConfig,
19932079
prepareFSfunc(fs afero.Fs),
2080+
opts...func(*agenttest.Client,*agent.Options),
19942081
)*ssh.Session {
19952082
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
19962083
defercancel()
1997-
//nolint:dogsled
1998-
conn,_,_,fs,_:=setupAgent(t,manifest,0,func(c*agenttest.Client,_*agent.Options) {
2084+
opts=append(opts,func(c*agenttest.Client,o*agent.Options) {
19992085
c.SetServiceBannerFunc(func() (codersdk.ServiceBannerConfig,error) {
20002086
returnserviceBanner,nil
20012087
})
20022088
})
2089+
//nolint:dogsled
2090+
conn,_,_,fs,_:=setupAgent(t,manifest,0,opts...)
20032091
ifprepareFS!=nil {
20042092
prepareFS(fs)
20052093
}
@@ -2057,6 +2145,7 @@ func setupAgent(t *testing.T, metadata agentsdk.Manifest, ptyTimeout time.Durati
20572145
Filesystem:fs,
20582146
Logger:logger.Named("agent"),
20592147
ReconnectingPTYTimeout:ptyTimeout,
2148+
EnvironmentVariables:map[string]string{},
20602149
}
20612150

20622151
for_,opt:=rangeopts {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp