-
Notifications
You must be signed in to change notification settings - Fork 59
fix(kasmvnc): optimize KasmVNC deployment script #329
Changes from all commits
a8cc861
8213a57
6d6e0dd
c59ba95
bb7d438
10a86bd
46bbcb9
30e6bed
4d831b4
9c3904d
4a72b2e
a2d8e72
026a5bc
4fc9f6d
d418c81
c4f88fa
52ba74c
d619e65
eff921e
eb974cb
f3a0f98
ab96d93
ebc57a1
86b48dd
15e3ec2
41baf48
7d7c7e8
f35b535
a0373c0
ccf299b
ef4f704
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
#!/usr/bin/env bash | ||
|
||
#!/bin/bash | ||
# Exit on error, undefined variables, and pipe failures | ||
set -euo pipefail | ||
|
||
# Function to check if vncserver is already installed | ||
check_installed() { | ||
|
@@ -14,166 +15,221 @@ check_installed() { | |
|
||
# 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 -fsSL $url -o $output | ||
local url="$1" | ||
local output="$2" | ||
local download_tool | ||
|
||
if command -v curl &> /dev/null; then | ||
# shellcheck disable=SC2034 | ||
download_tool=(curl -fsSL) | ||
elif command -v wget &> /dev/null; then | ||
# shellcheck disable=SC2034 | ||
download_tool=(wget -q -O-) | ||
elif command -v busybox &> /dev/null; then | ||
busybox wget -O $output $url | ||
# shellcheck disable=SC2034 | ||
download_tool=(busybox wget -O-) | ||
else | ||
echo "Neither wget, curl, nor busybox is installed. Please install one of them to proceed." | ||
echo "ERROR: No download tool available (curl, wget, or busybox required)" | ||
exit 1 | ||
fi | ||
|
||
# shellcheck disable=SC2288 | ||
"$${download_tool[@]}" "$url" > "$output" || { | ||
echo "ERROR: Failed to download $url" | ||
exit 1 | ||
} | ||
} | ||
|
||
# Function to install kasmvncserver for debian-based distros | ||
install_deb() { | ||
local url=$1 | ||
download_file $url /tmp/kasmvncserver.deb | ||
sudo apt-get update | ||
DEBIAN_FRONTEND=noninteractive sudo apt-get install --yes -qq --no-install-recommends --no-install-suggests /tmp/kasmvncserver.deb | ||
sudo adduser $USER ssl-cert | ||
rm /tmp/kasmvncserver.deb | ||
} | ||
local kasmdeb="/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 | ||
} | ||
download_file "$url" "$kasmdeb" | ||
|
||
# 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 | ||
CACHE_DIR="/var/lib/apt/lists/partial" | ||
# Check if the directory exists and was modified in the last 60 minutes | ||
if [[ ! -d "$CACHE_DIR" ]] || ! find "$CACHE_DIR" -mmin -60 -print -quit &> /dev/null; then | ||
echo "Stale package cache, updating..." | ||
# Update package cache with a 300-second timeout for dpkg lock | ||
sudo apt-get -o DPkg::Lock::Timeout=300 -qq update | ||
fi | ||
|
||
DEBIAN_FRONTEND=noninteractive sudo apt-get -o DPkg::Lock::Timeout=300 install --yes -qq --no-install-recommends --no-install-suggests "$kasmdeb" | ||
rm "$kasmdeb" | ||
} | ||
|
||
# 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 | ||
local kasmrpm="/tmp/kasmvncserver.rpm" | ||
local package_manager | ||
|
||
if command -v dnf &> /dev/null; then | ||
# shellcheck disable=SC2034 | ||
package_manager=(dnf localinstall -y) | ||
elif command -v zypper &> /dev/null; then | ||
# shellcheck disable=SC2034 | ||
package_manager=(zypper install -y) | ||
elif command -v yum &> /dev/null; then | ||
# shellcheck disable=SC2034 | ||
package_manager=(yum localinstall -y) | ||
elif command -v rpm &> /dev/null; then | ||
# Do we need to manually handle missing dependencies? | ||
# shellcheck disable=SC2034 | ||
package_manager=(rpm -i) | ||
else | ||
echo "ERROR: No supported package manager available (dnf, zypper, yum, or rpm required)" | ||
exit 1 | ||
fi | ||
|
||
download_file "$url" "$kasmrpm" | ||
|
||
# shellcheck disable=SC2288 | ||
sudo "$${package_manager[@]}" "$kasmrpm" || { | ||
echo "ERROR: Failed to install $kasmrpm" | ||
exit 1 | ||
} | ||
|
||
rm "$kasmrpm" | ||
} | ||
|
||
# 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 | ||
local kasmtgz="/tmp/kasmvncserver.tgz" | ||
|
||
download_file "$url" "$kasmtgz" | ||
|
||
tar -xzf "$kasmtgz" -C /usr/local/bin/ | ||
rm "$kasmtgz" | ||
} | ||
|
||
# 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) | ||
if [[ ! -f /etc/os-release ]]; then | ||
djarbz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
echo "ERROR: Cannot detect OS: /etc/os-release not found" | ||
exit 1 | ||
fi | ||
|
||
# shellcheck disable=SC1091 | ||
source /etc/os-release | ||
distro="$ID" | ||
distro_version="$VERSION_ID" | ||
codename="$VERSION_CODENAME" | ||
arch="$(uname -m)" | ||
if [[ "$ID" == "ol" ]]; then | ||
distro="oracle" | ||
distro_version="$${distro_version%%.*}" | ||
elif [[ "$ID" == "fedora" ]]; then | ||
distro_version="$(grep -oP '\(\K[\w ]+' /etc/fedora-release | tr '[:upper:]' '[:lower:]' | tr -d ' ')" | ||
fi | ||
|
||
echo "Detected Distribution: $distro" | ||
echo "Detected Version: $version" | ||
echo "Detected Version: $distro_version" | ||
echo "Detected Codename: $codename" | ||
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 | ||
case "$arch" in | ||
x86_64) | ||
if [[ "$distro" =~ ^(ubuntu|debian|kali)$ ]]; then | ||
arch="amd64" | ||
fi | ||
;; | ||
aarch64) | ||
if [[ "$distro" =~ ^(ubuntu|debian|kali)$ ]]; then | ||
arch="arm64" | ||
fi | ||
;; | ||
arm64) | ||
: # This is effectively a noop | ||
;; | ||
*) | ||
echo "ERROR: Unsupported architecture: $arch" | ||
exit 1 | ||
;; | ||
esac | ||
|
||
# Check if vncserver is installed, and install if not | ||
if ! check_installed; then | ||
echo "Installing KASM version: ${VERSION}" | ||
# Check for NOPASSWD sudo (required) | ||
if ! command -v sudo &> /dev/null || ! sudo -n true 2> /dev/null; then | ||
echo "ERROR: sudo NOPASSWD access required!" | ||
exit 1 | ||
fi | ||
|
||
base_url="https://github.com/kasmtech/KasmVNC/releases/download/v${KASM_VERSION}" | ||
|
||
echo "Installing KASM version: ${KASM_VERSION}" | ||
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 | ||
bin_name="kasmvncserver_$${codename}_${KASM_VERSION}_$${arch}.deb" | ||
install_deb "$base_url/$bin_name" | ||
;; | ||
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 | ||
oracle | fedora | opensuse) | ||
bin_name="kasmvncserver_$${distro}_$${distro_version}_${KASM_VERSION}_$${arch}.rpm" | ||
djarbz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
install_rpm "$base_url/$bin_name" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably need both I'm not sure if this is a script meant for installing the kasmvnc built package or something else, but this at least gives hints for the expectation per distro: https://github.com/kasmtech/KasmVNC/blob/3a8517d7dc461eaccc7ed8e3d3b155e233426fc8/builder/scripts/common.sh#L22-L29 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps in the Priority:
|
||
;; | ||
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" | ||
bin_name="kasmvnc.alpine_$${distro_version//./}_$${arch}.tgz" | ||
install_alpine "$base_url/$bin_name" | ||
;; | ||
*) | ||
echo "Unsupported distribution: $${distro}" | ||
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 | ||
if command -v sudo &> /dev/null && sudo -n true 2> /dev/null; then | ||
kasm_config_file="/etc/kasmvnc/kasmvnc.yaml" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have not run into the need for it. |
||
SUDO=sudo | ||
else | ||
kasm_config_file="$HOME/.vnc/kasmvnc.yaml" | ||
SUDO= | ||
|
||
echo "WARNING: Sudo access not available, using user config dir!" | ||
|
||
if [[ -f "$kasm_config_file" ]]; then | ||
echo "WARNING: Custom user KasmVNC config exists, not overwriting!" | ||
echo "WARNING: Ensure that you manually configure the appropriate settings." | ||
kasm_config_file="/dev/stderr" | ||
djarbz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else | ||
echo "WARNING: This may prevent custom user KasmVNC settings from applying!" | ||
mkdir -p "$HOME/.vnc" | ||
fi | ||
fi | ||
|
||
echo "Writing KasmVNC config to $kasm_config_file" | ||
$SUDO tee "$kasm_config_file" > /dev/null << EOF | ||
network: | ||
protocol: http | ||
websocket_port: ${PORT} | ||
ssl: | ||
require_ssl: false | ||
pem_certificate: | ||
pem_key: | ||
udp: | ||
public_ip: 127.0.0.1 | ||
EOF" | ||
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 | ||
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 & | ||
pid=$! | ||
|
||
# Wait for server to start | ||
sleep 5 | ||
grep -v '^[[:space:]]*$' /tmp/kasmvncserver.log | tail -n 10 | ||
if ps -p $pid | grep -q "^$pid"; then | ||
echo "ERROR: Failed to start KasmVNC server. Check full logs at /tmp/kasmvncserver.log" | ||
exit 1 | ||
fi | ||
printf "🚀 KasmVNC server started successfully!\n" |
Uh oh!
There was an error while loading. Please reload this page.