Compare commits

...

11 Commits

Author SHA1 Message Date
Muhammad Atif Ali
92097e398d Update KasmVNC user group and config settings
- Use `usermod` to add user to ssl-cert group for compatibility.
- Simplify KasmVNC config with protocol and SSL parameters.
- Ensure UDP communication is confined to localhost for security.
2024-10-24 19:49:11 +05:00
Muhammad Atif Ali
e4a57f4a6a Update KasmVNC with custom image config steps
Add instructions for extending kasmtech custom images and modify the
run script to attempt system-wide config creation, ensuring flexibility
for environments without sudo access.
2024-10-24 12:58:20 +05:00
Muhammad Atif Ali
66b0bf6d27 Fix user group command in KasmVNC installation script 2024-10-24 12:00:48 +05:00
Muhammad Atif Ali
f6ebe73aea Simplify VNC server installation and config setup
- Streamlined the installation script's messaging for clarity.
- Added default SSL certificate path in the config.
2024-10-24 10:20:07 +05:00
Muhammad Atif Ali
2e0f3eddc0 Simplify config file creation in kasmvnc script 2024-10-23 21:18:56 +05:00
Muhammad Atif Ali
f63b460971 Enhance kasmvnc to simplify user permissions management 2024-10-23 21:07:33 +05:00
Muhammad Atif Ali
df507ca559 feat(kasmvnc): support images without sudo access
- Allow KasmVNC to be installed and run on systems where `sudo` is not available.
- Automatically adjust config file location and server start method based on `sudo` availability.
- Enhance portability for broader usage across various environments.
2024-10-23 20:12:08 +05:00
Steven Masley
ce5a5b383a feat(vscode-web): support hosting on a subpath with subdomain=false (#288)
Co-authored-by: Muhammad Atif Ali <atif@coder.com>
Co-authored-by: Muhammad Atif Ali <me@matifali.dev>
2024-10-21 13:46:19 +05:00
framctr
1b147ae90d feat(jupyterlab): add support for subdomain=false (#316)
Co-authored-by: Muhammad Atif Ali <atif@coder.com>
Co-authored-by: Asher <ash@coder.com>
2024-10-21 12:06:10 +05:00
djarbz
7992d9d265 fix(kasmVNC): fix debian installation and improve logging (#326) 2024-10-21 08:04:59 +05:00
Yves ANDOLFATTO
20d97a25dd fix(filebrowser): support custom base_url in case of custom db path (#320)
Co-authored-by: Muhammad Atif Ali <atif@coder.com>
Co-authored-by: Muhammad Atif Ali <me@matifali.dev>
2024-10-18 17:21:36 +05:00
11 changed files with 142 additions and 58 deletions

View File

@@ -47,6 +47,7 @@ You can test a module locally by updating the source as follows
```tf
module "example" {
source = "git::https://github.com/<USERNAME>/<REPO>.git//<MODULE-NAME>?ref=<BRANCH-NAME>"
# You may need to remove the 'version' field, it is incompatible with some sources.
}
```

View File

@@ -14,7 +14,7 @@ A file browser for your workspace.
```tf
module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.19"
version = "1.0.22"
agent_id = coder_agent.example.id
}
```
@@ -28,7 +28,7 @@ module "filebrowser" {
```tf
module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.19"
version = "1.0.22"
agent_id = coder_agent.example.id
folder = "/home/coder/project"
}
@@ -39,7 +39,7 @@ module "filebrowser" {
```tf
module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.19"
version = "1.0.22"
agent_id = coder_agent.example.id
database_path = ".config/filebrowser.db"
}

View File

@@ -18,7 +18,7 @@ if [ "${DB_PATH}" != "filebrowser.db" ]; then
fi
# set baseurl to be able to run if sudomain=false; if subdomain=true the SERVER_BASE_PATH value will be ""
filebrowser config set --baseurl "${SERVER_BASE_PATH}" > ${LOG_PATH} 2>&1
filebrowser config set --baseurl "${SERVER_BASE_PATH}"$${DB_FLAG} > ${LOG_PATH} 2>&1
printf "📂 Serving $${ROOT_DIR} at http://localhost:${PORT} \n\n"

View File

@@ -16,7 +16,7 @@ A module that adds JupyterLab in your Coder template.
```tf
module "jupyterlab" {
source = "registry.coder.com/modules/jupyterlab/coder"
version = "1.0.19"
version = "1.0.22"
agent_id = coder_agent.example.id
}
```

View File

@@ -9,6 +9,9 @@ terraform {
}
}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
# Add required variables for your modules and remove any unneeded variables
variable "agent_id" {
type = string
@@ -36,6 +39,12 @@ variable "share" {
}
}
variable "subdomain" {
type = bool
description = "Determines whether JupyterLab will be accessed via its own subdomain or whether it will be accessed via a path on Coder."
default = true
}
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)."
@@ -49,17 +58,18 @@ resource "coder_script" "jupyterlab" {
script = templatefile("${path.module}/run.sh", {
LOG_PATH : var.log_path,
PORT : var.port
BASE_URL : var.subdomain ? "" : "/@${data.coder_workspace_owner.me.name}/${data.coder_workspace.me.name}/apps/jupyterlab"
})
run_on_start = true
}
resource "coder_app" "jupyterlab" {
agent_id = var.agent_id
slug = "jupyterlab"
slug = "jupyterlab" # sync with the usage in URL
display_name = "JupyterLab"
url = "http://localhost:${var.port}"
url = var.subdomain ? "http://localhost:${var.port}" : "http://localhost:${var.port}/@${data.coder_workspace_owner.me.name}/${data.coder_workspace.me.name}/apps/jupyterlab"
icon = "/icon/jupyter.svg"
subdomain = true
subdomain = var.subdomain
share = var.share
order = var.order
}

View File

@@ -1,5 +1,9 @@
#!/usr/bin/env sh
if [ -n "${BASE_URL}" ]; then
BASE_URL_FLAG="--ServerApp.base_url=${BASE_URL}"
fi
BOLD='\033[0;1m'
printf "$${BOLD}Installing jupyterlab!\n"
@@ -15,11 +19,17 @@ if ! command -v jupyterlab > /dev/null 2>&1; then
fi
# install jupyterlab
pipx install -q jupyterlab
echo "🥳 jupyterlab has been installed\n\n"
printf "%s\n\n" "🥳 jupyterlab has been installed"
else
echo "🥳 jupyterlab is already installed\n\n"
printf "%s\n\n" "🥳 jupyterlab is already installed"
fi
echo "👷 Starting jupyterlab in background..."
echo "check logs at ${LOG_PATH}"
$HOME/.local/bin/jupyter-lab --ServerApp.ip='0.0.0.0' --ServerApp.port=${PORT} --no-browser --ServerApp.token='' --ServerApp.password='' > ${LOG_PATH} 2>&1 &
printf "👷 Starting jupyterlab in background..."
printf "check logs at ${LOG_PATH}"
$HOME/.local/bin/jupyter-lab --no-browser \
"$BASE_URL_FLAG" \
--ServerApp.ip='*' \
--ServerApp.port="${PORT}" \
--ServerApp.token='' \
--ServerApp.password='' \
> "${LOG_PATH}" 2>&1 &

View File

@@ -14,10 +14,29 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and
```tf
module "kasmvnc" {
source = "registry.coder.com/modules/kasmvnc/coder"
version = "1.0.21"
version = "1.0.23"
agent_id = coder_agent.example.id
desktop_environment = "xfce"
}
```
> **Note:** This module only works on workspaces with a pre-installed desktop environment. As an example base image you can use `codercom/enterprise-desktop` image.
> **Note:** You can also use the kasmtech [custom images](https://kasmweb.com/docs/latest/guide/custom_images.html) by extending them as following:
```Dockerfile
FROM kasmweb/postman:1.16.0
ARG USER=kasm-user
USER root
# Overwrite the existing config file to disable ssl
RUN cat <<EOF > /etc/kasmvnc/kasmvnc.yaml
network:
protocol: http
ssl:
require_ssl: false
udp:
public_ip: 127.0.0.1
EOF
RUN addgroup $USER ssl-cert
USER $USER
```

View File

@@ -5,7 +5,7 @@
# Function to check if vncserver is already installed
check_installed() {
if command -v vncserver &> /dev/null; then
echo "vncserver is already installed."
echo "A binary with name vncserver already installed."
return 0 # Don't exit, just indicate it's installed
else
return 1 # Indicates not installed
@@ -19,7 +19,7 @@ download_file() {
if command -v wget &> /dev/null; then
wget $url -O $output
elif command -v curl &> /dev/null; then
curl -L $url -o $output
curl -fsSL $url -o $output
elif command -v busybox &> /dev/null; then
busybox wget -O $output $url
else
@@ -32,8 +32,9 @@ download_file() {
install_deb() {
local url=$1
download_file $url /tmp/kasmvncserver.deb
sudo apt-get install --yes --no-install-recommends --no-install-suggests /tmp/kasmvncserver.deb
sudo adduser $USER ssl-cert
sudo apt-get update
DEBIAN_FRONTEND=noninteractive sudo apt-get install --yes -qq --no-install-recommends --no-install-suggests /tmp/kasmvncserver.deb
sudo usermod -aG ssl-cert $USER
rm /tmp/kasmvncserver.deb
}
@@ -74,35 +75,36 @@ install_alpine() {
rm /tmp/kasmvncserver.tgz
}
# Detect system information
distro=$(grep "^ID=" /etc/os-release | awk -F= '{print $2}')
version=$(grep "^VERSION_ID=" /etc/os-release | awk -F= '{print $2}' | tr -d '"')
arch=$(uname -m)
echo "Detected Distribution: $distro"
echo "Detected Version: $version"
echo "Detected Architecture: $arch"
# Map arch to package arch
if [[ "$arch" == "x86_64" ]]; then
if [[ "$distro" == "ubuntu" || "$distro" == "debian" || "$distro" == "kali" ]]; then
arch="amd64"
else
arch="x86_64"
fi
elif [[ "$arch" == "aarch64" || "$arch" == "arm64" ]]; then
if [[ "$distro" == "ubuntu" || "$distro" == "debian" || "$distro" == "kali" ]]; then
arch="arm64"
else
arch="aarch64"
fi
else
echo "Unsupported architecture: $arch"
exit 1
fi
# Check if vncserver is installed, and install if not
if ! check_installed; then
# Detect system information
distro=$(grep "^ID=" /etc/os-release | awk -F= '{print $2}')
version=$(grep "^VERSION_ID=" /etc/os-release | awk -F= '{print $2}' | tr -d '"')
arch=$(uname -m)
echo "Detected Distribution: $distro"
echo "Detected Version: $version"
echo "Detected Architecture: $arch"
# Map arch to package arch
if [[ "$arch" == "x86_64" ]]; then
if [[ "$distro" == "ubuntu" || "$distro" == "debian" || "$distro" == "kali" ]]; then
arch="amd64"
else
arch="x86_64"
fi
elif [[ "$arch" == "aarch64" || "$arch" == "arm64" ]]; then
if [[ "$distro" == "ubuntu" || "$distro" == "debian" || "$distro" == "kali" ]]; then
arch="arm64"
else
arch="aarch64"
fi
else
echo "Unsupported architecture: $arch"
exit 1
fi
echo "Installing KASM version: ${VERSION}"
case $distro in
ubuntu | debian | kali)
case $version in
@@ -153,10 +155,12 @@ if ! check_installed; then
;;
esac
else
echo "vncserver already installed. Skipping installation."
echo "Skipping installation."
fi
# Coder port-forwarding from dashboard only supports HTTP
# Try to create /etc/kasmvnc/kasmvnc.yaml system-wide
# we don't fail as some images might be missing sudo permissions
sudo mkdir -p /etc/kasmvnc || true
sudo bash -c "cat > /etc/kasmvnc/kasmvnc.yaml <<EOF
network:
protocol: http
@@ -165,7 +169,22 @@ network:
require_ssl: false
udp:
public_ip: 127.0.0.1
EOF"
EOF" || true
# There could already be a config file in the image at /etc/kasmvnc/kasmvnc.yaml, but we need to set the websocket port
mkdir -p "$HOME/.vnc"
cat > "$HOME/.vnc/kasmvnc.yaml" <<EOF
network:
protocol: http
websocket_port: ${PORT}
ssl:
require_ssl: false
pem_certificate:
pem_key:
udp:
public_ip: 127.0.0.1
EOF
# This password is not used since we start the server without auth.
# The server is protected via the Coder session token / tunnel
@@ -174,4 +193,4 @@ echo -e "password\npassword\n" | vncpasswd -wo -u $USER
# Start the server
printf "🚀 Starting KasmVNC server...\n"
sudo -u $USER bash -c "vncserver -select-de ${DESKTOP_ENVIRONMENT} -disableBasicAuth" > /tmp/kasmvncserver.log 2>&1 &
vncserver -select-de ${DESKTOP_ENVIRONMENT} -disableBasicAuth > /tmp/kasmvncserver.log 2>&1 &

View File

@@ -14,7 +14,7 @@ Automatically install [Visual Studio Code Server](https://code.visualstudio.com/
```tf
module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.20"
version = "1.0.22"
agent_id = coder_agent.example.id
accept_license = true
}
@@ -29,7 +29,7 @@ module "vscode-web" {
```tf
module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.20"
version = "1.0.22"
agent_id = coder_agent.example.id
install_prefix = "/home/coder/.vscode-web"
folder = "/home/coder"
@@ -42,7 +42,7 @@ module "vscode-web" {
```tf
module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.20"
version = "1.0.22"
agent_id = coder_agent.example.id
extensions = ["github.copilot", "ms-python.python", "ms-toolsai.jupyter"]
accept_license = true
@@ -56,7 +56,7 @@ Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarte
```tf
module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.20"
version = "1.0.22"
agent_id = coder_agent.example.id
extensions = ["dracula-theme.theme-dracula"]
settings = {

View File

@@ -121,6 +121,18 @@ variable "auto_install_extensions" {
default = false
}
variable "subdomain" {
type = bool
description = <<-EOT
Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder.
If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible.
EOT
default = true
}
data "coder_workspace_owner" "me" {}
data "coder_workspace" "me" {}
resource "coder_script" "vscode-web" {
agent_id = var.agent_id
display_name = "VS Code Web"
@@ -138,6 +150,7 @@ resource "coder_script" "vscode-web" {
EXTENSIONS_DIR : var.extensions_dir,
FOLDER : var.folder,
AUTO_INSTALL_EXTENSIONS : var.auto_install_extensions,
SERVER_BASE_PATH : local.server_base_path,
})
run_on_start = true
@@ -158,15 +171,21 @@ resource "coder_app" "vscode-web" {
agent_id = var.agent_id
slug = var.slug
display_name = var.display_name
url = var.folder == "" ? "http://localhost:${var.port}" : "http://localhost:${var.port}?folder=${var.folder}"
url = local.url
icon = "/icon/code.svg"
subdomain = true
subdomain = var.subdomain
share = var.share
order = var.order
healthcheck {
url = "http://localhost:${var.port}/healthz"
url = local.healthcheck_url
interval = 5
threshold = 6
}
}
locals {
server_base_path = var.subdomain ? "" : format("/@%s/%s/apps/%s/", data.coder_workspace_owner.me.name, data.coder_workspace.me.name, var.slug)
url = var.folder == "" ? "http://localhost:${var.port}${local.server_base_path}" : "http://localhost:${var.port}${local.server_base_path}?folder=${var.folder}"
healthcheck_url = var.subdomain ? "http://localhost:${var.port}/healthz" : "http://localhost:${var.port}${local.server_base_path}/healthz"
}

View File

@@ -10,10 +10,16 @@ if [ -n "${EXTENSIONS_DIR}" ]; then
EXTENSION_ARG="--extensions-dir=${EXTENSIONS_DIR}"
fi
# Set extension directory
SERVER_BASE_PATH_ARG=""
if [ -n "${SERVER_BASE_PATH}" ]; then
SERVER_BASE_PATH_ARG="--server-base-path=${SERVER_BASE_PATH}"
fi
run_vscode_web() {
echo "👷 Running $VSCODE_WEB serve-local $EXTENSION_ARG --port ${PORT} --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level ${TELEMETRY_LEVEL} in the background..."
echo "👷 Running $VSCODE_WEB serve-local $EXTENSION_ARG $SERVER_BASE_PATH_ARG --port ${PORT} --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level ${TELEMETRY_LEVEL} in the background..."
echo "Check logs at ${LOG_PATH}!"
"$VSCODE_WEB" serve-local "$EXTENSION_ARG" --port "${PORT}" --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level "${TELEMETRY_LEVEL}" > "${LOG_PATH}" 2>&1 &
"$VSCODE_WEB" serve-local "$EXTENSION_ARG" "$SERVER_BASE_PATH_ARG" --port "${PORT}" --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level "${TELEMETRY_LEVEL}" > "${LOG_PATH}" 2>&1 &
}
# Check if the settings file exists...