Skip to content

Commit 35f7917

Browse files
mtojekmafredri
authored andcommitted
Run script
1 parent d1677a9 commit 35f7917

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

604604
func (a *agent) runStartupScript(ctx context.Context, script string) error {
605+
return a.runScript(ctx, "startup", script)
606+
}
607+
608+
func (a *agent) runShutdownScript(ctx context.Context, script string) error {
609+
return a.runScript(ctx, "shutdown", script)
610+
}
611+
612+
func (a *agent) runScript(ctx context.Context, lifecycle, script string) error {
605613
if script == "" {
606614
return nil
607615
}
608616

609-
a.logger.Info(ctx, "running startup script", slog.F("script", script))
610-
writer, err := a.filesystem.OpenFile(filepath.Join(a.logDir, "coder-startup-script.log"), os.O_CREATE|os.O_RDWR, 0o600)
617+
a.logger.Info(ctx, "running script", slog.F("lifecycle", lifecycle), slog.F("script", script))
618+
writer, err := a.filesystem.OpenFile(filepath.Join(a.logDir, fmt.Sprintf("coder-%s-script.log", lifecycle)), os.O_CREATE|os.O_RDWR, 0o600)
611619
if err != nil {
612-
return xerrors.Errorf("open startup script log file: %w", err)
620+
return xerrors.Errorf("open %s script log file: %w", lifecycle, err)
613621
}
614622
defer func() {
615623
_ = writer.Close()
@@ -788,7 +796,7 @@ func (a *agent) createCommand(ctx context.Context, rawCommand string, env []stri
788796

789797
rawMetadata := a.metadata.Load()
790798
if rawMetadata == nil {
791-
return nil, xerrors.Errorf("no metadata was provided: %w", err)
799+
return nil, xerrors.Errorf("no metadata was provided")
792800
}
793801
metadata, valid := rawMetadata.(agentsdk.Metadata)
794802
if !valid {
@@ -1187,6 +1195,22 @@ func (a *agent) Close() error {
11871195
}
11881196
close(a.closed)
11891197
a.closeCancel()
1198+
1199+
rawMetadata := a.metadata.Load()
1200+
if rawMetadata == nil {
1201+
return xerrors.Errorf("no metadata was provided")
1202+
}
1203+
metadata, valid := rawMetadata.(codersdk.WorkspaceAgentMetadata)
1204+
if !valid {
1205+
return xerrors.Errorf("metadata is the wrong type: %T", metadata)
1206+
}
1207+
1208+
ctx := context.Background()
1209+
err := a.runShutdownScript(ctx, metadata.ShutdownScript)
1210+
if err != nil {
1211+
a.logger.Error(ctx, "shutdown script failed", slog.Error(err))
1212+
}
1213+
11901214
if a.network != nil {
11911215
_ = a.network.Close()
11921216
}

agent/agent_test.go

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

790843
func TestAgent_Startup(t *testing.T) {

docs/templates.md

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

402402
### Agent does not become ready
403403

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)