Merge branch 'main' into patches/filebrowser
						commit
						0d51312c13
					
				@ -0,0 +1,23 @@
 | 
			
		||||
---
 | 
			
		||||
display_name: KasmVNC
 | 
			
		||||
description: A modern open source VNC server
 | 
			
		||||
icon: ../.icons/kasmvnc.svg
 | 
			
		||||
maintainer_github: coder
 | 
			
		||||
verified: true
 | 
			
		||||
tags: [helper, vnc, desktop]
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# KasmVNC
 | 
			
		||||
 | 
			
		||||
Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard.
 | 
			
		||||
 | 
			
		||||
```tf
 | 
			
		||||
module "kasmvnc" {
 | 
			
		||||
  source              = "registry.coder.com/modules/kasmvnc/coder"
 | 
			
		||||
  version             = "1.0.21"
 | 
			
		||||
  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.
 | 
			
		||||
@ -0,0 +1,37 @@
 | 
			
		||||
import { describe, expect, it } from "bun:test";
 | 
			
		||||
import {
 | 
			
		||||
  runTerraformApply,
 | 
			
		||||
  runTerraformInit,
 | 
			
		||||
  testRequiredVariables,
 | 
			
		||||
} from "../test";
 | 
			
		||||
 | 
			
		||||
const allowedDesktopEnvs = ["xfce", "kde", "gnome", "lxde", "lxqt"] as const;
 | 
			
		||||
type AllowedDesktopEnv = (typeof allowedDesktopEnvs)[number];
 | 
			
		||||
 | 
			
		||||
type TestVariables = Readonly<{
 | 
			
		||||
  agent_id: string;
 | 
			
		||||
  desktop_environment: AllowedDesktopEnv;
 | 
			
		||||
  port?: string;
 | 
			
		||||
  kasm_version?: string;
 | 
			
		||||
}>;
 | 
			
		||||
 | 
			
		||||
describe("Kasm VNC", async () => {
 | 
			
		||||
  await runTerraformInit(import.meta.dir);
 | 
			
		||||
  testRequiredVariables<TestVariables>(import.meta.dir, {
 | 
			
		||||
    agent_id: "foo",
 | 
			
		||||
    desktop_environment: "gnome",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it("Successfully installs for all expected Kasm desktop versions", async () => {
 | 
			
		||||
    for (const v of allowedDesktopEnvs) {
 | 
			
		||||
      const applyWithEnv = () => {
 | 
			
		||||
        runTerraformApply<TestVariables>(import.meta.dir, {
 | 
			
		||||
          agent_id: "foo",
 | 
			
		||||
          desktop_environment: v,
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      expect(applyWithEnv).not.toThrow();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@ -0,0 +1,63 @@
 | 
			
		||||
terraform {
 | 
			
		||||
  required_version = ">= 1.0"
 | 
			
		||||
 | 
			
		||||
  required_providers {
 | 
			
		||||
    coder = {
 | 
			
		||||
      source  = "coder/coder"
 | 
			
		||||
      version = ">= 0.12"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
variable "agent_id" {
 | 
			
		||||
  type        = string
 | 
			
		||||
  description = "The ID of a Coder agent."
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
variable "port" {
 | 
			
		||||
  type        = number
 | 
			
		||||
  description = "The port to run KasmVNC on."
 | 
			
		||||
  default     = 6800
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
variable "kasm_version" {
 | 
			
		||||
  type        = string
 | 
			
		||||
  description = "Version of KasmVNC to install."
 | 
			
		||||
  default     = "1.3.2"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
variable "desktop_environment" {
 | 
			
		||||
  type        = string
 | 
			
		||||
  description = "Specifies the desktop environment of the workspace. This should be pre-installed on the workspace."
 | 
			
		||||
  validation {
 | 
			
		||||
    condition     = contains(["xfce", "kde", "gnome", "lxde", "lxqt"], var.desktop_environment)
 | 
			
		||||
    error_message = "Invalid desktop environment. Please specify a valid desktop environment."
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
resource "coder_script" "kasm_vnc" {
 | 
			
		||||
  agent_id     = var.agent_id
 | 
			
		||||
  display_name = "KasmVNC"
 | 
			
		||||
  icon         = "/icon/kasmvnc.svg"
 | 
			
		||||
  script = templatefile("${path.module}/run.sh", {
 | 
			
		||||
    PORT : var.port,
 | 
			
		||||
    DESKTOP_ENVIRONMENT : var.desktop_environment,
 | 
			
		||||
    VERSION : var.kasm_version
 | 
			
		||||
  })
 | 
			
		||||
  run_on_start = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
resource "coder_app" "kasm_vnc" {
 | 
			
		||||
  agent_id     = var.agent_id
 | 
			
		||||
  slug         = "kasm-vnc"
 | 
			
		||||
  display_name = "kasmVNC"
 | 
			
		||||
  url          = "http://localhost:${var.port}"
 | 
			
		||||
  icon         = "/icon/kasmvnc.svg"
 | 
			
		||||
  subdomain    = true
 | 
			
		||||
  share        = "owner"
 | 
			
		||||
  healthcheck {
 | 
			
		||||
    url       = "http://localhost:${var.port}/app"
 | 
			
		||||
    interval  = 5
 | 
			
		||||
    threshold = 5
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,177 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# Function to check if vncserver is already installed
 | 
			
		||||
check_installed() {
 | 
			
		||||
  if command -v vncserver &> /dev/null; then
 | 
			
		||||
    echo "vncserver is already installed."
 | 
			
		||||
    return 0 # Don't exit, just indicate it's installed
 | 
			
		||||
  else
 | 
			
		||||
    return 1 # Indicates not installed
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Function to download a file using wget, curl, or busybox as a fallback
 | 
			
		||||
download_file() {
 | 
			
		||||
  local url=$1
 | 
			
		||||
  local output=$2
 | 
			
		||||
  if command -v wget &> /dev/null; then
 | 
			
		||||
    wget $url -O $output
 | 
			
		||||
  elif command -v curl &> /dev/null; then
 | 
			
		||||
    curl -L $url -o $output
 | 
			
		||||
  elif command -v busybox &> /dev/null; then
 | 
			
		||||
    busybox wget -O $output $url
 | 
			
		||||
  else
 | 
			
		||||
    echo "Neither wget, curl, nor busybox is installed. Please install one of them to proceed."
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Function to install kasmvncserver for debian-based distros
 | 
			
		||||
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
 | 
			
		||||
  rm /tmp/kasmvncserver.deb
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Function to install kasmvncserver for Oracle 8
 | 
			
		||||
install_rpm_oracle8() {
 | 
			
		||||
  local url=$1
 | 
			
		||||
  download_file $url /tmp/kasmvncserver.rpm
 | 
			
		||||
  sudo dnf config-manager --set-enabled ol8_codeready_builder
 | 
			
		||||
  sudo dnf install oracle-epel-release-el8 -y
 | 
			
		||||
  sudo dnf localinstall /tmp/kasmvncserver.rpm -y
 | 
			
		||||
  sudo usermod -aG kasmvnc-cert $USER
 | 
			
		||||
  rm /tmp/kasmvncserver.rpm
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Function to install kasmvncserver for CentOS 7
 | 
			
		||||
install_rpm_centos7() {
 | 
			
		||||
  local url=$1
 | 
			
		||||
  download_file $url /tmp/kasmvncserver.rpm
 | 
			
		||||
  sudo yum install epel-release -y
 | 
			
		||||
  sudo yum install /tmp/kasmvncserver.rpm -y
 | 
			
		||||
  sudo usermod -aG kasmvnc-cert $USER
 | 
			
		||||
  rm /tmp/kasmvncserver.rpm
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Function to install kasmvncserver for rpm-based distros
 | 
			
		||||
install_rpm() {
 | 
			
		||||
  local url=$1
 | 
			
		||||
  download_file $url /tmp/kasmvncserver.rpm
 | 
			
		||||
  sudo rpm -i /tmp/kasmvncserver.rpm
 | 
			
		||||
  rm /tmp/kasmvncserver.rpm
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Function to install kasmvncserver for Alpine Linux
 | 
			
		||||
install_alpine() {
 | 
			
		||||
  local url=$1
 | 
			
		||||
  download_file $url /tmp/kasmvncserver.tgz
 | 
			
		||||
  tar -xzf /tmp/kasmvncserver.tgz -C /usr/local/bin/
 | 
			
		||||
  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
 | 
			
		||||
  case $distro in
 | 
			
		||||
    ubuntu | debian | kali)
 | 
			
		||||
      case $version in
 | 
			
		||||
        "20.04")
 | 
			
		||||
          install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_focal_${VERSION}_$${arch}.deb"
 | 
			
		||||
          ;;
 | 
			
		||||
        "22.04")
 | 
			
		||||
          install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_jammy_${VERSION}_$${arch}.deb"
 | 
			
		||||
          ;;
 | 
			
		||||
        "24.04")
 | 
			
		||||
          install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_noble_${VERSION}_$${arch}.deb"
 | 
			
		||||
          ;;
 | 
			
		||||
        *)
 | 
			
		||||
          echo "Unsupported Ubuntu/Debian/Kali version: $${version}"
 | 
			
		||||
          exit 1
 | 
			
		||||
          ;;
 | 
			
		||||
      esac
 | 
			
		||||
      ;;
 | 
			
		||||
    oracle)
 | 
			
		||||
      if [[ "$version" == "8" ]]; then
 | 
			
		||||
        install_rpm_oracle8 "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_oracle_8_${VERSION}_$${arch}.rpm"
 | 
			
		||||
      else
 | 
			
		||||
        echo "Unsupported Oracle version: $${version}"
 | 
			
		||||
        exit 1
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    centos)
 | 
			
		||||
      if [[ "$version" == "7" ]]; then
 | 
			
		||||
        install_rpm_centos7 "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_centos_core_${VERSION}_$${arch}.rpm"
 | 
			
		||||
      else
 | 
			
		||||
        install_rpm "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_centos_core_${VERSION}_$${arch}.rpm"
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    alpine)
 | 
			
		||||
      if [[ "$version" == "3.17" || "$version" == "3.18" || "$version" == "3.19" || "$version" == "3.20" ]]; then
 | 
			
		||||
        install_alpine "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvnc.alpine_$${version}_$${arch}.tgz"
 | 
			
		||||
      else
 | 
			
		||||
        echo "Unsupported Alpine version: $${version}"
 | 
			
		||||
        exit 1
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    fedora | opensuse)
 | 
			
		||||
      install_rpm "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_$${distro}_$${version}_${VERSION}_$${arch}.rpm"
 | 
			
		||||
      ;;
 | 
			
		||||
    *)
 | 
			
		||||
      echo "Unsupported distribution: $${distro}"
 | 
			
		||||
      exit 1
 | 
			
		||||
      ;;
 | 
			
		||||
  esac
 | 
			
		||||
else
 | 
			
		||||
  echo "vncserver already installed. Skipping installation."
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Coder port-forwarding from dashboard only supports HTTP
 | 
			
		||||
sudo bash -c "cat > /etc/kasmvnc/kasmvnc.yaml <<EOF
 | 
			
		||||
network:
 | 
			
		||||
  protocol: http
 | 
			
		||||
  websocket_port: ${PORT}
 | 
			
		||||
  ssl:
 | 
			
		||||
    require_ssl: false
 | 
			
		||||
  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
 | 
			
		||||
# and does not listen publicly
 | 
			
		||||
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 &
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue