Skip to content

Commit f55352b

Browse files
committed
Merge branch 'main' into org-members-page
2 parents d6969ef + a6d66cc commit f55352b

File tree

167 files changed

+1938
-712
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+1938
-712
lines changed

Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,7 @@ lint/ts:
448448
lint/go:
449449
./scripts/check_enterprise_imports.sh
450450
linter_ver=$(shell egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/Dockerfile | cut -d '=' -f 2)
451-
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$$linter_ver
452-
golangci-lint run
451+
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v$$linter_ver run
453452
.PHONY: lint/go
454453

455454
lint/examples:

agent/agentscripts/agentscripts.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript)
349349
"This usually means a child process was started with references to stdout or stderr. As a result, this " +
350350
"process may now have been terminated. Consider redirecting the output or using a separate " +
351351
"\"coder_script\" for the process, see " +
352-
"https://coder.com/docs/v2/latest/templates/troubleshooting#startup-script-issues for more information.",
352+
"https://coder.com/docs/templates/troubleshooting#startup-script-issues for more information.",
353353
)
354354
// Inform the user by propagating the message via log writers.
355355
_, _ = fmt.Fprintf(cmd.Stderr, "WARNING: %s. %s\n", message, details)

apiversion/apiversion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type APIVersion struct {
2626
}
2727

2828
func (v *APIVersion) WithBackwardCompat(majs ...int) *APIVersion {
29-
v.additionalMajors = append(v.additionalMajors, majs[:]...)
29+
v.additionalMajors = append(v.additionalMajors, majs...)
3030
return v
3131
}
3232

cli/cliui/agent.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
116116
if agent.Status == codersdk.WorkspaceAgentTimeout {
117117
now := time.Now()
118118
sw.Log(now, codersdk.LogLevelInfo, "The workspace agent is having trouble connecting, wait for it to connect or restart your workspace.")
119-
sw.Log(now, codersdk.LogLevelInfo, troubleshootingMessage(agent, "https://coder.com/docs/v2/latest/templates#agent-connection-issues"))
119+
sw.Log(now, codersdk.LogLevelInfo, troubleshootingMessage(agent, "https://coder.com/docs/templates#agent-connection-issues"))
120120
for agent.Status == codersdk.WorkspaceAgentTimeout {
121121
if agent, err = fetch(); err != nil {
122122
return xerrors.Errorf("fetch: %w", err)
@@ -132,7 +132,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
132132
}
133133

134134
stage := "Running workspace agent startup scripts"
135-
follow := opts.Wait
135+
follow := opts.Wait && agent.LifecycleState.Starting()
136136
if !follow {
137137
stage += " (non-blocking)"
138138
}
@@ -209,19 +209,25 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
209209
case codersdk.WorkspaceAgentLifecycleReady:
210210
sw.Complete(stage, safeDuration(sw, agent.ReadyAt, agent.StartedAt))
211211
case codersdk.WorkspaceAgentLifecycleStartTimeout:
212-
sw.Fail(stage, 0)
212+
// Backwards compatibility: Avoid printing warning if
213+
// coderd is old and doesn't set ReadyAt for timeouts.
214+
if agent.ReadyAt == nil {
215+
sw.Fail(stage, 0)
216+
} else {
217+
sw.Fail(stage, safeDuration(sw, agent.ReadyAt, agent.StartedAt))
218+
}
213219
sw.Log(time.Time{}, codersdk.LogLevelWarn, "Warning: A startup script timed out and your workspace may be incomplete.")
214220
case codersdk.WorkspaceAgentLifecycleStartError:
215221
sw.Fail(stage, safeDuration(sw, agent.ReadyAt, agent.StartedAt))
216222
// Use zero time (omitted) to separate these from the startup logs.
217223
sw.Log(time.Time{}, codersdk.LogLevelWarn, "Warning: A startup script exited with an error and your workspace may be incomplete.")
218-
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent, "https://coder.com/docs/v2/latest/templates/troubleshooting#startup-script-exited-with-an-error"))
224+
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent, "https://coder.com/docs/templates/troubleshooting#startup-script-exited-with-an-error"))
219225
default:
220226
switch {
221227
case agent.LifecycleState.Starting():
222228
// Use zero time (omitted) to separate these from the startup logs.
223229
sw.Log(time.Time{}, codersdk.LogLevelWarn, "Notice: The startup scripts are still running and your workspace may be incomplete.")
224-
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent, "https://coder.com/docs/v2/latest/templates/troubleshooting#your-workspace-may-be-incomplete"))
230+
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent, "https://coder.com/docs/templates/troubleshooting#your-workspace-may-be-incomplete"))
225231
// Note: We don't complete or fail the stage here, it's
226232
// intentionally left open to indicate this stage didn't
227233
// complete.
@@ -243,7 +249,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
243249
stage := "The workspace agent lost connection"
244250
sw.Start(stage)
245251
sw.Log(time.Now(), codersdk.LogLevelWarn, "Wait for it to reconnect or restart your workspace.")
246-
sw.Log(time.Now(), codersdk.LogLevelWarn, troubleshootingMessage(agent, "https://coder.com/docs/v2/latest/templates/troubleshooting#agent-connection-issues"))
252+
sw.Log(time.Now(), codersdk.LogLevelWarn, troubleshootingMessage(agent, "https://coder.com/docs/templates/troubleshooting#agent-connection-issues"))
247253

248254
disconnectedAt := agent.DisconnectedAt
249255
for agent.Status == codersdk.WorkspaceAgentDisconnected {

cli/cliui/agent_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ func TestAgent(t *testing.T) {
9595
iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
9696
func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
9797
agent.Status = codersdk.WorkspaceAgentConnecting
98+
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStarting
99+
agent.StartedAt = ptr.Ref(time.Now())
98100
return nil
99101
},
100102
func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
@@ -104,6 +106,7 @@ func TestAgent(t *testing.T) {
104106
agent.Status = codersdk.WorkspaceAgentConnected
105107
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStartTimeout
106108
agent.FirstConnectedAt = ptr.Ref(time.Now())
109+
agent.ReadyAt = ptr.Ref(time.Now())
107110
return nil
108111
},
109112
},
@@ -255,10 +258,9 @@ func TestAgent(t *testing.T) {
255258
},
256259
},
257260
want: []string{
258-
"⧗ Running workspace agent startup scripts",
259-
"ℹ︎ To connect immediately, reconnect with --wait=no or CODER_SSH_WAIT=no, see --help for more information.",
261+
"⧗ Running workspace agent startup scripts (non-blocking)",
260262
"Hello world",
261-
"✘ Running workspace agent startup scripts",
263+
"✘ Running workspace agent startup scripts (non-blocking)",
262264
"Warning: A startup script exited with an error and your workspace may be incomplete.",
263265
"For more information and troubleshooting, see",
264266
},

cli/dotfiles.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func (r *RootCmd) dotfiles() *serpent.Command {
204204
}
205205

206206
if fi.Mode()&0o111 == 0 {
207-
return xerrors.Errorf("script %q is not executable. See https://coder.com/docs/v2/latest/dotfiles for information on how to resolve the issue.", script)
207+
return xerrors.Errorf("script %q is not executable. See https://coder.com/docs/dotfiles for information on how to resolve the issue.", script)
208208
}
209209

210210
// it is safe to use a variable command here because it's from

cli/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ func (r *RootCmd) CoreSubcommands() []*serpent.Command {
117117
r.stop(),
118118
r.unfavorite(),
119119
r.update(),
120+
r.whoami(),
120121

121122
// Hidden
122123
r.gitssh(),

cli/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
838838
}
839839
defer options.Telemetry.Close()
840840
} else {
841-
logger.Warn(ctx, `telemetry disabled, unable to notify of security issues. Read more: https://coder.com/docs/v2/latest/admin/telemetry`)
841+
logger.Warn(ctx, `telemetry disabled, unable to notify of security issues. Read more: https://coder.com/docs/admin/telemetry`)
842842
}
843843

844844
// This prevents the pprof import from being accidentally deleted.

cli/ssh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ func (r *RootCmd) ssh() *serpent.Command {
437437
}
438438

