@milaboratories/pl-deployments 2.8.2 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"pl.js","sources":["../../src/ssh/pl.ts"],"sourcesContent":["import type * as ssh from 'ssh2';\nimport { SshClient } from './ssh';\nimport type { MiLogger } from '@milaboratories/ts-helpers';\nimport { sleep, notEmpty } from '@milaboratories/ts-helpers';\nimport type { DownloadBinaryResult } from '../common/pl_binary_download';\nimport { downloadBinaryNoExtract } from '../common/pl_binary_download';\nimport upath from 'upath';\nimport * as plpath from './pl_paths';\nimport { getDefaultPlVersion } from '../common/pl_version';\n\nimport net from 'node:net';\nimport type { PlConfig, PlLicenseMode, SshPlConfigGenerationResult } from '@milaboratories/pl-config';\nimport { getFreePort, generateSshPlConfigs } from '@milaboratories/pl-config';\nimport type { SupervisorStatus } from './supervisord';\nimport { supervisorStatus, supervisorStop as supervisorCtlShutdown, generateSupervisordConfigWithMinio, supervisorCtlStart, isSupervisordRunning, generateSupervisordConfig, isAllAlive } from './supervisord';\nimport type { ConnectionInfo, SshPlPorts } from './connection_info';\nimport { newConnectionInfo, parseConnectionInfo, stringifyConnectionInfo } from './connection_info';\nimport type { PlBinarySourceDownload } from '../common/pl_binary';\n\nconst minRequiredGlibcVersion = 2.28;\n\nexport class SshPl {\n private initState: PlatformaInitState = { step: 'init' };\n constructor(\n public readonly logger: MiLogger,\n public readonly sshClient: SshClient,\n private readonly username: string,\n ) { }\n\n public info() {\n return {\n username: this.username,\n initState: this.initState,\n };\n }\n\n public static async init(logger: MiLogger, config: ssh.ConnectConfig): Promise<SshPl> {\n try {\n const sshClient = await SshClient.init(logger, config);\n return new SshPl(logger, sshClient, notEmpty(config.username));\n } catch (e: unknown) {\n logger.error(`Connection error in SshClient.init: ${e}`);\n throw e;\n }\n }\n\n public cleanUp() {\n this.sshClient.close();\n }\n\n /** Provides an info if the platforma and minio are running along with the debug info. */\n public async isAlive(): Promise<SupervisorStatus> {\n const arch = await this.getArch();\n const remoteHome = await this.getUserHomeDirectory();\n return await supervisorStatus(this.logger, this.sshClient, remoteHome, arch.arch);\n }\n\n /** Starts all the services on the server.\n * Idempotent semantic: we could call it several times. */\n public async start(shouldUseMinio: boolean) {\n const arch = await this.getArch();\n const remoteHome = await this.getUserHomeDirectory();\n\n try {\n if (!isAllAlive(await this.isAlive(), shouldUseMinio)) {\n await supervisorCtlStart(this.sshClient, remoteHome, arch.arch);\n\n // We are waiting for Platforma to run to ensure that it has started.\n return await this.checkIsAliveWithInterval(shouldUseMinio);\n }\n } catch (e: unknown) {\n let msg = `SshPl.start: ${e}`;\n\n let logs = '';\n try {\n logs = await this.sshClient.readFile(plpath.platformaCliLogs(remoteHome));\n msg += `, platforma cli logs: ${logs}`;\n } catch (e: unknown) {\n msg += `, Can not read platforma cli logs: ${e}`;\n }\n\n this.logger.error(msg);\n throw new Error(msg);\n }\n }\n\n /** Stops all the services on the server.\n * Idempotent semantic: we could call it several times. */\n public async stop() {\n const arch = await this.getArch();\n const remoteHome = await this.getUserHomeDirectory();\n\n try {\n const alive = await this.isAlive();\n if (isSupervisordRunning(alive)) {\n await supervisorCtlShutdown(this.sshClient, remoteHome, arch.arch);\n // Check if Minio is running by looking at the alive status\n const shouldUseMinio = alive.minio === true;\n return await this.checkIsAliveWithInterval(shouldUseMinio, 1000, 15, false);\n }\n } catch (e: unknown) {\n const msg = `PlSsh.stop: ${e}`;\n this.logger.error(msg);\n throw new Error(msg);\n }\n }\n\n /** Stops the services, deletes a directory with the state and closes SSH connection. */\n public async reset(): Promise<boolean> {\n await this.stopAndClean();\n this.cleanUp();\n return true;\n }\n\n /** Stops platforma and deletes its state. */\n public async stopAndClean(): Promise<void> {\n const remoteHome = await this.getUserHomeDirectory();\n\n this.logger.info(`pl.reset: Stop Platforma on the server`);\n await this.stop();\n\n this.logger.info(`pl.reset: Deleting Platforma workDir ${plpath.workDir(remoteHome)} on the server`);\n await this.sshClient.deleteFolder(plpath.workDir(remoteHome));\n }\n\n /** Downloads binaries and untar them on the server,\n * generates all the configs, creates necessary dirs,\n * and finally starts all the services. */\n public async platformaInit(options: SshPlConfig): Promise<ConnectionInfo> {\n const state: PlatformaInitState = { localWorkdir: options.localWorkdir, step: 'init' };\n\n const { onProgress } = options;\n\n // merge options with default ops.\n const ops: SshPlConfig = {\n ...defaultSshPlConfig,\n ...options,\n };\n state.plBinaryOps = ops.plBinary;\n\n try {\n await this.doStepDetectArch(state, onProgress);\n await this.doStepDetectHome(state, onProgress);\n\n const needRestartPlatforma = await this.doStepReadExistedConfig(state, ops, onProgress);\n if (!needRestartPlatforma) {\n await onProgress?.('Platforma is already running. Skipping initialization.');\n return state.existedSettings!;\n }\n await this.doStepStopExistedPlatforma(state, onProgress);\n\n await onProgress?.('Installation platforma...');\n\n await this.doStepDownloadBinaries(state, onProgress, ops);\n await this.doStepFetchPorts(state);\n await this.doStepGenerateNewConfig(state, onProgress, ops);\n await this.doStepCreateFoldersAndSaveFiles(state, onProgress);\n await this.doStepConfigureSupervisord(state, onProgress);\n await this.doStepSaveNewConnectionInfo(state, onProgress, ops);\n await this.doStepStartPlatforma(state, onProgress);\n\n return state.connectionInfo!;\n } catch (e: unknown) {\n const msg = `SshPl.platformaInit: ${e}, state: ${JSON.stringify(this.removeSensitiveData(state))}`;\n this.logger.error(msg);\n\n throw new Error(msg);\n }\n }\n\n private async doStepStopExistedPlatforma(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'stopExistedPlatforma';\n if (!isAllAlive(state.alive!, state.shouldUseMinio ?? false)) {\n return;\n }\n\n await onProgress?.('Stopping services...');\n await this.stop();\n }\n\n private removeSensitiveData(state: PlatformaInitState): PlatformaInitState {\n const stateCopy = { ...state };\n stateCopy.generatedConfig = { ...stateCopy.generatedConfig, filesToCreate: { skipped: 'sanitized' } } as SshPlConfigGenerationResult;\n return stateCopy;\n }\n\n private async doStepStartPlatforma(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'startPlatforma';\n await onProgress?.('Starting Platforma on the server...');\n await this.start(state.shouldUseMinio ?? false);\n state.started = true;\n this.initState = state;\n\n await onProgress?.('Platforma has been started successfully.');\n }\n\n private async doStepSaveNewConnectionInfo(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined, ops: SshPlConfig) {\n state.step = 'saveNewConnectionInfo';\n const config = state.generatedConfig!;\n await onProgress?.('Saving connection information...');\n state.connectionInfo = newConnectionInfo(\n config.plUser,\n config.plPassword,\n state.ports!,\n notEmpty(ops.useGlobalAccess),\n ops.plBinary!.version,\n state.shouldUseMinio ?? false,\n );\n await this.sshClient.writeFileOnTheServer(\n plpath.connectionInfo(state.remoteHome!),\n stringifyConnectionInfo(state.connectionInfo),\n );\n await onProgress?.('Connection information saved.');\n }\n\n private async doStepConfigureSupervisord(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n await onProgress?.('Writing supervisord configuration...');\n state.step = 'configureSupervisord';\n\n const config = state.generatedConfig!;\n\n let supervisorConfig: string;\n if (state.shouldUseMinio) {\n supervisorConfig = generateSupervisordConfigWithMinio(\n config.minioConfig.storageDir,\n config.minioConfig.envs,\n await this.getFreePortForPlatformaOnServer(state.remoteHome!, state.arch!),\n config.workingDir,\n config.plConfig.configPath,\n state.binPaths!.minioRelPath!,\n state.binPaths!.downloadedPl,\n );\n } else {\n supervisorConfig = generateSupervisordConfig(\n await this.getFreePortForPlatformaOnServer(state.remoteHome!, state.arch!),\n config.workingDir,\n config.plConfig.configPath,\n state.binPaths!.downloadedPl,\n );\n }\n\n const writeResult = await this.sshClient.writeFileOnTheServer(plpath.supervisorConf(state.remoteHome!), supervisorConfig);\n if (!writeResult) {\n throw new Error(`Can not write supervisord config on the server ${plpath.workDir(state.remoteHome!)}`);\n }\n await onProgress?.('Supervisord configuration written.');\n }\n\n private async doStepCreateFoldersAndSaveFiles(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'createFoldersAndSaveFiles';\n const config = state.generatedConfig!;\n await onProgress?.('Generating folder structure...');\n for (const [filePath, content] of Object.entries(config.filesToCreate)) {\n await this.sshClient.writeFileOnTheServer(filePath, content);\n this.logger.info(`Created file ${filePath}`);\n }\n\n for (const dir of config.dirsToCreate) {\n await this.sshClient.ensureRemoteDirCreated(dir);\n this.logger.info(`Created directory ${dir}`);\n }\n await onProgress?.('Folder structure created.');\n }\n\n private async doStepGenerateNewConfig(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined, ops: SshPlConfig) {\n state.step = 'generateNewConfig';\n\n await onProgress?.('Generating new config...');\n const config = await generateSshPlConfigs({\n logger: this.logger,\n workingDir: plpath.workDir(state.remoteHome!),\n portsMode: {\n type: 'customWithMinio',\n ports: {\n debug: state.ports!.debug.remote,\n grpc: state.ports!.grpc.remote,\n http: state.ports!.http!.remote,\n minio: state.ports!.minioPort.remote,\n minioConsole: state.ports!.minioConsolePort.remote,\n monitoring: state.ports!.monitoring.remote,\n\n httpLocal: state.ports!.http!.local,\n grpcLocal: state.ports!.grpc.local,\n minioLocal: state.ports!.minioPort.local,\n },\n },\n licenseMode: ops.license,\n useGlobalAccess: notEmpty(ops.useGlobalAccess),\n plConfigPostprocessing: ops.plConfigPostprocessing,\n useMinio: state.shouldUseMinio ?? false,\n });\n state.generatedConfig = { ...config };\n await onProgress?.('New config generated');\n }\n\n private async doStepFetchPorts(state: PlatformaInitState) {\n state.step = 'fetchPorts';\n state.ports = await this.fetchPorts(state.remoteHome!, state.arch!);\n\n if (!state.ports.debug.remote\n || !state.ports.grpc.remote\n || !state.ports.minioPort.remote\n || !state.ports.minioConsolePort.remote\n || !state.ports.monitoring.remote\n || !state.ports.http?.remote) {\n throw new Error(`SshPl.platformaInit: remote ports are not defined`);\n }\n }\n\n private async doStepDownloadBinaries(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined, ops: SshPlConfig) {\n state.step = 'downloadBinaries';\n await onProgress?.('Downloading and uploading required binaries...');\n\n const glibcVersion = await getGlibcVersion(this.logger, this.sshClient);\n if (glibcVersion < minRequiredGlibcVersion)\n throw new Error(`glibc version ${glibcVersion} is too old. Version ${minRequiredGlibcVersion} or higher is required for Platforma.`);\n\n const downloadRes = await this.downloadBinariesAndUploadToTheServer(\n ops.localWorkdir, ops.plBinary!, state.remoteHome!, state.arch!, state.shouldUseMinio ?? false,\n );\n await onProgress?.('All required binaries have been downloaded and uploaded.');\n\n state.binPaths = { ...downloadRes, history: undefined };\n state.downloadedBinaries = downloadRes.history;\n }\n\n private async doStepDetectArch(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'detectArch';\n await onProgress?.('Detecting server architecture...');\n state.arch = await this.getArch();\n await onProgress?.('Server architecture detected.');\n }\n\n private async doStepDetectHome(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'detectHome';\n await onProgress?.('Fetching user home directory...');\n state.remoteHome = await this.getUserHomeDirectory();\n await onProgress?.('User home directory retrieved.');\n }\n\n private async doStepReadExistedConfig(\n state: PlatformaInitState,\n ops: SshPlConfig,\n onProgress: ((...args: any) => Promise<any>) | undefined,\n ): Promise<boolean> {\n state.step = 'checkAlive';\n await onProgress?.('Checking platform status...');\n state.alive = await this.isAlive();\n\n if (!state.alive?.platforma) {\n return true;\n }\n\n await onProgress?.('All required services are running.');\n\n state.existedSettings = await this.readExistedConfig(state.remoteHome!);\n if (!state.existedSettings) {\n throw new Error(`SshPl.platformaInit: platforma is alive but existed settings are not found`);\n }\n\n const sameGA = state.existedSettings.useGlobalAccess == ops.useGlobalAccess;\n const samePlVersion = state.existedSettings.plVersion == ops.plBinary!.version;\n state.needRestart = !(sameGA && samePlVersion);\n this.logger.info(`SshPl.platformaInit: need restart? ${state.needRestart}`);\n\n state.shouldUseMinio = state.existedSettings.minioIsUsed;\n if (state.shouldUseMinio) {\n this.logger.info(`SshPl.platformaInit: minio is used`);\n } else {\n this.logger.info(`SshPl.platformaInit: minio is not used`);\n }\n\n if (!state.needRestart) {\n await onProgress?.('Server setup completed.');\n return false;\n }\n\n await onProgress?.('Stopping services...');\n await this.stop();\n\n return true;\n }\n\n public async downloadBinariesAndUploadToTheServer(\n localWorkdir: string,\n plBinary: PlBinarySourceDownload,\n remoteHome: string,\n arch: Arch,\n shouldUseMinio: boolean,\n ) {\n const state: DownloadAndUntarState[] = [];\n try {\n const pl = await this.downloadAndUntar(\n localWorkdir, remoteHome, arch,\n 'pl', `pl-${plBinary.version}`,\n );\n state.push(pl);\n\n const supervisor = await this.downloadAndUntar(\n localWorkdir, remoteHome, arch,\n 'supervisord', plpath.supervisordDirName,\n );\n state.push(supervisor);\n\n const minioPath = plpath.minioBin(remoteHome, arch.arch);\n if (shouldUseMinio) {\n const minio = await this.downloadAndUntar(\n localWorkdir, remoteHome, arch,\n 'minio', plpath.minioDirName,\n );\n state.push(minio);\n await this.sshClient.chmod(minioPath, 0o750);\n }\n\n return {\n history: state,\n minioRelPath: shouldUseMinio ? minioPath : undefined,\n downloadedPl: plpath.platformaBin(remoteHome, arch.arch),\n };\n } catch (e: unknown) {\n const msg = `SshPl.downloadBinariesAndUploadToServer: ${e}, state: ${JSON.stringify(state)}`;\n this.logger.error(msg);\n throw e;\n }\n }\n\n /** We have to extract pl in the remote server,\n * because Windows doesn't support symlinks\n * that are found in Linux pl binaries tgz archive.\n * For this reason, we extract all to the remote server.\n * It requires `tar` to be installed on the server\n * (it's not installed for Rocky Linux for example). */\n public async downloadAndUntar(\n localWorkdir: string,\n remoteHome: string,\n arch: Arch,\n softwareName: string,\n tgzName: string,\n ): Promise<DownloadAndUntarState> {\n const state: DownloadAndUntarState = {};\n state.binBasePath = plpath.binariesDir(remoteHome);\n await this.sshClient.ensureRemoteDirCreated(state.binBasePath);\n state.binBasePathCreated = true;\n\n let downloadBinaryResult: DownloadBinaryResult | null = null;\n const attempts = 5;\n for (let i = 1; i <= attempts; i++) {\n try {\n downloadBinaryResult = await downloadBinaryNoExtract(\n this.logger,\n localWorkdir,\n softwareName,\n tgzName,\n arch.arch, arch.platform,\n );\n break;\n } catch (e: unknown) {\n await sleep(300);\n if (i == attempts) {\n throw new Error(`downloadAndUntar: ${attempts} attempts, last error: ${e}`);\n }\n }\n }\n state.downloadResult = notEmpty(downloadBinaryResult);\n\n state.localArchivePath = upath.resolve(state.downloadResult.archivePath);\n state.remoteDir = upath.join(state.binBasePath, state.downloadResult.baseName);\n state.remoteArchivePath = state.remoteDir + '.tgz';\n\n await this.sshClient.ensureRemoteDirCreated(state.remoteDir);\n await this.sshClient.uploadFile(state.localArchivePath, state.remoteArchivePath);\n state.uploadDone = true;\n\n try {\n await this.sshClient.exec('hash tar');\n } catch (_) {\n throw new Error(`tar is not installed on the server. Please install it before running Platforma.`);\n }\n\n // TODO: Create a proper archive to avoid xattr warnings\n const untarResult = await this.sshClient.exec(\n `tar --warning=no-all -xvf ${state.remoteArchivePath} --directory=${state.remoteDir}`,\n );\n\n if (untarResult.stderr)\n throw new Error(`downloadAndUntar: untar: stderr occurred: ${untarResult.stderr}, stdout: ${untarResult.stdout}`);\n\n state.untarDone = true;\n\n return state;\n }\n\n public async needDownload(remoteHome: string, arch: Arch) {\n const checkPathSupervisor = plpath.supervisorBin(remoteHome, arch.arch);\n const checkPathMinio = plpath.minioDir(remoteHome, arch.arch);\n const checkPathPlatforma = plpath.platformaBin(remoteHome, arch.arch);\n\n if (!await this.sshClient.checkFileExists(checkPathPlatforma)\n || !await this.sshClient.checkFileExists(checkPathMinio)\n || !await this.sshClient.checkFileExists(checkPathSupervisor)) {\n return true;\n }\n\n return false;\n }\n\n public async checkIsAliveWithInterval(shouldUseMinio: boolean, interval: number = 1000, count = 15, shouldStart = true): Promise<void> {\n const maxMs = count * interval;\n\n let total = 0;\n let alive = await this.isAlive();\n while (shouldStart ? !isAllAlive(alive, shouldUseMinio) : isAllAlive(alive, shouldUseMinio)) {\n await sleep(interval);\n total += interval;\n if (total > maxMs) {\n throw new Error(`isAliveWithInterval: The process did not ${shouldStart ? 'started' : 'stopped'} after ${maxMs} ms. Live status: ${JSON.stringify(alive)}`);\n }\n alive = await this.isAlive();\n }\n }\n\n public async readExistedConfig(remoteHome: string): Promise<ConnectionInfo> {\n const connectionInfo = await this.sshClient.readFile(plpath.connectionInfo(remoteHome));\n return parseConnectionInfo(connectionInfo);\n }\n\n public async fetchPorts(remoteHome: string, arch: Arch): Promise<SshPlPorts> {\n const ports: SshPlPorts = {\n grpc: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n monitoring: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n debug: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n http: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n minioPort: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n minioConsolePort: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n };\n\n return ports;\n }\n\n public async getLocalFreePort(): Promise<number> {\n return new Promise((res) => {\n const srv = net.createServer();\n srv.listen(0, () => {\n const port = (srv.address() as net.AddressInfo).port;\n srv.close((_) => res(port));\n });\n });\n }\n\n public async getFreePortForPlatformaOnServer(remoteHome: string, arch: Arch): Promise<number> {\n const freePortBin = plpath.platformaFreePortBin(remoteHome, arch.arch);\n\n const { stdout, stderr } = await this.sshClient.exec(`${freePortBin}`);\n if (stderr) {\n throw new Error(`getFreePortForPlatformaOnServer: stderr is not empty: ${stderr}, stdout: ${stdout}`);\n }\n\n return +stdout;\n }\n\n public async getArch(): Promise<Arch> {\n const { stdout, stderr } = await this.sshClient.exec('uname -s && uname -m');\n if (stderr)\n throw new Error(`getArch: stderr is not empty: ${stderr}, stdout: ${stdout}`);\n\n const arr = stdout.split('\\n');\n\n return {\n platform: arr[0],\n arch: arr[1],\n };\n }\n\n public async getUserHomeDirectory() {\n const { stdout, stderr } = await this.sshClient.exec('echo $HOME');\n\n if (stderr) {\n const home = `/home/${this.username}`;\n console.warn(`getUserHomeDirectory: stderr is not empty: ${stderr}, stdout: ${stdout}, will get a default home: ${home}`);\n\n return home;\n }\n\n return stdout.trim();\n }\n}\n\ntype Arch = { platform: string; arch: string };\n\nexport type SshPlConfig = {\n localWorkdir: string;\n license: PlLicenseMode;\n useGlobalAccess?: boolean;\n plBinary?: PlBinarySourceDownload;\n\n onProgress?: (...args: any) => Promise<any>;\n plConfigPostprocessing?: (config: PlConfig) => PlConfig;\n};\n\nconst defaultSshPlConfig: Pick<\n SshPlConfig,\n | 'useGlobalAccess'\n | 'plBinary'\n> = {\n useGlobalAccess: false,\n plBinary: {\n type: 'Download',\n version: getDefaultPlVersion(),\n },\n};\n\ntype BinPaths = {\n history?: DownloadAndUntarState[];\n minioRelPath?: string;\n downloadedPl: string;\n};\n\ntype DownloadAndUntarState = {\n binBasePath?: string;\n binBasePathCreated?: boolean;\n downloadResult?: DownloadBinaryResult;\n attempts?: number;\n\n localArchivePath?: string;\n remoteDir?: string;\n remoteArchivePath?: string;\n uploadDone?: boolean;\n untarDone?: boolean;\n};\n\ntype PlatformaInitStep =\n 'init'\n | 'detectArch'\n | 'detectHome'\n | 'checkAlive'\n | 'stopExistedPlatforma'\n | 'downloadBinaries'\n | 'fetchPorts'\n | 'generateNewConfig'\n | 'createFoldersAndSaveFiles'\n | 'configureSupervisord'\n | 'saveNewConnectionInfo'\n | 'startPlatforma';\n\ntype PlatformaInitState = {\n step: PlatformaInitStep;\n localWorkdir?: string;\n plBinaryOps?: PlBinarySourceDownload;\n arch?: Arch;\n remoteHome?: string;\n alive?: SupervisorStatus;\n existedSettings?: ConnectionInfo;\n needRestart?: boolean;\n shouldUseMinio?: boolean;\n downloadedBinaries?: DownloadAndUntarState[];\n binPaths?: BinPaths;\n ports?: SshPlPorts;\n generatedConfig?: SshPlConfigGenerationResult;\n connectionInfo?: ConnectionInfo;\n started?: boolean;\n};\n\n/**\n * Gets the glibc version on the remote system\n * @returns The glibc version as a number\n * @throws Error if version cannot be determined\n */\nasync function getGlibcVersion(logger: MiLogger, sshClient: SshClient): Promise <number> {\n try {\n const { stdout, stderr } = await sshClient.exec('ldd --version | head -n 1');\n if (stderr) {\n throw new Error(`Failed to check glibc version: ${stderr}`);\n }\n return parseGlibcVersion(stdout);\n } catch (e: unknown) {\n logger.error(`glibc version check failed: ${e}`);\n throw e;\n }\n}\n\nexport function parseGlibcVersion(output: string): number {\n const versionMatch = output.match(/\\d+\\.\\d+/);\n if (!versionMatch) {\n throw new Error(`Could not parse glibc version from: ${output}`);\n }\n\n return parseFloat(versionMatch[0]);\n}\n"],"names":["plpath.platformaCliLogs","supervisorCtlShutdown","plpath.workDir","plpath.connectionInfo","plpath.supervisorConf","plpath.supervisordDirName","plpath.minioBin","plpath.minioDirName","plpath.platformaBin","plpath.binariesDir","plpath.supervisorBin","plpath.minioDir","connectionInfo","plpath.platformaFreePortBin"],"mappings":"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"}
1
+ {"version":3,"file":"pl.js","sources":["../../src/ssh/pl.ts"],"sourcesContent":["import type * as ssh from 'ssh2';\nimport { SshClient } from './ssh';\nimport type { MiLogger } from '@milaboratories/ts-helpers';\nimport { sleep, notEmpty } from '@milaboratories/ts-helpers';\nimport type { DownloadBinaryResult } from '../common/pl_binary_download';\nimport { downloadBinaryNoExtract } from '../common/pl_binary_download';\nimport upath from 'upath';\nimport * as plpath from './pl_paths';\nimport { getDefaultPlVersion } from '../common/pl_version';\n\nimport net from 'node:net';\nimport type { PlConfig, PlLicenseMode, SshPlConfigGenerationResult } from '@milaboratories/pl-config';\nimport { getFreePort, generateSshPlConfigs } from '@milaboratories/pl-config';\nimport type { SupervisorStatus } from './supervisord';\nimport { supervisorStatus, supervisorStop as supervisorCtlShutdown, generateSupervisordConfigWithMinio, supervisorCtlStart, isSupervisordRunning, generateSupervisordConfig, isAllAlive } from './supervisord';\nimport type { ConnectionInfo, SshPlPorts } from './connection_info';\nimport { newConnectionInfo, parseConnectionInfo, stringifyConnectionInfo } from './connection_info';\nimport type { PlBinarySourceDownload } from '../common/pl_binary';\n\nconst minRequiredGlibcVersion = 2.28;\n\nexport class SshPl {\n private initState: PlatformaInitState = { step: 'init' };\n constructor(\n public readonly logger: MiLogger,\n public readonly sshClient: SshClient,\n private readonly username: string,\n ) { }\n\n public info() {\n return {\n username: this.username,\n initState: this.initState,\n };\n }\n\n public static async init(logger: MiLogger, config: ssh.ConnectConfig): Promise<SshPl> {\n try {\n const sshClient = await SshClient.init(logger, config);\n return new SshPl(logger, sshClient, notEmpty(config.username));\n } catch (e: unknown) {\n logger.error(`Connection error in SshClient.init: ${e}`);\n throw e;\n }\n }\n\n public cleanUp() {\n this.sshClient.close();\n }\n\n /** Provides an info if the platforma and minio are running along with the debug info. */\n public async isAlive(): Promise<SupervisorStatus> {\n const arch = await this.getArch();\n const remoteHome = await this.getUserHomeDirectory();\n return await supervisorStatus(this.logger, this.sshClient, remoteHome, arch.arch);\n }\n\n /** Starts all the services on the server.\n * Idempotent semantic: we could call it several times. */\n public async start(shouldUseMinio: boolean) {\n const arch = await this.getArch();\n const remoteHome = await this.getUserHomeDirectory();\n\n try {\n if (!isAllAlive(await this.isAlive(), shouldUseMinio)) {\n await supervisorCtlStart(this.sshClient, remoteHome, arch.arch);\n\n // We are waiting for Platforma to run to ensure that it has started.\n return await this.checkIsAliveWithInterval(shouldUseMinio);\n }\n } catch (e: unknown) {\n let msg = `SshPl.start: ${e}`;\n\n let logs = '';\n try {\n logs = await this.sshClient.readFile(plpath.platformaCliLogs(remoteHome));\n msg += `, platforma cli logs: ${logs}`;\n } catch (e: unknown) {\n msg += `, Can not read platforma cli logs: ${e}`;\n }\n\n this.logger.error(msg);\n throw new Error(msg);\n }\n }\n\n /** Stops all the services on the server.\n * Idempotent semantic: we could call it several times. */\n public async stop() {\n const arch = await this.getArch();\n const remoteHome = await this.getUserHomeDirectory();\n\n try {\n const alive = await this.isAlive();\n if (isSupervisordRunning(alive)) {\n await supervisorCtlShutdown(this.sshClient, remoteHome, arch.arch);\n // Check if Minio is running by looking at the alive status\n const shouldUseMinio = alive.minio === true;\n return await this.checkIsAliveWithInterval(shouldUseMinio, 1000, 15, false);\n }\n } catch (e: unknown) {\n const msg = `PlSsh.stop: ${e}`;\n this.logger.error(msg);\n throw new Error(msg);\n }\n }\n\n /** Stops the services, deletes a directory with the state and closes SSH connection. */\n public async reset(): Promise<boolean> {\n await this.stopAndClean();\n this.cleanUp();\n return true;\n }\n\n /** Stops platforma and deletes its state. */\n public async stopAndClean(): Promise<void> {\n const remoteHome = await this.getUserHomeDirectory();\n\n this.logger.info(`pl.reset: Stop Platforma on the server`);\n await this.stop();\n\n this.logger.info(`pl.reset: Deleting Platforma workDir ${plpath.workDir(remoteHome)} on the server`);\n await this.sshClient.deleteFolder(plpath.workDir(remoteHome));\n }\n\n /** Downloads binaries and untar them on the server,\n * generates all the configs, creates necessary dirs,\n * and finally starts all the services. */\n public async platformaInit(options: SshPlConfig): Promise<ConnectionInfo> {\n const state: PlatformaInitState = { localWorkdir: options.localWorkdir, step: 'init' };\n\n const { onProgress } = options;\n\n // merge options with default ops.\n const ops: SshPlConfig = {\n ...defaultSshPlConfig,\n ...options,\n };\n state.plBinaryOps = ops.plBinary;\n\n try {\n await this.doStepDetectArch(state, onProgress);\n await this.doStepDetectHome(state, onProgress);\n\n const needRestartPlatforma = await this.doStepReadExistedConfig(state, ops, onProgress);\n if (!needRestartPlatforma) {\n await onProgress?.('Platforma is already running. Skipping initialization.');\n return state.existedSettings!;\n }\n await this.doStepStopExistedPlatforma(state, onProgress);\n\n await onProgress?.('Installation platforma...');\n\n await this.doStepDownloadBinaries(state, onProgress, ops);\n await this.doStepFetchPorts(state);\n await this.doStepGenerateNewConfig(state, onProgress, ops);\n await this.doStepCreateFoldersAndSaveFiles(state, onProgress);\n await this.doStepConfigureSupervisord(state, onProgress);\n await this.doStepSaveNewConnectionInfo(state, onProgress, ops);\n await this.doStepStartPlatforma(state, onProgress);\n\n return state.connectionInfo!;\n } catch (e: unknown) {\n const msg = `SshPl.platformaInit: ${e}, state: ${JSON.stringify(this.removeSensitiveData(state))}`;\n this.logger.error(msg);\n\n throw new Error(msg);\n }\n }\n\n private async doStepStopExistedPlatforma(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'stopExistedPlatforma';\n if (!isAllAlive(state.alive!, state.shouldUseMinio ?? false)) {\n return;\n }\n\n await onProgress?.('Stopping services...');\n await this.stop();\n }\n\n private removeSensitiveData(state: PlatformaInitState): PlatformaInitState {\n const stateCopy = { ...state };\n stateCopy.generatedConfig = { ...stateCopy.generatedConfig, filesToCreate: { skipped: 'sanitized' } } as SshPlConfigGenerationResult;\n return stateCopy;\n }\n\n private async doStepStartPlatforma(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'startPlatforma';\n await onProgress?.('Starting Platforma on the server...');\n await this.start(state.shouldUseMinio ?? false);\n state.started = true;\n this.initState = state;\n\n await onProgress?.('Platforma has been started successfully.');\n }\n\n private async doStepSaveNewConnectionInfo(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined, ops: SshPlConfig) {\n state.step = 'saveNewConnectionInfo';\n const config = state.generatedConfig!;\n await onProgress?.('Saving connection information...');\n state.connectionInfo = newConnectionInfo(\n config.plUser,\n config.plPassword,\n state.ports!,\n notEmpty(ops.useGlobalAccess),\n ops.plBinary!.version,\n state.shouldUseMinio ?? false,\n );\n await this.sshClient.writeFileOnTheServer(\n plpath.connectionInfo(state.remoteHome!),\n stringifyConnectionInfo(state.connectionInfo),\n );\n await onProgress?.('Connection information saved.');\n }\n\n private async doStepConfigureSupervisord(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n await onProgress?.('Writing supervisord configuration...');\n state.step = 'configureSupervisord';\n\n const config = state.generatedConfig!;\n\n let supervisorConfig: string;\n if (state.shouldUseMinio) {\n supervisorConfig = generateSupervisordConfigWithMinio(\n config.minioConfig.storageDir,\n config.minioConfig.envs,\n await this.getFreePortForPlatformaOnServer(state.remoteHome!, state.arch!),\n config.workingDir,\n config.plConfig.configPath,\n state.binPaths!.minioRelPath!,\n state.binPaths!.downloadedPl,\n );\n } else {\n supervisorConfig = generateSupervisordConfig(\n await this.getFreePortForPlatformaOnServer(state.remoteHome!, state.arch!),\n config.workingDir,\n config.plConfig.configPath,\n state.binPaths!.downloadedPl,\n );\n }\n\n const writeResult = await this.sshClient.writeFileOnTheServer(plpath.supervisorConf(state.remoteHome!), supervisorConfig);\n if (!writeResult) {\n throw new Error(`Can not write supervisord config on the server ${plpath.workDir(state.remoteHome!)}`);\n }\n await onProgress?.('Supervisord configuration written.');\n }\n\n private async doStepCreateFoldersAndSaveFiles(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'createFoldersAndSaveFiles';\n const config = state.generatedConfig!;\n await onProgress?.('Generating folder structure...');\n for (const [filePath, content] of Object.entries(config.filesToCreate)) {\n await this.sshClient.writeFileOnTheServer(filePath, content);\n this.logger.info(`Created file ${filePath}`);\n }\n\n for (const dir of config.dirsToCreate) {\n await this.sshClient.ensureRemoteDirCreated(dir);\n this.logger.info(`Created directory ${dir}`);\n }\n await onProgress?.('Folder structure created.');\n }\n\n private async doStepGenerateNewConfig(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined, ops: SshPlConfig) {\n state.step = 'generateNewConfig';\n\n await onProgress?.('Generating new config...');\n const config = await generateSshPlConfigs({\n logger: this.logger,\n workingDir: plpath.workDir(state.remoteHome!),\n portsMode: {\n type: 'customWithMinio',\n ports: {\n debug: state.ports!.debug.remote,\n grpc: state.ports!.grpc.remote,\n http: state.ports!.http!.remote,\n minio: state.ports!.minioPort.remote,\n minioConsole: state.ports!.minioConsolePort.remote,\n monitoring: state.ports!.monitoring.remote,\n\n httpLocal: state.ports!.http!.local,\n grpcLocal: state.ports!.grpc.local,\n minioLocal: state.ports!.minioPort.local,\n },\n },\n licenseMode: ops.license,\n useGlobalAccess: notEmpty(ops.useGlobalAccess),\n plConfigPostprocessing: ops.plConfigPostprocessing,\n useMinio: state.shouldUseMinio ?? false,\n });\n state.generatedConfig = { ...config };\n await onProgress?.('New config generated');\n }\n\n private async doStepFetchPorts(state: PlatformaInitState) {\n state.step = 'fetchPorts';\n state.ports = await this.fetchPorts(state.remoteHome!, state.arch!);\n\n if (!state.ports.debug.remote\n || !state.ports.grpc.remote\n || !state.ports.minioPort.remote\n || !state.ports.minioConsolePort.remote\n || !state.ports.monitoring.remote\n || !state.ports.http?.remote) {\n throw new Error(`SshPl.platformaInit: remote ports are not defined`);\n }\n }\n\n private async doStepDownloadBinaries(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined, ops: SshPlConfig) {\n state.step = 'downloadBinaries';\n await onProgress?.('Downloading and uploading required binaries...');\n\n const glibcVersion = await getGlibcVersion(this.logger, this.sshClient);\n if (glibcVersion < minRequiredGlibcVersion)\n throw new Error(`glibc version ${glibcVersion} is too old. Version ${minRequiredGlibcVersion} or higher is required for Platforma.`);\n\n const downloadRes = await this.downloadBinariesAndUploadToTheServer(\n ops.localWorkdir, ops.plBinary!, state.remoteHome!, state.arch!, state.shouldUseMinio ?? false,\n );\n await onProgress?.('All required binaries have been downloaded and uploaded.');\n\n state.binPaths = { ...downloadRes, history: undefined };\n state.downloadedBinaries = downloadRes.history;\n }\n\n private async doStepDetectArch(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'detectArch';\n await onProgress?.('Detecting server architecture...');\n state.arch = await this.getArch();\n await onProgress?.('Server architecture detected.');\n }\n\n private async doStepDetectHome(state: PlatformaInitState, onProgress: ((...args: any) => Promise<any>) | undefined) {\n state.step = 'detectHome';\n await onProgress?.('Fetching user home directory...');\n state.remoteHome = await this.getUserHomeDirectory();\n await onProgress?.('User home directory retrieved.');\n }\n\n private async doStepReadExistedConfig(\n state: PlatformaInitState,\n ops: SshPlConfig,\n onProgress: ((...args: any) => Promise<any>) | undefined,\n ): Promise<boolean> {\n state.step = 'checkAlive';\n await onProgress?.('Checking platform status...');\n state.alive = await this.isAlive();\n\n if (!state.alive?.platforma) {\n return true;\n }\n\n await onProgress?.('All required services are running.');\n\n state.existedSettings = await this.readExistedConfig(state.remoteHome!);\n if (!state.existedSettings) {\n throw new Error(`SshPl.platformaInit: platforma is alive but existed settings are not found`);\n }\n\n const sameGA = state.existedSettings.useGlobalAccess == ops.useGlobalAccess;\n const samePlVersion = state.existedSettings.plVersion == ops.plBinary!.version;\n state.needRestart = !(sameGA && samePlVersion);\n this.logger.info(`SshPl.platformaInit: need restart? ${state.needRestart}`);\n\n state.shouldUseMinio = state.existedSettings.minioIsUsed;\n if (state.shouldUseMinio) {\n this.logger.info(`SshPl.platformaInit: minio is used`);\n } else {\n this.logger.info(`SshPl.platformaInit: minio is not used`);\n }\n\n if (!state.needRestart) {\n await onProgress?.('Server setup completed.');\n return false;\n }\n\n await onProgress?.('Stopping services...');\n await this.stop();\n\n return true;\n }\n\n public async downloadBinariesAndUploadToTheServer(\n localWorkdir: string,\n plBinary: PlBinarySourceDownload,\n remoteHome: string,\n arch: Arch,\n shouldUseMinio: boolean,\n ) {\n const state: DownloadAndUntarState[] = [];\n try {\n const pl = await this.downloadAndUntar(\n localWorkdir, remoteHome, arch,\n 'pl', `pl-${plBinary.version}`,\n );\n state.push(pl);\n\n const supervisor = await this.downloadAndUntar(\n localWorkdir, remoteHome, arch,\n 'supervisord', plpath.supervisordDirName,\n );\n state.push(supervisor);\n\n const minioPath = plpath.minioBin(remoteHome, arch.arch);\n if (shouldUseMinio) {\n const minio = await this.downloadAndUntar(\n localWorkdir, remoteHome, arch,\n 'minio', plpath.minioDirName,\n );\n state.push(minio);\n await this.sshClient.chmod(minioPath, 0o750);\n }\n\n return {\n history: state,\n minioRelPath: shouldUseMinio ? minioPath : undefined,\n downloadedPl: plpath.platformaBin(remoteHome, arch.arch),\n };\n } catch (e: unknown) {\n const msg = `SshPl.downloadBinariesAndUploadToServer: ${e}, state: ${JSON.stringify(state)}`;\n this.logger.error(msg);\n throw e;\n }\n }\n\n /** We have to extract pl in the remote server,\n * because Windows doesn't support symlinks\n * that are found in Linux pl binaries tgz archive.\n * For this reason, we extract all to the remote server.\n * It requires `tar` to be installed on the server\n * (it's not installed for Rocky Linux for example). */\n public async downloadAndUntar(\n localWorkdir: string,\n remoteHome: string,\n arch: Arch,\n softwareName: string,\n tgzName: string,\n ): Promise<DownloadAndUntarState> {\n const state: DownloadAndUntarState = {};\n state.binBasePath = plpath.binariesDir(remoteHome);\n await this.sshClient.ensureRemoteDirCreated(state.binBasePath);\n state.binBasePathCreated = true;\n\n let downloadBinaryResult: DownloadBinaryResult | null = null;\n const attempts = 5;\n for (let i = 1; i <= attempts; i++) {\n try {\n downloadBinaryResult = await downloadBinaryNoExtract({\n logger: this.logger,\n baseDir: localWorkdir,\n softwareName,\n tgzName,\n arch: arch.arch,\n platform: arch.platform,\n });\n break;\n } catch (e: unknown) {\n await sleep(300);\n if (i == attempts) {\n throw new Error(`downloadAndUntar: ${attempts} attempts, last error: ${e}`);\n }\n }\n }\n state.downloadResult = notEmpty(downloadBinaryResult);\n\n state.localArchivePath = upath.resolve(state.downloadResult.archivePath);\n state.remoteDir = upath.join(state.binBasePath, state.downloadResult.baseName);\n state.remoteArchivePath = state.remoteDir + '.tgz';\n\n await this.sshClient.ensureRemoteDirCreated(state.remoteDir);\n await this.sshClient.uploadFile(state.localArchivePath, state.remoteArchivePath);\n state.uploadDone = true;\n\n try {\n await this.sshClient.exec('hash tar');\n } catch (_) {\n throw new Error(`tar is not installed on the server. Please install it before running Platforma.`);\n }\n\n // TODO: Create a proper archive to avoid xattr warnings\n const untarResult = await this.sshClient.exec(\n `tar --warning=no-all -xvf ${state.remoteArchivePath} --directory=${state.remoteDir}`,\n );\n\n if (untarResult.stderr)\n throw new Error(`downloadAndUntar: untar: stderr occurred: ${untarResult.stderr}, stdout: ${untarResult.stdout}`);\n\n state.untarDone = true;\n\n return state;\n }\n\n public async needDownload(remoteHome: string, arch: Arch) {\n const checkPathSupervisor = plpath.supervisorBin(remoteHome, arch.arch);\n const checkPathMinio = plpath.minioDir(remoteHome, arch.arch);\n const checkPathPlatforma = plpath.platformaBin(remoteHome, arch.arch);\n\n if (!await this.sshClient.checkFileExists(checkPathPlatforma)\n || !await this.sshClient.checkFileExists(checkPathMinio)\n || !await this.sshClient.checkFileExists(checkPathSupervisor)) {\n return true;\n }\n\n return false;\n }\n\n public async checkIsAliveWithInterval(shouldUseMinio: boolean, interval: number = 1000, count = 15, shouldStart = true): Promise<void> {\n const maxMs = count * interval;\n\n let total = 0;\n let alive = await this.isAlive();\n while (shouldStart ? !isAllAlive(alive, shouldUseMinio) : isAllAlive(alive, shouldUseMinio)) {\n await sleep(interval);\n total += interval;\n if (total > maxMs) {\n throw new Error(`isAliveWithInterval: The process did not ${shouldStart ? 'started' : 'stopped'} after ${maxMs} ms. Live status: ${JSON.stringify(alive)}`);\n }\n alive = await this.isAlive();\n }\n }\n\n public async readExistedConfig(remoteHome: string): Promise<ConnectionInfo> {\n const connectionInfo = await this.sshClient.readFile(plpath.connectionInfo(remoteHome));\n return parseConnectionInfo(connectionInfo);\n }\n\n public async fetchPorts(remoteHome: string, arch: Arch): Promise<SshPlPorts> {\n const ports: SshPlPorts = {\n grpc: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n monitoring: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n debug: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n http: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n minioPort: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n minioConsolePort: {\n local: await getFreePort(),\n remote: await this.getFreePortForPlatformaOnServer(remoteHome, arch),\n },\n };\n\n return ports;\n }\n\n public async getLocalFreePort(): Promise<number> {\n return new Promise((res) => {\n const srv = net.createServer();\n srv.listen(0, () => {\n const port = (srv.address() as net.AddressInfo).port;\n srv.close((_) => res(port));\n });\n });\n }\n\n public async getFreePortForPlatformaOnServer(remoteHome: string, arch: Arch): Promise<number> {\n const freePortBin = plpath.platformaFreePortBin(remoteHome, arch.arch);\n\n const { stdout, stderr } = await this.sshClient.exec(`${freePortBin}`);\n if (stderr) {\n throw new Error(`getFreePortForPlatformaOnServer: stderr is not empty: ${stderr}, stdout: ${stdout}`);\n }\n\n return +stdout;\n }\n\n public async getArch(): Promise<Arch> {\n const { stdout, stderr } = await this.sshClient.exec('uname -s && uname -m');\n if (stderr)\n throw new Error(`getArch: stderr is not empty: ${stderr}, stdout: ${stdout}`);\n\n const arr = stdout.split('\\n');\n\n return {\n platform: arr[0],\n arch: arr[1],\n };\n }\n\n public async getUserHomeDirectory() {\n const { stdout, stderr } = await this.sshClient.exec('echo $HOME');\n\n if (stderr) {\n const home = `/home/${this.username}`;\n console.warn(`getUserHomeDirectory: stderr is not empty: ${stderr}, stdout: ${stdout}, will get a default home: ${home}`);\n\n return home;\n }\n\n return stdout.trim();\n }\n}\n\ntype Arch = { platform: string; arch: string };\n\nexport type SshPlConfig = {\n localWorkdir: string;\n license: PlLicenseMode;\n useGlobalAccess?: boolean;\n plBinary?: PlBinarySourceDownload;\n\n onProgress?: (...args: any) => Promise<any>;\n plConfigPostprocessing?: (config: PlConfig) => PlConfig;\n};\n\nconst defaultSshPlConfig: Pick<\n SshPlConfig,\n | 'useGlobalAccess'\n | 'plBinary'\n> = {\n useGlobalAccess: false,\n plBinary: {\n type: 'Download',\n version: getDefaultPlVersion(),\n },\n};\n\ntype BinPaths = {\n history?: DownloadAndUntarState[];\n minioRelPath?: string;\n downloadedPl: string;\n};\n\ntype DownloadAndUntarState = {\n binBasePath?: string;\n binBasePathCreated?: boolean;\n downloadResult?: DownloadBinaryResult;\n attempts?: number;\n\n localArchivePath?: string;\n remoteDir?: string;\n remoteArchivePath?: string;\n uploadDone?: boolean;\n untarDone?: boolean;\n};\n\ntype PlatformaInitStep =\n 'init'\n | 'detectArch'\n | 'detectHome'\n | 'checkAlive'\n | 'stopExistedPlatforma'\n | 'downloadBinaries'\n | 'fetchPorts'\n | 'generateNewConfig'\n | 'createFoldersAndSaveFiles'\n | 'configureSupervisord'\n | 'saveNewConnectionInfo'\n | 'startPlatforma';\n\ntype PlatformaInitState = {\n step: PlatformaInitStep;\n localWorkdir?: string;\n plBinaryOps?: PlBinarySourceDownload;\n arch?: Arch;\n remoteHome?: string;\n alive?: SupervisorStatus;\n existedSettings?: ConnectionInfo;\n needRestart?: boolean;\n shouldUseMinio?: boolean;\n downloadedBinaries?: DownloadAndUntarState[];\n binPaths?: BinPaths;\n ports?: SshPlPorts;\n generatedConfig?: SshPlConfigGenerationResult;\n connectionInfo?: ConnectionInfo;\n started?: boolean;\n};\n\n/**\n * Gets the glibc version on the remote system\n * @returns The glibc version as a number\n * @throws Error if version cannot be determined\n */\nasync function getGlibcVersion(logger: MiLogger, sshClient: SshClient): Promise <number> {\n try {\n const { stdout, stderr } = await sshClient.exec('ldd --version | head -n 1');\n if (stderr) {\n throw new Error(`Failed to check glibc version: ${stderr}`);\n }\n return parseGlibcVersion(stdout);\n } catch (e: unknown) {\n logger.error(`glibc version check failed: ${e}`);\n throw e;\n }\n}\n\nexport function parseGlibcVersion(output: string): number {\n const versionMatch = output.match(/\\d+\\.\\d+/);\n if (!versionMatch) {\n throw new Error(`Could not parse glibc version from: ${output}`);\n }\n\n return parseFloat(versionMatch[0]);\n}\n"],"names":["plpath.platformaCliLogs","supervisorCtlShutdown","plpath.workDir","plpath.connectionInfo","plpath.supervisorConf","plpath.supervisordDirName","plpath.minioBin","plpath.minioDirName","plpath.platformaBin","plpath.binariesDir","plpath.supervisorBin","plpath.minioDir","connectionInfo","plpath.platformaFreePortBin"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pl-deployments",
3
- "version": "2.8.2",
3
+ "version": "2.9.1",
4
4
  "pl-version": "1.42.1",
5
5
  "description": "MiLaboratories Platforma Backend code service run wrapper",
6
6
  "engines": {
@@ -41,20 +41,22 @@
41
41
  "typescript": "~5.6.3",
42
42
  "utility-types": "^3.11.0",
43
43
  "vitest": "^2.1.9",
44
- "@milaboratories/build-configs": "1.0.8",
45
- "@milaboratories/ts-configs": "1.0.6",
46
44
  "@milaboratories/ts-builder": "1.0.5",
45
+ "@milaboratories/ts-configs": "1.0.6",
46
+ "@milaboratories/build-configs": "1.0.8",
47
47
  "@milaboratories/eslint-config": "1.0.4"
48
48
  },
49
49
  "dependencies": {
50
50
  "decompress": "^4.2.1",
51
- "upath": "^2.0.1",
52
51
  "ssh2": "^1.16.0",
53
52
  "tar": "^7.4.3",
54
53
  "undici": "~7.16.0",
54
+ "upath": "^2.0.1",
55
55
  "yaml": "^2.8.0",
56
56
  "zod": "~3.23.8",
57
57
  "@milaboratories/pl-config": "1.7.6",
58
+ "@milaboratories/pl-http": "1.2.0",
59
+ "@milaboratories/pl-model-common": "^1.21.0",
58
60
  "@milaboratories/ts-helpers": "1.5.1"
59
61
  },
60
62
  "scripts": {
@@ -6,6 +6,7 @@ import os from 'node:os';
6
6
  import upath from 'upath';
7
7
  import type { OSType } from './os_and_arch';
8
8
  import { newOs } from './os_and_arch';
9
+ import type { Dispatcher } from 'undici';
9
10
 
10
11
  /** Shows how the binary should be got. */
11
12
  export type PlBinarySource = PlBinarySourceDownload | PlBinarySourceLocal;
@@ -25,14 +26,25 @@ export function newDefaultPlBinarySource(): PlBinarySourceDownload {
25
26
  }
26
27
 
27
28
  export async function resolveLocalPlBinaryPath(
28
- logger: MiLogger,
29
- downloadDir: string,
30
- src: PlBinarySource,
29
+ { logger, downloadDir, src, dispatcher }: {
30
+ logger: MiLogger;
31
+ downloadDir: string;
32
+ src: PlBinarySource;
33
+ dispatcher?: Dispatcher;
34
+ },
31
35
  ): Promise<string> {
32
36
  switch (src.type) {
33
37
  case 'Download':
34
38
  // eslint-disable-next-line no-case-declarations
35
- const ops = await downloadBinary(logger, downloadDir, 'pl', `pl-${src.version}`, os.arch(), os.platform());
39
+ const ops = await downloadBinary({
40
+ logger,
41
+ baseDir: downloadDir,
42
+ softwareName: 'pl',
43
+ archiveName: `pl-${src.version}`,
44
+ arch: os.arch(),
45
+ platform: os.platform(),
46
+ dispatcher,
47
+ });
36
48
  return upath.join(ops.baseName, 'binaries', osToBinaryName[newOs(os.platform())]);
37
49
 
38
50
  case 'Local':
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import fsp from 'node:fs/promises';
3
3
  import upath from 'upath';
4
+ import type { Dispatcher } from 'undici';
4
5
  import { request } from 'undici';
5
6
  import { Writable, Readable } from 'node:stream';
6
7
  import { text } from 'node:stream/consumers';
@@ -27,21 +28,24 @@ export type DownloadBinaryResult = {
27
28
  };
28
29
 
29
30
  export async function downloadBinaryNoExtract(
30
- logger: MiLogger,
31
- baseDir: string,
32
- softwareName: string,
33
- tgzName: string,
34
- arch: string,
35
- platform: string,
31
+ { logger, baseDir, softwareName, tgzName, arch, platform, dispatcher }: {
32
+ logger: MiLogger;
33
+ baseDir: string;
34
+ softwareName: string;
35
+ tgzName: string;
36
+ arch: string;
37
+ platform: string;
38
+ dispatcher?: Dispatcher;
39
+ },
36
40
  ): Promise<DownloadBinaryResult> {
37
41
  const opts = getPathsForDownload(softwareName, tgzName, baseDir, newArch(arch), newOs(platform));
38
42
  const { archiveUrl, alternativeArchiveGAUrl, archivePath } = opts;
39
43
 
40
44
  try {
41
- await downloadArchive(logger, archiveUrl, archivePath);
45
+ await downloadArchive({ logger, archiveUrl, archivePath, dispatcher });
42
46
  opts.wasDownloadedFrom = archiveUrl;
43
47
  } catch (_e) {
44
- await downloadArchive(logger, alternativeArchiveGAUrl, archivePath);
48
+ await downloadArchive({ logger, archiveUrl: alternativeArchiveGAUrl, archivePath, dispatcher });
45
49
  opts.wasDownloadedFrom = alternativeArchiveGAUrl;
46
50
  }
47
51
 
@@ -49,21 +53,24 @@ export async function downloadBinaryNoExtract(
49
53
  }
50
54
 
51
55
  export async function downloadBinary(
52
- logger: MiLogger,
53
- baseDir: string,
54
- softwareName: string,
55
- archiveName: string,
56
- arch: string,
57
- platform: string,
56
+ { logger, baseDir, softwareName, archiveName, arch, platform, dispatcher }: {
57
+ logger: MiLogger;
58
+ baseDir: string;
59
+ softwareName: string;
60
+ archiveName: string;
61
+ arch: string;
62
+ platform: string;
63
+ dispatcher?: Dispatcher;
64
+ },
58
65
  ): Promise<DownloadBinaryResult> {
59
66
  const opts = getPathsForDownload(softwareName, archiveName, baseDir, newArch(arch), newOs(platform));
60
67
  const { archiveUrl, alternativeArchiveGAUrl, archivePath, archiveType, targetFolder } = opts;
61
68
 
62
69
  try {
63
- await downloadArchive(logger, archiveUrl, archivePath);
70
+ await downloadArchive({ logger, archiveUrl, archivePath, dispatcher });
64
71
  opts.wasDownloadedFrom = archiveUrl;
65
72
  } catch (_e) {
66
- await downloadArchive(logger, alternativeArchiveGAUrl, archivePath);
73
+ await downloadArchive({ logger, archiveUrl: alternativeArchiveGAUrl, archivePath, dispatcher });
67
74
  opts.wasDownloadedFrom = alternativeArchiveGAUrl;
68
75
  }
69
76
 
@@ -100,7 +107,7 @@ function getPathsForDownload(
100
107
  }
101
108
 
102
109
  export type DownloadInfo = {
103
- dstArchive?: string;
110
+ archivePath?: string;
104
111
  fileExisted?: boolean;
105
112
  dirnameCreated?: boolean;
106
113
  statusCode?: number;
@@ -113,24 +120,29 @@ export type DownloadInfo = {
113
120
  };
114
121
 
115
122
  export async function downloadArchive(
116
- logger: MiLogger, archiveUrl: string, dstArchiveFile: string,
123
+ { logger, archiveUrl, archivePath, dispatcher }: {
124
+ logger: MiLogger;
125
+ archiveUrl: string;
126
+ archivePath: string;
127
+ dispatcher?: Dispatcher;
128
+ },
117
129
  ): Promise<DownloadInfo> {
118
130
  const state: DownloadInfo = {};
119
- state.dstArchive = dstArchiveFile;
131
+ state.archivePath = archivePath;
120
132
 
121
133
  try {
122
- state.fileExisted = await fileExists(dstArchiveFile);
134
+ state.fileExisted = await fileExists(archivePath);
123
135
  if (state.fileExisted) {
124
- logger.info(`Platforma Backend archive download skipped: '${dstArchiveFile}' already exists`);
136
+ logger.info(`Platforma Backend archive download skipped: '${archivePath}' already exists`);
125
137
  return state;
126
138
  }
127
139
 
128
- await fsp.mkdir(upath.dirname(dstArchiveFile), { recursive: true });
140
+ await fsp.mkdir(upath.dirname(archivePath), { recursive: true });
129
141
  state.dirnameCreated = true;
130
142
 
131
- logger.info(`Downloading archive:\n URL: ${archiveUrl}\n Save to: ${dstArchiveFile}`);
143
+ logger.info(`Downloading archive:\n URL: ${archiveUrl}\n Save to: ${archivePath}`);
132
144
 
133
- const { body, statusCode } = await request(archiveUrl);
145
+ const { body, statusCode } = await request(archiveUrl, { dispatcher });
134
146
  state.statusCode = statusCode;
135
147
  if (statusCode != 200) {
136
148
  // completely draining the stream to prevent leaving open connections
@@ -141,16 +153,16 @@ export async function downloadArchive(
141
153
  }
142
154
 
143
155
  // to prevent incomplete downloads we first write in a temp file
144
- state.tmpPath = dstArchiveFile + '.tmp';
156
+ state.tmpPath = archivePath + '.tmp';
145
157
  // eslint-disable-next-line n/no-unsupported-features/node-builtins
146
158
  await Readable.toWeb(body).pipeTo(Writable.toWeb(fs.createWriteStream(state.tmpPath)));
147
159
  state.wroteTmp = true;
148
160
  state.tmpExisted = await fileExists(state.tmpPath);
149
161
 
150
162
  // and then atomically rename it
151
- await fsp.rename(state.tmpPath, dstArchiveFile);
163
+ await fsp.rename(state.tmpPath, archivePath);
152
164
  state.renamed = true;
153
- state.newExisted = await fileExists(dstArchiveFile);
165
+ state.newExisted = await fileExists(archivePath);
154
166
 
155
167
  return state;
156
168
  } catch (e: unknown) {
package/src/local/pl.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type {
2
- ProcessOptions } from './process';
1
+ import type { ProcessOptions } from './process';
3
2
  import {
4
3
  isProcessAlive,
5
4
  processStop,
@@ -18,6 +17,9 @@ import upath from 'upath';
18
17
  import fsp from 'node:fs/promises';
19
18
  import type { Required } from 'utility-types';
20
19
  import * as os from 'node:os';
20
+ import type { ProxySettings } from '@milaboratories/pl-http';
21
+ import { defaultHttpDispatcher } from '@milaboratories/pl-http';
22
+ import { parseHttpAuth } from '@milaboratories/pl-model-common';
21
23
 
22
24
  export const LocalConfigYaml = 'config-local.yaml';
23
25
 
@@ -128,6 +130,12 @@ export type LocalPlOptions = {
128
130
  * (default: true)
129
131
  */
130
132
  readonly closeOld?: boolean;
133
+ /**
134
+ * Proxy settings to use to fetch the binary and pass it down
135
+ * as a HTTPS_PROXY/HTTP_PROXY environment variable;
136
+ * Backend only supports Basic auth.
137
+ */
138
+ readonly proxy?: ProxySettings;
131
139
 
132
140
  readonly onClose?: (pl: LocalPl) => Promise<void>;
133
141
  readonly onError?: (pl: LocalPl) => Promise<void>;
@@ -163,10 +171,33 @@ export async function localPlatformaInit(logger: MiLogger, _ops: LocalPlOptions)
163
171
  await fsp.writeFile(configPath, ops.config);
164
172
 
165
173
  const plBinPath = upath.join(workDir, 'binaries');
166
- const baseBinaryPath = await resolveLocalPlBinaryPath(logger, plBinPath, ops.plBinary);
174
+ const baseBinaryPath = await resolveLocalPlBinaryPath({
175
+ logger,
176
+ downloadDir: plBinPath,
177
+ src: ops.plBinary,
178
+ dispatcher: defaultHttpDispatcher(ops.proxy),
179
+ });
167
180
  const binaryPath = trace('binaryPath', upath.join('binaries', baseBinaryPath));
168
181
 
169
- const processOpts = plProcessOps(binaryPath, configPath, ops, workDir, process.env);
182
+ const env = { ...process.env };
183
+
184
+ if (ops.proxy?.url) {
185
+ const url = new URL(ops.proxy.url);
186
+ if (ops.proxy.auth) {
187
+ const parsed = parseHttpAuth(ops.proxy.auth);
188
+ if (parsed.scheme !== 'Basic') {
189
+ throw new Error(`\
190
+ Unsupported auth scheme: ${parsed.scheme}. \
191
+ Only Basic auth is supported by the backend.`);
192
+ }
193
+ url.username = parsed.username;
194
+ url.password = parsed.password;
195
+ }
196
+ env.http_proxy = url.toString();
197
+ env.https_proxy = url.toString();
198
+ }
199
+
200
+ const processOpts = plProcessOps(binaryPath, configPath, ops, workDir, env);
170
201
  trace('processOpts', {
171
202
  cmd: processOpts.cmd,
172
203
  args: processOpts.args,
@@ -92,13 +92,14 @@ describe('SshPl', async () => {
92
92
  it('Transfer Platforma to server', async () => {
93
93
  const arch = await sshPl.getArch();
94
94
 
95
- const plPath = await downloadBinary(
96
- new ConsoleLoggerAdapter(),
97
- downloadDestination,
98
- 'pl', `pl-${getDefaultPlVersion()}`,
99
- arch.arch,
100
- arch.platform,
101
- );
95
+ const plPath = await downloadBinary({
96
+ logger: new ConsoleLoggerAdapter(),
97
+ baseDir: downloadDestination,
98
+ softwareName: 'pl',
99
+ archiveName: `pl-${getDefaultPlVersion()}`,
100
+ arch: arch.arch,
101
+ platform: arch.platform,
102
+ });
102
103
 
103
104
  const plFolderName = upath.basename(plPath.targetFolder);
104
105
  const dirPath = upath.resolve(downloadDestination, plFolderName);
@@ -200,13 +201,14 @@ describe('SshPl', async () => {
200
201
  it('Download pl. We have archive and extracted data', async () => {
201
202
  const arch = await sshPl.getArch();
202
203
 
203
- const result = await downloadBinary(
204
- new ConsoleLoggerAdapter(),
205
- downloadDestination,
206
- 'pl', `pl-${getDefaultPlVersion()}`,
207
- arch.arch,
208
- arch.platform,
209
- );
204
+ const result = await downloadBinary({
205
+ logger: new ConsoleLoggerAdapter(),
206
+ baseDir: downloadDestination,
207
+ softwareName: 'pl',
208
+ archiveName: `pl-${getDefaultPlVersion()}`,
209
+ arch: arch.arch,
210
+ platform: arch.platform,
211
+ });
210
212
 
211
213
  const version = getDefaultPlVersion();
212
214
  expect(!!result).toBe(true);
@@ -219,13 +221,14 @@ describe('SshPl', async () => {
219
221
  const softwareName = 'supervisord';
220
222
  const tgzName = 'supervisord-0.7.3';
221
223
 
222
- const result = await downloadBinary(
223
- new ConsoleLoggerAdapter(),
224
- downloadDestination,
225
- softwareName, tgzName,
226
- arch.arch,
227
- arch.platform,
228
- );
224
+ const result = await downloadBinary({
225
+ logger: new ConsoleLoggerAdapter(),
226
+ baseDir: downloadDestination,
227
+ softwareName,
228
+ archiveName: tgzName,
229
+ arch: arch.arch,
230
+ platform: arch.platform,
231
+ });
229
232
 
230
233
  expect(!!result).toBe(true);
231
234
  expect(existsSync(`${downloadDestination}/${tgzName}-${newArch(arch.arch)}.tgz`)).toBe(true);
package/src/ssh/pl.ts CHANGED
@@ -446,13 +446,14 @@ export class SshPl {
446
446
  const attempts = 5;
447
447
  for (let i = 1; i <= attempts; i++) {
448
448
  try {
449
- downloadBinaryResult = await downloadBinaryNoExtract(
450
- this.logger,
451
- localWorkdir,
449
+ downloadBinaryResult = await downloadBinaryNoExtract({
450
+ logger: this.logger,
451
+ baseDir: localWorkdir,
452
452
  softwareName,
453
453
  tgzName,
454
- arch.arch, arch.platform,
455
- );
454
+ arch: arch.arch,
455
+ platform: arch.platform,
456
+ });
456
457
  break;
457
458
  } catch (e: unknown) {
458
459
  await sleep(300);