Skip to content

Commit bab8b6d

Browse files
Extend objectscript.conn.docker-compose settings object to handle superserver port identification (#1485)
* Extend `objectscript.conn.docker-compose` settings object to handle superserver port identification * Tweak updating of superserverPort cached value
1 parent e9dba8c commit bab8b6d

File tree

4 files changed

+69
-17
lines changed

4 files changed

+69
-17
lines changed

package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,11 @@
12891289
"type": "string"
12901290
},
12911291
"internalPort": {
1292-
"description": "Target port inside the service in docker-compose.",
1292+
"description": "Target webserver port inside the service in docker-compose.",
1293+
"type": "number"
1294+
},
1295+
"internalSuperserverPort": {
1296+
"description": "Target superserver port inside the service in docker-compose.",
12931297
"type": "number"
12941298
},
12951299
"file": {

src/api/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface ConnectionSettings {
3030
https: boolean;
3131
host: string;
3232
port: number;
33+
superserverPort?: number;
3334
pathPrefix: string;
3435
ns: string;
3536
username: string;
@@ -67,6 +68,9 @@ export class AtelierAPI {
6768
const wsKey = this.configName.toLowerCase();
6869
const host = this.externalServer ? this._config.host : workspaceState.get(wsKey + ":host", this._config.host);
6970
const port = this.externalServer ? this._config.port : workspaceState.get(wsKey + ":port", this._config.port);
71+
const superserverPort = this.externalServer
72+
? this._config.superserverPort
73+
: workspaceState.get(wsKey + ":superserverPort", this._config.superserverPort);
7074
const password = workspaceState.get(wsKey + ":password", this._config.password);
7175
const apiVersion = workspaceState.get(wsKey + ":apiVersion", DEFAULT_API_VERSION);
7276
const serverVersion = workspaceState.get(wsKey + ":serverVersion", DEFAULT_SERVER_VERSION);
@@ -80,6 +84,7 @@ export class AtelierAPI {
8084
https,
8185
host,
8286
port,
87+
superserverPort,
8388
pathPrefix,
8489
ns,
8590
username,
@@ -211,6 +216,7 @@ export class AtelierAPI {
211216
webServer: { scheme, host, port, pathPrefix = "" },
212217
username,
213218
password,
219+
superServer,
214220
} = getResolvedConnectionSpec(serverName, config("intersystems.servers", workspaceFolderName).get(serverName));
215221
this._config = {
216222
serverName,
@@ -221,6 +227,7 @@ export class AtelierAPI {
221227
ns,
222228
host,
223229
port,
230+
superserverPort: superServer.port,
224231
username,
225232
password,
226233
pathPrefix,
@@ -241,6 +248,7 @@ export class AtelierAPI {
241248
webServer: { scheme, host, port, pathPrefix = "" },
242249
username,
243250
password,
251+
superServer,
244252
} = resolvedSpec;
245253
this._config = {
246254
serverName: "",
@@ -251,6 +259,7 @@ export class AtelierAPI {
251259
ns,
252260
host,
253261
port,
262+
superserverPort: superServer.port,
254263
username,
255264
password,
256265
pathPrefix,

src/extension.ts

+24-5
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ export async function resolveConnectionSpec(serverName: string, uri?: vscode.Uri
250250
port: serverForUri.port,
251251
pathPrefix: serverForUri.pathPrefix,
252252
},
253+
superServer: {
254+
port: serverForUri.superserverPort,
255+
},
253256
username: serverForUri.username,
254257
password: serverForUri.password ? serverForUri.password : undefined,
255258
description: `Server for workspace folder '${serverName}'`,
@@ -330,14 +333,15 @@ export async function checkConnection(
330333
/// clean-up cached values
331334
await workspaceState.update(wsKey + ":host", undefined);
332335
await workspaceState.update(wsKey + ":port", undefined);
336+
await workspaceState.update(wsKey + ":superserverPort", undefined);
333337
await workspaceState.update(wsKey + ":password", undefined);
334338
await workspaceState.update(wsKey + ":apiVersion", undefined);
335339
await workspaceState.update(wsKey + ":serverVersion", undefined);
336340
await workspaceState.update(wsKey + ":docker", undefined);
337341
_onDidChangeConnection.fire();
338342
}
339343
let api = new AtelierAPI(apiTarget, false);
340-
const { active, host = "", port = 0, username, ns = "" } = api.config;
344+
const { active, host = "", port = 0, superserverPort = 0, username, ns = "" } = api.config;
341345
vscode.commands.executeCommand("setContext", "vscode-objectscript.connectActive", active);
342346
if (!panel.text) {
343347
panel.text = `${PANEL_LABEL}`;
@@ -360,11 +364,16 @@ export async function checkConnection(
360364

361365
if (!workspaceState.get(wsKey + ":port") && !api.externalServer) {
362366
try {
363-
const { port: dockerPort, docker: withDocker, service } = await portFromDockerCompose();
367+
const {
368+
port: dockerPort,
369+
superserverPort: dockerSuperserverPort,
370+
docker: withDocker,
371+
service,
372+
} = await portFromDockerCompose(configName);
364373
workspaceState.update(wsKey + ":docker", withDocker);
365374
workspaceState.update(wsKey + ":dockerService", service);
366375
if (withDocker) {
367-
if (!dockerPort) {
376+
if (!dockerPort || !dockerSuperserverPort) {
368377
const errorMessage = `Something is wrong with your docker-compose connection settings, or your service is not running.`;
369378
handleError(errorMessage);
370379
panel.text = `${PANEL_LABEL} $(error)`;
@@ -377,6 +386,9 @@ export async function checkConnection(
377386
workspaceState.update(wsKey + ":host", "localhost");
378387
workspaceState.update(wsKey + ":port", dockerPort);
379388
}
389+
if (dockerSuperserverPort !== superserverPort) {
390+
workspaceState.update(wsKey + ":superserverPort", dockerSuperserverPort);
391+
}
380392
connInfo = `localhost:${dockerPort}[${ns}]`;
381393
_onDidChangeConnection.fire();
382394
}
@@ -1627,6 +1639,7 @@ function serverForUri(uri: vscode.Uri): any {
16271639
host = "",
16281640
https,
16291641
port,
1642+
superserverPort,
16301643
pathPrefix,
16311644
username,
16321645
password,
@@ -1640,6 +1653,7 @@ function serverForUri(uri: vscode.Uri): any {
16401653
scheme: https ? "https" : "http",
16411654
host,
16421655
port,
1656+
superserverPort,
16431657
pathPrefix,
16441658
username,
16451659
password:
@@ -1661,9 +1675,14 @@ async function asyncServerForUri(uri: vscode.Uri): Promise<any> {
16611675
if (apiTarget instanceof vscode.Uri) {
16621676
apiTarget = vscode.workspace.getWorkspaceFolder(apiTarget)?.name;
16631677
}
1664-
const { port: dockerPort, docker: withDocker } = await portFromDockerCompose(apiTarget);
1665-
if (withDocker && dockerPort) {
1678+
const {
1679+
port: dockerPort,
1680+
superserverPort: dockerSuperserverPort,
1681+
docker: withDocker,
1682+
} = await portFromDockerCompose(apiTarget);
1683+
if (withDocker && dockerPort && dockerSuperserverPort) {
16661684
server.port = dockerPort;
1685+
server.superserverPort = dockerSuperserverPort;
16671686
server.host = "localhost";
16681687
server.pathPrefix = "";
16691688
server.https = false;

src/utils/index.ts

+31-11
Original file line numberDiff line numberDiff line change
@@ -490,24 +490,30 @@ async function composeCommand(cwd?: string): Promise<string> {
490490

491491
export async function portFromDockerCompose(
492492
workspaceFolderName?: string
493-
): Promise<{ port: number; docker: boolean; service?: string }> {
493+
): Promise<{ port: number; superserverPort: number; docker: boolean; service?: string }> {
494494
// When running remotely, behave as if there is no docker-compose object within objectscript.conn
495495
if (extensionContext.extension.extensionKind === vscode.ExtensionKind.Workspace) {
496-
return { docker: false, port: null };
496+
return { docker: false, port: null, superserverPort: null };
497497
}
498498

499499
// Seek a valid docker-compose object within objectscript.conn
500500
const { "docker-compose": dockerCompose = {} } = config("conn", workspaceFolderName);
501-
const { service, file = "docker-compose.yml", internalPort = 52773, envFile } = dockerCompose;
502-
if (!internalPort || !file || !service || service === "") {
503-
return { docker: false, port: null };
504-
}
505-
506-
const result = { port: null, docker: true, service };
501+
const {
502+
service,
503+
file = "docker-compose.yml",
504+
internalPort = 52773,
505+
internalSuperserverPort = 1972,
506+
envFile,
507+
} = dockerCompose;
508+
if (!internalPort || !internalSuperserverPort || !file || !service || service === "") {
509+
return { docker: false, port: null, superserverPort: null };
510+
}
511+
512+
const result = { port: null, superserverPort: null, docker: true, service };
507513
const workspaceFolder = uriOfWorkspaceFolder(workspaceFolderName);
508514
if (!workspaceFolder) {
509515
// No workspace folders are open
510-
return { docker: false, port: null };
516+
return { docker: false, port: null, superserverPort: null };
511517
}
512518
const workspaceFolderPath = workspaceFolder.fsPath;
513519
const workspaceRootPath = vscode.workspace.workspaceFolders[0].uri.fsPath;
@@ -548,9 +554,23 @@ export async function portFromDockerCompose(
548554
}
549555
const [, port] = stdout.match(/:(\d+)/) || [];
550556
if (!port) {
551-
reject(`Port ${internalPort} not published for service '${service}' in '${path.join(cwd, file)}'.`);
557+
reject(`Webserver port ${internalPort} not published for service '${service}' in '${path.join(cwd, file)}'.`);
552558
}
553-
resolve({ port: parseInt(port, 10), docker: true, service });
559+
result.port = parseInt(port, 10);
560+
561+
exec(`${cmd} port --protocol=tcp ${service} ${internalSuperserverPort}`, { cwd }, (error, stdout) => {
562+
if (error) {
563+
reject(error.message);
564+
}
565+
const [, superserverPort] = stdout.match(/:(\d+)/) || [];
566+
if (!superserverPort) {
567+
reject(
568+
`Superserver port ${internalSuperserverPort} not published for service '${service}' in '${path.join(cwd, file)}'.`
569+
);
570+
}
571+
result.superserverPort = parseInt(superserverPort, 10);
572+
resolve(result);
573+
});
554574
});
555575
});
556576
});

0 commit comments

Comments
 (0)