439439
err = sshSession.Wait()
440-
conn.SendDisconnectedTelemetry("ssh")
440+
conn.SendDisconnectedTelemetry()
441441
if err != nil {
442442
if exitErr := (&gossh.ExitError{}); errors.As(err, &exitErr) {
443443
// Clear the error since it's not useful beyond

cli/templatelist_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ func TestTemplateList(t *testing.T) {
122122
_ = coderdtest.CreateTemplate(t, client, owner.OrganizationID, firstVersion.ID)
123123

124124
secondOrg := coderdtest.CreateOrganization(t, client, coderdtest.CreateOrganizationOptions{
125-
IncludeProvisionerDaemon: true,
125+
// Listing templates does not require the template actually completes.
126+
// We cannot provision an external provisioner in AGPL tests.
127+
IncludeProvisionerDaemon: false,
126128
})
127129
secondVersion := coderdtest.CreateTemplateVersion(t, client, secondOrg.ID, nil)
128130
_ = coderdtest.CreateTemplate(t, client, secondOrg.ID, secondVersion.ID)

cli/testdata/coder_--help.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ SUBCOMMANDS:
5555
date
5656
users Manage users
5757
version Show coder version
58+
whoami Fetch authenticated user info for Coder deployment
5859

5960
GLOBAL OPTIONS:
6061
Global options are applied to all commands. They can be set using environment
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
coder v0.0.0-devel
2+
3+
USAGE:
4+
coder whoami
5+
6+
Fetch authenticated user info for Coder deployment
7+
8+
———
9+
Run `coder --help` for a list of global options.

cli/testdata/server-config.yaml.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,8 @@ termsOfServiceURL: ""
427427
# (default: ed25519, type: string)
428428
sshKeygenAlgorithm: ed25519
429429
# URL to use for agent troubleshooting when not set in the template.
430-
# (default: https://coder.com/docs/v2/latest/templates/troubleshooting, type: url)
431-
agentFallbackTroubleshootingURL: https://coder.com/docs/v2/latest/templates/troubleshooting
430+
# (default: https://coder.com/docs/templates/troubleshooting, type: url)
431+
agentFallbackTroubleshootingURL: https://coder.com/docs/templates/troubleshooting
432432
# Disable workspace apps that are not served from subdomains. Path-based apps can
433433
# make requests to the Coder API and pose a security risk when the workspace
434434
# serves malicious JavaScript. This is recommended for security purposes if a

cli/whoami.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/coder/coder/v2/cli/cliui"
7+
"github.com/coder/coder/v2/codersdk"
8+
"github.com/coder/pretty"
9+
"github.com/coder/serpent"
10+
)
11+
12+
func (r *RootCmd) whoami() *serpent.Command {
13+
client := new(codersdk.Client)
14+
cmd := &serpent.Command{
15+
Annotations: workspaceCommand,
16+
Use: "whoami",
17+
Short: "Fetch authenticated user info for Coder deployment",
18+
Middleware: serpent.Chain(
19+
serpent.RequireNArgs(0),
20+
r.InitClient(client),
21+
),
22+
Handler: func(inv *serpent.Invocation) error {
23+
ctx := inv.Context()
24+
// Fetch the user info
25+
resp, err := client.User(ctx, codersdk.Me)
26+
// Get Coder instance url
27+
clientURL := client.URL
28+
29+
if err != nil {
30+
return err
31+
}
32+
33+
_, _ = fmt.Fprintf(inv.Stdout, Caret+"Coder is running at %s, You're authenticated as %s !\n", pretty.Sprint(cliui.DefaultStyles.Keyword, clientURL), pretty.Sprint(cliui.DefaultStyles.Keyword, resp.Username))
34+
return err
35+
},
36+
}
37+
return cmd
38+
}

cli/whoami_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package cli_test
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/coder/coder/v2/cli/clitest"
10+
"github.com/coder/coder/v2/coderd/coderdtest"
11+
)
12+
13+
func TestWhoami(t *testing.T) {
14+
t.Parallel()
15+
16+
t.Run("InitialUserNoTTY", func(t *testing.T) {
17+
t.Parallel()
18+
client := coderdtest.New(t, nil)
19+
root, _ := clitest.New(t, "login", client.URL.String())
20+
err := root.Run()
21+
require.Error(t, err)
22+
})
23+
24+
t.Run("OK", func(t *testing.T) {
25+
t.Parallel()
26+
client := coderdtest.New(t, nil)
27+
_ = coderdtest.CreateFirstUser(t, client)
28+
inv, root := clitest.New(t, "whoami")
29+
clitest.SetupConfig(t, client, root)
30+
buf := new(bytes.Buffer)
31+
inv.Stdout = buf
32+
err := inv.Run()
33+
require.NoError(t, err)
34+
whoami := buf.String()
35+
require.NotEmpty(t, whoami)
36+
})
37+
}

coderd/agentapi/lifecycle.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ func (a *LifecycleAPI) UpdateLifecycle(ctx context.Context, req *agentproto.Upda
9898
// This agent is (re)starting, so it's not ready yet.
9999
readyAt.Time = time.Time{}
100100
readyAt.Valid = false
101-
case database.WorkspaceAgentLifecycleStateReady, database.WorkspaceAgentLifecycleStateStartError:
101+
case database.WorkspaceAgentLifecycleStateReady,
102+
database.WorkspaceAgentLifecycleStateStartTimeout,
103+
database.WorkspaceAgentLifecycleStateStartError:
102104
if !startedAt.Valid {
103105
startedAt = dbChangedAt
104106
}

coderd/agentapi/lifecycle_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ func TestUpdateLifecycle(t *testing.T) {
275275
if state == agentproto.Lifecycle_STARTING {
276276
expectedStartedAt = sql.NullTime{Valid: true, Time: stateNow}
277277
}
278-
if state == agentproto.Lifecycle_READY || state == agentproto.Lifecycle_START_ERROR {
278+
if state == agentproto.Lifecycle_READY || state == agentproto.Lifecycle_START_TIMEOUT || state == agentproto.Lifecycle_START_ERROR {
279279
expectedReadyAt = sql.NullTime{Valid: true, Time: stateNow}
280280
}
281281

0 commit comments

Comments
 (0)