Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3ee962f

Browse files
mtojekmafredri
authored andcommitted
Run script
1 parent 4a0888c commit 3ee962f

File tree

4 files changed

+88
-10
lines changed

4 files changed

+88
-10
lines changed

agent/agent.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,14 +606,22 @@ func (a *agent) runCoordinator(ctx context.Context, network *tailnet.Conn) error
606606
}
607607

608608
func (a *agent) runStartupScript(ctx context.Context, script string) error {
609+
return a.runScript(ctx, "startup", script)
610+
}
611+
612+
func (a *agent) runShutdownScript(ctx context.Context, script string) error {
613+
return a.runScript(ctx, "shutdown", script)
614+
}
615+
616+
func (a *agent) runScript(ctx context.Context, lifecycle, script string) error {
609617
if script == "" {
610618
return nil
611619
}
612620

613-
a.logger.Info(ctx, "running startup script", slog.F("script", script))
614-
writer, err := a.filesystem.OpenFile(filepath.Join(a.logDir, "coder-startup-script.log"), os.O_CREATE|os.O_RDWR, 0o600)
621+
a.logger.Info(ctx, "running script", slog.F("lifecycle", lifecycle), slog.F("script", script))
622+
writer, err := a.filesystem.OpenFile(filepath.Join(a.logDir, fmt.Sprintf("coder-%s-script.log", lifecycle)), os.O_CREATE|os.O_RDWR, 0o600)
615623
if err != nil {
616-
return xerrors.Errorf("open startup script log file: %w", err)
624+
return xerrors.Errorf("open %s script log file: %w", lifecycle, err)
617625
}
618626
defer func() {
619627
_ = writer.Close()
@@ -774,7 +782,7 @@ func (a *agent) createCommand(ctx context.Context, rawCommand string, env []stri
774782

775783
rawMetadata := a.metadata.Load()
776784
if rawMetadata == nil {
777-
return nil, xerrors.Errorf("no metadata was provided: %w", err)
785+
return nil, xerrors.Errorf("no metadata was provided")
778786
}
779787
metadata, valid := rawMetadata.(agentsdk.Metadata)
780788
if !valid {
@@ -1292,6 +1300,22 @@ func (a *agent) Close() error {
12921300
}
12931301
close(a.closed)
12941302
a.closeCancel()
1303+
1304+
rawMetadata := a.metadata.Load()
1305+
if rawMetadata == nil {
1306+
return xerrors.Errorf("no metadata was provided")
1307+
}
1308+
metadata, valid := rawMetadata.(codersdk.WorkspaceAgentMetadata)
1309+
if !valid {
1310+
return xerrors.Errorf("metadata is the wrong type: %T", metadata)
1311+
}
1312+
1313+
ctx := context.Background()
1314+
err := a.runShutdownScript(ctx, metadata.ShutdownScript)
1315+
if err != nil {
1316+
a.logger.Error(ctx, "shutdown script failed", slog.Error(err))
1317+
}
1318+
12951319
if a.network != nil {
12961320
_ = a.network.Close()
12971321
}

agent/agent_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,59 @@ func TestAgent_Lifecycle(t *testing.T) {
826826
require.Equal(t, want, got)
827827
}
828828
})
829+
830+
t.Run("ShutdownScriptOnce", func(t *testing.T) {
831+
t.Parallel()
832+
833+
expected := "this-is-shutdown"
834+
client := &client{
835+
t: t,
836+
agentID: uuid.New(),
837+
metadata: codersdk.WorkspaceAgentMetadata{
838+
DERPMap: tailnettest.RunDERPAndSTUN(t),
839+
StartupScript: "echo 1",
840+
ShutdownScript: "echo " + expected,
841+
},
842+
statsChan: make(chan *codersdk.AgentStats),
843+
coordinator: tailnet.NewCoordinator(),
844+
}
845+
846+
fs := afero.NewMemMapFs()
847+
agent := agent.New(agent.Options{
848+
Client: client,
849+
Logger: slogtest.Make(t, nil).Leveled(slog.LevelInfo),
850+
Filesystem: fs,
851+
})
852+
853+
// agent.Close() loads the shutdown script from the agent metadata.
854+
// The metadata is populated just before execution of the startup script, so it's mandatory to wait
855+
// until the startup starts.
856+
require.Eventually(t, func() bool {
857+
outputPath := filepath.Join(os.TempDir(), "coder-startup-script.log")
858+
content, err := afero.ReadFile(fs, outputPath)
859+
if err != nil {
860+
t.Logf("read file %q: %s", outputPath, err)
861+
return false
862+
}
863+
return len(content) > 0 // something is in the startup log file
864+
}, testutil.WaitShort, testutil.IntervalMedium)
865+
866+
err := agent.Close()
867+
require.NoError(t, err, "agent should be closed successfully")
868+
869+
outputPath := filepath.Join(os.TempDir(), "coder-shutdown-script.log")
870+
logFirstRead, err := afero.ReadFile(fs, outputPath)
871+
require.NoError(t, err, "log file should be present")
872+
require.Equal(t, expected, string(bytes.TrimSpace(logFirstRead)))
873+
874+
// Make sure that script can't be executed twice.
875+
err = agent.Close()
876+
require.NoError(t, err, "don't need to close the agent twice, no effect")
877+
878+
logSecondRead, err := afero.ReadFile(fs, outputPath)
879+
require.NoError(t, err, "log file should be present")
880+
require.Equal(t, string(bytes.TrimSpace(logFirstRead)), string(bytes.TrimSpace(logSecondRead)))
881+
})
829882
}
830883

831884
func TestAgent_Startup(t *testing.T) {

docs/templates.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,8 @@ practices:
444444
URL](./admin/configure.md#access-url)
445445
- Manually connect to the resource and check the agent logs (e.g., `kubectl exec`, `docker exec` or AWS console)
446446
- The Coder agent logs are typically stored in `/tmp/coder-agent.log`
447-
- The Coder agent startup script logs are typically stored in
448-
`/tmp/coder-startup-script.log`
447+
- The Coder agent startup script logs are typically stored in `/tmp/coder-startup-script.log`
448+
- The Coder agent shutdown script logs are typically stored in `/tmp/coder-shutdown-script.log`
449449
- This can also happen if the websockets are not being forwarded correctly when running Coder behind a reverse proxy. [Read our reverse-proxy docs](https://coder.com/docs/v2/latest/admin/configure#tls--reverse-proxy)
450450

451451
### Agent does not become ready

docs/workspaces.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ coder update <your workspace name> --always-prompt
8484

8585
Coder stores macOS and Linux logs at the following locations:
8686

87-
| Service | Location |
88-
| ---------------- | ------------------------------- |
89-
| `startup_script` | `/tmp/coder-startup-script.log` |
90-
| Agent | `/tmp/coder-agent.log` |
87+
| Service | Location |
88+
| ----------------- | -------------------------------- |
89+
| `startup_script` | `/tmp/coder-startup-script.log` |
90+
| `shutdown_script` | `/tmp/coder-shutdown-script.log` |
91+
| Agent | `/tmp/coder-agent.log` |
9192

9293
---
9394

0 commit comments

Comments
 (0)