Skip to content

Commit eef9bf7

Browse files
committed
Merge branch 'main' of github.com:/coder/coder into dk/llm-proxy
Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2 parents ed91ba8 + d4b4418 commit eef9bf7

File tree

222 files changed

+8358
-1605
lines changed

Some content is hidden

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

222 files changed

+8358
-1605
lines changed

.devcontainer/filebrowser/install.sh

100644100755
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@ printf "%sInstalling filebrowser\n\n" "${BOLD}"
88

99
# Check if filebrowser is installed.
1010
if ! command -v filebrowser &>/dev/null; then
11-
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
11+
VERSION="v2.42.1"
12+
EXPECTED_HASH="7d83c0f077df10a8ec9bfd9bf6e745da5d172c3c768a322b0e50583a6bc1d3cc"
13+
14+
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/download/${VERSION}/linux-amd64-filebrowser.tar.gz" -o /tmp/filebrowser.tar.gz
15+
echo "${EXPECTED_HASH} /tmp/filebrowser.tar.gz" | sha256sum -c
16+
tar -xzf /tmp/filebrowser.tar.gz -C /tmp
17+
sudo mv /tmp/filebrowser /usr/local/bin/
18+
sudo chmod +x /usr/local/bin/filebrowser
19+
rm /tmp/filebrowser.tar.gz
1220
fi
1321

1422
# Create entrypoint.

.devcontainer/scripts/post_create.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/sh
22

33
install_devcontainer_cli() {
4-
npm install -g @devcontainers/cli
4+
npm install -g @devcontainers/cli@0.80.0 --integrity=sha512-w2EaxgjyeVGyzfA/KUEZBhyXqu/5PyWNXcnrXsZOBrt3aN2zyGiHrXoG54TF6K0b5DSCF01Rt5fnIyrCeFzFKw==
55
}
66

