Skip to content

Commit dc39ba5

Browse files
committed
Support for custom scheme in connection URI.
- Some forked editor definitions may choose a non-'vscode://' URI - Improvements to OAuth host for the 'logged in' link - Remove unnecessary -p flag from 'cp' to reduce warnings Signed-off-by: Roland Grunberg <rgrunber@redhat.com>
1 parent 69a4168 commit dc39ba5

3 files changed

Lines changed: 69 additions & 16 deletions

File tree

build/scripts/code-sshd-page/page-utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function syncDocsContent() {
3838
docsElem.innerHTML = useExtension ? extensionElem.innerHTML : manualElem.innerHTML;
3939
}
4040

41-
function openDevspacesURI(namespace, podName, userName, dwName, encodedKeyMessage, encodedUrl) {
42-
const gatewayLink = `vscode://redhat.devspaces-remote-ssh?namespace=${namespace}&podName=${podName}&userName=${userName}&dwName=${dwName}&key=${encodedKeyMessage}&url=${encodedUrl}`;
41+
function openDevspacesURI(scheme, namespace, podName, userName, dwName, encodedKeyMessage, encodedUrl) {
42+
const gatewayLink = `${scheme}://redhat.devspaces-remote-ssh?namespace=${namespace}&podName=${podName}&userName=${userName}&dwName=${dwName}&key=${encodedKeyMessage}&url=${encodedUrl}`;
4343
window.open(gatewayLink, "_self");
4444
}

build/scripts/code-sshd-page/server.js

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
const http = require('http');
11+
const https = require('https');
1112
const fs = require('fs');
1213
const os = require('os');
1314

@@ -21,6 +22,16 @@ try {
2122
// continue
2223
}
2324

25+
let uriScheme = 'vscode';
26+
try {
27+
const schemeArg = process.argv.slice(2)[0];
28+
if (schemeArg) {
29+
uriScheme = schemeArg;
30+
}
31+
} catch (error) {
32+
// continue
33+
}
34+
2435
const server = http.createServer((req, res) => {
2536
if (req.url === '/') {
2637
res.statusCode = 200;
@@ -52,6 +63,7 @@ const server = http.createServer((req, res) => {
5263
let keyMessage = hasUserPrefSSHKey ? userPubKey : genKey;
5364
let encodedKeyMessage = Buffer.from(hasUserPrefSSHKey ? userKey : genKey).toString('base64url');
5465
let encodedUrl = encodeURIComponent(process.env["CHE_DASHBOARD_URL"]);
66+
getHostURL((hostURL) => {
5567

5668
res.end(`
5769
<!DOCTYPE html>
@@ -87,8 +99,8 @@ const server = http.createServer((req, res) => {
8799
<li class="extension-li">Click the URI below (you may need to accept the prompt allowing this page to open the link with your VS Code-based editor) <b>OR</b> from the "Remote Explorer" view, select the <code>Connect to Dev Spaces</code> command and input the URI below.</li>
88100
<div class="parent">
89101
<div>
90-
<a href="vscode://redhat.devspaces-remote-ssh?namespace=${process.env["DEVWORKSPACE_NAMESPACE"]}&podName=${process.env["HOSTNAME"]}&userName=${username}&dwName=${process.env["DEVWORKSPACE_NAME"]}&key=${encodedKeyMessage}&url=${encodedUrl}">
91-
<pre id="uri-connection">vscode://redhat.devspaces-remote-ssh?namespace=${process.env["DEVWORKSPACE_NAMESPACE"]}&podName=${process.env["HOSTNAME"]}&userName=${username}&dwName=${process.env["DEVWORKSPACE_NAME"]}&key=${encodedKeyMessage}&url=${encodedUrl}</pre>
102+
<a href="${uriScheme}://redhat.devspaces-remote-ssh?namespace=${process.env["DEVWORKSPACE_NAMESPACE"]}&podName=${process.env["HOSTNAME"]}&userName=${username}&dwName=${process.env["DEVWORKSPACE_NAME"]}&key=${encodedKeyMessage}&url=${encodedUrl}">
103+
<pre id="uri-connection">${uriScheme}://redhat.devspaces-remote-ssh?namespace=${process.env["DEVWORKSPACE_NAMESPACE"]}&podName=${process.env["HOSTNAME"]}&userName=${username}&dwName=${process.env["DEVWORKSPACE_NAME"]}&key=${encodedKeyMessage}&url=${encodedUrl}</pre>
92104
</a>
93105
</div>
94106
<div class="clipboard">
@@ -104,7 +116,7 @@ const server = http.createServer((req, res) => {
104116
</div>
105117
<div id="docs-manual" hidden>
106118
<ol>
107-
<li>Make sure your local <a href="${process.env["CLUSTER_CONSOLE_URL"]}/command-line-tools">oc client</a> is <a href="https://oauth-openshift${getHostURL()}/oauth/token/request">logged in</a> to your OpenShift cluster</li>
119+
<li>Make sure your local <a href="${process.env["CLUSTER_CONSOLE_URL"]}/command-line-tools">oc client</a> is <a href="${hostURL}/oauth/token/request">logged in</a> to your OpenShift cluster</li>
108120
<li><p class="center">Run <code id="port-forward">oc port-forward -n ${process.env["DEVWORKSPACE_NAMESPACE"]} ${process.env["HOSTNAME"]} 2022:2022</code><a href="#"><svg class="clipboard-img-code" onclick="copyToClipboard('port-forward')" title="Copy" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 20 20">
109121
<path fill="currentColor" d="M12 0H2C.9 0 0 .9 0 2v10h1V2c0-.6.4-1 1-1h10V0z"></path>
110122
<path fill="currentColor" d="M18 20H8c-1.1 0-2-.9-2-2V8c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2v10c0 1.1-.9 2-2 2zM8 7c-.6 0-1 .4-1 1v10c0 .6.4 1 1 1h10c.6 0 1-.4 1-1V8c0-.6-.4-1-1-1H8z"></path>
@@ -159,11 +171,13 @@ const server = http.createServer((req, res) => {
159171
</div>
160172
<script>
161173
initializePlatformContent();
162-
openDevspacesURI("${process.env["DEVWORKSPACE_NAMESPACE"]}", "${process.env["HOSTNAME"]}", "${username}", "${process.env["DEVWORKSPACE_NAME"]}", "${encodedKeyMessage}", "${encodedUrl}");
174+
openDevspacesURI("${uriScheme}", "${process.env["DEVWORKSPACE_NAMESPACE"]}", "${process.env["HOSTNAME"]}", "${username}", "${process.env["DEVWORKSPACE_NAME"]}", "${encodedKeyMessage}", "${encodedUrl}");
163175
</script>
164176
</body>
165177
</html>
166178
`);
179+
180+
});
167181
} else {
168182
let loc = req.url.substring(1);
169183
let isBinaryData = false;
@@ -197,16 +211,51 @@ server.listen(port, hostname, () => {
197211
console.log(`Server running at http://${hostname}:${port}/`);
198212
});
199213

200-
function getHostURL () {
214+
function getHostURL (callback) {
215+
201216
const consoleURL = process.env["CLUSTER_CONSOLE_URL"];
202217
const devspacesURL = process.env["CHE_DASHBOARD_URL"];
218+
203219
if (consoleURL === undefined || devspacesURL === undefined) {
204-
return undefined;
220+
return callback(undefined);
205221
}
206-
let i = 0;
207-
while (i < consoleURL.length && i < devspacesURL.length
208-
&& consoleURL.substring(consoleURL.length - 1 - i) === devspacesURL.substring(devspacesURL.length - 1 - i)) {
209-
i++;
210-
}
211-
return consoleURL.substring(consoleURL.length - i);
222+
223+
console.log(`Discovering cluster API URL via ${devspacesURL}`);
224+
const host = new URL(devspacesURL);
225+
const oauthStartURL = `${host.protocol}//${host.host}/oauth/start`;
226+
227+
const getFallbackURL = () => {
228+
console.log('Falling back to legacy discovery method.');
229+
let i = 0;
230+
while (i < consoleURL.length && i < devspacesURL.length
231+
&& consoleURL.substring(consoleURL.length - 1 - i) === devspacesURL.substring(devspacesURL.length - 1 - i)) {
232+
i++;
233+
}
234+
return `https://oauth-openshift${consoleURL.substring(consoleURL.length - i)}`;
235+
};
236+
237+
// Follow the /oauth/start redirect to discover the real cluster hostname
238+
const mod = host.protocol === "https:" ? https : http;
239+
const req = mod.get(oauthStartURL, { rejectUnauthorized: false }, (res) => {
240+
clearTimeout(timer);
241+
res.resume(); // only interested in headers, so consume body
242+
if (res.statusCode === 302 && res.headers.location) {
243+
const resHost = new URL(res.headers.location);
244+
const resURL = `${resHost.protocol}//${resHost.host}`;
245+
console.log(`Resolved API URL: ${resURL}`);
246+
callback(resURL);
247+
} else {
248+
callback(getFallbackURL());
249+
}
250+
});
251+
252+
const timer = setTimeout(() => {
253+
req.destroy();
254+
callback(getFallbackURL());
255+
}, 10000);
256+
257+
req.on('error', () => {
258+
clearTimeout(timer);
259+
callback(getFallbackURL());
260+
});
212261
}

build/scripts/sshd.init

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#
1010

1111
# copy provisioned data (from che-code-sshd) to shared volume
12-
cp -rp /sshd-staging/. /sshd/
12+
cp -r /sshd-staging/. /sshd/
1313

1414
# wait for main container to set up sshd (will indicate username)
1515
while [ ! -e /sshd/username ]; do
@@ -21,7 +21,11 @@ ide_provider="$1"
2121
if [ "$ide_provider" = "jetbrains" ]; then
2222
pushd /opt/www/jetbrains
2323
else # default to landing page for Code
24+
uri_scheme="$2"
2425
pushd /opt/www/code
2526
fi
2627

27-
exec node server.js
28+
echo "IDE Provider : ${ide_provider}"
29+
echo "URI Scheme : ${uri_scheme}"
30+
31+
exec node server.js ${uri_scheme}

0 commit comments

Comments
 (0)