Skip to content

Commit

Permalink
Extend objectscript.conn.docker-compose settings object to handle s…
Browse files Browse the repository at this point in the history
…uperserver port identification (#1485)

* Extend `objectscript.conn.docker-compose` settings object to handle superserver port identification

* Tweak updating of superserverPort cached value
  • Loading branch information
gjsjohnmurray authored Feb 22, 2025
1 parent e9dba8c commit bab8b6d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 17 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,11 @@
"type": "string"
},
"internalPort": {
"description": "Target port inside the service in docker-compose.",
"description": "Target webserver port inside the service in docker-compose.",
"type": "number"
},
"internalSuperserverPort": {
"description": "Target superserver port inside the service in docker-compose.",
"type": "number"
},
"file": {
Expand Down
9 changes: 9 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface ConnectionSettings {
https: boolean;
host: string;
port: number;
superserverPort?: number;
pathPrefix: string;
ns: string;
username: string;
Expand Down Expand Up @@ -67,6 +68,9 @@ export class AtelierAPI {
const wsKey = this.configName.toLowerCase();
const host = this.externalServer ? this._config.host : workspaceState.get(wsKey + ":host", this._config.host);
const port = this.externalServer ? this._config.port : workspaceState.get(wsKey + ":port", this._config.port);
const superserverPort = this.externalServer
? this._config.superserverPort
: workspaceState.get(wsKey + ":superserverPort", this._config.superserverPort);
const password = workspaceState.get(wsKey + ":password", this._config.password);
const apiVersion = workspaceState.get(wsKey + ":apiVersion", DEFAULT_API_VERSION);
const serverVersion = workspaceState.get(wsKey + ":serverVersion", DEFAULT_SERVER_VERSION);
Expand All @@ -80,6 +84,7 @@ export class AtelierAPI {
https,
host,
port,
superserverPort,
pathPrefix,
ns,
username,
Expand Down Expand Up @@ -211,6 +216,7 @@ export class AtelierAPI {
webServer: { scheme, host, port, pathPrefix = "" },
username,
password,
superServer,
} = getResolvedConnectionSpec(serverName, config("intersystems.servers", workspaceFolderName).get(serverName));
this._config = {
serverName,
Expand All @@ -221,6 +227,7 @@ export class AtelierAPI {
ns,
host,
port,
superserverPort: superServer.port,
username,
password,
pathPrefix,
Expand All @@ -241,6 +248,7 @@ export class AtelierAPI {
webServer: { scheme, host, port, pathPrefix = "" },
username,
password,
superServer,
} = resolvedSpec;
this._config = {
serverName: "",
Expand All @@ -251,6 +259,7 @@ export class AtelierAPI {
ns,
host,
port,
superserverPort: superServer.port,
username,
password,
pathPrefix,
Expand Down
29 changes: 24 additions & 5 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ export async function resolveConnectionSpec(serverName: string, uri?: vscode.Uri
port: serverForUri.port,
pathPrefix: serverForUri.pathPrefix,
},
superServer: {
port: serverForUri.superserverPort,
},
username: serverForUri.username,
password: serverForUri.password ? serverForUri.password : undefined,
description: `Server for workspace folder '${serverName}'`,
Expand Down Expand Up @@ -330,14 +333,15 @@ export async function checkConnection(
/// clean-up cached values
await workspaceState.update(wsKey + ":host", undefined);
await workspaceState.update(wsKey + ":port", undefined);
await workspaceState.update(wsKey + ":superserverPort", undefined);
await workspaceState.update(wsKey + ":password", undefined);
await workspaceState.update(wsKey + ":apiVersion", undefined);
await workspaceState.update(wsKey + ":serverVersion", undefined);
await workspaceState.update(wsKey + ":docker", undefined);
_onDidChangeConnection.fire();
}
let api = new AtelierAPI(apiTarget, false);
const { active, host = "", port = 0, username, ns = "" } = api.config;
const { active, host = "", port = 0, superserverPort = 0, username, ns = "" } = api.config;
vscode.commands.executeCommand("setContext", "vscode-objectscript.connectActive", active);
if (!panel.text) {
panel.text = `${PANEL_LABEL}`;
Expand All @@ -360,11 +364,16 @@ export async function checkConnection(

if (!workspaceState.get(wsKey + ":port") && !api.externalServer) {
try {
const { port: dockerPort, docker: withDocker, service } = await portFromDockerCompose();
const {
port: dockerPort,
superserverPort: dockerSuperserverPort,
docker: withDocker,
service,
} = await portFromDockerCompose(configName);
workspaceState.update(wsKey + ":docker", withDocker);
workspaceState.update(wsKey + ":dockerService", service);
if (withDocker) {
if (!dockerPort) {
if (!dockerPort || !dockerSuperserverPort) {
const errorMessage = `Something is wrong with your docker-compose connection settings, or your service is not running.`;
handleError(errorMessage);
panel.text = `${PANEL_LABEL} $(error)`;
Expand All @@ -377,6 +386,9 @@ export async function checkConnection(
workspaceState.update(wsKey + ":host", "localhost");
workspaceState.update(wsKey + ":port", dockerPort);
}
if (dockerSuperserverPort !== superserverPort) {
workspaceState.update(wsKey + ":superserverPort", dockerSuperserverPort);
}
connInfo = `localhost:${dockerPort}[${ns}]`;
_onDidChangeConnection.fire();
}
Expand Down Expand Up @@ -1627,6 +1639,7 @@ function serverForUri(uri: vscode.Uri): any {
host = "",
https,
port,
superserverPort,
pathPrefix,
username,
password,
Expand All @@ -1640,6 +1653,7 @@ function serverForUri(uri: vscode.Uri): any {
scheme: https ? "https" : "http",
host,
port,
superserverPort,
pathPrefix,
username,
password:
Expand All @@ -1661,9 +1675,14 @@ async function asyncServerForUri(uri: vscode.Uri): Promise<any> {
if (apiTarget instanceof vscode.Uri) {
apiTarget = vscode.workspace.getWorkspaceFolder(apiTarget)?.name;
}
const { port: dockerPort, docker: withDocker } = await portFromDockerCompose(apiTarget);
if (withDocker && dockerPort) {
const {
port: dockerPort,
superserverPort: dockerSuperserverPort,
docker: withDocker,
} = await portFromDockerCompose(apiTarget);
if (withDocker && dockerPort && dockerSuperserverPort) {
server.port = dockerPort;
server.superserverPort = dockerSuperserverPort;
server.host = "localhost";
server.pathPrefix = "";
server.https = false;
Expand Down
42 changes: 31 additions & 11 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,24 +490,30 @@ async function composeCommand(cwd?: string): Promise<string> {

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

// Seek a valid docker-compose object within objectscript.conn
const { "docker-compose": dockerCompose = {} } = config("conn", workspaceFolderName);
const { service, file = "docker-compose.yml", internalPort = 52773, envFile } = dockerCompose;
if (!internalPort || !file || !service || service === "") {
return { docker: false, port: null };
}

const result = { port: null, docker: true, service };
const {
service,
file = "docker-compose.yml",
internalPort = 52773,
internalSuperserverPort = 1972,
envFile,
} = dockerCompose;
if (!internalPort || !internalSuperserverPort || !file || !service || service === "") {
return { docker: false, port: null, superserverPort: null };
}

const result = { port: null, superserverPort: null, docker: true, service };
const workspaceFolder = uriOfWorkspaceFolder(workspaceFolderName);
if (!workspaceFolder) {
// No workspace folders are open
return { docker: false, port: null };
return { docker: false, port: null, superserverPort: null };
}
const workspaceFolderPath = workspaceFolder.fsPath;
const workspaceRootPath = vscode.workspace.workspaceFolders[0].uri.fsPath;
Expand Down Expand Up @@ -548,9 +554,23 @@ export async function portFromDockerCompose(
}
const [, port] = stdout.match(/:(\d+)/) || [];
if (!port) {
reject(`Port ${internalPort} not published for service '${service}' in '${path.join(cwd, file)}'.`);
reject(`Webserver port ${internalPort} not published for service '${service}' in '${path.join(cwd, file)}'.`);
}
resolve({ port: parseInt(port, 10), docker: true, service });
result.port = parseInt(port, 10);

exec(`${cmd} port --protocol=tcp ${service} ${internalSuperserverPort}`, { cwd }, (error, stdout) => {
if (error) {
reject(error.message);
}
const [, superserverPort] = stdout.match(/:(\d+)/) || [];
if (!superserverPort) {
reject(
`Superserver port ${internalSuperserverPort} not published for service '${service}' in '${path.join(cwd, file)}'.`
);
}
result.superserverPort = parseInt(superserverPort, 10);
resolve(result);
});
});
});
});
Expand Down

0 comments on commit bab8b6d

Please sign in to comment.