77
install_ssh_config() {

.gitattributes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ provisionersdk/proto/*.go linguist-generated=true
1515
*.tfstate.json linguist-generated=true
1616
*.tfstate.dot linguist-generated=true
1717
*.tfplan.dot linguist-generated=true
18+
site/e2e/google/protobuf/timestampGenerated.ts
1819
site/e2e/provisionerGenerated.ts linguist-generated=true
20+
site/src/api/countriesGenerated.tsx linguist-generated=true
21+
site/src/api/rbacresourcesGenerated.tsx linguist-generated=true
1922
site/src/api/typesGenerated.ts linguist-generated=true
20-
site/src/pages/SetupPage/countries.tsx linguist-generated=true

.github/workflows/ci.yaml

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ jobs:
340340
- name: Disable Spotlight Indexing
341341
if: runner.os == 'macOS'
342342
run: |
343+
enabled=$(sudo mdutil -a -s | grep "Indexing enabled" | wc -l)
344+
if [ $enabled -eq 0 ]; then
345+
echo "Spotlight indexing is already disabled"
346+
exit 0
347+
fi
343348
sudo mdutil -a -i off
344349
sudo mdutil -X /
345350
sudo launchctl bootout system /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
@@ -485,6 +490,12 @@ jobs:
485490
gotestsum --format standard-quiet --packages "$PACKAGES" \
486491
-- -timeout=20m -v -p $NUM_PARALLEL_PACKAGES -parallel=$NUM_PARALLEL_TESTS $TESTCOUNT
487492
493+
- name: Upload failed test db dumps
494+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
495+
with:
496+
name: failed-test-db-dump-${{matrix.os}}
497+
path: "**/*.test.sql"
498+
488499
- name: Upload Go Build Cache
489500
uses: ./.github/actions/test-cache/upload
490501
with:
@@ -959,7 +970,7 @@ jobs:
959970
- name: Switch XCode Version
960971
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
961972
with:
962-
xcode-version: "16.0.0"
973+
xcode-version: "16.1.0"
963974

964975
- name: Setup Go
965976
uses: ./.github/actions/setup-go
@@ -1060,6 +1071,27 @@ jobs:
10601071
- name: Setup Go
10611072
uses: ./.github/actions/setup-go
10621073

1074+
- name: Install rcodesign
1075+
run: |
1076+
set -euo pipefail
1077+
wget -O /tmp/rcodesign.tar.gz https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.22.0/apple-codesign-0.22.0-x86_64-unknown-linux-musl.tar.gz
1078+
sudo tar -xzf /tmp/rcodesign.tar.gz \
1079+
-C /usr/bin \
1080+
--strip-components=1 \
1081+
apple-codesign-0.22.0-x86_64-unknown-linux-musl/rcodesign
1082+
rm /tmp/rcodesign.tar.gz
1083+
1084+
- name: Setup Apple Developer certificate
1085+
run: |
1086+
set -euo pipefail
1087+
touch /tmp/{apple_cert.p12,apple_cert_password.txt}
1088+
chmod 600 /tmp/{apple_cert.p12,apple_cert_password.txt}
1089+
echo "$AC_CERTIFICATE_P12_BASE64" | base64 -d > /tmp/apple_cert.p12
1090+
echo "$AC_CERTIFICATE_PASSWORD" > /tmp/apple_cert_password.txt
1091+
env:
1092+
AC_CERTIFICATE_P12_BASE64: ${{ secrets.AC_CERTIFICATE_P12_BASE64 }}
1093+
AC_CERTIFICATE_PASSWORD: ${{ secrets.AC_CERTIFICATE_PASSWORD }}
1094+
10631095
# Necessary for signing Windows binaries.
10641096
- name: Setup Java
10651097
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
@@ -1138,6 +1170,9 @@ jobs:
11381170
CODER_WINDOWS_RESOURCES: "1"
11391171
CODER_SIGN_GPG: "1"
11401172
CODER_GPG_RELEASE_KEY_BASE64: ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
1173+
CODER_SIGN_DARWIN: "1"
1174+
AC_CERTIFICATE_FILE: /tmp/apple_cert.p12
1175+
AC_CERTIFICATE_PASSWORD_FILE: /tmp/apple_cert_password.txt
11411176
EV_KEY: ${{ secrets.EV_KEY }}
11421177
EV_KEYSTORE: ${{ secrets.EV_KEYSTORE }}
11431178
EV_TSA_URL: ${{ secrets.EV_TSA_URL }}

.github/workflows/nightly-gauntlet.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ jobs:
3737
- name: Disable Spotlight Indexing
3838
if: runner.os == 'macOS'
3939
run: |
40+
enabled=$(sudo mdutil -a -s | grep "Indexing enabled" | wc -l)
41+
if [ $enabled -eq 0 ]; then
42+
echo "Spotlight indexing is already disabled"
43+
exit 0
44+
fi
4045
sudo mdutil -a -i off
4146
sudo mdutil -X /
4247
sudo launchctl bootout system /System/Library/LaunchDaemons/com.apple.metadata.mds.plist

.github/workflows/release.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
- name: Switch XCode Version
6161
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
6262
with:
63-
xcode-version: "16.0.0"
63+
xcode-version: "16.1.0"
6464

6565
- name: Setup Go
6666
uses: ./.github/actions/setup-go
@@ -655,7 +655,7 @@ jobs:
655655
detached_signature="${binary}.asc"
656656
gcloud storage cp "./site/out/bin/${binary}" "gs://releases.coder.com/coder-cli/${version}/${binary}"
657657
gcloud storage cp "./site/out/bin/${detached_signature}" "gs://releases.coder.com/coder-cli/${version}/${detached_signature}"
658-
done
658+
done
659659
660660
- name: Publish release
661661
run: |

CODEOWNERS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,15 @@ coderd/rbac/ @Emyrk
1717

1818
# Mainly dependent on coder/guts, which is maintained by @Emyrk
1919
scripts/apitypings/ @Emyrk
20+
scripts/gensite/ @aslilac
21+
22+
site/ @aslilac
23+
site/src/hooks/ @Parkreiner
24+
# These rules intentionally do not specify any owners. More specific rules
25+
# override less specific rules, so these files are "ignored" by the site/ rule.
26+
site/e2e/google/protobuf/timestampGenerated.ts
27+
site/e2e/provisionerGenerated.ts
28+
site/src/api/countriesGenerated.ts
29+
site/src/api/rbacresourcesGenerated.ts
30+
site/src/api/typesGenerated.ts
31+
site/CLAUDE.md

agent/agent_test.go

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,6 +2458,212 @@ func TestAgent_DevcontainersDisabledForSubAgent(t *testing.T) {
24582458
require.Contains(t, err.Error(), "Dev Container integration inside other Dev Containers is explicitly not supported.")
24592459
}
24602460

2461+
// TestAgent_DevcontainerPrebuildClaim tests that we correctly handle
2462+
// the claiming process for running devcontainers.
2463+
//
2464+
// You can run it manually as follows:
2465+
//
2466+
// CODER_TEST_USE_DOCKER=1 go test -count=1 ./agent -run TestAgent_DevcontainerPrebuildClaim
2467+
//
2468+
//nolint:paralleltest // This test sets an environment variable.
2469+
func TestAgent_DevcontainerPrebuildClaim(t *testing.T) {
2470+
if os.Getenv("CODER_TEST_USE_DOCKER") != "1" {
2471+
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
2472+
}
2473+
if _, err := exec.LookPath("devcontainer"); err != nil {
2474+
t.Skip("This test requires the devcontainer CLI: npm install -g @devcontainers/cli")
2475+
}
2476+
2477+
pool, err := dockertest.NewPool("")
2478+
require.NoError(t, err, "Could not connect to docker")
2479+
2480+
var (
2481+
ctx = testutil.Context(t, testutil.WaitShort)
2482+
2483+
devcontainerID = uuid.New()
2484+
devcontainerLogSourceID = uuid.New()
2485+
2486+
workspaceFolder = filepath.Join(t.TempDir(), "project")
2487+
devcontainerPath = filepath.Join(workspaceFolder, ".devcontainer")
2488+
devcontainerConfig = filepath.Join(devcontainerPath, "devcontainer.json")
2489+
)
2490+
2491+
// Given: A devcontainer project.
2492+
t.Logf("Workspace folder: %s", workspaceFolder)
2493+
2494+
err = os.MkdirAll(devcontainerPath, 0o755)
2495+
require.NoError(t, err, "create dev container directory")
2496+
2497+
// Given: This devcontainer project specifies an app that uses the owner name and workspace name.
2498+
err = os.WriteFile(devcontainerConfig, []byte(`{
2499+
"name": "project",
2500+
"image": "busybox:latest",
2501+
"cmd": ["sleep", "infinity"],
2502+
"runArgs": ["--label=`+agentcontainers.DevcontainerIsTestRunLabel+`=true"],
2503+
"customizations": {
2504+
"coder": {
2505+
"apps": [{
2506+
"slug": "zed",
2507+
"url": "zed://ssh/${localEnv:CODER_WORKSPACE_AGENT_NAME}.${localEnv:CODER_WORKSPACE_NAME}.${localEnv:CODER_WORKSPACE_OWNER_NAME}.coder${containerWorkspaceFolder}"
2508+
}]
2509+
}
2510+
}
2511+
}`), 0o600)
2512+
require.NoError(t, err, "write devcontainer config")
2513+
2514+
// Given: A manifest with a prebuild username and workspace name.
2515+
manifest := agentsdk.Manifest{
2516+
OwnerName: "prebuilds",
2517+
WorkspaceName: "prebuilds-xyz-123",
2518+
2519+
Devcontainers: []codersdk.WorkspaceAgentDevcontainer{
2520+
{ID: devcontainerID, Name: "test", WorkspaceFolder: workspaceFolder},
2521+
},
2522+
Scripts: []codersdk.WorkspaceAgentScript{
2523+
{ID: devcontainerID, LogSourceID: devcontainerLogSourceID},
2524+
},
2525+
}
2526+
2527+
// When: We create an agent with devcontainers enabled.
2528+
//nolint:dogsled
2529+
conn, client, _, _, _ := setupAgent(t, manifest, 0, func(_ *agenttest.Client, o *agent.Options) {
2530+
o.Devcontainers = true
2531+
o.DevcontainerAPIOptions = append(o.DevcontainerAPIOptions,
2532+
agentcontainers.WithContainerLabelIncludeFilter(agentcontainers.DevcontainerLocalFolderLabel, workspaceFolder),
2533+
agentcontainers.WithContainerLabelIncludeFilter(agentcontainers.DevcontainerIsTestRunLabel, "true"),
2534+
)
2535+
})
2536+
2537+
testutil.Eventually(ctx, t, func(ctx context.Context) bool {
2538+
return slices.Contains(client.GetLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
2539+
}, testutil.IntervalMedium, "agent not ready")
2540+
2541+
var dcPrebuild codersdk.WorkspaceAgentDevcontainer
2542+
testutil.Eventually(ctx, t, func(ctx context.Context) bool {
2543+
resp, err := conn.ListContainers(ctx)
2544+
require.NoError(t, err)
2545+
2546+
for _, dc := range resp.Devcontainers {
2547+
if dc.Container == nil {
2548+
continue
2549+
}
2550+
2551+
v, ok := dc.Container.Labels[agentcontainers.DevcontainerLocalFolderLabel]
2552+
if ok && v == workspaceFolder {
2553+
dcPrebuild = dc
2554+
return true
2555+
}
2556+
}
2557+
2558+
return false
2559+
}, testutil.IntervalMedium, "devcontainer not found")
2560+
defer func() {
2561+
pool.Client.RemoveContainer(docker.RemoveContainerOptions{
2562+
ID: dcPrebuild.Container.ID,
2563+
RemoveVolumes: true,
2564+
Force: true,
2565+
})
2566+
}()
2567+
2568+
// Then: We expect a sub agent to have been created.
2569+
subAgents := client.GetSubAgents()
2570+
require.Len(t, subAgents, 1)
2571+
2572+
subAgent := subAgents[0]
2573+
subAgentID, err := uuid.FromBytes(subAgent.GetId())
2574+
require.NoError(t, err)
2575+
2576+
// And: We expect there to be 1 app.
2577+
subAgentApps, err := client.GetSubAgentApps(subAgentID)
2578+
require.NoError(t, err)
2579+
require.Len(t, subAgentApps, 1)
2580+
2581+
// And: This app should contain the prebuild workspace name and owner name.
2582+
subAgentApp := subAgentApps[0]
2583+
require.Equal(t, "zed://ssh/project.prebuilds-xyz-123.prebuilds.coder/workspaces/project", subAgentApp.GetUrl())
2584+
2585+
// Given: We close the client and connection
2586+
client.Close()
2587+
conn.Close()
2588+
2589+
// Given: A new manifest with a regular user owner name and workspace name.
2590+
manifest = agentsdk.Manifest{
2591+
OwnerName: "user",
2592+
WorkspaceName: "user-workspace",
2593+
2594+
Devcontainers: []codersdk.WorkspaceAgentDevcontainer{
2595+
{ID: devcontainerID, Name: "test", WorkspaceFolder: workspaceFolder},
2596+
},
2597+
Scripts: []codersdk.WorkspaceAgentScript{
2598+
{ID: devcontainerID, LogSourceID: devcontainerLogSourceID},
2599+
},
2600+
}
2601+
2602+
// When: We create an agent with devcontainers enabled.
2603+
//nolint:dogsled
2604+
conn, client, _, _, _ = setupAgent(t, manifest, 0, func(_ *agenttest.Client, o *agent.Options) {
2605+
o.Devcontainers = true
2606+
o.DevcontainerAPIOptions = append(o.DevcontainerAPIOptions,
2607+
agentcontainers.WithContainerLabelIncludeFilter(agentcontainers.DevcontainerLocalFolderLabel, workspaceFolder),
2608+
agentcontainers.WithContainerLabelIncludeFilter(agentcontainers.DevcontainerIsTestRunLabel, "true"),
2609+
)
2610+
})
2611+
2612+
testutil.Eventually(ctx, t, func(ctx context.Context) bool {
2613+
return slices.Contains(client.GetLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
2614+
}, testutil.IntervalMedium, "agent not ready")
2615+
2616+
var dcClaimed codersdk.WorkspaceAgentDevcontainer
2617+
testutil.Eventually(ctx, t, func(ctx context.Context) bool {
2618+
resp, err := conn.ListContainers(ctx)
2619+
require.NoError(t, err)
2620+
2621+
for _, dc := range resp.Devcontainers {
2622+
if dc.Container == nil {
2623+
continue
2624+
}
2625+
2626+
v, ok := dc.Container.Labels[agentcontainers.DevcontainerLocalFolderLabel]
2627+
if ok && v == workspaceFolder {
2628+
dcClaimed = dc
2629+
return true
2630+
}
2631+
}
2632+
2633+
return false
2634+
}, testutil.IntervalMedium, "devcontainer not found")
2635+
defer func() {
2636+
if dcClaimed.Container.ID != dcPrebuild.Container.ID {
2637+
pool.Client.RemoveContainer(docker.RemoveContainerOptions{
2638+
ID: dcClaimed.Container.ID,
2639+
RemoveVolumes: true,
2640+
Force: true,
2641+
})
2642+
}
2643+
}()
2644+
2645+
// Then: We expect the claimed devcontainer and prebuild devcontainer
2646+
// to be using the same underlying container.
2647+
require.Equal(t, dcPrebuild.Container.ID, dcClaimed.Container.ID)
2648+
2649+
// And: We expect there to be a sub agent created.
2650+
subAgents = client.GetSubAgents()
2651+
require.Len(t, subAgents, 1)
2652+
2653+
subAgent = subAgents[0]
2654+
subAgentID, err = uuid.FromBytes(subAgent.GetId())
2655+
require.NoError(t, err)
2656+
2657+
// And: We expect there to be an app.
2658+
subAgentApps, err = client.GetSubAgentApps(subAgentID)
2659+
require.NoError(t, err)
2660+
require.Len(t, subAgentApps, 1)
2661+
2662+
// And: We expect this app to have the user's owner name and workspace name.
2663+
subAgentApp = subAgentApps[0]
2664+
require.Equal(t, "zed://ssh/project.user-workspace.user.coder/workspaces/project", subAgentApp.GetUrl())
2665+
}
2666+
24612667
func TestAgent_Dial(t *testing.T) {
24622668
t.Parallel()
24632669

0 commit comments

Comments
 (0)