Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions registry/coder/modules/code-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Automatically install [code-server](https://github.com/coder/code-server) in a w
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
}
```
Expand All @@ -29,7 +29,7 @@ module "code-server" {
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
install_version = "4.106.3"
}
Expand All @@ -43,7 +43,7 @@ Install the Dracula theme from [OpenVSX](https://open-vsx.org/):
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
extensions = [
"dracula-theme.theme-dracula"
Expand All @@ -61,7 +61,7 @@ Configure VS Code's [User settings.json](https://code.visualstudio.com/docs/gets
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
extensions = ["dracula-theme.theme-dracula"]
settings = {
Expand All @@ -81,7 +81,7 @@ Install multiple extensions from [OpenVSX](https://open-vsx.org/) by adding them
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
}
Expand All @@ -95,7 +95,7 @@ Open a [`.code-workspace`](https://coder.com/docs/code-server/FAQ#how-does-code-
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
workspace = "/home/coder/project/my.code-workspace"
}
Expand All @@ -109,7 +109,7 @@ You can pass additional command-line arguments to code-server using the `additio
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
additional_args = "--disable-workspace-trust"
}
Expand All @@ -125,7 +125,7 @@ Run an existing copy of code-server if found, otherwise download from GitHub:
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
use_cached = true
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
Expand All @@ -138,7 +138,7 @@ Just run code-server in the background, don't fetch it from GitHub:
module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "1.5.1"
version = "1.6.0"
agent_id = coder_agent.example.id
offline = true
}
Expand Down
33 changes: 33 additions & 0 deletions registry/coder/modules/code-server/code-server.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,36 @@ run "workspace_extension_rejected" {
}
expect_failures = [var.workspace]
}

run "debug_flag_enabled" {
command = plan

variables {
agent_id = "foo"
debug = true
}
}

run "overwrite_settings_flags" {
command = plan

variables {
agent_id = "foo"
overwrite_settings = true
overwrite_machine_settings = true
}
}

run "settings_jsonencode_with_interpolation" {
command = plan

variables {
agent_id = "foo"
settings = {
"window.title" = "My Window"
}
machine_settings = {
"git.blame.editorDecoration.template" = "$${authorName}"
}
}
}
21 changes: 21 additions & 0 deletions registry/coder/modules/code-server/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,24 @@ variable "settings" {
default = {}
}

variable "overwrite_settings" {
type = bool
description = "If true, overwrites the User settings.json instead of attempting to merge."
default = false
}

variable "machine_settings" {
type = any
description = "A map of template level machine settings to apply to code-server. These settings are merged with any existing machine settings on startup."
default = {}
}

variable "overwrite_machine_settings" {
type = bool
description = "If true, overwrites the Machine settings.json instead of attempting to merge."
default = false
}

