mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: add support for coder_script
(#9584)
* Add basic migrations * Improve schema * Refactor agent scripts into it's own package * Support legacy start and stop script format * Pipe the scripts! * Finish the piping * Fix context usage * It works! * Fix sql query * Fix SQL query * Rename `LogSourceID` -> `SourceID` * Fix the FE * fmt * Rename migrations * Fix log tests * Fix lint err * Fix gen * Fix story type * Rename source to script * Fix schema jank * Uncomment test * Rename proto to TimeoutSeconds * Fix comments * Fix comments * Fix legacy endpoint without specified log_source * Fix non-blocking by default in agent * Fix resources tests * Fix dbfake * Fix resources * Fix linting I think * Add fixtures * fmt * Fix startup script behavior * Fix comments * Fix context * Fix cancel * Fix SQL tests * Fix e2e tests * Interrupt on Windows * Fix agent leaking script process * Fix migrations * Fix stories * Fix duplicate logs appearing * Gen * Fix log location * Fix tests * Fix tests * Fix log output * Show display name in output * Fix print * Return timeout on start context * Gen * Fix fixture * Fix the agent status * Fix startup timeout msg * Fix command using shared context * Fix timeout draining * Change signal type * Add deterministic colors to startup script logs --------- Co-authored-by: Muhammad Atif Ali <atif@coder.com>
This commit is contained in:
@ -12,6 +12,7 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"cdr.dev/slog"
|
||||
@ -77,6 +78,8 @@ func (api *API) workspaceBuild(rw http.ResponseWriter, r *http.Request) {
|
||||
data.metadata,
|
||||
data.agents,
|
||||
data.apps,
|
||||
data.scripts,
|
||||
data.logSources,
|
||||
data.templateVersions[0],
|
||||
)
|
||||
if err != nil {
|
||||
@ -191,6 +194,8 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
||||
data.metadata,
|
||||
data.agents,
|
||||
data.apps,
|
||||
data.scripts,
|
||||
data.logSources,
|
||||
data.templateVersions,
|
||||
)
|
||||
if err != nil {
|
||||
@ -279,6 +284,8 @@ func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Requ
|
||||
data.metadata,
|
||||
data.agents,
|
||||
data.apps,
|
||||
data.scripts,
|
||||
data.logSources,
|
||||
data.templateVersions[0],
|
||||
)
|
||||
if err != nil {
|
||||
@ -404,6 +411,8 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
||||
[]database.WorkspaceResourceMetadatum{},
|
||||
[]database.WorkspaceAgent{},
|
||||
[]database.WorkspaceApp{},
|
||||
[]database.WorkspaceAgentScript{},
|
||||
[]database.WorkspaceAgentLogSource{},
|
||||
database.TemplateVersion{},
|
||||
)
|
||||
if err != nil {
|
||||
@ -637,6 +646,8 @@ type workspaceBuildsData struct {
|
||||
metadata []database.WorkspaceResourceMetadatum
|
||||
agents []database.WorkspaceAgent
|
||||
apps []database.WorkspaceApp
|
||||
scripts []database.WorkspaceAgentScript
|
||||
logSources []database.WorkspaceAgentLogSource
|
||||
}
|
||||
|
||||
func (api *API) workspaceBuildsData(ctx context.Context, workspaces []database.Workspace, workspaceBuilds []database.WorkspaceBuild) (workspaceBuildsData, error) {
|
||||
@ -715,10 +726,31 @@ func (api *API) workspaceBuildsData(ctx context.Context, workspaces []database.W
|
||||
agentIDs = append(agentIDs, agent.ID)
|
||||
}
|
||||
|
||||
// nolint:gocritic // Getting workspace apps by agent IDs is a system function.
|
||||
apps, err := api.Database.GetWorkspaceAppsByAgentIDs(dbauthz.AsSystemRestricted(ctx), agentIDs)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return workspaceBuildsData{}, xerrors.Errorf("fetching workspace apps: %w", err)
|
||||
var (
|
||||
apps []database.WorkspaceApp
|
||||
scripts []database.WorkspaceAgentScript
|
||||
logSources []database.WorkspaceAgentLogSource
|
||||
)
|
||||
|
||||
var eg errgroup.Group
|
||||
eg.Go(func() (err error) {
|
||||
// nolint:gocritic // Getting workspace apps by agent IDs is a system function.
|
||||
apps, err = api.Database.GetWorkspaceAppsByAgentIDs(dbauthz.AsSystemRestricted(ctx), agentIDs)
|
||||
return err
|
||||
})
|
||||
eg.Go(func() (err error) {
|
||||
// nolint:gocritic // Getting workspace scripts by agent IDs is a system function.
|
||||
scripts, err = api.Database.GetWorkspaceAgentScriptsByAgentIDs(dbauthz.AsSystemRestricted(ctx), agentIDs)
|
||||
return err
|
||||
})
|
||||
eg.Go(func() error {
|
||||
// nolint:gocritic // Getting workspace agent log sources by agent IDs is a system function.
|
||||
logSources, err = api.Database.GetWorkspaceAgentLogSourcesByAgentIDs(dbauthz.AsSystemRestricted(ctx), agentIDs)
|
||||
return err
|
||||
})
|
||||
err = eg.Wait()
|
||||
if err != nil {
|
||||
return workspaceBuildsData{}, err
|
||||
}
|
||||
|
||||
return workspaceBuildsData{
|
||||
@ -729,6 +761,8 @@ func (api *API) workspaceBuildsData(ctx context.Context, workspaces []database.W
|
||||
metadata: metadata,
|
||||
agents: agents,
|
||||
apps: apps,
|
||||
scripts: scripts,
|
||||
logSources: logSources,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -741,6 +775,8 @@ func (api *API) convertWorkspaceBuilds(
|
||||
resourceMetadata []database.WorkspaceResourceMetadatum,
|
||||
resourceAgents []database.WorkspaceAgent,
|
||||
agentApps []database.WorkspaceApp,
|
||||
agentScripts []database.WorkspaceAgentScript,
|
||||
agentLogSources []database.WorkspaceAgentLogSource,
|
||||
templateVersions []database.TemplateVersion,
|
||||
) ([]codersdk.WorkspaceBuild, error) {
|
||||
workspaceByID := map[uuid.UUID]database.Workspace{}
|
||||
@ -781,6 +817,8 @@ func (api *API) convertWorkspaceBuilds(
|
||||
resourceMetadata,
|
||||
resourceAgents,
|
||||
agentApps,
|
||||
agentScripts,
|
||||
agentLogSources,
|
||||
templateVersion,
|
||||
)
|
||||
if err != nil {
|
||||
@ -802,6 +840,8 @@ func (api *API) convertWorkspaceBuild(
|
||||
resourceMetadata []database.WorkspaceResourceMetadatum,
|
||||
resourceAgents []database.WorkspaceAgent,
|
||||
agentApps []database.WorkspaceApp,
|
||||
agentScripts []database.WorkspaceAgentScript,
|
||||
agentLogSources []database.WorkspaceAgentLogSource,
|
||||
templateVersion database.TemplateVersion,
|
||||
) (codersdk.WorkspaceBuild, error) {
|
||||
userByID := map[uuid.UUID]database.User{}
|
||||
@ -824,6 +864,14 @@ func (api *API) convertWorkspaceBuild(
|
||||
for _, app := range agentApps {
|
||||
appsByAgentID[app.AgentID] = append(appsByAgentID[app.AgentID], app)
|
||||
}
|
||||
scriptsByAgentID := map[uuid.UUID][]database.WorkspaceAgentScript{}
|
||||
for _, script := range agentScripts {
|
||||
scriptsByAgentID[script.WorkspaceAgentID] = append(scriptsByAgentID[script.WorkspaceAgentID], script)
|
||||
}
|
||||
logSourcesByAgentID := map[uuid.UUID][]database.WorkspaceAgentLogSource{}
|
||||
for _, logSource := range agentLogSources {
|
||||
logSourcesByAgentID[logSource.WorkspaceAgentID] = append(logSourcesByAgentID[logSource.WorkspaceAgentID], logSource)
|
||||
}
|
||||
|
||||
owner, exists := userByID[workspace.OwnerID]
|
||||
if !exists {
|
||||
@ -837,8 +885,10 @@ func (api *API) convertWorkspaceBuild(
|
||||
apiAgents := make([]codersdk.WorkspaceAgent, 0)
|
||||
for _, agent := range agents {
|
||||
apps := appsByAgentID[agent.ID]
|
||||
scripts := scriptsByAgentID[agent.ID]
|
||||
logSources := logSourcesByAgentID[agent.ID]
|
||||
apiAgent, err := convertWorkspaceAgent(
|
||||
api.DERPMap(), *api.TailnetCoordinator.Load(), agent, convertApps(apps, agent, owner, workspace), api.AgentInactiveDisconnectTimeout,
|
||||
api.DERPMap(), *api.TailnetCoordinator.Load(), agent, convertApps(apps, agent, owner, workspace), convertScripts(scripts), convertLogSources(logSources), api.AgentInactiveDisconnectTimeout,
|
||||
api.DeploymentValues.AgentFallbackTroubleshootingURL.String(),
|
||||
)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user