Compare commits

...

6 Commits

Author SHA1 Message Date
Atif Ali 6b9d0d4803 chore: update RDP modules display names, icon and docs (#175) 2025-07-06 11:42:33 +00:00
blink-so[bot] eb27843e4a Add Zed IDE module (#179)
Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Co-authored-by: matifali <10648092+matifali@users.noreply.github.com>
2025-07-03 20:42:33 +00:00
Florian Bittner e95d90d9e8 fix(jetbrains-gateway) add agent id to url (#167)
## Description

<!-- Briefly describe what this PR does and why -->
This PR adds the agent_id parameter to the url so jetbrains-gateway can
handle multiple agents.

---

## Type of Change

- [ ] New module
- [ ] Bug fix
- [x] Feature/enhancement
- [ ] Documentation
- [ ] Other

---

## Testing & Validation

- [x] Tests pass (`bun test`)
- [ ] Code formatted (`bun run fmt`)
- [ ] Changes tested locally

---

## Related Issues

<!-- Link related issues or write "None" if not applicable -->

Closes #166
2025-07-03 22:45:32 +05:00
Atif Ali bd5ad3b3e4 Revert "chore: update RDP modules display names, icon and docs" (#174) 2025-07-03 06:33:31 +02:00
Atif Ali 6537aebb1f chore: update RDP modules display names, icon and docs (#169)
## Description

Use more descriptive names

Depends on coder/coder#https://github.com/coder/coder/pull/18716

---

## Type of Change

- [ ] New module
- [ ] Bug fix
- [ ] Feature/enhancement
- [x] Documentation
- [ ] Other
2025-07-03 06:17:12 +02:00
DevCats 358f47b6ed fix: resolve failing filebrowser tests (#173)
## Description

- Increase timeouts for tests so that they reliably succeed.
- Remove filebrowser admin user creation since noauth is set
- Remove duplicate log declaration in coder_script

---

## Type of Change

- [ ] New module
- [X] Bug fix
- [ ] Feature/enhancement
- [ ] Documentation
- [ ] Other

---

## Module Information

<!-- Delete this section if not applicable -->

**Path:** `registry/[namespace]/modules/filebrowser`  
**New version:** `v1.1.1`  
**Breaking change:** [ ] Yes [X] No

---

## Testing & Validation

- [X] Tests pass (`bun test`)
- [X] Code formatted (`bun run fmt`)
- [X] Changes tested locally

---

## Related 


(https://github.com/coder/registry/actions/runs/15975017391/job/45055105439?pr=160)
2025-07-02 23:04:11 -05:00
27 changed files with 326 additions and 92 deletions
+35
View File
@@ -0,0 +1,35 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" fill="none" viewBox="0 0 512 512">
<g transform="translate(256 256)scale(8.96)">
<linearGradient id="a" x1="6.221" x2="37.408" y1="6.221" y2="37.408" gradientUnits="userSpaceOnUse">
<stop offset="0%" style="stop-color:#f0f0f0;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#bbc1c4;stop-opacity:1"/>
</linearGradient>
<path d="M24 5C13.507 5 5 13.507 5 24s8.507 19 19 19 19-8.507 19-19S34.493 5 24 5" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:url(#a);fill-rule:nonzero;opacity:1" transform="translate(-24 -24)"/>
</g>
<g transform="translate(256 256)scale(8.96)">
<linearGradient id="b" x1="12.859" x2="35.224" y1="12.859" y2="35.224" gradientUnits="userSpaceOnUse">
<stop offset="0%" style="stop-color:#e04f12;stop-opacity:1"/>
<stop offset="61.5%" style="stop-color:#ce400d;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#c03409;stop-opacity:1"/>
</linearGradient>
<path d="M24 40c8.837 0 16-7.163 16-16S32.837 8 24 8 8 15.163 8 24s7.163 16 16 16" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:url(#b);fill-rule:nonzero;opacity:1" transform="translate(-24 -24)"/>
</g>
<path d="m30.414 20 3.89-3.89c.708-.708.449-1.772 0-2.221l-2.195-2.195a1.573 1.573 0 0 0-2.218.001l-7.194 7.194c-.549.549-.752 1.469-.001 2.22l7.196 7.196c.76.76 1.592.625 2.218-.001l2.194-2.194c.707-.707.716-1.505.001-2.22z" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:#000;fill-rule:nonzero;opacity:.05" transform="translate(40.96 40.96)scale(8.96)"/>
<path d="m33.951 14.244-2.195-2.195a1.07 1.07 0 0 0-1.511 0l-7.195 7.195c-.386.386-.487 1.025 0 1.512l7.196 7.196c.491.491 1.087.424 1.511 0l2.195-2.195c.464-.464.469-1.044 0-1.512L29.707 20l4.244-4.244c.465-.465.335-1.177 0-1.512" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:#000;fill-rule:nonzero;opacity:.07" transform="translate(40.96 40.96)scale(8.96)"/>
<path d="m17.586 28-3.89 3.89c-.708.708-.449 1.772 0 2.221l2.195 2.195c.611.609 1.606.61 2.218-.001l7.194-7.194c.549-.549.752-1.469.001-2.22l-7.196-7.196c-.76-.76-1.592-.625-2.218.001l-2.194 2.194c-.707.707-.716 1.505-.001 2.22z" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:#000;fill-rule:nonzero;opacity:.05" transform="translate(40.96 40.96)scale(8.96)"/>
<path d="m14.049 33.756 2.195 2.195a1.07 1.07 0 0 0 1.511 0l7.195-7.195c.386-.386.487-1.025 0-1.512l-7.196-7.196c-.491-.491-1.087-.424-1.511 0l-2.195 2.195c-.464.464-.469 1.044 0 1.512L18.293 28l-4.244 4.244c-.465.465-.335 1.177 0 1.512" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:#000;fill-rule:nonzero;opacity:.07" transform="translate(40.96 40.96)scale(8.96)"/>
<g transform="translate(296.83 220.16)scale(8.96)">
<linearGradient id="c" x1="23.755" x2="38.564" y1="9.93" y2="33.557" gradientUnits="userSpaceOnUse">
<stop offset="0%" style="stop-color:#fcfcfc;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#c3c9cd;stop-opacity:1"/>
</linearGradient>
<path d="m33.598 14.598-2.196-2.196a.57.57 0 0 0-.804 0l-7.196 7.196a.57.57 0 0 0 0 .804l7.196 7.196a.57.57 0 0 0 .804 0l2.196-2.196a.57.57 0 0 0 0-.804L29 20l4.598-4.598a.57.57 0 0 0 0-.804" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:url(#c);fill-rule:nonzero;opacity:1" transform="translate(-28.5 -20)"/>
</g>
<g transform="translate(215.17 291.84)scale(8.96)">
<linearGradient id="d" x1="11.438" x2="26.247" y1="17.637" y2="41.265" gradientUnits="userSpaceOnUse">
<stop offset="0%" style="stop-color:#fcfcfc;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#c3c9cd;stop-opacity:1"/>
</linearGradient>
<path d="M14.402 23.402 19 28l-4.598 4.598a.57.57 0 0 0 0 .804l2.196 2.196a.57.57 0 0 0 .804 0l7.196-7.196a.57.57 0 0 0 0-.804l-7.196-7.196a.57.57 0 0 0-.804 0l-2.196 2.196a.57.57 0 0 0 0 .804" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:url(#d);fill-rule:nonzero;opacity:1" transform="translate(-19.5 -28)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="90" viewBox="0 0 90 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.4375 5.625C6.8842 5.625 5.625 6.8842 5.625 8.4375V70.3125H0V8.4375C0 3.7776 3.7776 0 8.4375 0H83.7925C87.551 0 89.4333 4.5442 86.7756 7.20186L40.3642 53.6133H53.4375V47.8125H59.0625V55.0195C59.0625 57.3495 57.1737 59.2383 54.8438 59.2383H34.7392L25.0712 68.9062H68.9062V33.75H74.5312V68.9062C74.5312 72.0128 72.0128 74.5312 68.9062 74.5312H19.4462L9.60248 84.375H81.5625C83.1158 84.375 84.375 83.1158 84.375 81.5625V19.6875H90V81.5625C90 86.2224 86.2224 90 81.5625 90H6.20749C2.44898 90 0.566723 85.4558 3.22438 82.7981L49.46 36.5625H36.5625V42.1875H30.9375V35.1562C30.9375 32.8263 32.8263 30.9375 35.1562 30.9375H55.085L64.9288 21.0938H21.0938V56.25H15.4688V21.0938C15.4688 17.9871 17.9871 15.4688 21.0938 15.4688H70.5538L80.3975 5.625H8.4375Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 904 B

+3 -7
View File
@@ -14,9 +14,7 @@ brew install go
sudo apt install golang-go
```
## Daily Tasks
### Review PRs
## Reviewing a PR
Check that PRs have:
@@ -26,7 +24,7 @@ Check that PRs have:
- [ ] Formatted code (`bun run fmt`)
- [ ] Avatar image for new namespaces (`avatar.png` or `avatar.svg` in `.images/`)
#### Version Guidelines
### Version Guidelines
When reviewing PRs, ensure the version change follows semantic versioning:
@@ -42,7 +40,7 @@ PRs should clearly indicate the version change (e.g., `v1.2.3 → v1.2.4`).
go build ./cmd/readmevalidation && ./readmevalidation
```
## Releases
## Making a Release
### Create Release Tags
@@ -99,5 +97,3 @@ status: "community" # or "partner", "official"
- **Tests fail**: Ensure Docker with `--network=host`, check Terraform syntax
- **Wrong file structure**: Use `./scripts/new_module.sh` for new modules
- **Missing namespace avatar**: Must be `avatar.png` or `avatar.svg` in `.images/` directory
That's it. Keep it simple.
BIN
View File
Binary file not shown.
+7 -7
View File
@@ -8,16 +8,16 @@
"update-version": "./update-version.sh"
},
"devDependencies": {
"@types/bun": "^1.2.9",
"bun-types": "^1.1.23",
"@types/bun": "^1.2.18",
"bun-types": "^1.2.18",
"gray-matter": "^4.0.3",
"marked": "^12.0.2",
"prettier": "^3.3.3",
"prettier-plugin-sh": "^0.13.1",
"marked": "^16.0.0",
"prettier": "^3.6.2",
"prettier-plugin-sh": "^0.18.0",
"prettier-plugin-terraform-formatter": "^1.2.1"
},
"peerDependencies": {
"typescript": "^5.5.4"
"typescript": "^5.8.3"
},
"prettier": {
"plugins": [
@@ -25,4 +25,4 @@
"prettier-plugin-terraform-formatter"
]
}
}
}
+4 -4
View File
@@ -15,7 +15,7 @@ A file browser for your workspace.
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/filebrowser/coder"
version = "1.1.0"
version = "1.1.1"
agent_id = coder_agent.example.id
}
```
@@ -30,7 +30,7 @@ module "filebrowser" {
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/filebrowser/coder"
version = "1.1.0"
version = "1.1.1"
agent_id = coder_agent.example.id
folder = "/home/coder/project"
}
@@ -42,7 +42,7 @@ module "filebrowser" {
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/filebrowser/coder"
version = "1.1.0"
version = "1.1.1"
agent_id = coder_agent.example.id
database_path = ".config/filebrowser.db"
}
@@ -54,7 +54,7 @@ module "filebrowser" {
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/filebrowser/coder"
version = "1.1.0"
version = "1.1.1"
agent_id = coder_agent.example.id
agent_name = "main"
subdomain = false
@@ -55,7 +55,7 @@ describe("filebrowser", async () => {
);
testBaseLine(output);
});
}, 15000);
it("runs with database_path var", async () => {
const state = await runTerraformApply(import.meta.dir, {
@@ -63,7 +63,7 @@ describe("filebrowser", async () => {
database_path: ".config/filebrowser.db",
});
const output = await await executeScriptInContainer(
const output = await executeScriptInContainer(
state,
"alpine/curl",
"sh",
@@ -71,20 +71,21 @@ describe("filebrowser", async () => {
);
testBaseLine(output);
});
}, 15000);
it("runs with folder var", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
folder: "/home/coder/project",
});
const output = await await executeScriptInContainer(
const output = await executeScriptInContainer(
state,
"alpine/curl",
"sh",
"apk add bash",
);
});
}, 15000);
it("runs with subdomain=false", async () => {
const state = await runTerraformApply(import.meta.dir, {
@@ -93,7 +94,7 @@ describe("filebrowser", async () => {
subdomain: false,
});
const output = await await executeScriptInContainer(
const output = await executeScriptInContainer(
state,
"alpine/curl",
"sh",
@@ -101,5 +102,5 @@ describe("filebrowser", async () => {
);
testBaseLine(output);
});
}, 15000);
});
+1 -1
View File
@@ -97,7 +97,6 @@ resource "coder_script" "filebrowser" {
LOG_PATH : var.log_path,
PORT : var.port,
FOLDER : var.folder,
LOG_PATH : var.log_path,
DB_PATH : var.database_path,
SUBDOMAIN : var.subdomain,
SERVER_BASE_PATH : local.server_base_path
@@ -128,3 +127,4 @@ locals {
url = "http://localhost:${var.port}${local.server_base_path}"
healthcheck_url = "http://localhost:${var.port}${local.server_base_path}/health"
}
+1 -1
View File
@@ -25,7 +25,7 @@ export FB_DATABASE="${DB_PATH}"
# Check if filebrowser db exists
if [[ ! -f "${DB_PATH}" ]]; then
filebrowser config init 2>&1 | tee -a ${LOG_PATH}
filebrowser users add admin "" --perm.admin=true --viewMode=mosaic 2>&1 | tee -a ${LOG_PATH}
filebrowser users add admin "coderPASSWORD" --perm.admin=true --viewMode=mosaic 2>&1 | tee -a ${LOG_PATH}
fi
filebrowser config set --baseurl=${SERVER_BASE_PATH} --port=${PORT} --auth.method=noauth --root=$ROOT_DIR 2>&1 | tee -a ${LOG_PATH}
@@ -18,7 +18,7 @@ Consult the [JetBrains documentation](https://www.jetbrains.com/help/idea/prereq
module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jetbrains-gateway/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = coder_agent.example.id
folder = "/home/coder/example"
jetbrains_ides = ["CL", "GO", "IU", "PY", "WS"]
@@ -36,7 +36,7 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jetbrains-gateway/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = coder_agent.example.id
folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"]
@@ -50,7 +50,7 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jetbrains-gateway/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = coder_agent.example.id
folder = "/home/coder/example"
jetbrains_ides = ["IU", "PY"]
@@ -65,7 +65,7 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jetbrains-gateway/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = coder_agent.example.id
folder = "/home/coder/example"
jetbrains_ides = ["IU", "PY"]
@@ -90,7 +90,7 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jetbrains-gateway/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = coder_agent.example.id
folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"]
@@ -108,7 +108,7 @@ Due to the highest priority of the `ide_download_link` parameter in the `(jetbra
module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jetbrains-gateway/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = coder_agent.example.id
folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"]
@@ -20,7 +20,7 @@ describe("jetbrains-gateway", async () => {
folder: "/home/coder",
});
expect(state.outputs.url.value).toBe(
"jetbrains-gateway://connect#type=coder&workspace=default&owner=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz",
"jetbrains-gateway://connect#type=coder&workspace=default&owner=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz&agent_id=foo",
);
const coder_app = state.resources.find(
@@ -348,6 +348,8 @@ resource "coder_app" "gateway" {
local.build_number,
"&ide_download_link=",
local.download_link,
"&agent_id=",
var.agent_id,
])
}
@@ -1,24 +1,25 @@
---
display_name: Windows RDP Desktop
display_name: RDP Desktop
description: Enable RDP on Windows and add a one-click Coder Desktop button for seamless access
icon: ../../../../.icons/desktop.svg
icon: ../../../../.icons/rdp.svg
maintainer_github: coder
verified: true
supported_os: [windows]
tags: [rdp, windows, desktop, remote]
tags: [rdp, windows, desktop, local]
---
# Windows RDP Desktop
This module enables Remote Desktop Protocol (RDP) on Windows workspaces and adds a one-click button to launch RDP sessions directly through [Coder Desktop](https://coder.com/docs/user-guides/desktop). It provides a complete, standalone solution for RDP access, eliminating the need for manual configuration or port forwarding through the Coder CLI.
> **Note**: [Coder Desktop](https://coder.com/docs/user-guides/desktop) is required on client devices to use the Local Windows RDP access feature.
> [!NOTE]
> [Coder Desktop](https://coder.com/docs/user-guides/desktop) is required on client devices to use the Local Windows RDP access feature.
```tf
module "rdp_desktop" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/local-windows-rdp/coder"
version = "1.0.0"
version = "1.0.1"
agent_id = coder_agent.main.id
agent_name = coder_agent.main.name
}
@@ -51,7 +52,7 @@ Uses default credentials (Username: `Administrator`, Password: `coderRDP!`):
module "rdp_desktop" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/local-windows-rdp/coder"
version = "1.0.0"
version = "1.0.1"
agent_id = coder_agent.main.id
agent_name = coder_agent.main.name
}
@@ -65,7 +66,7 @@ Specify a custom display name for the `coder_app` button:
module "rdp_desktop" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/local-windows-rdp/coder"
version = "1.0.0"
version = "1.0.1"
agent_id = coder_agent.windows.id
agent_name = "windows"
display_name = "Windows Desktop"
@@ -73,7 +73,7 @@ describe("local-windows-rdp", async () => {
expect(app).not.toBeNull();
expect(app?.slug).toBe("rdp-desktop");
expect(app?.display_name).toBe("RDP Desktop");
expect(app?.icon).toBe("/icon/desktop.svg");
expect(app?.icon).toBe("/icon/rdp.svg");
expect(app?.external).toBe(true);
// Verify the URI format
@@ -95,7 +95,7 @@ describe("local-windows-rdp", async () => {
// Verify the script was created
expect(script).not.toBeNull();
expect(script?.display_name).toBe("Configure RDP");
expect(script?.icon).toBe("/icon/desktop.svg");
expect(script?.icon).toBe("/icon/rdp.svg");
expect(script?.run_on_start).toBe(true);
expect(script?.run_on_stop).toBe(false);
@@ -60,7 +60,7 @@ data "coder_workspace" "me" {}
resource "coder_script" "rdp_setup" {
agent_id = var.agent_id
display_name = "Configure RDP"
icon = "/icon/desktop.svg"
icon = "/icon/rdp.svg"
script = templatefile("${path.module}/configure-rdp.ps1", {
username = var.username
password = var.password
@@ -73,9 +73,8 @@ resource "coder_app" "rdp_desktop" {
slug = "rdp-desktop"
display_name = var.display_name
url = "coder://${local.server_name}/v0/open/ws/${data.coder_workspace.me.name}/agent/${var.agent_name}/rdp?username=${var.username}&password=${var.password}"
icon = "/icon/desktop.svg"
icon = "/icon/rdp.svg"
external = true
order = var.order
group = var.group
}
+15 -23
View File
@@ -1,5 +1,5 @@
---
display_name: Windows RDP
display_name: RDP Web
description: RDP Server and Web Client, powered by Devolutions Gateway
icon: ../../../../.icons/desktop.svg
maintainer_github: coder
@@ -14,11 +14,10 @@ Enable Remote Desktop + a web based client on Windows workspaces, powered by [de
```tf
# AWS example. See below for examples of using this module with other providers
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.1"
agent_id = resource.coder_agent.main.id
resource_id = resource.aws_instance.dev.id
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.2"
agent_id = resource.coder_agent.main.id
}
```
@@ -32,11 +31,10 @@ module "windows_rdp" {
```tf
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.1"
agent_id = resource.coder_agent.main.id
resource_id = resource.aws_instance.dev.id
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.2"
agent_id = resource.coder_agent.main.id
}
```
@@ -44,11 +42,10 @@ module "windows_rdp" {
```tf
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.1"
agent_id = resource.coder_agent.main.id
resource_id = resource.google_compute_instance.dev[0].id
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.2"
agent_id = resource.coder_agent.main.id
}
```
@@ -58,13 +55,8 @@ module "windows_rdp" {
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.1"
version = "1.2.2"
agent_id = resource.coder_agent.main.id
resource_id = resource.aws_instance.dev.id
devolutions_gateway_version = "2025.1.6" # Specify a specific version
devolutions_gateway_version = "2025.2.2" # Specify a specific version
}
```
## Roadmap
- [ ] Test on Microsoft Azure.
@@ -8,7 +8,6 @@ import {
type TestVariables = Readonly<{
agent_id: string;
resource_id: string;
share?: string;
admin_username?: string;
admin_password?: string;
@@ -45,13 +44,11 @@ describe("Web RDP", async () => {
await runTerraformInit(import.meta.dir);
testRequiredVariables<TestVariables>(import.meta.dir, {
agent_id: "foo",
resource_id: "bar",
});
it("Has the PowerShell script install Devolutions Gateway", async () => {
const state = await runTerraformApply<TestVariables>(import.meta.dir, {
agent_id: "foo",
resource_id: "bar",
});
const lines = findWindowsRdpScript(state)
@@ -96,7 +93,6 @@ describe("Web RDP", async () => {
import.meta.dir,
{
agent_id: "foo",
resource_id: "bar",
},
);
@@ -116,7 +112,6 @@ describe("Web RDP", async () => {
import.meta.dir,
{
agent_id: "foo",
resource_id: "bar",
admin_username: customAdminUsername,
admin_password: customAdminPassword,
},
+5 -10
View File
@@ -4,7 +4,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = ">= 0.17"
version = ">= 2.5"
}
}
}
@@ -35,11 +35,6 @@ variable "agent_id" {
description = "The ID of a Coder agent."
}
variable "resource_id" {
type = string
description = "The ID of the primary Coder resource (e.g. VM)."
}
variable "admin_username" {
type = string
default = "Administrator"
@@ -53,14 +48,14 @@ variable "admin_password" {
variable "devolutions_gateway_version" {
type = string
default = "2025.2.1"
default = "2025.2.2"
description = "Version of Devolutions Gateway to install. Defaults to the latest available version."
}
resource "coder_script" "windows-rdp" {
agent_id = var.agent_id
display_name = "windows-rdp"
icon = "/icon/desktop.svg"
icon = "/icon/rdp.svg"
script = templatefile("${path.module}/powershell-installation-script.tftpl", {
admin_username = var.admin_username
@@ -101,7 +96,7 @@ resource "coder_app" "rdp-docs" {
agent_id = var.agent_id
display_name = "Local RDP Docs"
slug = "rdp-docs"
icon = "https://raw.githubusercontent.com/matifali/logos/main/windows.svg"
url = "https://coder.com/docs/ides/remote-desktops#rdp-desktop"
icon = "/icon/windows.svg"
url = "https://coder.com/docs/user-guides/workspace-access/remote-desktops#rdp"
external = true
}
+65
View File
@@ -0,0 +1,65 @@
---
display_name: Zed
description: Add a one-click button to launch Zed
icon: ../../../../.icons/zed.svg
maintainer_github: coder
verified: true
tags: [ide, zed, editor]
---
# Zed
Add a button to open any workspace with a single click in Zed.
Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
> [!IMPORTANT]
> Zed needs you to either have Coder CLI installed with `coder config-ssh` run or [Coder Desktop](https://coder.com/docs/user-guides/desktop)
```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
}
```
## Examples
### Open in a specific directory
```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
folder = "/home/coder/project"
}
```
### Custom display name and order
```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
display_name = "Zed Editor"
order = 1
}
```
### With custom agent name
```tf
module "zed" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/zed/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
agent_name = coder_agent.example.name
}
```
+81
View File
@@ -0,0 +1,81 @@
import { describe, expect, it } from "bun:test";
import {
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "~test";
describe("zed", async () => {
await runTerraformInit(import.meta.dir);
testRequiredVariables(import.meta.dir, {
agent_id: "foo",
});
it("default output", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
});
expect(state.outputs.zed_url.value).toBe(
"zed://ssh/default.coder",
);
const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "zed",
);
expect(coder_app).not.toBeNull();
expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.order).toBeNull();
});
it("adds folder", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
folder: "/foo/bar",
});
expect(state.outputs.zed_url.value).toBe(
"zed://ssh/default.coder/foo/bar",
);
});
it("expect order to be set", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
order: "22",
});
const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "zed",
);
expect(coder_app).not.toBeNull();
expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.order).toBe(22);
});
it("expect display_name to be set", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
display_name: "Custom Zed",
});
const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "zed",
);
expect(coder_app).not.toBeNull();
expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.display_name).toBe("Custom Zed");
});
it("adds agent_name to hostname", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
agent_name: "myagent",
});
expect(state.outputs.zed_url.value).toBe(
"zed://ssh/myagent.default.default.coder",
);
});
});
+77
View File
@@ -0,0 +1,77 @@
terraform {
required_version = ">= 1.0"
required_providers {
coder = {
source = "coder/coder"
version = ">= 2.5"
}
}
}
variable "agent_id" {
type = string
description = "The ID of a Coder agent"
}
variable "agent_name" {
type = string
description = "The name of the agent"
default = ""
}
variable "folder" {
type = string
description = "The folder to open in Zed"
default = ""
}
variable "order" {
type = number
description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)"
default = null
}
variable "group" {
type = string
description = "The name of a group that this app belongs to"
default = null
}
variable "slug" {
type = string
description = "The slug of the app"
default = "zed"
}
variable "display_name" {
type = string
description = "The display name of the app"
default = "Zed"
}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
locals {
workspace_name = lower(data.coder_workspace.me.name)
owner_name = lower(data.coder_workspace_owner.me.name)
agent_name = lower(var.agent_name)
hostname = var.agent_name != "" ? "${local.agent_name}.${local.workspace_name}.${local.owner_name}.coder" : "${local.workspace_name}.coder"
}
resource "coder_app" "zed" {
agent_id = var.agent_id
display_name = var.display_name
slug = var.slug
icon = "/icon/zed.svg"
external = true
order = var.order
group = var.group
url = "zed://ssh/${local.hostname}${var.folder}"
}
output "zed_url" {
value = coder_app.zed.url
description = "Zed URL"
}
@@ -20,16 +20,13 @@ To deploy workspaces as DigitalOcean Droplets, you'll need:
- DigitalOcean [personal access token (PAT)](https://docs.digitalocean.com/reference/api/create-personal-access-token)
- DigitalOcean project ID (you can get your project information via the `doctl` CLI by running `doctl projects list`)
- Remove the following sections from the `main.tf` file if you don't want to
associate your workspaces with a project:
- `variable "project_uuid"`
- `resource "digitalocean_project_resources" "project"`
- **Optional:** DigitalOcean SSH key ID (obtain via the `doctl` CLI by running
`doctl compute ssh-key list`)
- Note that this is only required for Fedora images to work.
### Authentication
@@ -34,7 +34,6 @@ a service account:
1. Click **Create and continue**, and choose the following IAM roles to grant to
the service account:
- Compute Admin
- Service Account User
@@ -32,7 +32,6 @@ a service account:
1. Click **Create and continue**, and choose the following IAM roles to grant to
the service account:
- Compute Admin
- Service Account User
@@ -32,7 +32,6 @@ a service account:
1. Click **Create and continue**, and choose the following IAM roles to grant to
the service account:
- Compute Admin
- Service Account User
@@ -32,7 +32,6 @@ a service account:
1. Click **Create and continue**, and choose the following IAM roles to grant to
the service account:
- Compute Admin
- Service Account User
-1
View File
@@ -15,7 +15,6 @@ Develop in an Incus System Container and run nested Docker containers using Incu
1. Install [Incus](https://linuxcontainers.org/incus/) on the same machine as Coder.
2. Allow Coder to access the Incus socket.
- If you're running Coder as system service, run `sudo usermod -aG incus-admin coder` and restart the Coder service.
- If you're running Coder as a Docker Compose service, get the group ID of the `incus-admin` group by running `getent group incus-admin` and add the following to your `compose.yaml` file: