diff --git a/cli/cliui/agent.go b/cli/cliui/agent.go index 0a4e53c591948..77feb69c62628 100644 --- a/cli/cliui/agent.go +++ b/cli/cliui/agent.go @@ -206,7 +206,13 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO case codersdk.WorkspaceAgentLifecycleReady: sw.Complete(stage, safeDuration(sw, agent.ReadyAt, agent.StartedAt)) case codersdk.WorkspaceAgentLifecycleStartTimeout: - sw.Fail(stage, 0) + // Backwards compatibility: Avoid printing warning if + // coderd is old and doesn't set ReadyAt for timeouts. + if agent.ReadyAt == nil { + sw.Fail(stage, 0) + } else { + sw.Fail(stage, safeDuration(sw, agent.ReadyAt, agent.StartedAt)) + } sw.Log(time.Time{}, codersdk.LogLevelWarn, "Warning: A startup script timed out and your workspace may be incomplete.") case codersdk.WorkspaceAgentLifecycleStartError: sw.Fail(stage, safeDuration(sw, agent.ReadyAt, agent.StartedAt)) diff --git a/cli/cliui/agent_test.go b/cli/cliui/agent_test.go index 8cfa481e838e3..7267a654f664f 100644 --- a/cli/cliui/agent_test.go +++ b/cli/cliui/agent_test.go @@ -95,6 +95,8 @@ func TestAgent(t *testing.T) { iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error { agent.Status = codersdk.WorkspaceAgentConnecting + agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStarting + agent.StartedAt = ptr.Ref(time.Now()) return nil }, func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error { @@ -104,6 +106,7 @@ func TestAgent(t *testing.T) { agent.Status = codersdk.WorkspaceAgentConnected agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStartTimeout agent.FirstConnectedAt = ptr.Ref(time.Now()) + agent.ReadyAt = ptr.Ref(time.Now()) return nil }, }, diff --git a/coderd/agentapi/lifecycle.go b/coderd/agentapi/lifecycle.go index de9d4bd10501d..e5211e804a7c4 100644 --- a/coderd/agentapi/lifecycle.go +++ b/coderd/agentapi/lifecycle.go @@ -98,7 +98,9 @@ func (a *LifecycleAPI) UpdateLifecycle(ctx context.Context, req *agentproto.Upda // This agent is (re)starting, so it's not ready yet. readyAt.Time = time.Time{} readyAt.Valid = false - case database.WorkspaceAgentLifecycleStateReady, database.WorkspaceAgentLifecycleStateStartError: + case database.WorkspaceAgentLifecycleStateReady, + database.WorkspaceAgentLifecycleStateStartTimeout, + database.WorkspaceAgentLifecycleStateStartError: if !startedAt.Valid { startedAt = dbChangedAt } diff --git a/coderd/agentapi/lifecycle_test.go b/coderd/agentapi/lifecycle_test.go index 3a88ee5cb3726..fe1469db0aa99 100644 --- a/coderd/agentapi/lifecycle_test.go +++ b/coderd/agentapi/lifecycle_test.go @@ -275,7 +275,7 @@ func TestUpdateLifecycle(t *testing.T) { if state == agentproto.Lifecycle_STARTING { expectedStartedAt = sql.NullTime{Valid: true, Time: stateNow} } - if state == agentproto.Lifecycle_READY || state == agentproto.Lifecycle_START_ERROR { + if state == agentproto.Lifecycle_READY || state == agentproto.Lifecycle_START_TIMEOUT || state == agentproto.Lifecycle_START_ERROR { expectedReadyAt = sql.NullTime{Valid: true, Time: stateNow} }