diff --git a/Dockerfile b/Dockerfile index 9eba7e3..c2ee4a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,18 +12,23 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM ubuntu:14.04 +#FROM ubuntu:14.04 +FROM ubuntu:20.04 ENV DEBIAN_FRONTEND noninteractive ENV HOME /root -RUN apt-get update && apt-get install -y --force-yes --no-install-recommends \ - supervisor xinetd x11vnc xvfb xdotool x11-utils curl unzip openjdk-7-jre \ - x11-xserver-utils xmlstarlet iptables xloadimage \ - && apt-get autoclean && apt-get autoremove && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -yyq --no-install-recommends \ + supervisor x11vnc xvfb xdotool x11-utils curl unzip openjdk-8-jre \ + x11-xserver-utils xmlstarlet iptables xloadimage git python3-pip \ + && pip3 install numpy \ + && apt-get autoclean && apt-get autoremove && rm -rf /var/lib/apt/lists/* \ + || exit ${?} ADD etc /etc ADD opt /opt +RUN tar xfz /opt/kvm-console/noVNC.tgz -C /opt/kvm-console + # The delay (in seconds) between connections before the container is terminated ENV CONSOLE_TTL "3600" @@ -36,14 +41,23 @@ ENV SPLASH_IMAGE "" # Screen size to show until we get the application working ENV SPLASH_SIZE "" +# The VNC password to use +ENV VNC_PASSWORD "no-password" + # The username to use when connecting to the BMC ENV IPMI_USERNAME "ADMIN" # The password to use when connecting to the BMC ENV IPMI_PASSWORD "ADMIN" +# The noVNC inactivity timeout (in seconds) +ENV INACTIVITY_TIMEOUT 1800 + # The address of the BMC to connect (MANDATORY) # Define with `docker run -e IPMI_ADDRESS=
` #ENV IPMI_ADDRESS "192.0.2.10" -EXPOSE 5900 +HEALTHCHECK --interval=10s --retries=3 --start-period=30s CMD /opt/kvm-console/bin/activity-watcher.sh + +#EXPOSE 5900 +EXPOSE 8080 ENTRYPOINT ["/opt/kvm-console/bin/startup.sh"] diff --git a/console-supermicro.sh b/console-supermicro.sh index e1b14dd..c422a99 100755 --- a/console-supermicro.sh +++ b/console-supermicro.sh @@ -6,7 +6,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -14,15 +14,38 @@ # See the License for the specific language governing permissions and # limitations under the License. +_console_supermicro() { + if [ 0 = ${#} ] || [ 3 -lt ${#} ] ; then + echo 'usage: console-supermicro.sh [username] [password]' + return + fi + docker build -t internap/kvm-console-supermicro $(dirname ${0}) || return ${?} -docker build -t internap/kvm-console-supermicro $(dirname ${0}) + id=$(docker run -P -d \ + -e IPMI_ADDRESS=${1} \ + -e IPMI_USERNAME=${2-ADMIN} \ + -e IPMI_PASSWORD=${3-ADMIN} \ + internap/kvm-console-supermicro) + if [ "" = "${id}" ] ; then + echo could not get container id: + docker ps | grep internap/kvm-console-supermicro + return 1 + fi -id=$(docker run -P -d \ - -e IPMI_ADDRESS=${1} \ - -e IPMI_USERNAME=${2-ADMIN} \ - -e IPMI_PASSWORD=${3-ADMIN} \ - internap/kvm-console-supermicro) + sleep 2 -sleep 2 -vncviewer $(docker port $id | cut -d ' ' -f 3) -docker rm --force $id + local port=$( docker port $id | sed 's,.*:,,' ) + local url="http://localhost:${port}/vnc.html?host=localhost&port=${port}&autoconnect=true&password=no-password" + echo ${url} | sed 's,.,-,g' + echo ${url} + echo ${url} | sed 's,.,-,g' + + echo hit enter to end me + read + + docker rm --force ${id} + + echo bye +} + +_console_supermicro ${*} diff --git a/etc/supervisor/conf.d/idle-timeout.conf b/etc/supervisor/conf.d/idle-timeout.conf index 09d2b81..4f150d7 100644 --- a/etc/supervisor/conf.d/idle-timeout.conf +++ b/etc/supervisor/conf.d/idle-timeout.conf @@ -17,8 +17,7 @@ priority=1 directory=/ command=/bin/bash -c '[ "$CONSOLE_TTL" ] && sleep $CONSOLE_TTL && supervisorctl shutdown' user=root -autostart=true +autostart=false stopsignal=KILL -stdout_logfile=/var/log/idle-timeout.log +stdout_logfile=/var/log/supervisor/idle-timeout.log redirect_stderr=true - diff --git a/etc/supervisor/conf.d/xinetd.conf b/etc/supervisor/conf.d/novnc.conf similarity index 79% rename from etc/supervisor/conf.d/xinetd.conf rename to etc/supervisor/conf.d/novnc.conf index d842d43..24e9a2f 100644 --- a/etc/supervisor/conf.d/xinetd.conf +++ b/etc/supervisor/conf.d/novnc.conf @@ -12,15 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -[program:xinetd] -priority=5 -directory=/ -command=/usr/sbin/xinetd -dontfork -user=root -autostart=true +[program:novnc] +command=/opt/kvm-console/bin/novnc.sh autorestart=true -stopsignal=QUIT -environment=HOME="/home/kvm-console" -stdout_logfile=/var/log/xinetd.log +autostart=true +priority=4 +user=root +stdout_logfile=/var/log/supervisor/novnc.log redirect_stderr=true - diff --git a/etc/supervisor/conf.d/viewer-app.conf b/etc/supervisor/conf.d/viewer-app.conf index 190d85e..8b1123a 100644 --- a/etc/supervisor/conf.d/viewer-app.conf +++ b/etc/supervisor/conf.d/viewer-app.conf @@ -17,10 +17,9 @@ priority=15 directory=/home/kvm-console command=/opt/kvm-console/bin/viewer-app.sh user=kvm-console -autostart=false +autostart=true autorestart=true stopsignal=QUIT environment=DISPLAY=":1",HOME="/home/kvm-console" -stdout_logfile=/var/log/viewer-app.log +stdout_logfile=/var/log/supervisor/viewer-app.log redirect_stderr=true - diff --git a/etc/supervisor/conf.d/vnc-export-app.conf b/etc/supervisor/conf.d/vnc-export-app.conf index cfc9326..92b1079 100644 --- a/etc/supervisor/conf.d/vnc-export-app.conf +++ b/etc/supervisor/conf.d/vnc-export-app.conf @@ -17,11 +17,11 @@ priority=16 directory=/home/kvm-console command=/opt/kvm-console/bin/vnc-export-app.sh user=kvm-console -autostart=false -autorestart=true +autostart=true +autorestart=false stopsignal=QUIT environment=DISPLAY=":1",HOME="/home/kvm-console" -stdout_logfile=/var/log/vnc-export-app.log +stdout_logfile=/var/log/supervisor/vnc-export-app.log redirect_stderr=true stopsignal=KILL diff --git a/etc/supervisor/conf.d/vnc-server.conf b/etc/supervisor/conf.d/vnc-server.conf index 54de68e..360b5a8 100644 --- a/etc/supervisor/conf.d/vnc-server.conf +++ b/etc/supervisor/conf.d/vnc-server.conf @@ -16,11 +16,10 @@ priority=20 directory=/ command=/opt/kvm-console/bin/vnc-server.sh -user=kvm-console -autostart=false +user=root +autostart=true autorestart=true stopsignal=QUIT environment=DISPLAY=":1",HOME="/home/kvm-console" -stdout_logfile=/var/log/vnc-server.log +stdout_logfile=/var/log/supervisor/vnc-server.log redirect_stderr=true - diff --git a/etc/supervisor/conf.d/x11-server.conf b/etc/supervisor/conf.d/x11-server.conf index 392b5f1..0a7ec2e 100644 --- a/etc/supervisor/conf.d/x11-server.conf +++ b/etc/supervisor/conf.d/x11-server.conf @@ -17,9 +17,8 @@ priority=10 directory=/ command=/usr/bin/Xvfb :1 -screen 0 1200x800x16 -dpms user=kvm-console -autostart=false +autostart=true autorestart=true stopsignal=QUIT -stdout_logfile=/var/log/x11-server.log +stdout_logfile=/var/log/supervisor/x11-server.log redirect_stderr=true - diff --git a/etc/xinetd.conf b/etc/xinetd.conf deleted file mode 100644 index f28064f..0000000 --- a/etc/xinetd.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2016 Internap. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -service console -{ - type = UNLISTED - socket_type = stream - protocol = tcp - port = 5900 - wait = no - server = /opt/kvm-console/bin/connection-handler.sh - user = root -} diff --git a/opt/kvm-console/bin/activity-watcher.sh b/opt/kvm-console/bin/activity-watcher.sh new file mode 100755 index 0000000..31129e7 --- /dev/null +++ b/opt/kvm-console/bin/activity-watcher.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +export EXPRESSION="listener exit due to --idle-timeout" +export LOG_FILE="/var/log/supervisor/novnc.log" + +_activity_watcher_main() { + local status=0 + + if [ -f "${LOG_FILE}" ] ; then + local idle_count=$( grep -c "${EXPRESSION}" "${LOG_FILE}" ) || return ${?} + if [ "0" = "${idle_count}" ] ; then + _activity_watcher_out "novnc is running" + else + _activity_watcher_out "novnc idled out." + status=${idle_count} + fi + else + _activity_watcher_out "novnc log to watch" + fi + + # may need see uptime or check the log... + local java_count=$( ps -ef | grep -v grep | grep -c 'java ' ) + if [ "0" = "${java_count}" ] ; then + _activity_watcher_out "java is not running" + let status=${status}+1000 + else + _activity_watcher_out "java is running...." + fi + + return ${status} +} + +_activity_watcher_out() { + echo -n "${*} ; " +} + +_activity_watcher_main ${*} diff --git a/opt/kvm-console/bin/connection-handler.sh b/opt/kvm-console/bin/connection-handler.sh deleted file mode 100755 index dc7221e..0000000 --- a/opt/kvm-console/bin/connection-handler.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -# Copyright 2016 Internap. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -tries=30 - -no_active_vnc_session() { - [ `ps x | grep -c '[0-9] nc 127.0.0.1 5901'` -eq 0 ] -} - -establish_reverse_proxy() { - nc 127.0.0.1 5901 2>/dev/null -} - -supervisorctl stop 'idle-timeout' > /dev/null 2>&1 -supervisorctl start 'console:*' > /dev/null 2>&1 -while [ $tries -gt 0 ]; do - if establish_reverse_proxy; then - if no_active_vnc_session; then - supervisorctl start 'idle-timeout' > /dev/null 2>&1 - supervisorctl stop 'console:*' > /dev/null 2>&1 - fi - exit 0 - else - sleep .5 - tries=$((tries-1)) - fi -done -supervisorctl stop 'console:*' > /dev/null 2>&1 -exit 1 diff --git a/opt/kvm-console/bin/novnc.sh b/opt/kvm-console/bin/novnc.sh new file mode 100755 index 0000000..51d2851 --- /dev/null +++ b/opt/kvm-console/bin/novnc.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +export DIRECTORY=/opt/kvm-console/noVNC +export COMMAND="${DIRECTORY}/utils/launch.sh" + +export LISTEN_PORT=8080 +export VNC_URI="localhost:5900" +export VNC_TIMEOUT=${INACTIVITY_TIMEOUT-1800} + +_novnc_main() { + cd ${DIRECTORY} || return {?} + + if [ -f /certificate.pem ] ; then + echo certificate found, starting securely + _novnc_tls + else + echo no certificate found, starting insecurely + _novnc_basic + fi +} + +_novnc_basic() { + ${COMMAND} --web ${DIRECTORY} --listen ${LISTEN_PORT} --vnc ${VNC_URI} --idle-timeout ${VNC_TIMEOUT} +} + +_novnc_tls() { + cat /certificate.pem /certificate-authority.pem > /tmp/combined.pem + ${COMMAND} \ + --listen ${LISTEN_PORT} \ + --vnc ${VNC_URI} \ + --cert /tmp/combined.pem \ + --key /private-key.key \ + --ssl-only \ + --web ${DIRECTORY} + --idle-timeout ${VNC_TIMEOUT} +} + +_novnc_main ${*} diff --git a/opt/kvm-console/bin/startup.sh b/opt/kvm-console/bin/startup.sh index d037b44..ec9257c 100755 --- a/opt/kvm-console/bin/startup.sh +++ b/opt/kvm-console/bin/startup.sh @@ -15,4 +15,6 @@ # limitations under the License. id -u kvm-console &>/dev/null || useradd --create-home --shell /bin/bash --user-group kvm-console +chown -R kvm-console.kvm-console /opt/noVNC* + exec /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf diff --git a/opt/kvm-console/bin/vnc-export-app.sh b/opt/kvm-console/bin/vnc-export-app.sh index 0693840..c3c50a3 100755 --- a/opt/kvm-console/bin/vnc-export-app.sh +++ b/opt/kvm-console/bin/vnc-export-app.sh @@ -14,7 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -while true; do +first_time=1 +for((i=0;i<1;i--)) ; do read winid width height < <(xwininfo -root -tree \ | grep -iE 'Java iKVM Viewer.+Resolution' \ | sed 's/^\(.*\)".*Resolution \([0-9]*\) X \([0-9]*\).*/\1 \2 \3/g') @@ -22,6 +23,8 @@ while true; do [ -z "$winid" ] && [ -z "$width" ] && [ -z "$height" ] && \ sleep 1 && continue + echo "winid is ${winid}: ${width} x ${height}" + width=$((width + 4)) height=$((height + 24)) actual_width=$(x11vnc -query wdpy_x 2>/dev/null | cut -d':' -f 2) @@ -30,9 +33,29 @@ while true; do [ "$width" -eq "$actual_width" ] && [ "$height" -eq "$actual_height" ] && \ sleep 1 && continue + echo "${width} == ${actual_width} and ${height} == ${actual_height}" + echo "clip to ${X11VNC_CLIP}" + xdotool windowfocus $winid windowsize $winid $width $height x11vnc -remote "clip:$X11VNC_CLIP" --sync x11vnc -remote "id:$winid" --sync - /opt/kvm-console/bin/splash-hide.sh + echo "hide the splash screen" + pid=$( pidof xview) + if [ "" = "${pid}" ] ; then + echo xview is not running + exit 0 + else + echo stop xview on ${pid} + kill ${pid} + pid=$( pidof xview) + if [ "" = "${pid}" ] ; then + echo "stopped xview" + exit 0 + else + echo could not stop xview on ${pid} + fi + fi + + sleep 1 done diff --git a/opt/kvm-console/bin/vnc-server.sh b/opt/kvm-console/bin/vnc-server.sh index 4dafb55..512fef5 100755 --- a/opt/kvm-console/bin/vnc-server.sh +++ b/opt/kvm-console/bin/vnc-server.sh @@ -36,4 +36,11 @@ splash_clip=${splash_width}x${splash_height}+${clip_x}+${clip_y} # Disable the screen saver xset s off s reset -exec x11vnc -rfbport 5901 -xkb -shared -forever -desktop "${X11VNC_TITLE-}" -clip $splash_clip +_run_novnc() { + sleep 3 + supervisorctl start novnc +} +_run_novnc 2>&1 | tee -a /tmp/novnc.txt & + +x11vnc -storepasswd ${VNC_PASSWORD} /tmp/vnc-password.txt +exec x11vnc -rfbport 5900 -rfbauth /tmp/vnc-password.txt -ncache 10 --xkb -shared -forever -desktop "${X11VNC_TITLE-}" -clip $splash_clip diff --git a/opt/kvm-console/noVNC.tgz b/opt/kvm-console/noVNC.tgz new file mode 100644 index 0000000..920af61 Binary files /dev/null and b/opt/kvm-console/noVNC.tgz differ