Skip to content

Commit d5fbade

Browse files
committed
test-guac: connection menu
1 parent c4dbd75 commit d5fbade

File tree

5 files changed

+136
-30
lines changed

5 files changed

+136
-30
lines changed

test-guac/desktop-linux/Dockerfile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ ENV DEBIAN_FRONTEND=noninteractive \
55
PASSWORD=Passw0rd!
66

77
# -------------------------------------------------
8-
# Base desktop stack + a few demo X11 apps
8+
# Base desktop stack + a few demo X11 apps + VNC
99
# -------------------------------------------------
1010
RUN apt-get update && \
1111
apt-get install -y --no-install-recommends \
1212
xrdp xorgxrdp \
1313
xfce4 xfce4-goodies dbus-x11 \
1414
xterm x11-apps \
15+
x11vnc xvfb \
1516
sudo \
1617
&& apt-get clean && rm -rf /var/lib/apt/lists/*
1718

@@ -32,8 +33,8 @@ RUN chmod +x /home/${USERNAME}/.xsession
3233
# Create Desktop directory
3334
RUN mkdir /home/${USERNAME}/Desktop && chown "${USERNAME}:${USERNAME}" /home/${USERNAME}/Desktop
3435

35-
# -------------------------------------------------
36-
# Expose RDP port and launch XRDP
37-
# -------------------------------------------------
38-
EXPOSE 3389
39-
CMD ["/bin/sh", "-c", "/usr/sbin/xrdp-sesman && exec /usr/sbin/xrdp -nodaemon"]
36+
COPY config/start-desktop.sh /usr/local/bin/start-desktop.sh
37+
RUN chmod +x /usr/local/bin/start-desktop.sh
38+
39+
EXPOSE 3389 5900
40+
CMD ["/usr/local/bin/start-desktop.sh"]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
export DISPLAY=:0
4+
5+
Xvfb :0 -screen 0 1280x720x24 &
6+
XVFB_PID=$!
7+
8+
# run XFCE inside its own dbus session on :0
9+
su -l "$USERNAME" -c "DISPLAY=:0 dbus-run-session -- xfce4-session" &
10+
XFCE_PID=$!
11+
12+
x11vnc -noxdamage -display :0 -forever -shared \
13+
-rfbport 5900 -passwd "$PASSWORD" &
14+
15+
/usr/sbin/xrdp-sesman &
16+
exec /usr/sbin/xrdp -nodaemon

test-guac/docker-compose.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ services:
99
build: ./desktop-linux
1010
container_name: desktop-linux
1111
shm_size: 1g
12-
expose: [ "3389" ]
12+
expose:
13+
- "3389" # RDP Port
14+
- "5900" # VNC Port
1315

1416
guacamole-lite-server:
1517
build:

test-guac/guacamole-lite-client/html/index.html

Lines changed: 103 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,42 @@
33
<title>guacamole-lite test</title>
44

55
<style>
6-
html,body { height:100%; margin:0 }
7-
#display { width:100%; height:100%; cursor:default }
8-
.guac-hide-cursor { cursor:url('dot.gif'), default }
6+
html, body { height: 100%; margin: 0; display: flex; flex-direction: column; }
7+
#display { flex-grow: 1; width: 100%; cursor: default; }
8+
.guac-hide-cursor { cursor: url('dot.gif'), default; }
9+
#connection-form { padding: 10px; border-bottom: 1px solid #ccc; display: flex; gap: 15px; align-items: center; }
10+
#remote-host-details { display: none; gap: 10px; }
11+
#remote-host-details.visible { display: flex; }
12+
label { margin-right: 5px; }
13+
input, select, button { padding: 5px; }
914
</style>
1015

16+
<!-- Connection Form -->
17+
<div id="connection-form">
18+
<label for="connect-target">Connect to:</label>
19+
<select id="connect-target">
20+
<option value="test-host" selected>Test Host (Linux Desktop)</option>
21+
<option value="remote-host">Remote Host</option>
22+
</select>
23+
24+
<label for="protocol">Protocol:</label>
25+
<select id="protocol">
26+
<option value="rdp" selected>RDP</option>
27+
<option value="vnc">VNC</option>
28+
</select>
29+
30+
<div id="remote-host-details">
31+
<label for="remote-hostname">Host:</label>
32+
<input type="text" id="remote-hostname" placeholder="hostname or IP">
33+
<label for="remote-username">Username:</label>
34+
<input type="text" id="remote-username">
35+
<label for="remote-password">Password:</label>
36+
<input type="password" id="remote-password">
37+
</div>
38+
39+
<button id="connect-button">Connect</button>
40+
</div>
41+
1142
<!-- official guacamole-common-js bundle copied by the Dockerfile -->
1243
<script src="js/all.min.js"></script>
1344

@@ -21,26 +52,78 @@
2152
<script src="js/guacamole-init.js"></script>
2253

2354
<script>
24-
(async () => {
55+
const connectTargetSelect = document.getElementById('connect-target');
56+
const remoteHostDetailsDiv = document.getElementById('remote-host-details');
57+
const connectButton = document.getElementById('connect-button');
58+
const protocolSelect = document.getElementById('protocol');
59+
const remoteHostnameInput = document.getElementById('remote-hostname');
60+
const remoteUsernameInput = document.getElementById('remote-username');
61+
const remotePasswordInput = document.getElementById('remote-password');
62+
63+
connectTargetSelect.addEventListener('change', () => {
64+
if (connectTargetSelect.value === 'remote-host') {
65+
remoteHostDetailsDiv.classList.add('visible');
66+
} else {
67+
remoteHostDetailsDiv.classList.remove('visible');
68+
}
69+
});
70+
71+
connectButton.addEventListener('click', async () => {
72+
const target = connectTargetSelect.value;
73+
const protocol = protocolSelect.value;
74+
let connectionSettings;
75+
76+
if (target === 'test-host') {
77+
connectionSettings = {
78+
hostname: "desktop-linux", // Service name in docker-compose
79+
username: "testuser",
80+
password: "Passw0rd!",
81+
security: "any",
82+
"ignore-cert": true,
83+
"enable-drive": protocol === 'rdp', // Drive redirection only for RDP
84+
"drive-path": protocol === 'rdp' ? "/tmp/guac-drive" : undefined,
85+
"create-drive-path": protocol === 'rdp',
86+
"enable-printing": protocol === 'rdp', // Printing only for RDP
87+
"audio": protocol === 'rdp' ? ["audio/L16;rate=44100"] : undefined // Audio only for RDP
88+
};
89+
// Adjust port based on protocol for test-host
90+
if (protocol === 'vnc') {
91+
connectionSettings.port = 5900; // Default VNC port
92+
}
93+
// RDP port is handled by default (3389) unless specified
94+
} else { // remote-host
95+
connectionSettings = {
96+
hostname: remoteHostnameInput.value,
97+
username: remoteUsernameInput.value,
98+
password: remotePasswordInput.value,
99+
// Add common settings or let Guacamole use defaults
100+
"ignore-cert": protocol === 'rdp' ? true : undefined, // Common for RDP self-signed certs
101+
};
102+
// Add port setting if needed, Guacamole uses defaults (3389 for RDP, 5900 for VNC)
103+
}
104+
25105
const tokenObj = {
26106
connection: {
27-
type: "rdp",
28-
settings: {
29-
"hostname": "desktop-linux",
30-
"username": "testuser",
31-
"password": "Passw0rd!",
32-
"security": "any",
33-
"ignore-cert": true,
34-
"enable-drive": true,
35-
"drive-path": "/tmp/guac-drive",
36-
"create-drive-path": true,
37-
"enable-printing": true,
38-
"audio": ["audio/L16;rate=44100"]
39-
}
107+
type: protocol,
108+
settings: connectionSettings
40109
}
41110
};
42111

43-
const token = await generateGuacamoleToken(tokenObj);
44-
await initGuacamole(token);
45-
})();
112+
try {
113+
// Clear previous display if any
114+
const displayDiv = document.getElementById('display');
115+
while (displayDiv.firstChild) {
116+
displayDiv.removeChild(displayDiv.firstChild);
117+
}
118+
119+
console.log("Generating token for:", tokenObj);
120+
const token = await generateGuacamoleToken(tokenObj);
121+
console.log("Token generated, initializing Guacamole...");
122+
await initGuacamole(token, protocol); // Pass protocol to initGuacamole
123+
console.log("Guacamole initialization called.");
124+
} catch (error) {
125+
console.error("Failed to connect:", error);
126+
alert("Connection failed: " + error.message);
127+
}
128+
});
46129
</script>

test-guac/guacamole-lite-client/html/js/guacamole-init.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
async function initGuacamole(token) {
1+
async function initGuacamole(token, protocol) {
22
/* ------------------------ initialise Guacamole ---------------------- */
33
const tunnel = new Guacamole.WebSocketTunnel(`ws://${location.hostname}:9091/`);
44
const client = new Guacamole.Client(tunnel);
@@ -35,8 +35,12 @@ async function initGuacamole(token) {
3535
};
3636
};
3737

38-
/* Connect (token is query parameter, add explicit audio request) */
39-
const connectString = `token=${encodeURIComponent(token)}&GUAC_AUDIO=audio/L16`;
38+
/* Connect (token is query parameter, add explicit audio request for RDP) */
39+
// Construct connection string, adding audio only if RDP
40+
let connectString = `token=${encodeURIComponent(token)}`;
41+
if (protocol === 'rdp') {
42+
connectString += `&GUAC_AUDIO=audio/L16`;
43+
}
4044
client.connect(connectString);
4145

4246
/* Disconnect cleanly when the tab is closed / reloaded */

0 commit comments

Comments
 (0)