Skip to content

Commit 7695257

Browse files
committed
devcontainer scripts and timings
1 parent e01aac3 commit 7695257

File tree

3 files changed

+71
-46
lines changed

3 files changed

+71
-46
lines changed

agent/agent.go

+22-5
Original file line numberDiff line numberDiff line change
@@ -1115,15 +1115,32 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
11151115
}
11161116
}
11171117

1118-
// Any defined Dev Containers may be autostarted after the start
1119-
// scripts have completed.
1120-
var postStartScripts []codersdk.WorkspaceAgentScript
1118+
var (
1119+
// Clone the scripts so we can remove the devcontainer scripts.
1120+
scripts = slices.Clone(manifest.Scripts)
1121+
// The post-start scripts are used to autostart Dev Containers
1122+
// after the start scripts have completed. This is necessary
1123+
// because the Dev Container may depend on the workspace being
1124+
// initialized (git clone, etc).
1125+
postStartScripts []codersdk.WorkspaceAgentScript
1126+
)
11211127
for _, dc := range manifest.Devcontainers {
1122-
dc = expandDevcontainerPaths(a.logger, dc)
11231128
// TODO(mafredri): Verify `@devcontainers/cli` presence.
11241129
// TODO(mafredri): Verify workspace folder exists.
11251130
// TODO(mafredri): If set, verify config path exists.
1126-
postStartScripts = append(postStartScripts, agentcontainers.DevcontainerStartupScript(dc))
1131+
dc = expandDevcontainerPaths(a.logger, dc)
1132+
1133+
for i, s := range scripts {
1134+
// The devcontainer scripts match the devcontainer ID for
1135+
// identification.
1136+
if s.ID == dc.ID {
1137+
scripts = slices.Delete(scripts, i, i+1)
1138+
if a.experimentalDevcontainersEnabled {
1139+
postStartScripts = append(postStartScripts, agentcontainers.DevcontainerStartupScript(dc, s))
1140+
}
1141+
break
1142+
}
1143+
}
11271144
}
11281145

11291146
err = a.scriptRunner.Init(

agent/agentcontainers/devcontainer.go

+5-14
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,14 @@ package agentcontainers
33
import (
44
"fmt"
55

6-
"github.com/google/uuid"
7-
86
"github.com/coder/coder/v2/codersdk"
97
)
108

11-
func DevcontainerStartupScript(dc codersdk.WorkspaceAgentDevcontainer) codersdk.WorkspaceAgentScript {
12-
script := fmt.Sprintf("devcontainer up --workspace-folder %q", dc.WorkspaceFolder)
9+
func DevcontainerStartupScript(dc codersdk.WorkspaceAgentDevcontainer, script codersdk.WorkspaceAgentScript) codersdk.WorkspaceAgentScript {
10+
cmd := fmt.Sprintf("devcontainer up --workspace-folder %q", dc.WorkspaceFolder)
1311
if dc.ConfigPath != "" {
14-
script = fmt.Sprintf("%s --config %q", script, dc.ConfigPath)
15-
}
16-
return codersdk.WorkspaceAgentScript{
17-
ID: uuid.New(),
18-
LogSourceID: uuid.Nil, // TODO(mafredri): Add a devcontainer log source?
19-
LogPath: "",
20-
Script: script,
21-
Cron: "",
22-
Timeout: 0,
23-
DisplayName: fmt.Sprintf("Dev Container (%s)", dc.WorkspaceFolder),
12+
cmd = fmt.Sprintf("%s --config %q", cmd, dc.ConfigPath)
2413
}
14+
script.Script = cmd
15+
return script
2516
}

coderd/provisionerdserver/provisionerdserver.go

+44-27
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,34 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
20512051
}
20522052
}
20532053

