diff --git a/cli/cliui/agent.go b/cli/cliui/agent.go index ab98070e13b75..00a6ae40606fa 100644 --- a/cli/cliui/agent.go +++ b/cli/cliui/agent.go @@ -35,12 +35,11 @@ func Agent(ctx context.Context, writer io.Writer, opts AgentOptions) error { if err != nil { return xerrors.Errorf("fetch: %w", err) } + if agent.Status == codersdk.WorkspaceAgentConnected { return nil } - if agent.Status == codersdk.WorkspaceAgentDisconnected { - opts.WarnInterval = 0 - } + spin := spinner.New(spinner.CharSets[78], 100*time.Millisecond, spinner.WithColor("fgHiGreen")) spin.Writer = writer spin.ForceOutput = true @@ -65,43 +64,70 @@ func Agent(ctx context.Context, writer io.Writer, opts AgentOptions) error { os.Exit(1) }() - ticker := time.NewTicker(opts.FetchInterval) - defer ticker.Stop() - timer := time.NewTimer(opts.WarnInterval) - defer timer.Stop() - go func() { - select { - case <-ctx.Done(): - return - case <-timer.C: - } + warningShown := false + warnAfter := time.NewTimer(opts.WarnInterval) + defer warnAfter.Stop() + showWarning := func() { + warnAfter.Stop() + resourceMutex.Lock() defer resourceMutex.Unlock() - message := "Don't panic, your workspace is booting up!" - if agent.Status == codersdk.WorkspaceAgentDisconnected { - message = "The workspace agent lost connection! Wait for it to reconnect or restart your workspace." + if warningShown { + return } + warningShown = true + + message := waitingMessage(agent) // This saves the cursor position, then defers clearing from the cursor // position to the end of the screen. _, _ = fmt.Fprintf(writer, "\033[s\r\033[2K%s\n\n", Styles.Paragraph.Render(Styles.Prompt.String()+message)) defer fmt.Fprintf(writer, "\033[u\033[J") + } + go func() { + select { + case <-ctx.Done(): + case <-warnAfter.C: + showWarning() + } }() + + fetchInterval := time.NewTicker(opts.FetchInterval) + defer fetchInterval.Stop() for { select { case <-ctx.Done(): return ctx.Err() - case <-ticker.C: + case <-fetchInterval.C: } resourceMutex.Lock() agent, err = opts.Fetch(ctx) if err != nil { - return xerrors.Errorf("fetch: %w", err) - } - if agent.Status != codersdk.WorkspaceAgentConnected { resourceMutex.Unlock() - continue + return xerrors.Errorf("fetch: %w", err) } resourceMutex.Unlock() - return nil + switch agent.Status { + case codersdk.WorkspaceAgentConnected: + return nil + case codersdk.WorkspaceAgentTimeout, codersdk.WorkspaceAgentDisconnected: + showWarning() + } + } +} + +func waitingMessage(agent codersdk.WorkspaceAgent) string { + var m string + switch agent.Status { + case codersdk.WorkspaceAgentTimeout: + m = "The workspace agent is having trouble connecting." + case codersdk.WorkspaceAgentDisconnected: + m = "The workspace agent lost connection!" + default: + // Not a failure state, no troubleshooting necessary. + return "Don't panic, your workspace is booting up!" + } + if agent.TroubleshootingURL != "" { + return fmt.Sprintf("%s See troubleshooting instructions at: %s", m, agent.TroubleshootingURL) } + return fmt.Sprintf("%s Wait for it to (re)connect or restart your workspace.", m) } diff --git a/cli/cliui/resources.go b/cli/cliui/resources.go index cbda8134d8259..1f2d8c0992ba3 100644 --- a/cli/cliui/resources.go +++ b/cli/cliui/resources.go @@ -127,6 +127,13 @@ func renderAgentStatus(agent codersdk.WorkspaceAgent) string { since := database.Now().Sub(*agent.DisconnectedAt) return Styles.Error.Render("⦾ disconnected") + " " + Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]") + case codersdk.WorkspaceAgentTimeout: + since := database.Now().Sub(agent.CreatedAt) + return fmt.Sprintf( + "%s %s", + Styles.Warn.Render("⦾ timeout"), + Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]"), + ) case codersdk.WorkspaceAgentConnected: return Styles.Keyword.Render("⦿ connected") default: diff --git a/cli/speedtest_test.go b/cli/speedtest_test.go index cf93eb0b95a6b..c7922d5f02dac 100644 --- a/cli/speedtest_test.go +++ b/cli/speedtest_test.go @@ -20,7 +20,7 @@ func TestSpeedtest(t *testing.T) { if testing.Short() { t.Skip("This test takes a minimum of 5ms per a hardcoded value in Tailscale!") } - client, workspace, agentToken := setupWorkspaceForAgent(t) + client, workspace, agentToken := setupWorkspaceForAgent(t, nil) agentClient := codersdk.New(client.URL) agentClient.SessionToken = agentToken agentCloser := agent.New(agent.Options{ diff --git a/cli/ssh_test.go b/cli/ssh_test.go index 7f81f52d8b965..c18352d1d38d9 100644 --- a/cli/ssh_test.go +++ b/cli/ssh_test.go @@ -31,8 +31,13 @@ import ( "github.com/coder/coder/testutil" ) -func setupWorkspaceForAgent(t *testing.T) (*codersdk.Client, codersdk.Workspace, string) { +func setupWorkspaceForAgent(t *testing.T, mutate func([]*proto.Agent) []*proto.Agent) (*codersdk.Client, codersdk.Workspace, string) { t.Helper() + if mutate == nil { + mutate = func(a []*proto.Agent) []*proto.Agent { + return a + } + } client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) user := coderdtest.CreateFirstUser(t, client) agentToken := uuid.NewString() @@ -45,12 +50,12 @@ func setupWorkspaceForAgent(t *testing.T) (*codersdk.Client, codersdk.Workspace, Resources: []*proto.Resource{{ Name: "dev", Type: "google_compute_instance", - Agents: []*proto.Agent{{ + Agents: mutate([]*proto.Agent{{ Id: uuid.NewString(), Auth: &proto.Agent_Token{ Token: agentToken, }, - }}, + }}), }}, }, }, @@ -69,7 +74,7 @@ func TestSSH(t *testing.T) { t.Run("ImmediateExit", func(t *testing.T) { t.Parallel() - client, workspace, agentToken := setupWorkspaceForAgent(t) + client, workspace, agentToken := setupWorkspaceForAgent(t, nil) cmd, root := clitest.New(t, "ssh", workspace.Name) clitest.SetupConfig(t, client, root) pty := ptytest.New(t) @@ -100,9 +105,38 @@ func TestSSH(t *testing.T) { pty.WriteLine("exit") <-cmdDone }) + t.Run("ShowTroubleshootingURLAfterTimeout", func(t *testing.T) { + t.Parallel() + + wantURL := "https://example.com/troubleshoot" + client, workspace, _ := setupWorkspaceForAgent(t, func(a []*proto.Agent) []*proto.Agent { + // Unfortunately, one second is the lowest + // we can go because 0 disables the feature. + a[0].ConnectionTimeoutSeconds = 1 + a[0].TroubleshootingUrl = wantURL + return a + }) + cmd, root := clitest.New(t, "ssh", workspace.Name) + clitest.SetupConfig(t, client, root) + pty := ptytest.New(t) + cmd.SetIn(pty.Input()) + cmd.SetErr(pty.Output()) + cmd.SetOut(pty.Output()) + + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + + cmdDone := tGo(t, func() { + err := cmd.ExecuteContext(ctx) + assert.ErrorIs(t, err, context.Canceled) + }) + pty.ExpectMatch(wantURL) + cancel() + <-cmdDone + }) t.Run("Stdio", func(t *testing.T) { t.Parallel() - client, workspace, agentToken := setupWorkspaceForAgent(t) + client, workspace, agentToken := setupWorkspaceForAgent(t, nil) _, _ = tGoContext(t, func(ctx context.Context) { // Run this async so the SSH command has to wait for // the build and agent to connect! @@ -171,7 +205,7 @@ func TestSSH(t *testing.T) { t.Parallel() - client, workspace, agentToken := setupWorkspaceForAgent(t) + client, workspace, agentToken := setupWorkspaceForAgent(t, nil) agentClient := codersdk.New(client.URL) agentClient.SessionToken = agentToken diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index db9719c11f4cf..e2b9f09f3c37f 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -154,6 +154,7 @@ func (q *fakeQuerier) AcquireProvisionerJob(_ context.Context, arg database.Acqu } return database.ProvisionerJob{}, sql.ErrNoRows } + func (*fakeQuerier) DeleteOldAgentStats(_ context.Context) error { // no-op return nil @@ -2362,20 +2363,22 @@ func (q *fakeQuerier) InsertWorkspaceAgent(_ context.Context, arg database.Inser defer q.mutex.Unlock() agent := database.WorkspaceAgent{ - ID: arg.ID, - CreatedAt: arg.CreatedAt, - UpdatedAt: arg.UpdatedAt, - ResourceID: arg.ResourceID, - AuthToken: arg.AuthToken, - AuthInstanceID: arg.AuthInstanceID, - EnvironmentVariables: arg.EnvironmentVariables, - Name: arg.Name, - Architecture: arg.Architecture, - OperatingSystem: arg.OperatingSystem, - Directory: arg.Directory, - StartupScript: arg.StartupScript, - InstanceMetadata: arg.InstanceMetadata, - ResourceMetadata: arg.ResourceMetadata, + ID: arg.ID, + CreatedAt: arg.CreatedAt, + UpdatedAt: arg.UpdatedAt, + ResourceID: arg.ResourceID, + AuthToken: arg.AuthToken, + AuthInstanceID: arg.AuthInstanceID, + EnvironmentVariables: arg.EnvironmentVariables, + Name: arg.Name, + Architecture: arg.Architecture, + OperatingSystem: arg.OperatingSystem, + Directory: arg.Directory, + StartupScript: arg.StartupScript, + InstanceMetadata: arg.InstanceMetadata, + ResourceMetadata: arg.ResourceMetadata, + ConnectionTimeoutSeconds: arg.ConnectionTimeoutSeconds, + TroubleshootingURL: arg.TroubleshootingURL, } q.provisionerJobAgents = append(q.provisionerJobAgents, agent) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 2267fdc108232..a32ea8af471f1 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -400,11 +400,17 @@ CREATE TABLE workspace_agents ( resource_metadata jsonb, directory character varying(4096) DEFAULT ''::character varying NOT NULL, version text DEFAULT ''::text NOT NULL, - last_connected_replica_id uuid + last_connected_replica_id uuid, + connection_timeout_seconds integer DEFAULT 0 NOT NULL, + troubleshooting_url text DEFAULT ''::text NOT NULL ); COMMENT ON COLUMN workspace_agents.version IS 'Version tracks the version of the currently running workspace agent. Workspace agents register their version upon start.'; +COMMENT ON COLUMN workspace_agents.connection_timeout_seconds IS 'Connection timeout in seconds, 0 means disabled.'; + +COMMENT ON COLUMN workspace_agents.troubleshooting_url IS 'URL for troubleshooting the agent.'; + CREATE TABLE workspace_apps ( id uuid NOT NULL, created_at timestamp with time zone NOT NULL, diff --git a/coderd/database/migrations/000072_add_agent_connection_timeout_and_troubleshooting_url.down.sql b/coderd/database/migrations/000072_add_agent_connection_timeout_and_troubleshooting_url.down.sql new file mode 100644 index 0000000000000..7486a8688d911 --- /dev/null +++ b/coderd/database/migrations/000072_add_agent_connection_timeout_and_troubleshooting_url.down.sql @@ -0,0 +1,9 @@ +BEGIN; + +ALTER TABLE workspace_agents + DROP COLUMN connection_timeout_seconds; + +ALTER TABLE workspace_agents + DROP COLUMN troubleshooting_url; + +COMMIT; diff --git a/coderd/database/migrations/000072_add_agent_connection_timeout_and_troubleshooting_url.up.sql b/coderd/database/migrations/000072_add_agent_connection_timeout_and_troubleshooting_url.up.sql new file mode 100644 index 0000000000000..3208ef8ece987 --- /dev/null +++ b/coderd/database/migrations/000072_add_agent_connection_timeout_and_troubleshooting_url.up.sql @@ -0,0 +1,13 @@ +BEGIN; + +ALTER TABLE workspace_agents + ADD COLUMN connection_timeout_seconds integer NOT NULL DEFAULT 0; + +COMMENT ON COLUMN workspace_agents.connection_timeout_seconds IS 'Connection timeout in seconds, 0 means disabled.'; + +ALTER TABLE workspace_agents + ADD COLUMN troubleshooting_url text NOT NULL DEFAULT ''; + +COMMENT ON COLUMN workspace_agents.troubleshooting_url IS 'URL for troubleshooting the agent.'; + +COMMIT; diff --git a/coderd/database/models.go b/coderd/database/models.go index bdebbf1a849cb..b3da222afa827 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -662,6 +662,10 @@ type WorkspaceAgent struct { // Version tracks the version of the currently running workspace agent. Workspace agents register their version upon start. Version string `db:"version" json:"version"` LastConnectedReplicaID uuid.NullUUID `db:"last_connected_replica_id" json:"last_connected_replica_id"` + // Connection timeout in seconds, 0 means disabled. + ConnectionTimeoutSeconds int32 `db:"connection_timeout_seconds" json:"connection_timeout_seconds"` + // URL for troubleshooting the agent. + TroubleshootingURL string `db:"troubleshooting_url" json:"troubleshooting_url"` } type WorkspaceApp struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 473634da9515f..7c1bf4bfcd34d 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -4520,7 +4520,7 @@ func (q *sqlQuerier) UpdateUserStatus(ctx context.Context, arg UpdateUserStatusP const getWorkspaceAgentByAuthToken = `-- name: GetWorkspaceAgentByAuthToken :one SELECT - id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id + id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url FROM workspace_agents WHERE @@ -4552,13 +4552,15 @@ func (q *sqlQuerier) GetWorkspaceAgentByAuthToken(ctx context.Context, authToken &i.Directory, &i.Version, &i.LastConnectedReplicaID, + &i.ConnectionTimeoutSeconds, + &i.TroubleshootingURL, ) return i, err } const getWorkspaceAgentByID = `-- name: GetWorkspaceAgentByID :one SELECT - id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id + id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url FROM workspace_agents WHERE @@ -4588,13 +4590,15 @@ func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (W &i.Directory, &i.Version, &i.LastConnectedReplicaID, + &i.ConnectionTimeoutSeconds, + &i.TroubleshootingURL, ) return i, err } const getWorkspaceAgentByInstanceID = `-- name: GetWorkspaceAgentByInstanceID :one SELECT - id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id + id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url FROM workspace_agents WHERE @@ -4626,13 +4630,15 @@ func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInst &i.Directory, &i.Version, &i.LastConnectedReplicaID, + &i.ConnectionTimeoutSeconds, + &i.TroubleshootingURL, ) return i, err } const getWorkspaceAgentsByResourceIDs = `-- name: GetWorkspaceAgentsByResourceIDs :many SELECT - id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id + id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url FROM workspace_agents WHERE @@ -4668,6 +4674,8 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids [] &i.Directory, &i.Version, &i.LastConnectedReplicaID, + &i.ConnectionTimeoutSeconds, + &i.TroubleshootingURL, ); err != nil { return nil, err } @@ -4683,7 +4691,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids [] } const getWorkspaceAgentsCreatedAfter = `-- name: GetWorkspaceAgentsCreatedAfter :many -SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id FROM workspace_agents WHERE created_at > $1 +SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url FROM workspace_agents WHERE created_at > $1 ` func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) { @@ -4715,6 +4723,8 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created &i.Directory, &i.Version, &i.LastConnectedReplicaID, + &i.ConnectionTimeoutSeconds, + &i.TroubleshootingURL, ); err != nil { return nil, err } @@ -4745,27 +4755,31 @@ INSERT INTO startup_script, directory, instance_metadata, - resource_metadata + resource_metadata, + connection_timeout_seconds, + troubleshooting_url ) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url ` type InsertWorkspaceAgentParams struct { - ID uuid.UUID `db:"id" json:"id"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - UpdatedAt time.Time `db:"updated_at" json:"updated_at"` - Name string `db:"name" json:"name"` - ResourceID uuid.UUID `db:"resource_id" json:"resource_id"` - AuthToken uuid.UUID `db:"auth_token" json:"auth_token"` - AuthInstanceID sql.NullString `db:"auth_instance_id" json:"auth_instance_id"` - Architecture string `db:"architecture" json:"architecture"` - EnvironmentVariables pqtype.NullRawMessage `db:"environment_variables" json:"environment_variables"` - OperatingSystem string `db:"operating_system" json:"operating_system"` - StartupScript sql.NullString `db:"startup_script" json:"startup_script"` - Directory string `db:"directory" json:"directory"` - InstanceMetadata pqtype.NullRawMessage `db:"instance_metadata" json:"instance_metadata"` - ResourceMetadata pqtype.NullRawMessage `db:"resource_metadata" json:"resource_metadata"` + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + Name string `db:"name" json:"name"` + ResourceID uuid.UUID `db:"resource_id" json:"resource_id"` + AuthToken uuid.UUID `db:"auth_token" json:"auth_token"` + AuthInstanceID sql.NullString `db:"auth_instance_id" json:"auth_instance_id"` + Architecture string `db:"architecture" json:"architecture"` + EnvironmentVariables pqtype.NullRawMessage `db:"environment_variables" json:"environment_variables"` + OperatingSystem string `db:"operating_system" json:"operating_system"` + StartupScript sql.NullString `db:"startup_script" json:"startup_script"` + Directory string `db:"directory" json:"directory"` + InstanceMetadata pqtype.NullRawMessage `db:"instance_metadata" json:"instance_metadata"` + ResourceMetadata pqtype.NullRawMessage `db:"resource_metadata" json:"resource_metadata"` + ConnectionTimeoutSeconds int32 `db:"connection_timeout_seconds" json:"connection_timeout_seconds"` + TroubleshootingURL string `db:"troubleshooting_url" json:"troubleshooting_url"` } func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error) { @@ -4784,6 +4798,8 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa arg.Directory, arg.InstanceMetadata, arg.ResourceMetadata, + arg.ConnectionTimeoutSeconds, + arg.TroubleshootingURL, ) var i WorkspaceAgent err := row.Scan( @@ -4806,6 +4822,8 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa &i.Directory, &i.Version, &i.LastConnectedReplicaID, + &i.ConnectionTimeoutSeconds, + &i.TroubleshootingURL, ) return i, err } diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index 3c0beb01b8892..cdcf34f28eb96 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -53,10 +53,12 @@ INSERT INTO startup_script, directory, instance_metadata, - resource_metadata + resource_metadata, + connection_timeout_seconds, + troubleshooting_url ) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) RETURNING *; + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING *; -- name: UpdateWorkspaceAgentConnectionByID :exec UPDATE diff --git a/coderd/database/sqlc.yaml b/coderd/database/sqlc.yaml index 3a6d6e55b6853..f1dfc58e58897 100644 --- a/coderd/database/sqlc.yaml +++ b/coderd/database/sqlc.yaml @@ -47,3 +47,4 @@ rename: jwt: JWT user_acl: UserACL group_acl: GroupACL + troubleshooting_url: TroubleshootingURL diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index 7e23382d950a6..ab47fc42f6047 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -678,7 +678,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. } snapshot.WorkspaceResources = append(snapshot.WorkspaceResources, telemetry.ConvertWorkspaceResource(resource)) - var appSlugs = make(map[string]struct{}) + appSlugs := make(map[string]struct{}) for _, prAgent := range protoResource.Agents { var instanceID sql.NullString if prAgent.GetInstanceId() != "" { @@ -723,6 +723,8 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. String: prAgent.StartupScript, Valid: prAgent.StartupScript != "", }, + ConnectionTimeoutSeconds: prAgent.GetConnectionTimeoutSeconds(), + TroubleshootingURL: prAgent.GetTroubleshootingUrl(), }) if err != nil { return xerrors.Errorf("insert agent: %w", err) diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 5b1ea4b48a0d4..f8d10d6ff33b8 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -669,19 +669,21 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin } } workspaceAgent := codersdk.WorkspaceAgent{ - ID: dbAgent.ID, - CreatedAt: dbAgent.CreatedAt, - UpdatedAt: dbAgent.UpdatedAt, - ResourceID: dbAgent.ResourceID, - InstanceID: dbAgent.AuthInstanceID.String, - Name: dbAgent.Name, - Architecture: dbAgent.Architecture, - OperatingSystem: dbAgent.OperatingSystem, - StartupScript: dbAgent.StartupScript.String, - Version: dbAgent.Version, - EnvironmentVariables: envs, - Directory: dbAgent.Directory, - Apps: apps, + ID: dbAgent.ID, + CreatedAt: dbAgent.CreatedAt, + UpdatedAt: dbAgent.UpdatedAt, + ResourceID: dbAgent.ResourceID, + InstanceID: dbAgent.AuthInstanceID.String, + Name: dbAgent.Name, + Architecture: dbAgent.Architecture, + OperatingSystem: dbAgent.OperatingSystem, + StartupScript: dbAgent.StartupScript.String, + Version: dbAgent.Version, + EnvironmentVariables: envs, + Directory: dbAgent.Directory, + Apps: apps, + ConnectionTimeoutSeconds: dbAgent.ConnectionTimeoutSeconds, + TroubleshootingURL: dbAgent.TroubleshootingURL, } node := coordinator.Node(dbAgent.ID) if node != nil { @@ -718,11 +720,20 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin if dbAgent.DisconnectedAt.Valid { workspaceAgent.DisconnectedAt = &dbAgent.DisconnectedAt.Time } + + connectionTimeout := time.Duration(dbAgent.ConnectionTimeoutSeconds) * time.Second switch { case !dbAgent.FirstConnectedAt.Valid: - // If the agent never connected, it's waiting for the compute - // to start up. - workspaceAgent.Status = codersdk.WorkspaceAgentConnecting + switch { + case connectionTimeout > 0 && database.Now().Sub(dbAgent.CreatedAt) > connectionTimeout: + // If the agent took too long to connect the first time, + // mark it as timed out. + workspaceAgent.Status = codersdk.WorkspaceAgentTimeout + default: + // If the agent never connected, it's waiting for the compute + // to start up. + workspaceAgent.Status = codersdk.WorkspaceAgentConnecting + } case dbAgent.DisconnectedAt.Time.After(dbAgent.LastConnectedAt.Time): // If we've disconnected after our last connection, we know the // agent is no longer connected. diff --git a/coderd/workspaceagents_test.go b/coderd/workspaceagents_test.go index 3e62311335fd1..d5b8bd9c59475 100644 --- a/coderd/workspaceagents_test.go +++ b/coderd/workspaceagents_test.go @@ -74,6 +74,53 @@ func TestWorkspaceAgent(t *testing.T) { _, err = client.WorkspaceAgent(ctx, workspace.LatestBuild.Resources[0].Agents[0].ID) require.NoError(t, err) }) + t.Run("Timeout", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{ + IncludeProvisionerDaemon: true, + }) + user := coderdtest.CreateFirstUser(t, client) + authToken := uuid.NewString() + tmpDir := t.TempDir() + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionDryRun: echo.ProvisionComplete, + Provision: []*proto.Provision_Response{{ + Type: &proto.Provision_Response_Complete{ + Complete: &proto.Provision_Complete{ + Resources: []*proto.Resource{{ + Name: "example", + Type: "aws_instance", + Agents: []*proto.Agent{{ + Id: uuid.NewString(), + Directory: tmpDir, + Auth: &proto.Agent_Token{ + Token: authToken, + }, + ConnectionTimeoutSeconds: 1, + TroubleshootingUrl: "https://example.com/troubleshoot", + }}, + }}, + }, + }, + }}, + }) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) + + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium) + defer cancel() + + testutil.Eventually(ctx, t, func(ctx context.Context) (done bool) { + workspace, err := client.Workspace(ctx, workspace.ID) + if !assert.NoError(t, err) { + return false + } + return workspace.LatestBuild.Resources[0].Agents[0].Status == codersdk.WorkspaceAgentTimeout + }, testutil.IntervalMedium, "agent status timeout") + }) } func TestWorkspaceAgentListen(t *testing.T) { diff --git a/codersdk/workspaceagents.go b/codersdk/workspaceagents.go index bf15820f57cd3..f7aaecca87d56 100644 --- a/codersdk/workspaceagents.go +++ b/codersdk/workspaceagents.go @@ -32,6 +32,7 @@ const ( WorkspaceAgentConnecting WorkspaceAgentStatus = "connecting" WorkspaceAgentConnected WorkspaceAgentStatus = "connected" WorkspaceAgentDisconnected WorkspaceAgentStatus = "disconnected" + WorkspaceAgentTimeout WorkspaceAgentStatus = "timeout" ) type WorkspaceAgent struct { @@ -53,7 +54,9 @@ type WorkspaceAgent struct { 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"` + DERPLatency map[string]DERPRegion `json:"latency,omitempty"` + ConnectionTimeoutSeconds int32 `json:"connection_timeout_seconds"` + TroubleshootingURL string `json:"troubleshooting_url,omitempty"` } type WorkspaceAgentResourceMetadata struct { diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index bb81bb403e22e..f1ad47e3c21b9 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -14,14 +14,16 @@ import ( // A mapping of attributes on the "coder_agent" resource. type agentAttributes struct { - Auth string `mapstructure:"auth"` - OperatingSystem string `mapstructure:"os"` - Architecture string `mapstructure:"arch"` - Directory string `mapstructure:"dir"` - ID string `mapstructure:"id"` - Token string `mapstructure:"token"` - Env map[string]string `mapstructure:"env"` - StartupScript string `mapstructure:"startup_script"` + Auth string `mapstructure:"auth"` + OperatingSystem string `mapstructure:"os"` + Architecture string `mapstructure:"arch"` + Directory string `mapstructure:"dir"` + ID string `mapstructure:"id"` + Token string `mapstructure:"token"` + Env map[string]string `mapstructure:"env"` + StartupScript string `mapstructure:"startup_script"` + ConnectionTimeoutSeconds int32 `mapstructure:"connection_timeout"` + TroubleshootingURL string `mapstructure:"troubleshooting_url"` } // A mapping of attributes on the "coder_app" resource. @@ -118,13 +120,15 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res return nil, xerrors.Errorf("decode agent attributes: %w", err) } agent := &proto.Agent{ - Name: tfResource.Name, - Id: attrs.ID, - Env: attrs.Env, - StartupScript: attrs.StartupScript, - OperatingSystem: attrs.OperatingSystem, - Architecture: attrs.Architecture, - Directory: attrs.Directory, + Name: tfResource.Name, + Id: attrs.ID, + Env: attrs.Env, + StartupScript: attrs.StartupScript, + OperatingSystem: attrs.OperatingSystem, + Architecture: attrs.Architecture, + Directory: attrs.Directory, + ConnectionTimeoutSeconds: attrs.ConnectionTimeoutSeconds, + TroubleshootingUrl: attrs.TroubleshootingURL, } switch attrs.Auth { case "token": diff --git a/provisioner/terraform/resources_test.go b/provisioner/terraform/resources_test.go index 4ca4244c675fd..15708d1203f2d 100644 --- a/provisioner/terraform/resources_test.go +++ b/provisioner/terraform/resources_test.go @@ -33,10 +33,11 @@ func TestConvertResources(t *testing.T) { Name: "b", Type: "null_resource", Agents: []*proto.Agent{{ - Name: "main", - OperatingSystem: "linux", - Architecture: "amd64", - Auth: &proto.Agent_Token{}, + Name: "main", + OperatingSystem: "linux", + Architecture: "amd64", + Auth: &proto.Agent_Token{}, + ConnectionTimeoutSeconds: 120, }}, }}, // This can happen when resources hierarchically conflict. @@ -46,10 +47,11 @@ func TestConvertResources(t *testing.T) { Name: "first", Type: "null_resource", Agents: []*proto.Agent{{ - Name: "main", - OperatingSystem: "linux", - Architecture: "amd64", - Auth: &proto.Agent_Token{}, + Name: "main", + OperatingSystem: "linux", + Architecture: "amd64", + Auth: &proto.Agent_Token{}, + ConnectionTimeoutSeconds: 120, }}, }, { Name: "second", @@ -60,10 +62,11 @@ func TestConvertResources(t *testing.T) { Name: "main", Type: "null_resource", Agents: []*proto.Agent{{ - Name: "main", - OperatingSystem: "linux", - Architecture: "amd64", - Auth: &proto.Agent_InstanceId{}, + Name: "main", + OperatingSystem: "linux", + Architecture: "amd64", + Auth: &proto.Agent_InstanceId{}, + ConnectionTimeoutSeconds: 120, }}, }}, // Ensures that calls to resources through modules work @@ -72,10 +75,11 @@ func TestConvertResources(t *testing.T) { Name: "example", Type: "null_resource", Agents: []*proto.Agent{{ - Name: "main", - OperatingSystem: "linux", - Architecture: "amd64", - Auth: &proto.Agent_Token{}, + Name: "main", + OperatingSystem: "linux", + Architecture: "amd64", + Auth: &proto.Agent_Token{}, + ConnectionTimeoutSeconds: 120, }}, }}, // Ensures the attachment of multiple agents to a single @@ -84,20 +88,24 @@ func TestConvertResources(t *testing.T) { Name: "dev", Type: "null_resource", Agents: []*proto.Agent{{ - Name: "dev1", - OperatingSystem: "linux", - Architecture: "amd64", - Auth: &proto.Agent_Token{}, + Name: "dev1", + OperatingSystem: "linux", + Architecture: "amd64", + Auth: &proto.Agent_Token{}, + ConnectionTimeoutSeconds: 120, }, { - Name: "dev2", - OperatingSystem: "darwin", - Architecture: "amd64", - Auth: &proto.Agent_Token{}, + Name: "dev2", + OperatingSystem: "darwin", + Architecture: "amd64", + Auth: &proto.Agent_Token{}, + ConnectionTimeoutSeconds: 1, }, { - Name: "dev3", - OperatingSystem: "windows", - Architecture: "arm64", - Auth: &proto.Agent_Token{}, + Name: "dev3", + OperatingSystem: "windows", + Architecture: "arm64", + Auth: &proto.Agent_Token{}, + ConnectionTimeoutSeconds: 120, + TroubleshootingUrl: "https://coder.com/troubleshoot", }}, }}, // Ensures multiple applications can be set for a single agent. @@ -131,7 +139,8 @@ func TestConvertResources(t *testing.T) { Subdomain: false, }, }, - Auth: &proto.Agent_Token{}, + Auth: &proto.Agent_Token{}, + ConnectionTimeoutSeconds: 120, }}, }}, // Tests fetching metadata about workspace resources. diff --git a/provisioner/terraform/testdata/calling-module/calling-module.tf b/provisioner/terraform/testdata/calling-module/calling-module.tf index 2d8d38bf2a5c4..c83c7dd2245b0 100644 --- a/provisioner/terraform/testdata/calling-module/calling-module.tf +++ b/provisioner/terraform/testdata/calling-module/calling-module.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.6.0" + version = "0.6.1" } } } diff --git a/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json b/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json index 1a79f2488c167..46381b0166485 100644 --- a/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json +++ b/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "planned_values": { "root_module": { "resources": [ @@ -14,10 +14,12 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} } @@ -73,10 +75,12 @@ "after": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -149,7 +153,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.6.0" + "version_constraint": "0.6.1" }, "module.module:null": { "name": "null", diff --git a/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json b/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json index adf9154876b17..6972321b7372a 100644 --- a/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json +++ b/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "values": { "root_module": { "resources": [ @@ -14,13 +14,15 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, - "id": "8a08d6a8-2ae8-4af3-b385-9d7c9230c3d3", + "id": "f7ee18b5-2baf-461b-9d82-7654c669930c", "init_script": "", "os": "linux", "startup_script": null, - "token": "e5397170-34e8-4f59-9b3d-85d11203aba1" + "token": "2b47c5a8-1511-46f5-9821-95510c83afb2", + "troubleshooting_url": null }, "sensitive_values": {} } @@ -44,7 +46,7 @@ "outputs": { "script": "" }, - "random": "4606778210381604065" + "random": "5577006791947779410" }, "sensitive_values": { "inputs": {}, @@ -59,7 +61,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "8484494817832091886", + "id": "8674665223082153551", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf index 8c4dfc2cb76ee..302a34fb17c03 100644 --- a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf +++ b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.6.0" + version = "0.6.1" } } } diff --git a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json index efc8bad808aa0..005545d0e9d61 100644 --- a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json +++ b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "planned_values": { "root_module": { "resources": [ @@ -14,10 +14,12 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -56,15 +58,19 @@ "name": "main", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -84,7 +90,9 @@ "name": "a", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -103,7 +111,9 @@ "name": "b", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -121,7 +131,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.6.0" + "version_constraint": "0.6.1" }, "null": { "name": "null", @@ -153,7 +163,9 @@ "name": "a", "provider_config_key": "null", "schema_version": 0, - "depends_on": ["null_resource.b"] + "depends_on": [ + "null_resource.b" + ] }, { "address": "null_resource.b", @@ -162,7 +174,9 @@ "name": "b", "provider_config_key": "null", "schema_version": 0, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] } ] } diff --git a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json index 2db8be2d6c4fc..51177db018be9 100644 --- a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json +++ b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "values": { "root_module": { "resources": [ @@ -14,13 +14,15 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, - "id": "8c46ed09-5988-47fe-8f1b-2afe4ec0b35a", + "id": "9f9cf95a-77ea-40bf-b9bc-055f4971923d", "init_script": "", "os": "linux", "startup_script": null, - "token": "af26634c-4fa8-4b60-aff4-736d43457b35" + "token": "0d846d9b-1fa9-4ab3-962c-f249395645a7", + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -32,11 +34,14 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "1333327345487383126", + "id": "8674665223082153551", "triggers": null }, "sensitive_values": {}, - "depends_on": ["coder_agent.main", "null_resource.b"] + "depends_on": [ + "coder_agent.main", + "null_resource.b" + ] }, { "address": "null_resource.b", @@ -46,11 +51,13 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "1306294717300675697", + "id": "5577006791947779410", "triggers": null }, "sensitive_values": {}, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] } ] } diff --git a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf index 5b8d6df78bdf4..e51020602ba31 100644 --- a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf +++ b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.6.0" + version = "0.6.1" } } } diff --git a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json index 9aaacf0134014..36668eb68b3fa 100644 --- a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json +++ b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "planned_values": { "root_module": { "resources": [ @@ -14,10 +14,12 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -56,15 +58,19 @@ "name": "main", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -84,7 +90,9 @@ "name": "first", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -103,7 +111,9 @@ "name": "second", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -121,7 +131,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.6.0" + "version_constraint": "0.6.1" }, "null": { "name": "null", @@ -153,7 +163,9 @@ "name": "first", "provider_config_key": "null", "schema_version": 0, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] }, { "address": "null_resource.second", @@ -162,7 +174,9 @@ "name": "second", "provider_config_key": "null", "schema_version": 0, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] } ] } diff --git a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json index 6e8f435ec9718..9d482ecd3d634 100644 --- a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json +++ b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "values": { "root_module": { "resources": [ @@ -14,13 +14,15 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, - "id": "3621f0c7-090a-4610-8fd0-bdcf835225bd", + "id": "aac3d245-52fa-4588-9759-694017908e7c", "init_script": "", "os": "linux", "startup_script": null, - "token": "4cb0ef71-0161-4a1a-b8f1-b9d81f53d658" + "token": "a9f32b40-d630-47f0-80a6-5727fd729fae", + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -32,11 +34,13 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "3108014752132131382", + "id": "5577006791947779410", "triggers": null }, "sensitive_values": {}, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] }, { "address": "null_resource.second", @@ -46,11 +50,13 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "8356243415524842498", + "id": "8674665223082153551", "triggers": null }, "sensitive_values": {}, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] } ] } diff --git a/provisioner/terraform/testdata/instance-id/instance-id.tf b/provisioner/terraform/testdata/instance-id/instance-id.tf index 19630450f6a9e..328ac453c490f 100644 --- a/provisioner/terraform/testdata/instance-id/instance-id.tf +++ b/provisioner/terraform/testdata/instance-id/instance-id.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.6.0" + version = "0.6.1" } } } diff --git a/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json b/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json index 3bf0652c934ef..a9f1e328d9a0d 100644 --- a/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json +++ b/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "planned_values": { "root_module": { "resources": [ @@ -14,10 +14,12 @@ "values": { "arch": "amd64", "auth": "google-instance-identity", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -56,15 +58,19 @@ "name": "main", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "amd64", "auth": "google-instance-identity", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -84,7 +90,9 @@ "name": "main", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "instance_id": "example" @@ -104,7 +112,9 @@ "name": "main", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -122,7 +132,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.6.0" + "version_constraint": "0.6.1" }, "null": { "name": "null", @@ -158,7 +168,10 @@ "provider_config_key": "coder", "expressions": { "agent_id": { - "references": ["coder_agent.main.id", "coder_agent.main"] + "references": [ + "coder_agent.main.id", + "coder_agent.main" + ] }, "instance_id": { "constant_value": "example" @@ -173,7 +186,9 @@ "name": "main", "provider_config_key": "null", "schema_version": 0, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] } ] } @@ -181,7 +196,9 @@ "relevant_attributes": [ { "resource": "coder_agent.main", - "attribute": ["id"] + "attribute": [ + "id" + ] } ] } diff --git a/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json b/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json index 091a485993c86..b771a3fc263b9 100644 --- a/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json +++ b/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "values": { "root_module": { "resources": [ @@ -14,13 +14,15 @@ "values": { "arch": "amd64", "auth": "google-instance-identity", + "connection_timeout": 120, "dir": null, "env": null, - "id": "1156666a-c202-4c54-9831-6b62dbf665fe", + "id": "327a022c-8b88-4d57-8d25-4b1dd66d817b", "init_script": "", "os": "linux", "startup_script": null, - "token": "80a893a4-fcb1-4a3a-824d-74cf5317d307" + "token": "a0082875-2172-456c-a8fe-ae45499443af", + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -32,12 +34,14 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "agent_id": "1156666a-c202-4c54-9831-6b62dbf665fe", - "id": "ec6451f5-fea2-4d6f-aedc-822b93723abd", + "agent_id": "327a022c-8b88-4d57-8d25-4b1dd66d817b", + "id": "ddb786af-b1a5-4b22-954b-387177e17f16", "instance_id": "example" }, "sensitive_values": {}, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] }, { "address": "null_resource.main", @@ -47,11 +51,13 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "5076117657273396114", + "id": "5577006791947779410", "triggers": null }, "sensitive_values": {}, - "depends_on": ["coder_agent.main"] + "depends_on": [ + "coder_agent.main" + ] } ] } diff --git a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf index 19813c586faea..48d34a3181239 100644 --- a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf +++ b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.6.0" + version = "0.6.1" } } } @@ -13,13 +13,15 @@ resource "coder_agent" "dev1" { } resource "coder_agent" "dev2" { - os = "darwin" - arch = "amd64" + os = "darwin" + arch = "amd64" + connection_timeout = 1 } resource "coder_agent" "dev3" { - os = "windows" - arch = "arm64" + os = "windows" + arch = "arm64" + troubleshooting_url = "https://coder.com/troubleshoot" } resource "null_resource" "dev" { diff --git a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json index 46d1ea7714ff6..937e59a44394e 100644 --- a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json +++ b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "planned_values": { "root_module": { "resources": [ @@ -14,10 +14,12 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -31,10 +33,12 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 1, "dir": null, "env": null, "os": "darwin", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -48,10 +52,12 @@ "values": { "arch": "arm64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "windows", - "startup_script": null + "startup_script": null, + "troubleshooting_url": "https://coder.com/troubleshoot" }, "sensitive_values": {} }, @@ -78,15 +84,19 @@ "name": "dev1", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -106,15 +116,19 @@ "name": "dev2", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "amd64", "auth": "token", + "connection_timeout": 1, "dir": null, "env": null, "os": "darwin", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -134,15 +148,19 @@ "name": "dev3", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "arm64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "windows", - "startup_script": null + "startup_script": null, + "troubleshooting_url": "https://coder.com/troubleshoot" }, "after_unknown": { "id": true, @@ -162,7 +180,9 @@ "name": "dev", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -180,7 +200,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.6.0" + "version_constraint": "0.6.1" }, "null": { "name": "null", @@ -215,6 +235,9 @@ "arch": { "constant_value": "amd64" }, + "connection_timeout": { + "constant_value": 1 + }, "os": { "constant_value": "darwin" } @@ -233,6 +256,9 @@ }, "os": { "constant_value": "windows" + }, + "troubleshooting_url": { + "constant_value": "https://coder.com/troubleshoot" } }, "schema_version": 0 diff --git a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json index 1143c69fe2c0d..55e960948ad08 100644 --- a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json +++ b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "values": { "root_module": { "resources": [ @@ -14,13 +14,15 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, - "id": "dc6b52bf-7bcb-4657-9c11-2859d8721ba9", + "id": "2777eff3-2f9f-4515-8cea-0dc7dbb53bf0", "init_script": "", "os": "linux", "startup_script": null, - "token": "85317d35-1e92-4565-850e-8ee17bf86992" + "token": "0fb4dd96-6acd-48d2-a41a-396e957cf5f6", + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -34,13 +36,15 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 1, "dir": null, "env": null, - "id": "a709bb80-b4df-4d4a-9cc3-4bedd009b44f", + "id": "48c7e389-c6a3-4cff-8331-aec26ee42cc4", "init_script": "", "os": "darwin", "startup_script": null, - "token": "a4b37df4-dbdd-494b-9434-92abaa88c23b" + "token": "0e9a30ca-59a4-4070-8517-0f7ebc5d1ab8", + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -54,13 +58,15 @@ "values": { "arch": "arm64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, - "id": "e429fb2c-1d4a-4c7c-9747-f495e5611c9e", + "id": "f4b435ff-47a5-4fd5-8529-5ca0288eec6d", "init_script": "", "os": "windows", "startup_script": null, - "token": "27009ab7-ec2e-476c-9193-177eeea0766c" + "token": "763e2baa-36d0-45d6-9511-08034fa752ca", + "troubleshooting_url": "https://coder.com/troubleshoot" }, "sensitive_values": {} }, @@ -72,7 +78,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "4682926564646626748", + "id": "5577006791947779410", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf index 3a6637ea6e922..3a713df629218 100644 --- a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf +++ b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.6.0" + version = "0.6.1" } } } diff --git a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json index 5c1e167f14813..ef24b1ccee579 100644 --- a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json +++ b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "planned_values": { "root_module": { "resources": [ @@ -14,10 +14,12 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -70,7 +72,9 @@ "url": null }, "sensitive_values": { - "healthcheck": [{}] + "healthcheck": [ + {} + ] } }, { @@ -119,15 +123,19 @@ "name": "dev1", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -147,7 +155,9 @@ "name": "app1", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "command": null, @@ -179,7 +189,9 @@ "name": "app2", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "command": null, @@ -201,12 +213,16 @@ }, "after_unknown": { "agent_id": true, - "healthcheck": [{}], + "healthcheck": [ + {} + ], "id": true }, "before_sensitive": false, "after_sensitive": { - "healthcheck": [{}] + "healthcheck": [ + {} + ] } } }, @@ -217,7 +233,9 @@ "name": "app3", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "command": null, @@ -249,7 +267,9 @@ "name": "dev", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -267,7 +287,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.6.0" + "version_constraint": "0.6.1" }, "null": { "name": "null", @@ -300,7 +320,10 @@ "provider_config_key": "coder", "expressions": { "agent_id": { - "references": ["coder_agent.dev1.id", "coder_agent.dev1"] + "references": [ + "coder_agent.dev1.id", + "coder_agent.dev1" + ] }, "slug": { "constant_value": "app1" @@ -316,7 +339,10 @@ "provider_config_key": "coder", "expressions": { "agent_id": { - "references": ["coder_agent.dev1.id", "coder_agent.dev1"] + "references": [ + "coder_agent.dev1.id", + "coder_agent.dev1" + ] }, "healthcheck": [ { @@ -348,7 +374,10 @@ "provider_config_key": "coder", "expressions": { "agent_id": { - "references": ["coder_agent.dev1.id", "coder_agent.dev1"] + "references": [ + "coder_agent.dev1.id", + "coder_agent.dev1" + ] }, "slug": { "constant_value": "app3" @@ -366,7 +395,9 @@ "name": "dev", "provider_config_key": "null", "schema_version": 0, - "depends_on": ["coder_agent.dev1"] + "depends_on": [ + "coder_agent.dev1" + ] } ] } @@ -374,7 +405,9 @@ "relevant_attributes": [ { "resource": "coder_agent.dev1", - "attribute": ["id"] + "attribute": [ + "id" + ] } ] } diff --git a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json index d419e904b366b..83b442def3129 100644 --- a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json +++ b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "values": { "root_module": { "resources": [ @@ -14,13 +14,15 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, - "id": "4fa379bd-8aa9-48f2-9868-2da104013c3c", + "id": "8cf70a43-80fa-4f84-b651-f6ff21f7fbcc", "init_script": "", "os": "linux", "startup_script": null, - "token": "4eb813cb-8f29-454c-91d9-b430d76d7fcd" + "token": "b41f44b7-f889-4ce9-9061-4f34952103d7", + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -32,12 +34,12 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "agent_id": "4fa379bd-8aa9-48f2-9868-2da104013c3c", + "agent_id": "8cf70a43-80fa-4f84-b651-f6ff21f7fbcc", "command": null, "display_name": null, "healthcheck": [], "icon": null, - "id": "f303f406-b9ea-4253-935e-f80f7be54a97", + "id": "927154ef-0b53-4b90-b6de-034581c46759", "name": null, "relative_path": null, "share": "owner", @@ -48,7 +50,9 @@ "sensitive_values": { "healthcheck": [] }, - "depends_on": ["coder_agent.dev1"] + "depends_on": [ + "coder_agent.dev1" + ] }, { "address": "coder_app.app2", @@ -58,7 +62,7 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "agent_id": "4fa379bd-8aa9-48f2-9868-2da104013c3c", + "agent_id": "8cf70a43-80fa-4f84-b651-f6ff21f7fbcc", "command": null, "display_name": null, "healthcheck": [ @@ -69,7 +73,7 @@ } ], "icon": null, - "id": "7086ae57-501d-4b39-bfaf-d30b83f753d4", + "id": "e8b2c750-ac93-4126-964f-603cb06aa12e", "name": null, "relative_path": null, "share": "owner", @@ -78,9 +82,13 @@ "url": null }, "sensitive_values": { - "healthcheck": [{}] + "healthcheck": [ + {} + ] }, - "depends_on": ["coder_agent.dev1"] + "depends_on": [ + "coder_agent.dev1" + ] }, { "address": "coder_app.app3", @@ -90,12 +98,12 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "agent_id": "4fa379bd-8aa9-48f2-9868-2da104013c3c", + "agent_id": "8cf70a43-80fa-4f84-b651-f6ff21f7fbcc", "command": null, "display_name": null, "healthcheck": [], "icon": null, - "id": "e4b1f16b-2b8d-4278-abec-1f876f8a6aba", + "id": "a1897b85-9691-4c7b-9a10-ff87c12efc89", "name": null, "relative_path": null, "share": "owner", @@ -106,7 +114,9 @@ "sensitive_values": { "healthcheck": [] }, - "depends_on": ["coder_agent.dev1"] + "depends_on": [ + "coder_agent.dev1" + ] }, { "address": "null_resource.dev", @@ -116,11 +126,13 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "7676198272426781226", + "id": "5577006791947779410", "triggers": null }, "sensitive_values": {}, - "depends_on": ["coder_agent.dev1"] + "depends_on": [ + "coder_agent.dev1" + ] } ] } diff --git a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf index 7dc8b361f7f4c..f08158652c2b9 100644 --- a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf +++ b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.6.0" + version = "0.6.1" } } } diff --git a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json index 006613db073dd..6627f89591360 100644 --- a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json +++ b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "planned_values": { "root_module": { "resources": [ @@ -14,10 +14,12 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -55,7 +57,12 @@ ] }, "sensitive_values": { - "item": [{}, {}, {}, {}] + "item": [ + {}, + {}, + {}, + {} + ] } }, { @@ -81,15 +88,19 @@ "name": "main", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, "os": "linux", - "startup_script": null + "startup_script": null, + "troubleshooting_url": null }, "after_unknown": { "id": true, @@ -109,7 +120,9 @@ "name": "about_info", "provider_name": "registry.terraform.io/coder/coder", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "hide": true, @@ -157,7 +170,12 @@ }, "before_sensitive": false, "after_sensitive": { - "item": [{}, {}, {}, {}] + "item": [ + {}, + {}, + {}, + {} + ] } } }, @@ -168,7 +186,9 @@ "name": "about", "provider_name": "registry.terraform.io/hashicorp/null", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "triggers": null @@ -186,7 +206,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.6.0" + "version_constraint": "0.6.1" }, "null": { "name": "null", @@ -259,7 +279,10 @@ } ], "resource_id": { - "references": ["null_resource.about.id", "null_resource.about"] + "references": [ + "null_resource.about.id", + "null_resource.about" + ] } }, "schema_version": 0 @@ -278,7 +301,9 @@ "relevant_attributes": [ { "resource": "null_resource.about", - "attribute": ["id"] + "attribute": [ + "id" + ] } ] } diff --git a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json index 65a381788aef5..9cf8f66d5c51d 100644 --- a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json +++ b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.8", + "terraform_version": "1.3.4", "values": { "root_module": { "resources": [ @@ -14,13 +14,15 @@ "values": { "arch": "amd64", "auth": "token", + "connection_timeout": 120, "dir": null, "env": null, - "id": "a7e62a9d-ef94-4abc-8bd5-e0555eae4aaf", + "id": "3aeed2cf-2a5a-40f7-a0d6-2c3508f601a4", "init_script": "", "os": "linux", "startup_script": null, - "token": "812935fe-858a-4ff5-b890-6c8eea6a3764" + "token": "c22c9b1f-b077-4ed3-afa6-e10fc5485399", + "troubleshooting_url": null }, "sensitive_values": {} }, @@ -34,7 +36,7 @@ "values": { "hide": true, "icon": "/icon/server.svg", - "id": "5e954683-7a6d-47f4-bc82-5831c0ea2120", + "id": "1f43c366-e7a6-49dc-ac19-894fd9fceac8", "item": [ { "is_null": false, @@ -61,12 +63,19 @@ "value": "squirrel" } ], - "resource_id": "288893601116381968" + "resource_id": "5577006791947779410" }, "sensitive_values": { - "item": [{}, {}, {}, {}] + "item": [ + {}, + {}, + {}, + {} + ] }, - "depends_on": ["null_resource.about"] + "depends_on": [ + "null_resource.about" + ] }, { "address": "null_resource.about", @@ -76,7 +85,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "288893601116381968", + "id": "5577006791947779410", "triggers": null }, "sensitive_values": {} diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 303420c157cbe..085fb1c3d5e9a 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -765,7 +765,9 @@ type Agent struct { // // *Agent_Token // *Agent_InstanceId - Auth isAgent_Auth `protobuf_oneof:"auth"` + Auth isAgent_Auth `protobuf_oneof:"auth"` + ConnectionTimeoutSeconds int32 `protobuf:"varint,11,opt,name=connection_timeout_seconds,json=connectionTimeoutSeconds,proto3" json:"connection_timeout_seconds,omitempty"` + TroubleshootingUrl string `protobuf:"bytes,12,opt,name=troubleshooting_url,json=troubleshootingUrl,proto3" json:"troubleshooting_url,omitempty"` } func (x *Agent) Reset() { @@ -877,6 +879,20 @@ func (x *Agent) GetInstanceId() string { return "" } +func (x *Agent) GetConnectionTimeoutSeconds() int32 { + if x != nil { + return x.ConnectionTimeoutSeconds + } + return 0 +} + +func (x *Agent) GetTroubleshootingUrl() string { + if x != nil { + return x.TroubleshootingUrl + } + return "" +} + type isAgent_Auth interface { isAgent_Auth() } @@ -2002,7 +2018,7 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x70, 0x75, 0x74, 0x22, 0x37, 0x0a, 0x14, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x8f, 0x03, 0x0a, + 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0xfe, 0x03, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x03, 0x65, 0x6e, @@ -2023,156 +2039,163 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x70, 0x70, 0x73, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x36, - 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3c, + 0x0a, 0x1a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x18, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x2f, 0x0a, 0x13, + 0x74, 0x72, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x73, 0x68, 0x6f, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x5f, + 0x75, 0x72, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x74, 0x72, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x73, 0x68, 0x6f, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x55, 0x72, 0x6c, 0x1a, 0x36, 0x0a, + 0x08, 0x45, 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x99, 0x02, + 0x0a, 0x03, 0x41, 0x70, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x75, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6c, 0x75, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x0b, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x41, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, + 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x70, 0x70, 0x53, + 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x0c, 0x73, 0x68, 0x61, + 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x59, 0x0a, 0x0b, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, + 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, + 0x68, 0x6f, 0x6c, 0x64, 0x22, 0xd2, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x04, 0x68, 0x69, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x69, + 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x99, - 0x02, 0x0a, 0x03, 0x41, 0x70, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x75, 0x67, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6c, 0x75, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, - 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, - 0x09, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x0b, 0x68, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x41, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x69, - 0x6e, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x70, 0x70, - 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x0c, 0x73, 0x68, - 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x59, 0x0a, 0x0b, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0xd2, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x06, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x04, 0x68, 0x69, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, - 0x69, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x05, 0x50, - 0x61, 0x72, 0x73, 0x65, 0x1a, 0x27, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x55, 0x0a, - 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x73, 0x1a, 0x73, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, - 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xae, 0x07, 0x0a, 0x09, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0xd1, 0x02, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, - 0x6c, 0x12, 0x53, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, - 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x1a, 0xd9, 0x01, 0x0a, 0x05, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, - 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x08, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, - 0x6c, 0x1a, 0x80, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, + 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, + 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x69, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x05, 0x50, 0x61, + 0x72, 0x73, 0x65, 0x1a, 0x27, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x55, 0x0a, 0x08, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x73, 0x1a, 0x73, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, + 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xae, 0x07, 0x0a, 0x09, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0xd1, 0x02, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, + 0x12, 0x53, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, + 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x1a, 0xd9, 0x01, 0x0a, 0x05, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x6e, 0x63, - 0x65, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x1a, 0x6b, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x1a, 0x77, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, - 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, - 0x6c, 0x6f, 0x67, 0x12, 0x3d, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, 0x08, 0x4c, 0x6f, - 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, - 0x00, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, - 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x03, - 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x2a, 0x3b, 0x0a, 0x0f, 0x41, - 0x70, 0x70, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, - 0x0a, 0x05, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x55, 0x54, - 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x02, 0x2a, 0x37, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, - 0x4f, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, - 0x02, 0x32, 0xa3, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x72, 0x12, 0x42, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, - 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, - 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, + 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x08, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x1a, 0x80, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x48, 0x00, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x1a, 0x6b, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x1a, 0x77, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x03, + 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, 0x6c, + 0x6f, 0x67, 0x12, 0x3d, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, 0x08, 0x4c, 0x6f, 0x67, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x00, + 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x49, + 0x4e, 0x46, 0x4f, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x03, 0x12, + 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x2a, 0x3b, 0x0a, 0x0f, 0x41, 0x70, + 0x70, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, + 0x05, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x55, 0x54, 0x48, + 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x50, + 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x02, 0x2a, 0x37, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x09, + 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, + 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x02, + 0x32, 0xa3, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x12, 0x42, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index 90f0e8fda1d9e..0f88705dd3e1b 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -85,6 +85,8 @@ message Agent { string token = 9; string instance_id = 10; } + int32 connection_timeout_seconds = 11; + string troubleshooting_url = 12; } enum AppSharingLevel { diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index b5b9297a61e25..b0055a2be5f2b 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -812,6 +812,8 @@ export interface WorkspaceAgent { readonly version: string readonly apps: WorkspaceApp[] readonly latency?: Record + readonly connection_timeout_seconds: number + readonly troubleshooting_url?: string } // From codersdk/workspaceagents.go @@ -1011,7 +1013,11 @@ export type TemplateRole = "" | "admin" | "use" export type UserStatus = "active" | "suspended" // From codersdk/workspaceagents.go -export type WorkspaceAgentStatus = "connected" | "connecting" | "disconnected" +export type WorkspaceAgentStatus = + | "connected" + | "connecting" + | "disconnected" + | "timeout" // From codersdk/workspaceapps.go export type WorkspaceAppHealth = diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 8e7c27951b9ca..343f2dd414c12 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -238,6 +238,8 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = { preferred: true, }, }, + connection_timeout_seconds: 120, + troubleshooting_url: "https://coder.com/troubleshoot", } export const MockWorkspaceAgentDisconnected: TypesGen.WorkspaceAgent = { @@ -281,6 +283,15 @@ export const MockWorkspaceAgentConnecting: TypesGen.WorkspaceAgent = { latency: {}, } +export const MockWorkspaceAgentTimeout: TypesGen.WorkspaceAgent = { + ...MockWorkspaceAgent, + id: "test-workspace-agent-timeout", + name: "a-timed-out-workspace-agent", + status: "timeout", + version: "", + latency: {}, +} + export const MockWorkspaceResource: TypesGen.WorkspaceResource = { agents: [ MockWorkspaceAgent, diff --git a/testutil/eventually.go b/testutil/eventually.go index 74084088b0e00..8b8b3f41acdf8 100644 --- a/testutil/eventually.go +++ b/testutil/eventually.go @@ -2,6 +2,7 @@ package testutil import ( "context" + "fmt" "testing" "time" @@ -20,22 +21,31 @@ import ( // // condition is not run in a goroutine; use the provided // context argument for cancellation if required. -func Eventually(ctx context.Context, t testing.TB, condition func(context.Context) bool, tick time.Duration) bool { +func Eventually(ctx context.Context, t testing.TB, condition func(ctx context.Context) (done bool), tick time.Duration, msgAndArgs ...interface{}) (done bool) { t.Helper() if _, ok := ctx.Deadline(); !ok { panic("developer error: must set deadline or timeout on ctx") } + msg := "Eventually timed out" + if len(msgAndArgs) > 0 { + if m, ok := msgAndArgs[0].(string); ok { + msg = fmt.Sprintf(m, msgAndArgs[1:]...) + } else { + panic("developer error: first argument of msgAndArgs must be a string") + } + } + ticker := time.NewTicker(tick) defer ticker.Stop() for tick := ticker.C; ; { select { case <-ctx.Done(): - assert.NoError(t, ctx.Err(), "Eventually timed out") + assert.NoError(t, ctx.Err(), msg) return false case <-tick: - if !assert.NoError(t, ctx.Err(), "Eventually timed out") { + if !assert.NoError(t, ctx.Err(), msg) { return false } if condition(ctx) {