diff --git a/.gitignore b/.gitignore index c178dbab..18d9fc5b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ recordings *.swp *~ noVNC-*.tgz + +vnc/turbovnc.deb \ No newline at end of file diff --git a/start.sh b/start.sh new file mode 100755 index 00000000..6ee7a82f --- /dev/null +++ b/start.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# export FORCE_REINSTALL_TURBOVNC=1 to reinstall turbovnc to the latest version + +set -e + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd "$SCRIPT_DIR" + +. ./utils/shell-logger + +hasUpdated=0 + +# desktop environment installation +if ! dpkg-query -W -f='${Status}' xfce4 2>/dev/null | grep -q "install ok installed"; then + sudo apt update + hasUpdated=1 + info "installing xfce4 desktop environment" + sudo DEBIAN_FRONTEND=noninteractive apt install -y xfce4 xfce4-goodies +fi + +# vnc server installation +if [ ! -d /opt/TurboVNC ] || [ ! -z $FORCE_REINSTALL_TURBOVNC ]; then + info "installing latest version of turbo vnc" + curl -s https://api.github.com/repos/TurboVNC/turbovnc/releases/latest | grep "browser_download_url.*amd64.deb" | cut -d : -f 2,3 | tr -d \" | wget --show-progress -O ./vnc/turbovnc.deb -qi - + sudo dpkg -i ./vnc/turbovnc.deb # Install turbo vnc +fi + +# utils +hash autocutsel 2>/dev/null || { + info "installing autocutsel for clipboard operations" + if [ $hasUpdated -eq 0 ]; then + sudo apt update + fi + sudo apt install autocutsel +} + +info "updating vnc startup initialization script @ ~/.vnc/xstartup" +cat > ~/.vnc/xstartup << EOF +#!/bin/bash +xrdb $HOME/.Xresources +# autocutsel -s CLIPBOARD -fork +startxfce4 & +EOF + +display=$(/opt/TurboVNC/bin/vncserver -list | grep -E "^:" | awk '{print $1}') + +if [ -z $display ]; then + info "restarting vnc server" + /opt/TurboVNC/bin/vncserver -kill $display + /opt/TurboVNC/bin/vncserver -localhost -depth 24 -geometry 3440x1440 +fi +cd utils + +# Start noVNC +info "starting vnc client and forwarder" +if lsof -t -i:6080; then + kill -9 $(lsof -t -i:6080) +fi + +echo "6080-$WEB_HOST:80" + +./novnc_proxy --vnc localhost:5901 diff --git a/utils/novnc_proxy b/utils/novnc_proxy index 4b2e3032..7d3b4fc0 100755 --- a/utils/novnc_proxy +++ b/utils/novnc_proxy @@ -224,7 +224,7 @@ fi echo -e "\n\nNavigate to this URL:\n" if [ "x$SSLONLY" == "x" ]; then - echo -e " http://${HOST}:${PORT}/vnc.html?host=${HOST}&port=${PORT}\n" + echo -e " ${PORT}-${WEB_HOST}/vnc.html\n" else echo -e " https://${HOST}:${PORT}/vnc.html?host=${HOST}&port=${PORT}\n" fi diff --git a/utils/shell-logger b/utils/shell-logger new file mode 100644 index 00000000..9ec4f9dc --- /dev/null +++ b/utils/shell-logger @@ -0,0 +1,258 @@ +#!/usr/bin/env bash + +## Description {{{ +# +# Logger for shell script. +# +# Homepage: https://github.com/rcmdnk/shell-logger +# +_LOGGER_NAME="shell-logger" +_LOGGER_VERSION="v0.2.0" +_LOGGER_DATE="04/Feb/2019" +# }}} + +## License {{{ +# +#MIT License +# +#Copyright (c) 2017 rcmdnk +# +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. +# }}} + +# Default variables {{{ +LOGGER_DATE_FORMAT=${LOGGER_DATE_FORMAT:-'%Y/%m/%d %H:%M:%S'} +LOGGER_LEVEL=${LOGGER_LEVEL:-1} # 0: debug, 1: info, 2: notice, 3: warning, 4: error +LOGGER_STDERR_LEVEL=${LOGGER_STDERR_LEVEL:-4} +LOGGER_DEBUG_COLOR=${LOGGER_DEBUG_COLOR:-"3"} +LOGGER_INFO_COLOR=${LOGGER_INFO_COLOR:-""} +LOGGER_NOTICE_COLOR=${LOGGER_NOTICE_COLOR:-"36"} +LOGGER_WARNING_COLOR=${LOGGER_WARNING_COLOR:-"33"} +LOGGER_ERROR_COLOR=${LOGGER_ERROR_COLOR:-"31"} +LOGGER_COLOR=${LOGGER_COLOR:-auto} +LOGGER_COLORS=("$LOGGER_DEBUG_COLOR" "$LOGGER_INFO_COLOR" "$LOGGER_NOTICE_COLOR" "$LOGGER_WARNING_COLOR" "$LOGGER_ERROR_COLOR") +if [ "${LOGGER_LEVELS:-}" = "" ];then + LOGGER_LEVELS=("DEBUG" "INFO" "NOTICE" "WARNING" "ERROR") +fi +LOGGER_SHOW_TIME=${LOGGER_SHOW_TIME:-1} +LOGGER_SHOW_FILE=${LOGGER_SHOW_FILE:-1} +LOGGER_SHOW_LEVEL=${LOGGER_SHOW_LEVEL:-1} +LOGGER_ERROR_RETURN_CODE=${LOGGER_ERROR_RETURN_CODE:-100} +LOGGER_ERROR_TRACE=${LOGGER_ERROR_TRACE:-1} +# }}} + +# Other global variables {{{ +_LOGGER_WRAP=0 +#}}} + +# Functions {{{ +_logger_version () { + printf "%s %s %s\\n" "$_LOGGER_NAME" "$_LOGGER_VERSION" "$_LOGGER_DATE" +} + +_get_level () { + if [ $# -eq 0 ];then + local level=1 + else + local level=$1 + fi + if ! expr "$level" : '[0-9]*' >/dev/null;then + [ -z "${ZSH_VERSION:-}" ] || emulate -L ksh + local i=0 + while [ $i -lt ${#LOGGER_LEVELS[@]} ];do + if [ "$level" = "${LOGGER_LEVELS[$i]}" ];then + level=$i + break + fi + ((i++)) + done + fi + echo $level +} + +_logger_level () { + [ "$LOGGER_SHOW_LEVEL" -ne 1 ] && return + if [ $# -eq 1 ];then + local level=$1 + else + local level=1 + fi + [ -z "${ZSH_VERSION:-}" ] || emulate -L ksh + printf "[${LOGGER_LEVELS[$level]}]" +} + +_logger_time () { + [ "$LOGGER_SHOW_TIME" -ne 1 ] && return + printf "[$(date +"$LOGGER_DATE_FORMAT")]" +} + +_logger_file () { + [ "$LOGGER_SHOW_FILE" -ne 1 ] && return + local i=0 + if [ $# -ne 0 ];then + i=$1 + fi + if [ -n "$BASH_VERSION" ];then + printf "[${BASH_SOURCE[$((i+1))]}:${BASH_LINENO[$i]}]" + else + emulate -L ksh + printf "[${funcfiletrace[$i]}]" + fi +} + +_logger () { + ((_LOGGER_WRAP++)) || true + local wrap=${_LOGGER_WRAP} + _LOGGER_WRAP=0 + if [ $# -eq 0 ];then + return + fi + local level="$1" + shift + if [ "$level" -lt "$(_get_level "$LOGGER_LEVEL")" ];then + return + fi + local msg_prefix="$(_logger_time)$(_logger_file "$wrap")$(_logger_level "$level")" + local msg="${msg_prefix:+$msg_prefix }$*" # add prefix with a space only if prefix not is empty + msg="${msg/\$/\\\$}" # escape $ is msg to be able to use eval below without trying to resolve a variable + local _logger_printf=printf + local out=1 + if [ "$level" -ge "$LOGGER_STDERR_LEVEL" ];then + out=2 + _logger_printf=">&2 printf" + fi + if [ "$LOGGER_COLOR" = "always" ] || { test "$LOGGER_COLOR" = "auto" && test -t $out ; };then + [ -z "${ZSH_VERSION:-}" ] || emulate -L ksh + eval "$_logger_printf \"\\e[${LOGGER_COLORS[$level]}m%s\\e[m\\n\" \"$msg\"" + else + eval "$_logger_printf \"%s\\n\" \"$msg\"" + fi +} + +debug () { + ((_LOGGER_WRAP++)) || true + _logger 0 "$*" +} + +information () { + ((_LOGGER_WRAP++)) || true + _logger 1 "$*" +} +info () { + ((_LOGGER_WRAP++)) || true + information "$*" +} + +notification () { + ((_LOGGER_WRAP++)) || true + _logger 2 "$*" +} +notice () { + ((_LOGGER_WRAP++)) || true + notification "$*" +} + +warning () { + ((_LOGGER_WRAP++)) || true + _logger 3 "$*" +} +warn () { + ((_LOGGER_WRAP++)) || true + warning "$*" +} + +error () { + ((_LOGGER_WRAP++)) || true + if [ "$LOGGER_ERROR_TRACE" -eq 1 ];then + { + [ -z "${ZSH_VERSION:-}" ] || emulate -L ksh + local first=0 + if [ -n "$BASH_VERSION" ];then + local current_source=$(echo "${BASH_SOURCE[0]##*/}"|cut -d"." -f1) + local func="${FUNCNAME[1]}" + local i=$((${#FUNCNAME[@]}-2)) + else + local current_source=$(echo "${funcfiletrace[0]##*/}"|cut -d":" -f1|cut -d"." -f1) + local func="${funcstack[1]}" + local i=$((${#funcstack[@]}-1)) + local last_source=${funcfiletrace[$i]%:*} + if [ "$last_source" = zsh ];then + ((i--)) + fi + fi + if [ "$current_source" = "shell-logger" ] && [ "$func" = err ];then + local first=1 + fi + if [ $i -ge $first ];then + echo "Traceback (most recent call last):" + fi + while [ $i -ge $first ];do + if [ -n "$BASH_VERSION" ];then + local file=${BASH_SOURCE[$((i+1))]} + local line=${BASH_LINENO[$i]} + local func="" + if [ ${BASH_LINENO[$((i+1))]} -ne 0 ];then + if [ "${FUNCNAME[$((i+1))]}" = "source" ];then + func=", in ${BASH_SOURCE[$((i+2))]}" + else + func=", in ${FUNCNAME[$((i+1))]}" + fi + fi + local func_call="${FUNCNAME[$i]}" + if [ "$func_call" = "source" ];then + func_call="${func_call} ${BASH_SOURCE[$i]}" + else + func_call="${func_call}()" + fi + else + local file=${funcfiletrace[$i]%:*} + local line=${funcfiletrace[$i]#*:} + local func="" + if [ -n "${funcstack[$((i+1))]}" ];then + if [ "${funcstack[$((i+1))]}" = "${funcfiletrace[$i]%:*}" ];then + func=", in ${funcfiletrace[$((i+1))]%:*}" + else + func=", in ${funcstack[$((i+1))]}" + fi + fi + local func_call="${funcstack[$i]}" + if [ "$func_call" = "${funcfiletrace[$((i-1))]%:*}" ];then + func_call="source ${funcfiletrace[$((i-1))]%:*}" + else + func_call="${func_call}()" + fi + fi + echo " File \"${file}\", line ${line}${func}" + if [ $i -gt $first ];then + echo " $func_call" + else + echo "" + fi + ((i--)) + done + } 1>&2 + fi + _logger 4 "$*" + return "$LOGGER_ERROR_RETURN_CODE" +} +err () { + ((_LOGGER_WRAP++)) || true + error "$*" +} +# }}} \ No newline at end of file diff --git a/vnc/.gitkeep b/vnc/.gitkeep new file mode 100644 index 00000000..e69de29b