variable "folder" {
type = string
description = "The folder to open in code-server."
Expand Down Expand Up @@ -167,6 +179,12 @@ variable "additional_args" {
default = ""
}

variable "debug" {
type = bool
description = "Enable debug mode for the code-server startup script, which dynamically runs set -x."
default = false
}

locals {
settings_b64 = var.settings != {} ? base64encode(jsonencode(var.settings)) : ""
machine_settings_b64 = var.machine_settings != {} ? base64encode(jsonencode(var.machine_settings)) : ""
Expand All @@ -184,7 +202,9 @@ resource "coder_script" "code-server" {
LOG_PATH : var.log_path,
INSTALL_PREFIX : var.install_prefix,
SETTINGS_B64 : local.settings_b64,
OVERWRITE_SETTINGS : var.overwrite_settings,
MACHINE_SETTINGS_B64 : local.machine_settings_b64,
OVERWRITE_MACHINE_SETTINGS : var.overwrite_machine_settings,
OFFLINE : var.offline,
USE_CACHED : var.use_cached,
USE_CACHED_EXTENSIONS : var.use_cached_extensions,
Expand All @@ -193,6 +213,7 @@ resource "coder_script" "code-server" {
WORKSPACE : var.workspace,
AUTO_INSTALL_EXTENSIONS : var.auto_install_extensions,
ADDITIONAL_ARGS : var.additional_args,
DEBUG : var.debug,
})
run_on_start = true

Expand Down
93 changes: 68 additions & 25 deletions registry/coder/modules/code-server/run.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/usr/bin/env bash

# Enable debug mode dynamically if the flag is true
if [ "${DEBUG}" = true ]; then
set -x
fi

EXTENSIONS=("${EXTENSIONS}")
BOLD='\033[0;1m'
CODE='\033[36;40;1m'
Expand All @@ -19,61 +24,99 @@ function run_code_server() {
$CODE_SERVER "$EXTENSION_ARG" --auth none --port "${PORT}" --app-name "${APP_NAME}" ${ADDITIONAL_ARGS} > "${LOG_PATH}" 2>&1 &
}

# Merge settings from module with existing settings file
merge_settings() {
# Merge, validate, save, and format settings.json
save_settings() {
local new_settings="$1"
local settings_file="$2"
local overwrite="$3"

if [ -z "$new_settings" ] || [ "$new_settings" = "{}" ]; then
return 0
fi

if [ ! -f "$settings_file" ]; then
mkdir -p "$(dirname "$settings_file")"
printf '%s\n' "$new_settings" > "$settings_file"
printf "⚙️ Creating settings file...\n"
return 0
local tool=""
if command -v jq > /dev/null 2>&1; then
tool="jq"
elif command -v python3 > /dev/null 2>&1; then
tool="python3"
fi

mkdir -p "$(dirname "$settings_file")"
local tmpfile
tmpfile="$(mktemp)"

if command -v jq > /dev/null 2>&1; then
if jq -s '.[0] * .[1]' "$settings_file" <(printf '%s\n' "$new_settings") > "$tmpfile" 2> /dev/null; then
mv "$tmpfile" "$settings_file"
printf "⚙️ Merging settings...\n"
return 0
# Create or Replace settings.json
if [ ! -f "$settings_file" ] || [ "$overwrite" = "true" ]; then
if [ "$tool" = "jq" ]; then
jq . <(printf '%s' "$new_settings") > "$tmpfile" 2> /dev/null || printf '%s\n' "$new_settings" > "$tmpfile"
elif [ "$tool" = "python3" ]; then
python3 -c "import json,sys; print(json.dumps(json.loads(sys.argv[1]), indent=2))" "$new_settings" > "$tmpfile" 2> /dev/null || printf '%s\n' "$new_settings" > "$tmpfile"
else
printf '%s\n' "$new_settings" > "$tmpfile"
fi
mv "$tmpfile" "$settings_file"
printf "⚙️ Creating or replacing settings file...\n"
return 0
fi

if command -v python3 > /dev/null 2>&1; then
if python3 -c "import json,sys;m=lambda a,b:{**a,**{k:m(a[k],v)if k in a and type(a[k])==type(v)==dict else v for k,v in b.items()}};print(json.dumps(m(json.load(open(sys.argv[1])),json.loads(sys.argv[2])),indent=2))" "$settings_file" "$new_settings" > "$tmpfile" 2> /dev/null; then
mv "$tmpfile" "$settings_file"
printf "⚙️ Merging settings...\n"
return 0
fi
# Check if required tooling exists to facilitate the merge
if [ -z "$tool" ]; then
rm -f "$tmpfile"
printf "Warning: Could not merge settings (jq or python3 required). Keeping existing settings.\n"
return 0
fi

# Validate existing JSON
local is_valid=0
if [ "$tool" = "jq" ]; then
jq empty "$settings_file" > /dev/null 2>&1 || is_valid=1
else
python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$settings_file" > /dev/null 2>&1 || is_valid=1
fi

if [ $is_valid -ne 0 ]; then
rm -f "$tmpfile"
printf "❌ Error: Existing settings file %s contains invalid JSON.\n" "$settings_file"
return 1
fi

# Merge to temp settings.json
local merge_success=0
if [ "$tool" = "jq" ]; then
jq -s '.[0] * .[1]' "$settings_file" <(printf '%s\n' "$new_settings") > "$tmpfile" 2> /dev/null || merge_success=1
else
python3 -c "import json,sys;m=lambda a,b:{**a,**{k:m(a[k],v)if k in a and type(a[k])==type(v)==dict else v for k,v in b.items()}};print(json.dumps(m(json.load(open(sys.argv[1])),json.loads(sys.argv[2])),indent=2))" "$settings_file" "$new_settings" > "$tmpfile" 2> /dev/null || merge_success=1
fi

rm -f "$tmpfile"
printf "Warning: Could not merge settings (jq or python3 required). Keeping existing settings.\n"
return 0
# Update settings.json with the newly merged configuration
if [ $merge_success -eq 0 ]; then
mv "$tmpfile" "$settings_file"
printf "⚙️ Merging settings...\n"
return 0
else
rm -f "$tmpfile"
printf "❌ Error: %s failed to write the new settings file %s.\n" "$tool" "$settings_file"
return 1
fi
}

# Apply user settings (merge with existing if present)
# Apply user settings (merge or overwrite based on flag)
SETTINGS_B64='${SETTINGS_B64}'
if [ -n "$SETTINGS_B64" ]; then
if SETTINGS_JSON="$(echo -n "$SETTINGS_B64" | base64 -d 2> /dev/null)" && [ -n "$SETTINGS_JSON" ]; then
merge_settings "$SETTINGS_JSON" ~/.local/share/code-server/User/settings.json
# Return 1 triggers exit 1 to halt execution if validation fails
save_settings "$SETTINGS_JSON" ~/.local/share/code-server/User/settings.json "${OVERWRITE_SETTINGS}" || exit 1
else
printf "Warning: Failed to decode settings. Skipping settings configuration.\n"
fi
fi

# Apply machine settings (merge with existing if present)
# Apply machine settings (merge or overwrite based on flag)
MACHINE_SETTINGS_B64='${MACHINE_SETTINGS_B64}'
if [ -n "$MACHINE_SETTINGS_B64" ]; then
if MACHINE_SETTINGS_JSON="$(echo -n "$MACHINE_SETTINGS_B64" | base64 -d 2> /dev/null)" && [ -n "$MACHINE_SETTINGS_JSON" ]; then
merge_settings "$MACHINE_SETTINGS_JSON" ~/.local/share/code-server/Machine/settings.json
# Return 1 triggers exit 1 to halt execution if validation fails
save_settings "$MACHINE_SETTINGS_JSON" ~/.local/share/code-server/Machine/settings.json "${OVERWRITE_MACHINE_SETTINGS}" || exit 1
else
printf "Warning: Failed to decode machine settings. Skipping machine settings configuration.\n"
fi
Expand Down
Loading