Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5ae8f2d

Browse files
committed
add dogfood
1 parent c11358a commit 5ae8f2d

File tree

5 files changed

+562
-0
lines changed

5 files changed

+562
-0
lines changed

better-vnc/for-dogfood/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
name: KasmVNC
3+
description: Run workspaces on a Docker host using registry images
4+
tags: [local, docker]
5+
icon: /icon/docker.png
6+
---
7+
8+
# KasmVNC in Coder
9+
10+
A significantly better VNC experience with copy & paste.
11+
12+
To get started, run `coder templates init`. When prompted, select this template.
13+
Follow the on-screen instructions to proceed.
14+
15+
## Editing the image
16+
17+
Edit the `Dockerfile` and run `coder templates push` to update workspaces.
18+
19+
## code-server
20+
21+
`code-server` is installed via the `startup_script` argument in the `coder_agent`
22+
resource block. The `coder_app` resource is defined to access `code-server` through
23+
the dashboard UI over `localhost:13337`.
24+
25+
## Extending this template
26+
27+
See the [kreuzwerker/docker](https://registry.terraform.io/providers/kreuzwerker/docker) Terraform provider documentation to
28+
add the following features to your Coder template:
29+
30+
- SSH/TCP docker host
31+
- Registry authentication
32+
- Build args
33+
- Volume mounts
34+
- Custom container spec
35+
- More
36+
37+
We also welcome contributions!
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM kasmweb/desktop:1.12.0
2+
3+
USER root
4+
5+
COPY kasmvnc.yaml /etc/kasmvnc/kasmvnc.yaml
6+
COPY vnc_startup.sh /dockerstartup/vnc_startup.sh
7+
RUN cp -r /home/kasm-user /tmp/kasm-user
8+
RUN apt-get update && apt-get install sudo
9+
RUN echo "kasm-user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers.d/nopasswd
10+
RUN DEBIAN_FRONTEND=noninteractive make-ssl-cert generate-default-snakeoil --force-overwrite
11+
RUN adduser kasm-user ssl-cert
12+
13+
USER 1000
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
network:
2+
protocol: http
3+
ssl:
4+
require_ssl: false
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
#!/bin/bash
2+
### every exit != 0 fails the script
3+
set -e
4+
5+
no_proxy="localhost,127.0.0.1"
6+
7+
# dict to store processes
8+
declare -A KASM_PROCS
9+
10+
# switch passwords to local variables
11+
tmpval=$VNC_VIEW_ONLY_PW
12+
unset VNC_VIEW_ONLY_PW
13+
VNC_VIEW_ONLY_PW=$tmpval
14+
tmpval=$VNC_PW
15+
unset VNC_PW
16+
VNC_PW=$tmpval
17+
BUILD_ARCH=$(uname -p)
18+
19+
STARTUP_COMPLETE=0
20+
21+
######## FUNCTION DECLARATIONS ##########
22+
23+
## print out help
24+
function help (){
25+
echo "
26+
USAGE:
27+
28+
OPTIONS:
29+
-w, --wait (default) keeps the UI and the vncserver up until SIGINT or SIGTERM will received
30+
-s, --skip skip the vnc startup and just execute the assigned command.
31+
example: docker run kasmweb/core --skip bash
32+
-d, --debug enables more detailed startup output
33+
e.g. 'docker run kasmweb/core --debug bash'
34+
-h, --help print out this help
35+
36+
Fore more information see: https://github.com/ConSol/docker-headless-vnc-container
37+
"
38+
}
39+
40+
## correct forwarding of shutdown signal
41+
function cleanup () {
42+
kill -s SIGTERM $!
43+
exit 0
44+
}
45+
46+
function start_kasmvnc (){
47+
if [[ $DEBUG == true ]]; then
48+
echo -e "\n------------------ Start KasmVNC Server ------------------------"
49+
fi
50+
51+
DISPLAY_NUM=$(echo $DISPLAY | grep -Po ':\d+')
52+
53+
if [[ $STARTUP_COMPLETE == 0 ]]; then
54+
vncserver -kill $DISPLAY &> $STARTUPDIR/vnc_startup.log \
55+
|| rm -rfv /tmp/.X*-lock /tmp/.X11-unix &> $STARTUPDIR/vnc_startup.log \
56+
|| echo "no locks present"
57+
fi
58+
59+
rm -rf $HOME/.vnc/*.pid
60+
61+
VNCOPTIONS="$VNCOPTIONS -select-de manual"
62+
if [[ "${BUILD_ARCH}" =~ ^aarch64$ ]] && [[ -f /lib/aarch64-linux-gnu/libgcc_s.so.1 ]] ; then
63+
LD_PRELOAD=/lib/aarch64-linux-gnu/libgcc_s.so.1 vncserver $DISPLAY -disableBasicAuth -depth $VNC_COL_DEPTH -geometry $VNC_RESOLUTION -websocketPort $NO_VNC_PORT -httpd ${KASM_VNC_PATH}/www -FrameRate=$MAX_FRAME_RATE -interface 0.0.0.0 -BlacklistThreshold=0 -FreeKeyMappings $VNCOPTIONS $KASM_SVC_SEND_CUT_TEXT $KASM_SVC_ACCEPT_CUT_TEXT
64+
else
65+
vncserver $DISPLAY -disableBasicAuth -depth $VNC_COL_DEPTH -geometry $VNC_RESOLUTION -websocketPort $NO_VNC_PORT -httpd ${KASM_VNC_PATH}/www -FrameRate=$MAX_FRAME_RATE -interface 0.0.0.0 -BlacklistThreshold=0 -FreeKeyMappings $VNCOPTIONS $KASM_SVC_SEND_CUT_TEXT $KASM_SVC_ACCEPT_CUT_TEXT
66+
fi
67+
68+
KASM_PROCS['kasmvnc']=$(cat $HOME/.vnc/*${DISPLAY_NUM}.pid)
69+
70+
if [[ $DEBUG == true ]]; then
71+
echo -e "\n------------------ Started Websockify ----------------------------"
72+
echo "Websockify PID: ${KASM_PROCS['kasmvnc']}";
73+
fi
74+
}
75+
76+
function start_window_manager (){
77+
echo -e "\n------------------ Xfce4 window manager startup------------------"
78+
79+
if [ "${START_XFCE4}" == "1" ] ; then
80+
if [ -f /opt/VirtualGL/bin/vglrun ] && [ ! -z "${KASM_EGL_CARD}" ] && [ ! -z "${KASM_RENDERD}" ] && [ -O "${KASM_RENDERD}" ] && [ -O "${KASM_EGL_CARD}" ] ; then
81+
echo "Starting XFCE with VirtualGL using EGL device ${KASM_EGL_CARD}"
82+
DISPLAY=:1 /opt/VirtualGL/bin/vglrun -d "${KASM_EGL_CARD}" /usr/bin/startxfce4 --replace &
83+
else
84+
echo "Starting XFCE"
85+
if [ -f '/usr/bin/zypper' ]; then
86+
DISPLAY=:1 /usr/bin/dbus-launch /usr/bin/startxfce4 --replace &
87+
else
88+
/usr/bin/startxfce4 --replace &
89+
fi
90+
fi
91+
KASM_PROCS['window_manager']=$!
92+
else
93+
echo "Skipping XFCE Startup"
94+
fi
95+
}
96+
97+
function start_audio_out_websocket (){
98+
if [[ ${KASM_SVC_AUDIO:-1} == 1 ]]; then
99+
echo 'Starting audio websocket server'
100+
$STARTUPDIR/jsmpeg/kasm_audio_out-linux kasmaudio 8081 4901 ${HOME}/.vnc/self.pem ${HOME}/.vnc/self.pem "kasm_user:$VNC_PW" &
101+
102+
KASM_PROCS['kasm_audio_out_websocket']=$!
103+
104+
if [[ $DEBUG == true ]]; then
105+
echo -e "\n------------------ Started Audio Out Websocket ----------------------------"
106+
echo "Kasm Audio Out Websocket PID: ${KASM_PROCS['kasm_audio_out_websocket']}";
107+
fi
108+
fi
109+
}
110+
111+
function start_audio_out (){
112+
if [[ ${KASM_SVC_AUDIO:-1} == 1 ]]; then
113+
echo 'Starting audio server'
114+
115+
if [ "${START_PULSEAUDIO:-0}" == "1" ] ;
116+
then
117+
echo "Starting Pulse"
118+
HOME=/var/run/pulse pulseaudio --start
119+
fi
120+
121+
if [[ $DEBUG == true ]]; then
122+
echo 'Starting audio service in debug mode'
123+
HOME=/var/run/pulse no_proxy=127.0.0.1 ffmpeg -f pulse -fragment_size ${PULSEAUDIO_FRAGMENT_SIZE:-2000} -ar 44100 -i default -f mpegts -correct_ts_overflow 0 -codec:a mp2 -b:a 128k -ac 1 -muxdelay 0.001 http://127.0.0.1:8081/kasmaudio &
124+
KASM_PROCS['kasm_audio_out']=$!
125+
else
126+
echo 'Starting audio service'
127+
HOME=/var/run/pulse no_proxy=127.0.0.1 ffmpeg -v verbose -f pulse -fragment_size ${PULSEAUDIO_FRAGMENT_SIZE:-2000} -ar 44100 -i default -f mpegts -correct_ts_overflow 0 -codec:a mp2 -b:a 128k -ac 1 -muxdelay 0.001 http://127.0.0.1:8081/kasmaudio > /dev/null 2>&1 &
128+
KASM_PROCS['kasm_audio_out']=$!
129+
echo -e "\n------------------ Started Audio Out ----------------------------"
130+
echo "Kasm Audio Out PID: ${KASM_PROCS['kasm_audio_out']}";
131+
fi
132+
fi
133+
}
134+
135+
function start_audio_in (){
136+
if [[ ${KASM_SVC_AUDIO_INPUT:-1} == 1 ]]; then
137+
echo 'Starting audio input server'
138+
$STARTUPDIR/audio_input/kasm_audio_input_server --ssl --auth-token "kasm_user:$VNC_PW" --cert ${HOME}/.vnc/self.pem --certkey ${HOME}/.vnc/self.pem &
139+
140+
KASM_PROCS['kasm_audio_in']=$!
141+
142+
if [[ $DEBUG == true ]]; then
143+
echo -e "\n------------------ Started Audio Out Websocket ----------------------------"
144+
echo "Kasm Audio In PID: ${KASM_PROCS['kasm_audio_in']}";
145+
fi
146+
fi
147+
}
148+
149+
function start_upload (){
150+
if [[ ${KASM_SVC_UPLOADS:-1} == 1 ]]; then
151+
echo 'Starting upload server'
152+
$STARTUPDIR/upload_server/kasm_upload_server --ssl --auth-token "kasm_user:$VNC_PW" &
153+
154+
KASM_PROCS['upload_server']=$!
155+
156+
if [[ $DEBUG == true ]]; then
157+
echo -e "\n------------------ Started Audio Out Websocket ----------------------------"
158+
echo "Kasm Audio In PID: ${KASM_PROCS['upload_server']}";
159+
fi
160+
fi
161+
}
162+
163+
function start_gamepad (){
164+
if [[ ${KASM_SVC_GAMEPAD:-1} == 1 ]]; then
165+
echo 'Starting gamepad server'
166+
$STARTUPDIR/gamepad/kasm_gamepad_server --ssl --auth-token "kasm_user:$VNC_PW" --cert ${HOME}/.vnc/self.pem --certkey ${HOME}/.vnc/self.pem &
167+
168+
KASM_PROCS['kasm_gamepad']=$!
169+
170+
if [[ $DEBUG == true ]]; then
171+
echo -e "\n------------------ Started Gamepad Websocket ----------------------------"
172+
echo "Kasm Gamepad PID: ${KASM_PROCS['kasm_gamepad']}";
173+
fi
174+
fi
175+
}
176+
177+
function custom_startup (){
178+
custom_startup_script=/dockerstartup/custom_startup.sh
179+
if [ -f "$custom_startup_script" ]; then
180+
if [ ! -x "$custom_startup_script" ]; then
181+
echo "${custom_startup_script}: not executable, exiting"
182+
exit 1
183+
fi
184+
185+
"$custom_startup_script" &
186+
KASM_PROCS['custom_startup']=$!
187+
fi
188+
}
189+
190+
############ END FUNCTION DECLARATIONS ###########
191+
192+
if [[ $1 =~ -h|--help ]]; then
193+
help
194+
exit 0
195+
fi
196+
197+
# should also source $STARTUPDIR/generate_container_user
198+
if [ -f $HOME/.bashrc ]; then
199+
source $HOME/.bashrc
200+
fi
201+
202+
if [[ ${KASM_DEBUG:-0} == 1 ]]; then
203+
echo -e "\n\n------------------ DEBUG KASM STARTUP -----------------"
204+
export DEBUG=true
205+
set -x
206+
fi
207+
208+
trap cleanup SIGINT SIGTERM
209+
210+
## resolve_vnc_connection
211+
VNC_IP=$(hostname -i)
212+
if [[ $DEBUG == true ]]; then
213+
echo "IP Address used for external bind: $VNC_IP"
214+
fi
215+
216+
# Create cert for KasmVNC
217+
mkdir -p ${HOME}/.vnc
218+
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout ${HOME}/.vnc/self.pem -out ${HOME}/.vnc/self.pem -subj "/C=US/ST=VA/L=None/O=None/OU=DoFu/CN=kasm/[email protected]"
219+
220+
# first entry is control, second is view (if only one is valid for both)
221+
mkdir -p "$HOME/.vnc"
222+
PASSWD_PATH="$HOME/.kasmpasswd"
223+
if [[ -f $PASSWD_PATH ]]; then
224+
echo -e "\n--------- purging existing VNC password settings ---------"
225+
rm -f $PASSWD_PATH
226+
fi
227+
VNC_PW_HASH=$(python3 -c "import crypt; print(crypt.crypt('${VNC_PW}', '\$5\$kasm\$'));")
228+
VNC_VIEW_PW_HASH=$(python3 -c "import crypt; print(crypt.crypt('${VNC_VIEW_ONLY_PW}', '\$5\$kasm\$'));")
229+
echo "kasm_user:${VNC_PW_HASH}:ow" > $PASSWD_PATH
230+
echo "kasm_viewer:${VNC_VIEW_PW_HASH}:" >> $PASSWD_PATH
231+
chmod 600 $PASSWD_PATH
232+
233+
234+
# start processes
235+
start_kasmvnc
236+
start_window_manager
237+
start_audio_out_websocket
238+
start_audio_out
239+
start_audio_in
240+
start_upload
241+
start_gamepad
242+
243+
STARTUP_COMPLETE=1
244+
245+
246+
## log connect options
247+
echo -e "\n\n------------------ KasmVNC environment started ------------------"
248+
249+
# tail vncserver logs
250+
tail -f $HOME/.vnc/*$DISPLAY.log &
251+
252+
KASMIP=$(hostname -i)
253+
echo "Kasm User ${KASM_USER}(${KASM_USER_ID}) started container id ${HOSTNAME} with local IP address ${KASMIP}"
254+
255+
# start custom startup script
256+
custom_startup
257+
258+
# Monitor Kasm Services
259+
sleep 3
260+
while :
261+
do
262+
for process in "${!KASM_PROCS[@]}"; do
263+
if ! kill -0 "${KASM_PROCS[$process]}" ; then
264+
265+
# If DLP Policy is set to fail secure, default is to be resilient
266+
if [[ ${DLP_PROCESS_FAIL_SECURE:-0} == 1 ]]; then
267+
exit 1
268+
fi
269+
270+
case $process in
271+
kasmvnc)
272+
if [ "$KASMVNC_AUTO_RECOVER" = true ] ; then
273+
echo "KasmVNC crashed, restarting"
274+
start_kasmvnc
275+
else
276+
echo "KasmVNC crashed, exiting container"
277+
exit 1
278+
fi
279+
;;
280+
window_manager)
281+
echo "Window manager crashed, restarting"
282+
start_window_manager
283+
;;
284+
kasm_audio_out_websocket)
285+
echo "Restarting Audio Out Websocket Service"
286+
start_audio_out_websocket
287+
;;
288+
kasm_audio_out)
289+
echo "Restarting Audio Out Service"
290+
start_audio_out
291+
;;
292+
kasm_audio_in)
293+
echo "Audio In Service Failed"
294+
# TODO: Needs work in python project to support auto restart
295+
# start_audio_in
296+
;;
297+
upload_server)
298+
echo "Restarting Upload Service"
299+
# TODO: This will only work if both processes are killed, requires more work
300+
start_upload
301+
;;
302+
kasm_gamepad)
303+
echo "Gamepad Service Failed"
304+
# TODO: Needs work in python project to support auto restart
305+
# start_gamepad
306+
;;
307+
custom_script)
308+
echo "The custom startup script exited."
309+
# custom startup scripts track the target process on their own, they should not exit
310+
custom_startup
311+
;;
312+
*)
313+
echo "Unknown Service: $process"
314+
;;
315+
esac
316+
fi
317+
done
318+
sleep 3
319+
done
320+
321+
322+
echo "Exiting Kasm container"

0 commit comments

Comments
 (0)