Files
Stend_mont/universal-runtime/entrypoint.sh

111 lines
3.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
IDLE_TIMEOUT="${IDLE_TIMEOUT:-1800}"
SCREEN_GEOMETRY="${SCREEN_GEOMETRY:-1920x1080x24}"
CHROME_WINDOW_SIZE="${CHROME_WINDOW_SIZE:-1920,1080}"
ENABLE_HEARTBEAT="${ENABLE_HEARTBEAT:-1}"
DISPLAY_NUM="${DISPLAY_NUM:-:1}"
mkdir -p /opt/portal
cp -r /usr/share/novnc/* /opt/portal/
cat > /opt/portal/index.html <<'HTML'
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Universal Session</title>
<style>
html,body,#screen{margin:0;height:100%;background:#111}
.status{
position:fixed;
left:12px;
top:12px;
z-index:50;
padding:8px 10px;
border-radius:8px;
background:rgba(16,22,32,.86);
border:1px solid rgba(255,255,255,.18);
color:#dce8f5;
font:600 13px/1.25 sans-serif;
max-width:min(92vw,560px);
}
.status.error{
background:rgba(85,20,20,.9);
border-color:rgba(255,130,130,.36);
color:#ffe3e3;
}
.status.hidden{display:none}
</style>
</head>
<body>
<div id="screen"></div>
<div id="status" class="status">Подключение к слоту...</div>
<script type="module">
import RFB from './core/rfb.js';
const basePath = location.pathname.replace(/\/+$/, '');
const wsUrl = (location.protocol === 'https:' ? 'wss://' : 'ws://') + location.host + basePath + '/websockify';
const statusEl = document.getElementById('status');
let connected = false;
let connectTimer = null;
function showStatus(text, isError = false) {
statusEl.textContent = text;
statusEl.classList.toggle('error', !!isError);
statusEl.classList.remove('hidden');
}
function hideStatus() {
statusEl.classList.add('hidden');
}
showStatus('Подключение к слоту...');
connectTimer = setTimeout(() => {
if (!connected) {
showStatus('Нет подключения к экрану слота. Откройте сервис заново из дашборда.', true);
}
}, 8000);
const rfb = new RFB(document.getElementById('screen'), wsUrl);
rfb.viewOnly = false;
rfb.scaleViewport = true;
rfb.resizeSession = true;
rfb.addEventListener('connect', () => {
connected = true;
if (connectTimer) clearTimeout(connectTimer);
hideStatus();
});
rfb.addEventListener('disconnect', () => {
connected = false;
showStatus('Соединение со слотом потеряно. Запустите сервис заново.', true);
});
const enableHeartbeat = (new URLSearchParams(location.search).get('hb') ?? '1') !== '0';
const sid = new URLSearchParams(location.search).get('sid');
async function touch() {
if (!sid) return;
try {
await fetch(`/api/sessions/${sid}/touch`, {method:'POST', credentials:'include'});
} catch (e) {}
}
if (enableHeartbeat) {
setInterval(touch, 60000);
touch();
}
document.addEventListener('contextmenu', (e) => e.preventDefault());
</script>
</body>
</html>
HTML
export DISPLAY="$DISPLAY_NUM"
export CHROME_WINDOW_SIZE
Xvfb "$DISPLAY_NUM" -screen 0 "$SCREEN_GEOMETRY" >/tmp/xvfb.log 2>&1 &
fluxbox >/tmp/fluxbox.log 2>&1 &
python3 /manager.py >/tmp/manager.log 2>&1 &
x11vnc -display "$DISPLAY_NUM" -rfbport 5900 -forever -shared -nopw -noxdamage >/tmp/x11vnc.log 2>&1 &
exec websockify --verbose --idle-timeout="$IDLE_TIMEOUT" --web=/opt/portal 6080 localhost:5900