Skip to content

Commit 6918b55

Browse files
authoredApr 14, 2024
Merge branch 'coder:main' into feat/coder-login-secret
2 parents 06b33fd + d3790bb commit 6918b55

34 files changed

+396
-57
lines changed
 

‎cli/open.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (r *RootCmd) openVSCode() *serpent.Command {
6464
// need to wait for the agent to start.
6565
workspaceQuery := inv.Args[0]
6666
autostart := true
67-
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, autostart, codersdk.Me, workspaceQuery)
67+
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, autostart, workspaceQuery)
6868
if err != nil {
6969
return xerrors.Errorf("get workspace and agent: %w", err)
7070
}

‎cli/ping.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (r *RootCmd) ping() *serpent.Command {
4242
_, workspaceAgent, err := getWorkspaceAndAgent(
4343
ctx, inv, client,
4444
false, // Do not autostart for a ping.
45-
codersdk.Me, workspaceName,
45+
workspaceName,
4646
)
4747
if err != nil {
4848
return err

‎cli/portforward.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (r *RootCmd) portForward() *serpent.Command {
7373
return xerrors.New("no port-forwards requested")
7474
}
7575

76-
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, !disableAutostart, codersdk.Me, inv.Args[0])
76+
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, !disableAutostart, inv.Args[0])
7777
if err != nil {
7878
return err
7979
}

‎cli/speedtest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (r *RootCmd) speedtest() *serpent.Command {
3939
ctx, cancel := context.WithCancel(inv.Context())
4040
defer cancel()
4141

42-
_, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, false, codersdk.Me, inv.Args[0])
42+
_, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, false, inv.Args[0])
4343
if err != nil {
4444
return err
4545
}

‎cli/ssh.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func (r *RootCmd) ssh() *serpent.Command {
157157
}
158158
}
159159

160-
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, !disableAutostart, codersdk.Me, inv.Args[0])
160+
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, !disableAutostart, inv.Args[0])
161161
if err != nil {
162162
return err
163163
}
@@ -551,10 +551,12 @@ startWatchLoop:
551551
// getWorkspaceAgent returns the workspace and agent selected using either the
552552
// `<workspace>[.<agent>]` syntax via `in`.
553553
// If autoStart is true, the workspace will be started if it is not already running.
554-
func getWorkspaceAndAgent(ctx context.Context, inv *serpent.Invocation, client *codersdk.Client, autostart bool, userID string, in string) (codersdk.Workspace, codersdk.WorkspaceAgent, error) { //nolint:revive
554+
func getWorkspaceAndAgent(ctx context.Context, inv *serpent.Invocation, client *codersdk.Client, autostart bool, input string) (codersdk.Workspace, codersdk.WorkspaceAgent, error) { //nolint:revive
555555
var (
556-
workspace codersdk.Workspace
557-
workspaceParts = strings.Split(in, ".")
556+
workspace codersdk.Workspace
557+
// The input will be `owner/name.agent`
558+
// The agent is optional.
559+
workspaceParts = strings.Split(input, ".")
558560
err error
559561
)
560562

‎cli/support.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,21 @@ func findAgent(agentName string, haystack []codersdk.WorkspaceResource) (*coders
232232
func writeBundle(src *support.Bundle, dest *zip.Writer) error {
233233
// We JSON-encode the following:
234234
for k, v := range map[string]any{
235-
"deployment/buildinfo.json": src.Deployment.BuildInfo,
236-
"deployment/config.json": src.Deployment.Config,
237-
"deployment/experiments.json": src.Deployment.Experiments,
238-
"deployment/health.json": src.Deployment.HealthReport,
239-
"network/netcheck.json": src.Network.Netcheck,
240-
"workspace/workspace.json": src.Workspace.Workspace,
241235
"agent/agent.json": src.Agent.Agent,
242236
"agent/listening_ports.json": src.Agent.ListeningPorts,
243237
"agent/manifest.json": src.Agent.Manifest,
244238
"agent/peer_diagnostics.json": src.Agent.PeerDiagnostics,
245239
"agent/ping_result.json": src.Agent.PingResult,
240+
"deployment/buildinfo.json": src.Deployment.BuildInfo,
241+
"deployment/config.json": src.Deployment.Config,
242+
"deployment/experiments.json": src.Deployment.Experiments,
243+
"deployment/health.json": src.Deployment.HealthReport,
244+
"network/connection_info.json": src.Network.ConnectionInfo,
245+
"network/netcheck.json": src.Network.Netcheck,
246246
"workspace/template.json": src.Workspace.Template,
247247
"workspace/template_version.json": src.Workspace.TemplateVersion,
248248
"workspace/parameters.json": src.Workspace.Parameters,
249+
"workspace/workspace.json": src.Workspace.Workspace,
249250
} {
250251
f, err := dest.Create(k)
251252
if err != nil {
@@ -265,17 +266,17 @@ func writeBundle(src *support.Bundle, dest *zip.Writer) error {
265266

266267
// The below we just write as we have them:
267268
for k, v := range map[string]string{
268-
"network/coordinator_debug.html": src.Network.CoordinatorDebug,
269-
"network/tailnet_debug.html": src.Network.TailnetDebug,
270-
"workspace/build_logs.txt": humanizeBuildLogs(src.Workspace.BuildLogs),
271269
"agent/logs.txt": string(src.Agent.Logs),
272270
"agent/agent_magicsock.html": string(src.Agent.AgentMagicsockHTML),
273271
"agent/client_magicsock.html": string(src.Agent.ClientMagicsockHTML),
274272
"agent/startup_logs.txt": humanizeAgentLogs(src.Agent.StartupLogs),
275273
"agent/prometheus.txt": string(src.Agent.Prometheus),
276-
"workspace/template_file.zip": string(templateVersionBytes),
277-
"logs.txt": strings.Join(src.Logs, "\n"),
278274
"cli_logs.txt": string(src.CLILogs),
275+
"logs.txt": strings.Join(src.Logs, "\n"),
276+
"network/coordinator_debug.html": src.Network.CoordinatorDebug,
277+
"network/tailnet_debug.html": src.Network.TailnetDebug,
278+
"workspace/build_logs.txt": humanizeBuildLogs(src.Workspace.BuildLogs),
279+
"workspace/template_file.zip": string(templateVersionBytes),
279280
} {
280281
f, err := dest.Create(k)
281282
if err != nil {

‎cli/support_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/coder/coder/v2/coderd/database"
2424
"github.com/coder/coder/v2/coderd/database/dbfake"
2525
"github.com/coder/coder/v2/coderd/database/dbtime"
26+
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
2627
"github.com/coder/coder/v2/codersdk"
2728
"github.com/coder/coder/v2/codersdk/agentsdk"
2829
"github.com/coder/coder/v2/codersdk/healthsdk"
@@ -182,20 +183,20 @@ func assertBundleContents(t *testing.T, path string, wantWorkspace bool, wantAge
182183
var v healthsdk.HealthcheckReport
183184
decodeJSONFromZip(t, f, &v)
184185
require.NotEmpty(t, v, "health report should not be empty")
186+
case "network/connection_info.json":
187+
var v workspacesdk.AgentConnectionInfo
188+
decodeJSONFromZip(t, f, &v)
189+
require.NotEmpty(t, v, "agent connection info should not be empty")
185190
case "network/coordinator_debug.html":
186191
bs := readBytesFromZip(t, f)
187192
require.NotEmpty(t, bs, "coordinator debug should not be empty")
188193
case "network/tailnet_debug.html":
189194
bs := readBytesFromZip(t, f)
190195
require.NotEmpty(t, bs, "tailnet debug should not be empty")
191196
case "network/netcheck.json":
192-
var v workspacesdk.AgentConnectionInfo
197+
var v derphealth.Report
193198
decodeJSONFromZip(t, f, &v)
194-
if !wantAgent || !wantWorkspace {
195-
require.Empty(t, v, "expected connection info to be empty")
196-
continue
197-
}
198-
require.NotEmpty(t, v, "connection info should not be empty")
199+
require.NotEmpty(t, v, "netcheck should not be empty")
199200
case "workspace/workspace.json":
200201
var v codersdk.Workspace
201202
decodeJSONFromZip(t, f, &v)

‎cli/vscodessh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (r *RootCmd) vscodeSSH() *serpent.Command {
110110
// will call this command after the workspace is started.
111111
autostart := false
112112

113-
_, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, autostart, owner, name)
113+
_, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, autostart, fmt.Sprintf("%s/%s", owner, name))
114114
if err != nil {
115115
return xerrors.Errorf("find workspace and agent: %w", err)
116116
}

‎docs/guides/support-bundle.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Generate and upload a Support Bundle to Coder Support
2+
3+
When you engage with Coder support to diagnose an issue with your deployment,
4+
you may be asked to generate and upload a "Support Bundle" for offline analysis.
5+
This document explains the contents of a support bundle and the steps to submit
6+
a support bundle to Coder staff.
7+
8+
## What is a Support Bundle?
9+
10+
A support bundle is an archive containing a snapshot of information about your
11+
Coder deployment.
12+
13+
It contains information about the workspace, the template it uses, running
14+
agents in the workspace, and other detailed information useful for
15+
troubleshooting.
16+
17+
It is primarily intended for troubleshooting connectivity issues to workspaces,
18+
but can be useful for diagnosing other issues as well.
19+
20+
**While we attempt to redact sensitive information from support bundles, they
21+
may contain information deemed sensitive by your organization and should be
22+
treated as such.**
23+
24+
A brief overview of all files contained in the bundle is provided below:
25+
26+
> Note: detailed descriptions of all the information available in the bundle is
27+
> out of scope, as support bundles are primarily intended for internal use.
28+
29+
| Filename | Description |
30+
| --------------------------------- | ------------------------------------------------------------------------------------------------ |
31+
| `agent/agent.json` | The agent used to connect to the workspace with environment variables stripped. |
32+
| `agent/agent_magicsock.html` | The contents of the HTTP debug endpoint of the agent's Tailscale connection. |
33+
| `agent/client_magicsock.html` | The contents of the HTTP debug endpoint of the client's Tailscale connection. |
34+
| `agent/listening_ports.json` | The listening ports detected by the selected agent running in the workspace. |
35+
| `agent/logs.txt` | The logs of the selected agent running in the workspace. |
36+
| `agent/manifest.json` | The manifest of the selected agent with environment variables stripped. |
37+
| `agent/startup_logs.txt` | Startup logs of the workspace agent. |
38+
| `agent/prometheus.txt` | The contents of the agent's Prometheus endpoint. |
39+
| `cli_logs.txt` | Logs from running the `coder support bundle` command. |
40+
| `deployment/buildinfo.json` | Coder version and build information. |
41+
| `deployment/config.json` | Deployment [configuration](../api/general.md#get-deployment-config), with secret values removed. |
42+
| `deployment/experiments.json` | Any [experiments](../cli/server.md#experiments) currently enabled for the deployment. |
43+
| `deployment/health.json` | A snapshot of the [health status](../admin/healthcheck.md) of the deployment. |
44+
| `logs.txt` | Logs from the `codersdk.Client` used to generate the bundle. |
45+
| `network/connection_info.json` | Information used by workspace agents used to connect to Coder (DERP map etc.) |
46+
| `network/coordinator_debug.html` | Peers currently connected to each Coder instance and the tunnels established between peers. |
47+
| `network/netcheck.json` | Results of running `coder netcheck` locally. |
48+
| `network/tailnet_debug.html` | Tailnet coordinators, their heartbeat ages, connected peers, and tunnels. |
49+
| `workspace/build_logs.txt` | Build logs of the selected workspace. |
50+
| `workspace/workspace.json` | Details of the selected workspace. |
51+
| `workspace/parameters.json` | Build parameters of the selected workspace. |
52+
| `workspace/template.json` | The template currently in use by the selected workspace. |
53+
| `workspace/template_file.zip` | The source code of the template currently in use by the selected workspace. |
54+
| `workspace/template_version.json` | The template version currently in use by the selected workspace. |
55+
56+
## How do I generate a Support Bundle?
57+
58+
1. Ensure your deployment is up and running. Generating a support bundle
59+
requires the Coder deployment to be available.
60+
61+
2. Ensure you have the Coder CLI installed on a local machine. See
62+
(installation)[../install/index.md] for steps on how to do this.
63+
64+
> Note: It is recommended to generate a support bundle from a location
65+
> experiencing workspace connectivity issues.
66+
67+
3. Ensure you are [logged in](../cli/login.md#login) to your Coder deployment as
68+
a user with the Owner privilege.
69+
70+
4. Run `coder support bundle [owner/workspace]`, and respond `yes` to the
71+
prompt. The support bundle will be generated in the current directory with
72+
the filename `coder-support-$TIMESTAMP.zip`.
73+
74+
> While support bundles can be generated without a running workspace, it is
75+
> recommended to specify one to maximize troubleshooting information.
76+
77+
5. (Recommended) Extract the support bundle and review its contents, redacting
78+
any information you deem necessary.
79+
80+
6. Coder staff will provide you a link where you can upload the bundle along
81+
with any other necessary supporting files.
82+
83+
> Note: It is helpful to leave an informative message regarding the nature of
84+
> supporting files.
85+
86+
Coder support will then review the information you provided and respond to you
87+
with next steps.

‎docs/manifest.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,11 @@
10751075
"path": "./guides/index.md",
10761076
"icon_path": "./images/icons/notes.svg",
10771077
"children": [
1078+
{
1079+
"title": "Generate a Support Bundle",
1080+
"description": "Generate and upload a Support Bundle to Coder Support",
1081+
"path": "./guides/support-bundle.md"
1082+
},
10781083
{
10791084
"title": "Configuring Okta",
10801085
"description": "Custom claims/scopes with Okta for group/role sync",

‎scripts/lib.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ if [[ "${CODER_LIBSH_NO_CHECK_DEPENDENCIES:-}" != *t* ]]; then
190190
if isdarwin; then
191191
log "On darwin:"
192192
log "- brew install bash"
193+
# shellcheck disable=SC2016
194+
log '- Add "$(brew --prefix bash)/bin" to your PATH'
193195
log "- Restart your terminal"
194196
fi
195197
log
@@ -203,7 +205,7 @@ if [[ "${CODER_LIBSH_NO_CHECK_DEPENDENCIES:-}" != *t* ]]; then
203205
log "On darwin:"
204206
log "- brew install gnu-getopt"
205207
# shellcheck disable=SC2016
206-
log '- Add "$(brew --prefix)/opt/gnu-getopt/bin" to your PATH'
208+
log '- Add "$(brew --prefix gnu-getopt)/bin" to your PATH'
207209
log "- Restart your terminal"
208210
fi
209211
log
@@ -226,7 +228,7 @@ if [[ "${CODER_LIBSH_NO_CHECK_DEPENDENCIES:-}" != *t* ]]; then
226228
log "On darwin:"
227229
log "- brew install make"
228230
# shellcheck disable=SC2016
229-
log '- Add "$(brew --prefix)/opt/make/libexec/gnubin" to your PATH (you should Google this first)'
231+
log '- Add "$(brew --prefix make)/libexec/gnubin" to your PATH'
230232
log "- Restart your terminal"
231233
fi
232234
log

‎site/e2e/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ cd site
1212
# Build the frontend assets. If you are actively changing
1313
# the site to debug an issue, add `--watch`.
1414
pnpm build
15+
# Alternatively, build with debug info and source maps:
16+
NODE_ENV=development pnpm vite build --mode=development
1517
# Install the browsers to `~/.cache/ms-playwright`.
1618
pnpm playwright:install
1719
# Run E2E tests. You can see the configuration of the server

‎site/e2e/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ export const requireEnterpriseTests = Boolean(
3737
process.env.CODER_E2E_REQUIRE_ENTERPRISE_TESTS,
3838
);
3939
export const enterpriseLicense = process.env.CODER_E2E_ENTERPRISE_LICENSE ?? "";
40+
41+
// Fake experiments to verify that site presents them as enabled.
42+
export const e2eFakeExperiment1 = "e2e-fake-experiment-1";
43+
export const e2eFakeExperiment2 = "e2e-fake-experiment-2";

‎site/e2e/playwright.config.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { defineConfig } from "@playwright/test";
22
import * as path from "path";
3-
import { coderMain, coderPort, coderdPProfPort, gitAuth } from "./constants";
3+
import {
4+
coderMain,
5+
coderPort,
6+
coderdPProfPort,
7+
e2eFakeExperiment1,
8+
e2eFakeExperiment2,
9+
gitAuth,
10+
} from "./constants";
411

512
export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT;
613

@@ -22,7 +29,7 @@ export default defineConfig({
2229
testMatch: /.*\.spec\.ts/,
2330
dependencies: ["testsSetup"],
2431
use: { storageState },
25-
timeout: 20_000,
32+
timeout: 50_000,
2633
},
2734
],
2835
reporter: [["./reporter.ts"]],
@@ -60,6 +67,8 @@ export default defineConfig({
6067
.join(" "),
6168
env: {
6269
...process.env,
70+
// Otherwise, the runner fails on Mac with: could not determine kind of name for C.uuid_string_t
71+
CGO_ENABLED: "0",
6372

6473
// This is the test provider for git auth with devices!
6574
CODER_GITAUTH_0_ID: gitAuth.deviceProvider,
@@ -101,6 +110,7 @@ export default defineConfig({
101110
gitAuth.validatePath,
102111
),
103112
CODER_PPROF_ADDRESS: "127.0.0.1:" + coderdPProfPort,
113+
CODER_EXPERIMENTS: e2eFakeExperiment1 + "," + e2eFakeExperiment2,
104114
},
105115
reuseExistingServer: false,
106116
},

‎site/e2e/tests/app.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from "../helpers";
1111
import { beforeCoderTest } from "../hooks";
1212

13-
test.beforeEach(async ({ page }) => await beforeCoderTest(page));
13+
test.beforeEach(({ page }) => beforeCoderTest(page));
1414

1515
test("app", async ({ context, page }) => {
1616
const appContent = "Hello World";

0 commit comments

Comments
 (0)