2054+
var (
2055+
devcontainers = prAgent.GetDevcontainers()
2056+
devcontainerIDs = make([]uuid.UUID, 0, len(devcontainers))
2057+
devcontainerNames = make([]string, 0, len(devcontainers))
2058+
devcontainerWorkspaceFolders = make([]string, 0, len(devcontainers))
2059+
devcontainerConfigPaths = make([]string, 0, len(devcontainers))
2060+
)
2061+
if len(devcontainers) > 0 {
2062+
for _, dc := range devcontainers {
2063+
devcontainerIDs = append(devcontainerIDs, uuid.New())
2064+
devcontainerNames = append(devcontainerNames, dc.Name)
2065+
devcontainerWorkspaceFolders = append(devcontainerWorkspaceFolders, dc.WorkspaceFolder)
2066+
devcontainerConfigPaths = append(devcontainerConfigPaths, dc.ConfigPath)
2067+
}
2068+
2069+
_, err = db.InsertWorkspaceAgentDevcontainers(ctx, database.InsertWorkspaceAgentDevcontainersParams{
2070+
WorkspaceAgentID: agentID,
2071+
CreatedAt: dbtime.Now(),
2072+
ID: devcontainerIDs,
2073+
Name: devcontainerNames,
2074+
WorkspaceFolder: devcontainerWorkspaceFolders,
2075+
ConfigPath: devcontainerConfigPaths,
2076+
})
2077+
if err != nil {
2078+
return xerrors.Errorf("insert agent devcontainer: %w", err)
2079+
}
2080+
}
2081+
20542082
logSourceIDs := make([]uuid.UUID, 0, len(prAgent.Scripts))
20552083
logSourceDisplayNames := make([]string, 0, len(prAgent.Scripts))
20562084
logSourceIcons := make([]string, 0, len(prAgent.Scripts))
@@ -2078,6 +2106,22 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
20782106
scriptRunOnStart = append(scriptRunOnStart, script.RunOnStart)
20792107
scriptRunOnStop = append(scriptRunOnStop, script.RunOnStop)
20802108
}
2109+
// Add a log source and script for each devcontainer so we can
2110+
// track logs and timings for each.
2111+
for _, id := range devcontainerIDs {
2112+
logSourceIDs = append(logSourceIDs, uuid.New())
2113+
logSourceDisplayNames = append(logSourceDisplayNames, "Dev Container")
2114+
logSourceIcons = append(logSourceIcons, "/emojis/1f4e6.png") // Emoji package. Or perhaps /icon/container.svg?
2115+
scriptIDs = append(scriptIDs, id) // Re-use the devcontainer ID as the script ID for identification.
2116+
scriptDisplayName = append(scriptDisplayName, "Dev Container") // TODO(mafredri): Make it unique? Grab from id used in TF?
2117+
scriptLogPaths = append(scriptLogPaths, "")
2118+
scriptSources = append(scriptSources, "")
2119+
scriptCron = append(scriptCron, "")
2120+
scriptTimeout = append(scriptTimeout, 0)
2121+
scriptStartBlocksLogin = append(scriptStartBlocksLogin, false)
2122+
scriptRunOnStart = append(scriptRunOnStart, false)
2123+
scriptRunOnStop = append(scriptRunOnStop, false)
2124+
}
20812125

20822126
_, err = db.InsertWorkspaceAgentLogSources(ctx, database.InsertWorkspaceAgentLogSourcesParams{
20832127
WorkspaceAgentID: agentID,
@@ -2108,33 +2152,6 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
21082152
return xerrors.Errorf("insert agent scripts: %w", err)
21092153
}
21102154

2111-
if devcontainers := prAgent.GetDevcontainers(); len(devcontainers) > 0 {
2112-
var (
2113-
devcontainerIDs = make([]uuid.UUID, 0, len(devcontainers))
2114-
devcontainerNames = make([]string, 0, len(devcontainers))
2115-
devcontainerWorkspaceFolders = make([]string, 0, len(devcontainers))
2116-
devcontainerConfigPaths = make([]string, 0, len(devcontainers))
2117-
)
2118-
for _, dc := range devcontainers {
2119-
devcontainerIDs = append(devcontainerIDs, uuid.New())
2120-
devcontainerNames = append(devcontainerNames, dc.Name)
2121-
devcontainerWorkspaceFolders = append(devcontainerWorkspaceFolders, dc.WorkspaceFolder)
2122-
devcontainerConfigPaths = append(devcontainerConfigPaths, dc.ConfigPath)
2123-
}
2124-
2125-
_, err = db.InsertWorkspaceAgentDevcontainers(ctx, database.InsertWorkspaceAgentDevcontainersParams{
2126-
WorkspaceAgentID: agentID,
2127-
CreatedAt: dbtime.Now(),
2128-
ID: devcontainerIDs,
2129-
Name: devcontainerNames,
2130-
WorkspaceFolder: devcontainerWorkspaceFolders,
2131-
ConfigPath: devcontainerConfigPaths,
2132-
})
2133-
if err != nil {
2134-
return xerrors.Errorf("insert agent devcontainer: %w", err)
2135-
}
2136-
}
2137-
21382155
for _, app := range prAgent.Apps {
21392156
// Similar logic is duplicated in terraform/resources.go.
21402157
slug := app.Slug

0 commit comments

Comments
 (0)