mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08: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:
co-authored by
Muhammad Atif Ali
parent
dac1375880
commit
1262eef2c0
+57
-54
@@ -58,7 +58,7 @@ const (
|
||||
// Starting returns true if the agent is in the process of starting.
|
||||
func (l WorkspaceAgentLifecycle) Starting() bool {
|
||||
switch l {
|
||||
case WorkspaceAgentLifecycleCreated, WorkspaceAgentLifecycleStarting, WorkspaceAgentLifecycleStartTimeout:
|
||||
case WorkspaceAgentLifecycleCreated, WorkspaceAgentLifecycleStarting:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -101,6 +101,7 @@ var WorkspaceAgentLifecycleOrder = []WorkspaceAgentLifecycle{
|
||||
// ready (can be overridden).
|
||||
//
|
||||
// Presently, non-blocking is the default, but this may change in the future.
|
||||
// Deprecated: `coder_script` allows configuration on a per-script basis.
|
||||
type WorkspaceAgentStartupScriptBehavior string
|
||||
|
||||
const (
|
||||
@@ -144,42 +145,61 @@ const (
|
||||
)
|
||||
|
||||
type WorkspaceAgent struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
|
||||
FirstConnectedAt *time.Time `json:"first_connected_at,omitempty" format:"date-time"`
|
||||
LastConnectedAt *time.Time `json:"last_connected_at,omitempty" format:"date-time"`
|
||||
DisconnectedAt *time.Time `json:"disconnected_at,omitempty" format:"date-time"`
|
||||
StartedAt *time.Time `json:"started_at,omitempty" format:"date-time"`
|
||||
ReadyAt *time.Time `json:"ready_at,omitempty" format:"date-time"`
|
||||
Status WorkspaceAgentStatus `json:"status"`
|
||||
LifecycleState WorkspaceAgentLifecycle `json:"lifecycle_state"`
|
||||
Name string `json:"name"`
|
||||
ResourceID uuid.UUID `json:"resource_id" format:"uuid"`
|
||||
InstanceID string `json:"instance_id,omitempty"`
|
||||
Architecture string `json:"architecture"`
|
||||
EnvironmentVariables map[string]string `json:"environment_variables"`
|
||||
OperatingSystem string `json:"operating_system"`
|
||||
StartupScript string `json:"startup_script,omitempty"`
|
||||
StartupScriptBehavior WorkspaceAgentStartupScriptBehavior `json:"startup_script_behavior"`
|
||||
StartupScriptTimeoutSeconds int32 `json:"startup_script_timeout_seconds"` // StartupScriptTimeoutSeconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout.
|
||||
LogsLength int32 `json:"logs_length"`
|
||||
LogsOverflowed bool `json:"logs_overflowed"`
|
||||
Directory string `json:"directory,omitempty"`
|
||||
ExpandedDirectory string `json:"expanded_directory,omitempty"`
|
||||
Version string `json:"version"`
|
||||
Apps []WorkspaceApp `json:"apps"`
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
|
||||
FirstConnectedAt *time.Time `json:"first_connected_at,omitempty" format:"date-time"`
|
||||
LastConnectedAt *time.Time `json:"last_connected_at,omitempty" format:"date-time"`
|
||||
DisconnectedAt *time.Time `json:"disconnected_at,omitempty" format:"date-time"`
|
||||
StartedAt *time.Time `json:"started_at,omitempty" format:"date-time"`
|
||||
ReadyAt *time.Time `json:"ready_at,omitempty" format:"date-time"`
|
||||
Status WorkspaceAgentStatus `json:"status"`
|
||||
LifecycleState WorkspaceAgentLifecycle `json:"lifecycle_state"`
|
||||
Name string `json:"name"`
|
||||
ResourceID uuid.UUID `json:"resource_id" format:"uuid"`
|
||||
InstanceID string `json:"instance_id,omitempty"`
|
||||
Architecture string `json:"architecture"`
|
||||
EnvironmentVariables map[string]string `json:"environment_variables"`
|
||||
OperatingSystem string `json:"operating_system"`
|
||||
LogsLength int32 `json:"logs_length"`
|
||||
LogsOverflowed bool `json:"logs_overflowed"`
|
||||
Directory string `json:"directory,omitempty"`
|
||||
ExpandedDirectory string `json:"expanded_directory,omitempty"`
|
||||
Version string `json:"version"`
|
||||
Apps []WorkspaceApp `json:"apps"`
|
||||
// DERPLatency is mapped by region name (e.g. "New York City", "Seattle").
|
||||
DERPLatency map[string]DERPRegion `json:"latency,omitempty"`
|
||||
ConnectionTimeoutSeconds int32 `json:"connection_timeout_seconds"`
|
||||
TroubleshootingURL string `json:"troubleshooting_url"`
|
||||
// Deprecated: Use StartupScriptBehavior instead.
|
||||
LoginBeforeReady bool `json:"login_before_ready"`
|
||||
ShutdownScript string `json:"shutdown_script,omitempty"`
|
||||
ShutdownScriptTimeoutSeconds int32 `json:"shutdown_script_timeout_seconds"`
|
||||
Subsystems []AgentSubsystem `json:"subsystems"`
|
||||
Health WorkspaceAgentHealth `json:"health"` // Health reports the health of the agent.
|
||||
DisplayApps []DisplayApp `json:"display_apps"`
|
||||
DERPLatency map[string]DERPRegion `json:"latency,omitempty"`
|
||||
ConnectionTimeoutSeconds int32 `json:"connection_timeout_seconds"`
|
||||
TroubleshootingURL string `json:"troubleshooting_url"`
|
||||
Subsystems []AgentSubsystem `json:"subsystems"`
|
||||
Health WorkspaceAgentHealth `json:"health"` // Health reports the health of the agent.
|
||||
DisplayApps []DisplayApp `json:"display_apps"`
|
||||
LogSources []WorkspaceAgentLogSource `json:"log_sources"`
|
||||
Scripts []WorkspaceAgentScript `json:"scripts"`
|
||||
|
||||
// StartupScriptBehavior is a legacy field that is deprecated in favor
|
||||
// of the `coder_script` resource. It's only referenced by old clients.
|
||||
// Deprecated: Remove in the future!
|
||||
StartupScriptBehavior WorkspaceAgentStartupScriptBehavior `json:"startup_script_behavior"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentLogSource struct {
|
||||
WorkspaceAgentID uuid.UUID `json:"workspace_agent_id" format:"uuid"`
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Icon string `json:"icon"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentScript struct {
|
||||
LogSourceID uuid.UUID `json:"log_source_id" format:"uuid"`
|
||||
LogPath string `json:"log_path"`
|
||||
Script string `json:"script"`
|
||||
Cron string `json:"cron"`
|
||||
RunOnStart bool `json:"run_on_start"`
|
||||
RunOnStop bool `json:"run_on_stop"`
|
||||
StartBlocksLogin bool `json:"start_blocks_login"`
|
||||
Timeout time.Duration `json:"timeout"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentHealth struct {
|
||||
@@ -530,13 +550,6 @@ func (c *Client) WorkspaceAgent(ctx context.Context, id uuid.UUID) (WorkspaceAge
|
||||
if err != nil {
|
||||
return WorkspaceAgent{}, err
|
||||
}
|
||||
// Backwards compatibility for cases where the API is older then the client.
|
||||
if workspaceAgent.StartupScriptBehavior == "" {
|
||||
workspaceAgent.StartupScriptBehavior = WorkspaceAgentStartupScriptBehaviorNonBlocking
|
||||
if !workspaceAgent.LoginBeforeReady {
|
||||
workspaceAgent.StartupScriptBehavior = WorkspaceAgentStartupScriptBehaviorBlocking
|
||||
}
|
||||
}
|
||||
return workspaceAgent, nil
|
||||
}
|
||||
|
||||
@@ -762,6 +775,7 @@ type WorkspaceAgentLog struct {
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
Output string `json:"output"`
|
||||
Level LogLevel `json:"level"`
|
||||
SourceID uuid.UUID `json:"source_id" format:"uuid"`
|
||||
}
|
||||
|
||||
type AgentSubsystem string
|
||||
@@ -780,14 +794,3 @@ func (s AgentSubsystem) Valid() bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type WorkspaceAgentLogSource string
|
||||
|
||||
const (
|
||||
WorkspaceAgentLogSourceStartupScript WorkspaceAgentLogSource = "startup_script"
|
||||
WorkspaceAgentLogSourceShutdownScript WorkspaceAgentLogSource = "shutdown_script"
|
||||
WorkspaceAgentLogSourceKubernetes WorkspaceAgentLogSource = "kubernetes"
|
||||
WorkspaceAgentLogSourceEnvbox WorkspaceAgentLogSource = "envbox"
|
||||
WorkspaceAgentLogSourceEnvbuilder WorkspaceAgentLogSource = "envbuilder"
|
||||
WorkspaceAgentLogSourceExternal WorkspaceAgentLogSource = "external"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user