diff --git a/.icons/rustdesk.svg b/.icons/rustdesk.svg new file mode 100644 index 000000000..6c8012333 --- /dev/null +++ b/.icons/rustdesk.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/registry/BenraouaneSoufiane/.images/avatar.png b/registry/BenraouaneSoufiane/.images/avatar.png new file mode 100644 index 000000000..297e89dfc Binary files /dev/null and b/registry/BenraouaneSoufiane/.images/avatar.png differ diff --git a/registry/BenraouaneSoufiane/README.md b/registry/BenraouaneSoufiane/README.md new file mode 100644 index 000000000..3067538a4 --- /dev/null +++ b/registry/BenraouaneSoufiane/README.md @@ -0,0 +1,14 @@ +--- +display_name: "Benraouane Soufiane" +bio: "Full stack developer creating awesome things." +avatar: "./.images/avatar.png" +github: "benraouanesoufiane" +linkedin: "https://www.linkedin.com/in/benraouane-soufiane" # Optional +website: "https://benraouanesoufiane.com" # Optional +support_email: "hello@benraouanesoufiane.com" # Optional +status: "community" +--- + +# Benraouane Soufiane + +Full stack developer creating awesome things. diff --git a/registry/BenraouaneSoufiane/modules/rustdesk/README.md b/registry/BenraouaneSoufiane/modules/rustdesk/README.md new file mode 100644 index 000000000..ae7c28969 --- /dev/null +++ b/registry/BenraouaneSoufiane/modules/rustdesk/README.md @@ -0,0 +1,82 @@ +--- +display_name: RustDesk +description: Run RustDesk in your workspace with virtual display +icon: ../../../../.icons/rustdesk.svg +verified: false +tags: [rustdesk, rdp, vm] +--- + +# RustDesk + +Launches RustDesk within your workspace with a virtual display to provide remote desktop access. The module outputs the RustDesk ID and password needed to connect from external RustDesk clients. + +```tf +module "rustdesk" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/BenraouaneSoufiane/rustdesk/coder" + version = "1.0.0" + agent_id = coder_agent.example.id +} +``` + +## Features + +- Automatically sets up virtual display (Xvfb) +- Downloads and configures RustDesk +- Outputs RustDesk ID and password for easy connection +- Provides external app link to RustDesk web client for browser-based access +- Starts virtual display (Xvfb) with customizable resolution +- Customizable screen resolution and RustDesk version + +## Requirements + +- Coder v2.5 or higher +- Linux workspace with `apt`, `dnf`, or `yum` package manager + +## Examples + +### Custom configuration with specific version + +```tf +module "rustdesk" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/BenraouaneSoufiane/rustdesk/coder" + version = "1.0.0" + agent_id = coder_agent.example.id + rustdesk_password = "mycustompass" + xvfb_resolution = "1920x1080x24" + rustdesk_version = "1.4.1" +} +``` + +### Docker container configuration + +It requires coder' server to be run as root, when using with Docker, add the following to your `docker_container` resource: + +```tf +resource "docker_container" "workspace" { + + # ... other configuration ... + + user = "root" + privileged = true + network_mode = "host" + + ports { + internal = 21115 + external = 21115 + } + ports { + internal = 21116 + external = 21116 + } + ports { + internal = 21118 + external = 21118 + } + ports { + internal = 21119 + external = 21119 + } +} +``` diff --git a/registry/BenraouaneSoufiane/modules/rustdesk/main.tf b/registry/BenraouaneSoufiane/modules/rustdesk/main.tf new file mode 100644 index 000000000..14edcff1f --- /dev/null +++ b/registry/BenraouaneSoufiane/modules/rustdesk/main.tf @@ -0,0 +1,75 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + coder = { + source = "coder/coder" + version = ">= 2.5" + } + } +} + +variable "log_path" { + type = string + description = "The path to log rustdesk to." + default = "/tmp/rustdesk.log" +} + +variable "agent_id" { + description = "Attach RustDesk setup to this agent" + type = string +} + +variable "order" { + description = "Run order among scripts/apps" + type = number + default = 1 +} + +# Optional knobs passed as env (you can expose these as variables too) +variable "rustdesk_password" { + description = "If empty, the script will generate one" + type = string + default = "" + sensitive = true +} + +variable "xvfb_resolution" { + description = "Xvfb screen size/depth" + type = string + default = "1024x768x16" +} + +variable "rustdesk_version" { + description = "RustDesk version to install (use 'latest' for most recent release)" + type = string + default = "latest" +} + +resource "coder_script" "rustdesk" { + agent_id = var.agent_id + display_name = "RustDesk" + run_on_start = true + + # Prepend env as bash exports, then append the script file literally. + script = <<-eot + # --- module-provided env knobs --- + export RUSTDESK_PASSWORD="${var.rustdesk_password}" + export XVFB_RESOLUTION="${var.xvfb_resolution}" + export RUSTDESK_VERSION="${var.rustdesk_version}" + # --------------------------------- + +${file("${path.module}/run.sh")} + EOT +} + +resource "coder_app" "rustdesk" { + agent_id = var.agent_id + slug = "rustdesk" + display_name = "Rustdesk" + url = "https://rustdesk.com/web" + icon = "/icon/rustdesk.svg" + order = var.order + external = true +} + diff --git a/registry/BenraouaneSoufiane/modules/rustdesk/run.sh b/registry/BenraouaneSoufiane/modules/rustdesk/run.sh new file mode 100644 index 000000000..b53714315 --- /dev/null +++ b/registry/BenraouaneSoufiane/modules/rustdesk/run.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +BOLD='033円[0;1m' +RESET='033円[0m' + +printf "${BOLD}πŸ–₯️ Installing RustDesk Remote Desktop\n${RESET}" + +# ---- configurable knobs (env overrides) ---- +RUSTDESK_VERSION="${RUSTDESK_VERSION:-latest}" +LOG_PATH="${LOG_PATH:-/tmp/rustdesk.log}" + +# ---- fetch latest version if needed ---- +if [ "$RUSTDESK_VERSION" = "latest" ]; then + printf "πŸ” Fetching latest RustDesk version...\n" + RUSTDESK_VERSION=$(curl -s https://api.github.com/repos/rustdesk/rustdesk/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/1円/' || echo "1.4.1") + printf "πŸ“Œ Fetched RustDesk version: ${RUSTDESK_VERSION}\n" +else + printf "πŸ“Œ Using specified RustDesk version: ${RUSTDESK_VERSION}\n" +fi +XVFB_RESOLUTION="${XVFB_RESOLUTION:-1024x768x16}" +RUSTDESK_PASSWORD="${RUSTDESK_PASSWORD:-}" + +# ---- detect package manager & arch ---- +ARCH="$(uname -m)" +case "$ARCH" in +x86_64 | amd64) PKG_ARCH="x86_64" ;; +aarch64 | arm64) PKG_ARCH="aarch64" ;; +*) + echo "❌ Unsupported arch: $ARCH" + exit 1 + ;; +esac + +if command -v apt-get>/dev/null 2>&1; then + PKG_SYS="deb" + PKG_NAME="rustdesk-${RUSTDESK_VERSION}-${PKG_ARCH}.deb" + INSTALL_DEPS='apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y wget libva2 libva-drm2 libva-x11-2 libgstreamer-plugins-base1.0-0 gstreamer1.0-pipewire xfce4 xfce4-goodies xvfb x11-xserver-utils dbus-x11 libegl1 libgl1 libglx0 libglu1-mesa mesa-utils libxrandr2 libxss1 libgtk-3-0t64 libgbm1 libdrm2 libxcomposite1 libxdamage1 libxfixes3' + INSTALL_CMD="apt-get install -y ./${PKG_NAME}" + CLEAN_CMD="rm -f \"${PKG_NAME}\"" +elif command -v dnf>/dev/null 2>&1; then + PKG_SYS="rpm" + PKG_NAME="rustdesk-${RUSTDESK_VERSION}-${PKG_ARCH}.rpm" + INSTALL_DEPS='dnf install -y wget libva libva-intel-driver gstreamer1-plugins-base pipewire xfce4-session xfce4-panel xorg-x11-server-Xvfb xorg-x11-xauth dbus-x11 mesa-libEGL mesa-libGL mesa-libGLU mesa-dri-drivers libXrandr libXScrnSaver gtk3 mesa-libgbm libdrm libXcomposite libXdamage libXfixes' + INSTALL_CMD="dnf install -y ./${PKG_NAME}" + CLEAN_CMD="rm -f \"${PKG_NAME}\"" +elif command -v yum>/dev/null 2>&1; then + PKG_SYS="rpm" + PKG_NAME="rustdesk-${RUSTDESK_VERSION}-${PKG_ARCH}.rpm" + INSTALL_DEPS='yum install -y wget libva libva-intel-driver gstreamer1-plugins-base pipewire xfce4-session xfce4-panel xorg-x11-server-Xvfb xorg-x11-xauth dbus-x11 mesa-libEGL mesa-libGL mesa-libGLU mesa-dri-drivers libXrandr libXScrnSaver gtk3 mesa-libgbm libdrm libXcomposite libXdamage libXfixes' + INSTALL_CMD="yum install -y ./${PKG_NAME}" + CLEAN_CMD="rm -f \"${PKG_NAME}\"" +else + echo "❌ Unsupported distro: need apt, dnf, or yum." + exit 1 +fi + +# ---- install rustdesk if missing ---- +if ! command -v rustdesk>/dev/null 2>&1; then + printf "πŸ“¦ Installing dependencies...\n" + sudo bash -c "$INSTALL_DEPS" 2>&1 | tee -a "${LOG_PATH}" + + printf "⬇️ Downloading RustDesk ${RUSTDESK_VERSION} (${PKG_SYS}, ${PKG_ARCH})...\n" + URL="https://github.com/rustdesk/rustdesk/releases/download/${RUSTDESK_VERSION}/${PKG_NAME}" + wget -q "$URL" 2>&1 | tee -a "${LOG_PATH}" + + printf "πŸ”§ Installing RustDesk...\n" + sudo bash -c "$INSTALL_CMD" 2>&1 | tee -a "${LOG_PATH}" + + printf "🧹 Cleaning up...\n" + bash -c "$CLEAN_CMD" 2>&1 | tee -a "${LOG_PATH}" +else + printf "βœ… RustDesk already installed\n" +fi + +# ---- start virtual display ---- +echo "Starting Xvfb with resolution ${XVFB_RESOLUTION}..." +Xvfb :99 -screen 0 "${XVFB_RESOLUTION}">>"${LOG_PATH}" 2>&1 & +export DISPLAY=:99 + +# Wait for X to be ready +for i in {1..10}; do + if xdpyinfo -display :99>/dev/null 2>&1; then + echo "X display is ready" + break + fi + sleep 1 +done + +# ---- create (or accept) password and start rustdesk ---- +if [[ -z "${RUSTDESK_PASSWORD}" ]]; then + RUSTDESK_PASSWORD="$(tr -dc 'a-zA-Z0-9@' >"${LOG_PATH}" 2>&1 & + +echo "Waiting for xfce4-session to initialize..." +sleep 5 + +printf "πŸ” Setting RustDesk password and starting service...\n" +rustdesk>>"${LOG_PATH}" 2>&1 & +sleep 2 + +rustdesk --password "${RUSTDESK_PASSWORD}">>"${LOG_PATH}" 2>&1 & +sleep 3 + +RID="$(rustdesk --get-id 2>/dev/null || echo 'ID_PENDING')" + +printf "πŸ₯³ RustDesk setup complete!\n\n" +printf "${BOLD}πŸ“‹ Connection Details:${RESET}\n" +printf " RustDesk ID: ${RID}\n" +printf " RustDesk Password: ${RUSTDESK_PASSWORD}\n" +printf " Display: ${DISPLAY} (${XVFB_RESOLUTION})\n" +printf "\nπŸ“ Logs available at: ${LOG_PATH}\n\n" + +echo "Setup script completed successfully. All services running in background." +exit 0

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /