From fc1362e249ac327403b841db25a2879b64fef75e Mon Sep 17 00:00:00 2001 From: Roland Grunberg Date: Mon, 15 Jun 2026 15:47:18 -0400 Subject: [PATCH] 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 --- build/scripts/code-sshd-page/page-utils.js | 4 +- build/scripts/code-sshd-page/server.js | 73 ++++++++++++++++++---- build/scripts/sshd.init | 8 ++- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/build/scripts/code-sshd-page/page-utils.js b/build/scripts/code-sshd-page/page-utils.js index f6974d1970bc..7c832a6fdd82 100644 --- a/build/scripts/code-sshd-page/page-utils.js +++ b/build/scripts/code-sshd-page/page-utils.js @@ -38,7 +38,7 @@ function syncDocsContent() { docsElem.innerHTML = useExtension ? extensionElem.innerHTML : manualElem.innerHTML; } -function openDevspacesURI(namespace, podName, userName, dwName, encodedKeyMessage, encodedUrl) { - const gatewayLink = `vscode://redhat.devspaces-remote-ssh?namespace=${namespace}&podName=${podName}&userName=${userName}&dwName=${dwName}&key=${encodedKeyMessage}&url=${encodedUrl}`; +function openDevspacesURI(scheme, namespace, podName, userName, dwName, encodedKeyMessage, encodedUrl) { + const gatewayLink = `${scheme}://redhat.devspaces-remote-ssh?namespace=${namespace}&podName=${podName}&userName=${userName}&dwName=${dwName}&key=${encodedKeyMessage}&url=${encodedUrl}`; window.open(gatewayLink, "_self"); } diff --git a/build/scripts/code-sshd-page/server.js b/build/scripts/code-sshd-page/server.js index 08d02e0ffb9c..e2489f925221 100644 --- a/build/scripts/code-sshd-page/server.js +++ b/build/scripts/code-sshd-page/server.js @@ -8,6 +8,7 @@ */ const http = require('http'); +const https = require('https'); const fs = require('fs'); const os = require('os'); @@ -21,6 +22,16 @@ try { // continue } +let uriScheme = 'vscode'; +try { + const schemeArg = process.argv.slice(2)[0]; + if (schemeArg) { + uriScheme = schemeArg; + } +} catch (error) { + // continue +} + const server = http.createServer((req, res) => { if (req.url === '/') { res.statusCode = 200; @@ -52,6 +63,7 @@ const server = http.createServer((req, res) => { let keyMessage = hasUserPrefSSHKey ? userPubKey : genKey; let encodedKeyMessage = Buffer.from(hasUserPrefSSHKey ? userKey : genKey).toString('base64url'); let encodedUrl = encodeURIComponent(process.env["CHE_DASHBOARD_URL"]); + getHostURL((hostURL) => { res.end(` @@ -87,8 +99,8 @@ const server = http.createServer((req, res) => {
  • Click the URI below (you may need to accept the prompt allowing this page to open the link with your VS Code-based editor) OR from the "Remote Explorer" view, select the Connect to Dev Spaces command and input the URI below.
  • - -
    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}
    +
    +
    ${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}
    @@ -104,7 +116,7 @@ const server = http.createServer((req, res) => {
    `); + + }); } else { let loc = req.url.substring(1); let isBinaryData = false; @@ -197,16 +211,51 @@ server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); -function getHostURL () { +function getHostURL (callback) { + const consoleURL = process.env["CLUSTER_CONSOLE_URL"]; const devspacesURL = process.env["CHE_DASHBOARD_URL"]; + if (consoleURL === undefined || devspacesURL === undefined) { - return undefined; + return callback(undefined); } - let i = 0; - while (i < consoleURL.length && i < devspacesURL.length - && consoleURL.substring(consoleURL.length - 1 - i) === devspacesURL.substring(devspacesURL.length - 1 - i)) { - i++; - } - return consoleURL.substring(consoleURL.length - i); + + console.log(`Discovering cluster API URL via ${devspacesURL}`); + const host = new URL(devspacesURL); + const oauthStartURL = `${host.protocol}//${host.host}/oauth/start`; + + const getFallbackURL = () => { + console.log('Falling back to legacy discovery method.'); + let i = 0; + while (i < consoleURL.length && i < devspacesURL.length + && consoleURL.substring(consoleURL.length - 1 - i) === devspacesURL.substring(devspacesURL.length - 1 - i)) { + i++; + } + return `https://oauth-openshift${consoleURL.substring(consoleURL.length - i)}`; + }; + + // Follow the /oauth/start redirect to discover the real cluster hostname + const mod = host.protocol === "https:" ? https : http; + const req = mod.get(oauthStartURL, { rejectUnauthorized: false }, (res) => { + clearTimeout(timer); + res.resume(); // only interested in headers, so consume body + if (res.statusCode === 302 && res.headers.location) { + const resHost = new URL(res.headers.location); + const resURL = `${resHost.protocol}//${resHost.host}`; + console.log(`Resolved API URL: ${resURL}`); + callback(resURL); + } else { + callback(getFallbackURL()); + } + }); + + const timer = setTimeout(() => { + req.destroy(); + callback(getFallbackURL()); + }, 10000); + + req.on('error', () => { + clearTimeout(timer); + callback(getFallbackURL()); + }); } diff --git a/build/scripts/sshd.init b/build/scripts/sshd.init index 01f7de07bd79..a73407015615 100755 --- a/build/scripts/sshd.init +++ b/build/scripts/sshd.init @@ -9,7 +9,7 @@ # # copy provisioned data (from che-code-sshd) to shared volume -cp -rp /sshd-staging/. /sshd/ +cp -r /sshd-staging/. /sshd/ # wait for main container to set up sshd (will indicate username) while [ ! -e /sshd/username ]; do @@ -21,7 +21,11 @@ ide_provider="$1" if [ "$ide_provider" = "jetbrains" ]; then pushd /opt/www/jetbrains else # default to landing page for Code + uri_scheme="$2" pushd /opt/www/code fi -exec node server.js +echo "IDE Provider : ${ide_provider}" +echo "URI Scheme : ${uri_scheme}" + +exec node server.js ${uri_scheme}