Skip to content

Commit b25b58c

Browse files
authored
Use min version once version api unreachable (#13)
1 parent 447c1af commit b25b58c

File tree

2 files changed

+48
-21
lines changed

2 files changed

+48
-21
lines changed

src/featureSupport.ts

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,21 @@
44
*--------------------------------------------------------------------------------------------*/
55
import * as semver from 'semver';
66
import fetch from 'node-fetch';
7+
import Log from './common/logger';
78

89
export class GitpodVersion {
9-
static DEFAULT_VERSION = '9999.99.99';
10+
static MAX_VERSION = '9999.99.99';
11+
static MIN_VERSION = '0.0.0';
12+
13+
static Max = new GitpodVersion(GitpodVersion.MAX_VERSION);
14+
static Min = new GitpodVersion(GitpodVersion.MIN_VERSION);
1015

1116
readonly version: string;
1217
readonly raw: string;
1318

1419
constructor(gitpodVersion: string = '') {
1520
this.raw = gitpodVersion;
16-
this.version = GitpodVersion.DEFAULT_VERSION;
21+
this.version = GitpodVersion.MIN_VERSION;
1722

1823
if (gitpodVersion.startsWith('release-')) {
1924
gitpodVersion = gitpodVersion.replace('release-', '');
@@ -32,39 +37,61 @@ export class GitpodVersion {
3237
}
3338

3439
let cacheGitpodVersion: { host: string; version: GitpodVersion } | undefined;
35-
async function getOrFetchVersionInfo(serviceUrl: string) {
40+
async function getOrFetchVersionInfo(serviceUrl: string, logger: Log) {
3641
if (serviceUrl === 'https://gitpod.io') {
37-
return undefined;
42+
logger.info(`Using SaaS, constant Max version ${GitpodVersion.Max.version}`);
43+
return {
44+
// SaaS default allow all features, should proper handle SaaS feature support if needed in the future
45+
version: GitpodVersion.Max,
46+
};
3847
}
3948

4049
if (serviceUrl === cacheGitpodVersion?.host) {
50+
logger.info(`Using cached version ${cacheGitpodVersion.version} for ${serviceUrl}`);
4151
return cacheGitpodVersion;
4252
}
4353

44-
let gitpodRawVersion: string;
45-
try {
46-
const versionEndPoint = `${serviceUrl}/api/version`;
47-
const versionResponse = await fetch(versionEndPoint);
48-
if (!versionResponse.ok) {
49-
return undefined;
54+
const fetchVersion = async (times: number = 3): Promise<string | undefined> => {
55+
try {
56+
const versionEndPoint = `${serviceUrl}/api/version`;
57+
const resp = await fetch(versionEndPoint, { timeout: 1500 });
58+
if (!resp.ok) {
59+
throw new Error(`Response with ${resp.status} ${resp.statusText}`);
60+
}
61+
return await resp.text();
62+
} catch (e) {
63+
logger.error(`Failed to fetch version with from: ${serviceUrl} left attempt: ${times - 1}`, e);
64+
if (times - 1 > 0) {
65+
await new Promise(resolve => setTimeout(resolve, 1000));
66+
return fetchVersion(times - 1);
67+
} else {
68+
return undefined;
69+
}
5070
}
71+
};
5172

52-
gitpodRawVersion = await versionResponse.text();
53-
} catch (e) {
54-
return undefined;
73+
const gitpodRawVersion = await fetchVersion();
74+
if (!gitpodRawVersion) {
75+
logger.info(`Failed to fetch version from: ${serviceUrl} fallback to Min: ${GitpodVersion.Min.version}`);
76+
return {
77+
host: serviceUrl,
78+
version: GitpodVersion.Min,
79+
};
5580
}
5681

82+
logger.info(`Got version from: ${serviceUrl} version: ${gitpodRawVersion}`);
83+
5784
cacheGitpodVersion = {
5885
host: serviceUrl,
5986
version: new GitpodVersion(gitpodRawVersion)
6087
};
6188
return cacheGitpodVersion;
6289
}
6390

64-
export async function getGitpodVersion(gitpodHost: string) {
91+
export async function getGitpodVersion(gitpodHost: string, logger: Log) {
6592
const serviceUrl = new URL(gitpodHost).toString().replace(/\/$/, '');
66-
const versionInfo = await getOrFetchVersionInfo(serviceUrl);
67-
return versionInfo?.version || new GitpodVersion();
93+
const versionInfo = await getOrFetchVersionInfo(serviceUrl, logger);
94+
return versionInfo.version || new GitpodVersion();
6895
}
6996

7097
type Feature = |

src/remoteConnector.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ export default class RemoteConnector extends Disposable {
515515

516516
private async getWorkspaceSSHDestination(accessToken: string, { workspaceId, gitpodHost }: SSHConnectionParams): Promise<{ destination: string; password?: string }> {
517517
const serviceUrl = new URL(gitpodHost);
518-
const gitpodVersion = await getGitpodVersion(gitpodHost);
518+
const gitpodVersion = await getGitpodVersion(gitpodHost, this.logger);
519519

520520
const [workspaceInfo, ownerToken, registeredSSHKeys] = await withServerApi(accessToken, serviceUrl.toString(), service => Promise.all([
521521
service.server.getWorkspace(workspaceId),
@@ -691,7 +691,7 @@ export default class RemoteConnector extends Disposable {
691691
private async showSSHPasswordModal(password: string, sshParams: SSHConnectionParams) {
692692
const maskedPassword = '•'.repeat(password.length - 3) + password.substring(password.length - 3);
693693

694-
const gitpodVersion = await getGitpodVersion(sshParams.gitpodHost);
694+
const gitpodVersion = await getGitpodVersion(sshParams.gitpodHost, this.logger);
695695
const sshKeysSupported = isFeatureSupported(gitpodVersion, 'SSHPublicKeys');
696696

697697
const copy: vscode.MessageItem = { title: 'Copy' };
@@ -734,7 +734,7 @@ export default class RemoteConnector extends Disposable {
734734
this.logger.info(`Updated 'gitpod.host' setting to '${gitpodHost}' while trying to connect to a Gitpod workspace`);
735735
}
736736

737-
const gitpodVersion = await getGitpodVersion(gitpodHost);
737+
const gitpodVersion = await getGitpodVersion(gitpodHost, this.logger);
738738
const sessionScopes = ['function:getWorkspace', 'function:getOwnerToken', 'function:getLoggedInUser', 'resource:default'];
739739
if (isFeatureSupported(gitpodVersion, 'SSHPublicKeys') /* && isFeatureSupported('', 'sendHeartBeat') */) {
740740
sessionScopes.push('function:getSSHPublicKeys', 'function:sendHeartBeat');
@@ -761,7 +761,7 @@ export default class RemoteConnector extends Disposable {
761761
}
762762

763763
const params: SSHConnectionParams = JSON.parse(uri.query);
764-
const gitpodVersion = await getGitpodVersion(params.gitpodHost);
764+
const gitpodVersion = await getGitpodVersion(params.gitpodHost, this.logger);
765765

766766
const session = await this.getGitpodSession(params.gitpodHost);
767767
if (!session) {
@@ -922,7 +922,7 @@ export default class RemoteConnector extends Disposable {
922922

923923
await this.context.globalState.update(`${RemoteConnector.SSH_DEST_KEY}${sshDestStr}`, { ...connectionInfo, isFirstConnection: false });
924924

925-
const gitpodVersion = await getGitpodVersion(connectionInfo.gitpodHost);
925+
const gitpodVersion = await getGitpodVersion(connectionInfo.gitpodHost, this.logger);
926926
if (isFeatureSupported(gitpodVersion, 'localHeartbeat')) {
927927
// gitpod remote extension installation is async so sometimes gitpod-desktop will activate before gitpod-remote
928928
// let's try a few times for it to finish install

0 commit comments

Comments
 (0)