33# Exit on error, undefined variables, and pipe failures
44set -euo pipefail
55
6+ info () { printf " 💁 INFO: %s\n" " $@ " ; }
7+ warn () { printf " 😱 WARNING: %s\n" " $@ " ; }
8+ error () { printf " 💀 ERROR: %s\n" " $@ " ; exit 1; }
9+ debug () {
10+ if [ " ${DEBUG} " != " Y" ]; then return ; fi
11+ printf " 🦺 DEBUG: %s\n" " $@ "
12+ }
13+
614# Function to check if vncserver is already installed
715check_installed () {
816 if command -v vncserver & > /dev/null; then
@@ -29,14 +37,12 @@ download_file() {
2937 # shellcheck disable=SC2034
3038 download_tool=(busybox wget -O-)
3139 else
32- echo " ERROR: No download tool available (curl, wget, or busybox required)"
33- exit 1
40+ error " No download tool available (curl, wget, or busybox required)"
3441 fi
3542
3643 # shellcheck disable=SC2288
3744 " $$ {download_tool[@]}" " $url " > " $output " || {
38- echo " ERROR: Failed to download $url "
39- exit 1
45+ error " Failed to download $url "
4046 }
4147}
4248
@@ -79,16 +85,14 @@ install_rpm() {
7985 # shellcheck disable=SC2034
8086 package_manager=(rpm -i)
8187 else
82- echo " ERROR: No supported package manager available (dnf, zypper, yum, or rpm required)"
83- exit 1
88+ error " No supported package manager available (dnf, zypper, yum, or rpm required)"
8489 fi
8590
8691 download_file " $url " " $kasmrpm "
8792
8893 # shellcheck disable=SC2288
8994 sudo " $$ {package_manager[@]}" " $kasmrpm " || {
90- echo " ERROR: Failed to install $kasmrpm "
91- exit 1
95+ error " Failed to install $kasmrpm "
9296 }
9397
9498 rm " $kasmrpm "
@@ -107,8 +111,8 @@ install_alpine() {
107111
108112# Detect system information
109113if [[ ! -f /etc/os-release ]]; then
110- echo " ERROR: Cannot detect OS: /etc/os-release not found"
111- exit 1
114+ error " Cannot detect OS: /etc/os-release not found"
115+
112116fi
113117
114118# shellcheck disable=SC1091
@@ -124,10 +128,11 @@ elif [[ "$ID" == "fedora" ]]; then
124128 distro_version=" $( grep -oP ' \(\K[\w ]+' /etc/fedora-release | tr ' [:upper:]' ' [:lower:]' | tr -d ' ' ) "
125129fi
126130
127- echo " Detected Distribution: $distro "
128- echo " Detected Version: $distro_version "
129- echo " Detected Codename: $codename "
130- echo " Detected Architecture: $arch "
131+ echo " 🕵 Detected Operating System Information"
132+ echo " 🔎 Distribution: $distro "
133+ echo " 🔎 Version: $distro_version "
134+ echo " 🔎 Codename: $codename "
135+ echo " 🔎 Architecture: $arch "
131136
132137# Map arch to package arch
133138case " $arch " in
@@ -145,17 +150,15 @@ case "$arch" in
145150 : # This is effectively a noop
146151 ;;
147152 * )
148- echo " ERROR: Unsupported architecture: $arch "
149- exit 1
153+ error " Unsupported architecture: $arch "
150154 ;;
151155esac
152156
153157# Check if vncserver is installed, and install if not
154158if ! check_installed; then
155159 # Check for NOPASSWD sudo (required)
156160 if ! command -v sudo & > /dev/null || ! sudo -n true 2> /dev/null; then
157- echo " ERROR: sudo NOPASSWD access required!"
158- exit 1
161+ error " sudo NOPASSWD access required!"
159162 fi
160163
161164 base_url=" https://github.com/kasmtech/KasmVNC/releases/download/v${KASM_VERSION} "
@@ -190,14 +193,14 @@ else
190193 kasm_config_file=" $HOME /.vnc/kasmvnc.yaml"
191194 SUDO=
192195
193- echo " WARNING: Sudo access not available, using user config dir!"
196+ warn " Sudo access not available, using user config dir!"
194197
195198 if [[ -f " $kasm_config_file " ]]; then
196- echo " WARNING: Custom user KasmVNC config exists, not overwriting!"
197- echo " WARNING: Ensure that you manually configure the appropriate settings."
199+ warn " Custom user KasmVNC config exists, not overwriting!"
200+ warm " Ensure that you manually configure the appropriate settings."
198201 kasm_config_file=" /dev/stderr"
199202 else
200- echo " WARNING: This may prevent custom user KasmVNC settings from applying!"
203+ warn " This may prevent custom user KasmVNC settings from applying!"
201204 mkdir -p " $HOME /.vnc"
202205 fi
203206fi
@@ -213,23 +216,119 @@ network:
213216 pem_key:
214217 udp:
215218 public_ip: 127.0.0.1
219+ logging:
220+ log_writer_name: all
221+ log_dest: logfile
222+ level: 30
216223EOF
217224
225+ get_http_dir () {
226+ # determine the served file path
227+ # Start with the default
228+ httpd_directory=" /usr/share/kasmvnc/www"
229+
230+ # Check the system configuration path
231+ if [[ -e /etc/kasmvnc/kasmvnc.yaml ]]; then
232+ d=($( grep -E " ^\s*httpd_directory:.*$" /etc/kasmvnc/kasmvnc.yaml) )
233+ # If this grep is successful, it will return:
234+ # httpd_directory: /usr/share/kasmvnc/www
235+ if [[ $$ {# d[@]} -eq 2 && -d "$${d[1]}" ]]; then
236+ httpd_directory= " $$ {d[1]}"
237+ fi
238+ fi
239+
240+ # Check the home directory for overriding values
241+ if [[ -e " $HOME /.vnc/kasmvnc.yaml" ]]; then
242+ d=($( grep -E " ^\s*httpd_directory:.*$" /etc/kasmvnc/kasmvnc.yaml) )
243+ if [[ $$ {# d[@]} -eq 2 && -d "$${d[1]}" ]]; then
244+ httpd_directory= " $$ {d[1]}"
245+ fi
246+ fi
247+ echo $httpd_directory
248+ }
249+
250+ fix_server_index_file (){
251+ local fname= $$ {FUNCNAME[0]} # gets current function name
252+ if [[ $# -ne 1 ]]; then
253+ error " $fname requires exactly 1 parameter:\n\tpath to KasmVNC httpd_directory"
254+ fi
255+ local httpdir= " $1 "
256+ if [[ ! -d " $httpdir " ]]; then
257+ error " $fname : $httpdir is not a directory"
258+ fi
259+ pushd " $httpdir " > /dev/null
260+
261+ cat << EOH > /tmp/path_vnc.html
262+ ${file(path.module)}
263+ EOH
264+ $SUDO mv /tmp/path_vnc.html .
265+ # check for the switcheroo
266+ if [[ -f " index.html" && -L " vnc.html" ]]; then
267+ $SUDO mv $httpdir /index.html $httpdir /vnc.html
268+ fi
269+ $SUDO ln -s -f path_vnc.html index.html
270+ popd > /dev/null
271+ }
272+
273+ patch_kasm_http_files (){
274+ homedir= $( get_http_dir)
275+ fix_server_index_file " $homedir "
276+ }
277+
278+ if [[ " ${SUBDOMAIN} " == " false" ]]; then
279+ info " 🩹 Patching up webserver files to support path-sharing..."
280+ patch_kasm_http_files
281+ fi
282+
283+
218284# This password is not used since we start the server without auth.
219285# The server is protected via the Coder session token / tunnel
220286# and does not listen publicly
221287echo -e " password\npassword\n" | vncpasswd -w o -u " $USER "
222288
223289# Start the server
224290printf " 🚀 Starting KasmVNC server...\n"
225- vncserver -select-de " ${DESKTOP_ENVIRONMENT} " -disableBasicAuth > /tmp/kasmvncserver.log 2>&1 &
226- pid=$!
227-
228- # Wait for server to start
229- sleep 5
230- grep -v ' ^[[:space:]]*$' /tmp/kasmvncserver.log | tail -n 10
231- if ps -p $pid | grep -q " ^$pid " ; then
232- echo " ERROR: Failed to start KasmVNC server. Check full logs at /tmp/kasmvncserver.log"
233- exit 1
291+ vncserver -s elect-de " ${DESKTOP_ENVIRONMENT} " -d isableBasicAuth > /tmp/kasmvncserver.log &
292+
293+ # Kasm writes the pid and the log into ~/.vnc. We can check them for liveness
294+ is_started () {
295+ debug " ls for pidfile: $( ls -alh ~ /.vnc/$( hostname) :1.pid 2>&1 ) "
296+
297+ pidfile=" $$ {HOME}/.vnc/$( hostname) :1.pid"
298+ if [[ ! -f $pidfile ]]; then
299+ debug " is_started(): no pidfile found"
300+ return 1
301+ fi
302+ pid=$( cat $$ {pidfile})
303+ debug " $( ps $pid ) "
304+ if kill -0 $pid ; then
305+ debug " is_started(): found a live PID, setting active"
306+ declare -gx active=" Y"
307+ return 0
308+ else
309+ debug " is_started(): PID is not active"
310+ return 1
311+ fi
312+ warning " is_started(): REACHED THE END WITHOUT HITTING A CASE"
313+ return 1
314+ }
315+
316+ # Use a sleep based polling timer to see when Kasm comes up.
317+ waited= 0
318+ is_started && debug " is Started: true" || debug " is_started: false"
319+ [[ waited -le 30 ]] && debug " waited -le 30: true" || debug " waited -le 30: false"
320+ while [[ waited -le 30 ]] && ! is_started; do
321+ sleep 1
322+ waited=$(( waited+ 1 ))
323+ if [[ waited -ne 0 && $(( waited % 5 )) -eq 0 ]]; then
324+ echo " ⏳ Waiting for KasmVNC to start ($waited seconds...)"
325+ fi
326+ is_started && debug " is Started: true" || debug " is_started: false"
327+ [[ waited -le 30 ]] && debug " waited -le 30: true" || debug " waited -le 30: false"
328+ done
329+
330+ if [[ " $active " == " " ]]; then
331+ error " timed out waiting for KasmVNC to start."
234332fi
235- printf " 🚀 KasmVNC server started successfully!\n"
333+
334+ printf " 🚀 KasmVNC server started successfully in $waited seconds!\n"
0 commit comments