mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
feat(agent): add devcontainer autostart support (#17076)
This change adds support for devcontainer autostart in workspaces. The preconditions for utilizing this feature are: 1. The `coder_devcontainer` resource must be defined in Terraform 2. By the time the startup scripts have completed, - The `@devcontainers/cli` tool must be installed - The given workspace folder must contain a devcontainer configuration Example Terraform: ```tf resource "coder_devcontainer" "coder" { agent_id = coder_agent.main.id workspace_folder = "/home/coder/coder" config_path = ".devcontainer/devcontainer.json" # (optional) } ``` Closes #16423
This commit is contained in:
committed by
GitHub
parent
2ba3d77c74
commit
7d4b3c8634
@ -2081,6 +2081,55 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
|
||||
scriptRunOnStop = append(scriptRunOnStop, script.RunOnStop)
|
||||
}
|
||||
|
||||
// Dev Containers require a script and log/source, so we do this before
|
||||
// the logs insert below.
|
||||
if devcontainers := prAgent.GetDevcontainers(); len(devcontainers) > 0 {
|
||||
var (
|
||||
devcontainerIDs = make([]uuid.UUID, 0, len(devcontainers))
|
||||
devcontainerNames = make([]string, 0, len(devcontainers))
|
||||
devcontainerWorkspaceFolders = make([]string, 0, len(devcontainers))
|
||||
devcontainerConfigPaths = make([]string, 0, len(devcontainers))
|
||||
)
|
||||
for _, dc := range devcontainers {
|
||||
id := uuid.New()
|
||||
devcontainerIDs = append(devcontainerIDs, id)
|
||||
devcontainerNames = append(devcontainerNames, dc.Name)
|
||||
devcontainerWorkspaceFolders = append(devcontainerWorkspaceFolders, dc.WorkspaceFolder)
|
||||
devcontainerConfigPaths = append(devcontainerConfigPaths, dc.ConfigPath)
|
||||
|
||||
// Add a log source and script for each devcontainer so we can
|
||||
// track logs and timings for each devcontainer.
|
||||
displayName := fmt.Sprintf("Dev Container (%s)", dc.Name)
|
||||
logSourceIDs = append(logSourceIDs, uuid.New())
|
||||
logSourceDisplayNames = append(logSourceDisplayNames, displayName)
|
||||
logSourceIcons = append(logSourceIcons, "/emojis/1f4e6.png") // Emoji package. Or perhaps /icon/container.svg?
|
||||
scriptIDs = append(scriptIDs, id) // Re-use the devcontainer ID as the script ID for identification.
|
||||
scriptDisplayName = append(scriptDisplayName, displayName)
|
||||
scriptLogPaths = append(scriptLogPaths, "")
|
||||
scriptSources = append(scriptSources, `echo "WARNING: Dev Containers are early access. If you're seeing this message then Dev Containers haven't been enabled for your workspace yet. To enable, the agent needs to run with the environment variable CODER_AGENT_DEVCONTAINERS_ENABLE=true set."`)
|
||||
scriptCron = append(scriptCron, "")
|
||||
scriptTimeout = append(scriptTimeout, 0)
|
||||
scriptStartBlocksLogin = append(scriptStartBlocksLogin, false)
|
||||
// Run on start to surface the warning message in case the
|
||||
// terraform resource is used, but the experiment hasn't
|
||||
// been enabled.
|
||||
scriptRunOnStart = append(scriptRunOnStart, true)
|
||||
scriptRunOnStop = append(scriptRunOnStop, false)
|
||||
}
|
||||
|
||||
_, err = db.InsertWorkspaceAgentDevcontainers(ctx, database.InsertWorkspaceAgentDevcontainersParams{
|
||||
WorkspaceAgentID: agentID,
|
||||
CreatedAt: dbtime.Now(),
|
||||
ID: devcontainerIDs,
|
||||
Name: devcontainerNames,
|
||||
WorkspaceFolder: devcontainerWorkspaceFolders,
|
||||
ConfigPath: devcontainerConfigPaths,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert agent devcontainer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = db.InsertWorkspaceAgentLogSources(ctx, database.InsertWorkspaceAgentLogSourcesParams{
|
||||
WorkspaceAgentID: agentID,
|
||||
ID: logSourceIDs,
|
||||
@ -2110,33 +2159,6 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
|
||||
return xerrors.Errorf("insert agent scripts: %w", err)
|
||||
}
|
||||
|
||||
if devcontainers := prAgent.GetDevcontainers(); len(devcontainers) > 0 {
|
||||
var (
|
||||
devcontainerIDs = make([]uuid.UUID, 0, len(devcontainers))
|
||||
devcontainerNames = make([]string, 0, len(devcontainers))
|
||||
devcontainerWorkspaceFolders = make([]string, 0, len(devcontainers))
|
||||
devcontainerConfigPaths = make([]string, 0, len(devcontainers))
|
||||
)
|
||||
for _, dc := range devcontainers {
|
||||
devcontainerIDs = append(devcontainerIDs, uuid.New())
|
||||
devcontainerNames = append(devcontainerNames, dc.Name)
|
||||
devcontainerWorkspaceFolders = append(devcontainerWorkspaceFolders, dc.WorkspaceFolder)
|
||||
devcontainerConfigPaths = append(devcontainerConfigPaths, dc.ConfigPath)
|
||||
}
|
||||
|
||||
_, err = db.InsertWorkspaceAgentDevcontainers(ctx, database.InsertWorkspaceAgentDevcontainersParams{
|
||||
WorkspaceAgentID: agentID,
|
||||
CreatedAt: dbtime.Now(),
|
||||
ID: devcontainerIDs,
|
||||
Name: devcontainerNames,
|
||||
WorkspaceFolder: devcontainerWorkspaceFolders,
|
||||
ConfigPath: devcontainerConfigPaths,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert agent devcontainer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, app := range prAgent.Apps {
|
||||
// Similar logic is duplicated in terraform/resources.go.
|
||||
slug := app.Slug
|
||||
|
Reference in New Issue
Block a user