Skip to content

Commit 9424a53

Browse files
mtojekmafredri
authored andcommitted
Run script
1 parent be86e26 commit 9424a53

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
@@ -612,14 +612,22 @@ func (a *agent) runCoordinator(ctx context.Context, network *tailnet.Conn) error
612612
}
613613

614614
func (a *agent) runStartupScript(ctx context.Context, script string) error {
615+
return a.runScript(ctx, "startup", script)
616+
}
617+
618+
func (a *agent) runShutdownScript(ctx context.Context, script string) error {
619+
return a.runScript(ctx, "shutdown", script)
620+
}
621+
622+
func (a *agent) runScript(ctx context.Context, lifecycle, script string) error {
615623
if script == "" {
616624
return nil
617625
}
618626

619-
a.logger.Info(ctx, "running startup script", slog.F("script", script))
620-
writer, err := a.filesystem.OpenFile(filepath.Join(a.logDir, "coder-startup-script.log"), os.O_CREATE|os.O_RDWR, 0o600)
627+
a.logger.Info(ctx, "running script", slog.F("lifecycle", lifecycle), slog.F("script", script))
628+
writer, err := a.filesystem.OpenFile(filepath.Join(a.logDir, fmt.Sprintf("coder-%s-script.log", lifecycle)), os.O_CREATE|os.O_RDWR, 0o600)
621629
if err != nil {
622-
return xerrors.Errorf("open startup script log file: %w", err)
630+
return xerrors.Errorf("open %s script log file: %w", lifecycle, err)
623631
}
624632
defer func() {
625633
_ = writer.Close()
@@ -798,7 +806,7 @@ func (a *agent) createCommand(ctx context.Context, rawCommand string, env []stri
798806

799807
rawMetadata := a.metadata.Load()
800808
if rawMetadata == nil {
801-
return nil, xerrors.Errorf("no metadata was provided: %w", err)
809+
return nil, xerrors.Errorf("no metadata was provided")
802810
}
803811
metadata, valid := rawMetadata.(agentsdk.Metadata)
804812
if !valid {
@@ -1197,6 +1205,22 @@ func (a *agent) Close() error {
11971205
}
11981206
close(a.closed)
11991207
a.closeCancel()
1208+
1209+
rawMetadata := a.metadata.Load()
1210+
if rawMetadata == nil {
1211+
return xerrors.Errorf("no metadata was provided")
1212+
}
1213+
metadata, valid := rawMetadata.(codersdk.WorkspaceAgentMetadata)
1214+
if !valid {
1215+
return xerrors.Errorf("metadata is the wrong type: %T", metadata)
1216+
}
1217+
1218+
ctx := context.Background()
1219+
err := a.runShutdownScript(ctx, metadata.ShutdownScript)
1220+
if err != nil {
1221+
a.logger.Error(ctx, "shutdown script failed", slog.Error(err))
1222+
}
1223+
12001224
if a.network != nil {
12011225
_ = a.network.Close()
12021226
}

agent/agent_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,59 @@ func TestAgent_Lifecycle(t *testing.T) {
786786
require.Equal(t, want, got)
787787
}
788788
})
789+
790+
t.Run("ShutdownScriptOnce", func(t *testing.T) {
791+
t.Parallel()
792+
793+
expected := "this-is-shutdown"
794+
client := &client{
795+
t: t,
796+
agentID: uuid.New(),
797+
metadata: codersdk.WorkspaceAgentMetadata{
798+
DERPMap: tailnettest.RunDERPAndSTUN(t),
799+
StartupScript: "echo 1",
800+
ShutdownScript: "echo " + expected,
801+
},
802+
statsChan: make(chan *codersdk.AgentStats),
803+
coordinator: tailnet.NewCoordinator(),
804+
}
805+
806+
fs := afero.NewMemMapFs()
807+
agent := agent.New(agent.Options{
808+
Client: client,
809+
Logger: slogtest.Make(t, nil).Leveled(slog.LevelInfo),
810+
Filesystem: fs,
811+
})
812+
813+
// agent.Close() loads the shutdown script from the agent metadata.
814+
// The metadata is populated just before execution of the startup script, so it's mandatory to wait
815+
// until the startup starts.
816+
require.Eventually(t, func() bool {
817+
outputPath := filepath.Join(os.TempDir(), "coder-startup-script.log")
818+
content, err := afero.ReadFile(fs, outputPath)
819+
if err != nil {
820+
t.Logf("read file %q: %s", outputPath, err)
821+
return false
822+
}
823+
return len(content) > 0 // something is in the startup log file
824+
}, testutil.WaitShort, testutil.IntervalMedium)
825+
826+
err := agent.Close()
827+
require.NoError(t, err, "agent should be closed successfully")
828+
829+
outputPath := filepath.Join(os.TempDir(), "coder-shutdown-script.log")
830+
logFirstRead, err := afero.ReadFile(fs, outputPath)
831+
require.NoError(t, err, "log file should be present")
832+
require.Equal(t, expected, string(bytes.TrimSpace(logFirstRead)))
833+
834+
// Make sure that script can't be executed twice.
835+
err = agent.Close()
836+
require.NoError(t, err, "don't need to close the agent twice, no effect")
837+
838+
logSecondRead, err := afero.ReadFile(fs, outputPath)
839+
require.NoError(t, err, "log file should be present")
840+
require.Equal(t, string(bytes.TrimSpace(logFirstRead)), string(bytes.TrimSpace(logSecondRead)))
841+
})
789842
}
790843

791844
func TestAgent_Startup(t *testing.T) {

docs/templates.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,8 @@ practices:
399399
URL](./admin/configure.md#access-url)
400400
- Manually connect to the resource and check the agent logs (e.g., `kubectl exec`, `docker exec` or AWS console)
401401
- The Coder agent logs are typically stored in `/tmp/coder-agent.log`
402-
- The Coder agent startup script logs are typically stored in
403-
`/tmp/coder-startup-script.log`
402+
- The Coder agent startup script logs are typically stored in `/tmp/coder-startup-script.log`
403+
- The Coder agent shutdown script logs are typically stored in `/tmp/coder-shutdown-script.log`
404404

405405
### Agent does not become ready
406406

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)