Skip to content

Commit

Permalink
feat(repeater): send runtime information upon repeater registration (#…
Browse files Browse the repository at this point in the history
…442)

closes #441
  • Loading branch information
lsndr authored Aug 23, 2023
1 parent 9070495 commit 27bdacb
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 5 deletions.
13 changes: 12 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ jobs:
- name: Install deps
uses: ./.github/workflows/composite/npm

- name: Set default distribution
run: npm pkg set brightCli.distribution=package

- name: Build package
run: npm run build

Expand Down Expand Up @@ -108,6 +111,9 @@ jobs:
with:
version: ${{ matrix.node }}

- name: Set distribution
run: npm pkg set brightCli.distribution=${{ matrix.target }}-executable

- name: Build executable file
run: npm run build:pkg -- -t node${{ matrix.node }}-${{ matrix.target }}-x64

Expand Down Expand Up @@ -163,14 +169,19 @@ jobs:
- name: Setup node
uses: ./.github/workflows/composite/npm

- name: Set NPM distribution
run: npm pkg set brightCli.distribution=npm

- run: npm publish --tag $TAG
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

# The scope does not align with the package name
# FIXME: once GitHub organization name has been changed, we should prevent this behavior
- name: Prepare GPR package
run: npm pkg set name='@neuralegion/bright-cli'
run: |
npm pkg set name='@neuralegion/bright-cli' \
&& npm pkg set brightCli.distribution=gpr
- name: Setup node
uses: ./.github/workflows/composite/npm
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ LABEL org.opencontainers.image.version="$VERSION"
# good colors for most applications
ENV TERM xterm

# inform cli that it's running inside docker container
ENV BRIGHT_CLI_DOCKER 1

# avoid million NPM install messages
ENV npm_config_loglevel warn
# allow installing when the main user is root
Expand Down
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@neuralegion/os-service": "^1.1.1",
"ajv": "^6.12.6",
"amqplib": "~0.10.2",
"arch": "^2.2.0",
"better-ajv-errors": "^1.2.0",
"chalk": "^4.1.2",
"content-type": "^1.0.4",
Expand Down Expand Up @@ -155,5 +156,8 @@
"build:pkg": "pkg .",
"prepare": "is-ci || husky install",
"start": "node -r ts-node/register/transpile-only -r tsconfig-paths/register src/index.ts"
},
"brightCli": {
"distribution": "unknown"
}
}
9 changes: 8 additions & 1 deletion src/Config/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ import {
RepeaterServer,
DefaultRepeaterServer,
RepeaterCommandHub,
DefaultRepeaterCommandHub
DefaultRepeaterCommandHub,
RuntimeDetector,
DefaultRuntimeDetector
} from '../Repeater';
import { container, Lifecycle } from 'tsyringe';

Expand Down Expand Up @@ -105,6 +107,11 @@ container
},
{ lifecycle: Lifecycle.Singleton }
)
.register(
RuntimeDetector,
{ useClass: DefaultRuntimeDetector },
{ lifecycle: Lifecycle.Singleton }
)
.register(
RepeaterServer,
{
Expand Down
12 changes: 11 additions & 1 deletion src/Handlers/Events/RepeaterRegistering.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { Event } from '../../Bus';

interface RepeaterRuntime {
readonly transport?: 'rabbitmq' | 'ws';
readonly arch?: string;
readonly os?: string;
readonly docker?: boolean;
readonly distribution?: string;
readonly nodeVersion?: string;
}

export class RepeaterRegistering implements Event {
constructor(
public readonly repeaterId: string,
public readonly version: string,
public readonly localScriptsUsed: boolean
public readonly localScriptsUsed: boolean,
public readonly runtime?: RepeaterRuntime
) {}
}
12 changes: 11 additions & 1 deletion src/Repeater/DefaultRepeaterLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '../Handlers';
import { CliInfo } from '../Config';
import { RepeaterCommandHub } from './RepeaterCommandHub';
import { RuntimeDetector } from './RuntimeDetector';
import { gt } from 'semver';
import chalk from 'chalk';
import { delay, inject, injectable } from 'tsyringe';
Expand All @@ -28,6 +29,7 @@ export class DefaultRepeaterLauncher implements RepeaterLauncher {
private repeaterStarted: boolean = false;

constructor(
@inject(RuntimeDetector) private readonly runtimeDetector: RuntimeDetector,
@inject(Bus) private readonly bus: Bus,
@inject(RepeaterCommandHub) private readonly commandHub: RepeaterCommandHub,
@inject(VirtualScripts) private readonly virtualScripts: VirtualScripts,
Expand Down Expand Up @@ -117,7 +119,15 @@ export class DefaultRepeaterLauncher implements RepeaterLauncher {
payload: new RepeaterRegistering(
repeaterId,
this.info.version,
!!this.virtualScripts.size
!!this.virtualScripts.size,
{
transport: 'rabbitmq',
os: this.runtimeDetector.os(),
arch: this.runtimeDetector.arch(),
docker: this.runtimeDetector.isInsideDocker(),
distribution: this.runtimeDetector.distribution(),
nodeVersion: this.runtimeDetector.nodeVersion()
}
)
});

Expand Down
110 changes: 110 additions & 0 deletions src/Repeater/DefaultRuntimeDetector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import packageInfo from '../../package.json';
import { RuntimeDetector } from './RuntimeDetector';
import arch from 'arch';
import { execSync } from 'child_process';
import os from 'os';

export class DefaultRuntimeDetector implements RuntimeDetector {
public distribution(): string | undefined {
return packageInfo.brightCli.distribution;
}

public isInsideDocker(): boolean {
return !!process.env['BRIGHT_CLI_DOCKER'];
}

public nodeVersion(): string {
return process.version;
}

public arch(): string {
try {
return arch();
} catch {
// pass
}

// As a fallback use arch info for which the Node.js binary was compiled
return os.arch();
}

public os(): string {
const platform = os.platform();

if (platform === 'darwin') {
return this.detectMacosVersion();
} else if (platform === 'linux') {
return this.detectLinuxVersion();
} else if (platform === 'win32') {
return this.detectWindowsVersion();
}

// As a fallback use OS info for which the Node.js binary was compiled
return `${os.platform()} (${os.release()})`;
}

private detectMacosVersion() {
try {
const name = execSync('sw_vers -productName', {
encoding: 'utf8'
}).trim();
const version = execSync('sw_vers -productVersion', {
encoding: 'utf8'
}).trim();
const build = execSync('sw_vers -buildVersion', {
encoding: 'utf8'
}).trim();

if (name.length && version.length && build.length) {
return `${name} ${version} (${build})`;
}
} catch {
// pass
}

return `${os.platform()} (${os.release()})`;
}

private detectLinuxVersion() {
try {
const osRelease = execSync('cat /etc/os-release', {
encoding: 'utf8'
}).trim();
const extractValue = (key: string) =>
new RegExp(
`(?:^|[\r\n]+)${key}(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*"(?:\\\\"|[^"])*"|\\s*\`(?:\\\\\`|[^\`])*\`|[^#\r\n]+)?`,
'i'
)
.exec(osRelease)?.[1]
.replace(/^(['"`])([\s\S]*)\1$/i, '$2');

const name = extractValue('NAME') || extractValue('ID');
const version = extractValue('VERSION') || extractValue('VERSION_ID');
const prettyName = extractValue('PRETTY_NAME');

if (name.length && version.length) {
return `${name} ${version}`;
} else if (prettyName.length) {
return prettyName;
}
} catch {
// pass
}

return `${os.platform()} (${os.release()})`;
}

private detectWindowsVersion() {
try {
const version = execSync('ver', { encoding: 'utf8' }).trim();

if (version.length) {
return version;
}
} catch {
// pass
}

return `${os.platform()} (${os.release()})`;
}
}
5 changes: 5 additions & 0 deletions src/Repeater/RepeaterServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export interface DeployCommandOptions {
export interface DeploymentRuntime {
version: string;
scriptsLoaded: boolean;
os?: string;
arch?: string;
docker?: boolean;
distribution?: string;
nodeVersion?: string;
}

export interface RepeaterServer {
Expand Down
13 changes: 13 additions & 0 deletions src/Repeater/RuntimeDetector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface RuntimeDetector {
os(): string;

arch(): string;

isInsideDocker(): boolean;

nodeVersion(): string;

distribution(): string | undefined;
}

export const RuntimeDetector: unique symbol = Symbol('RuntimeDetector');
9 changes: 8 additions & 1 deletion src/Repeater/ServerRepeaterLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
RepeaterServerReconnectionFailedEvent,
RepeaterServerRequestEvent
} from './RepeaterServer';
import { RuntimeDetector } from './RuntimeDetector';
import { ScriptLoader, VirtualScripts } from '../Scripts';
import { StartupManager } from '../StartupScripts';
import { Certificates, Request } from '../RequestExecutor';
Expand All @@ -20,6 +21,7 @@ export class ServerRepeaterLauncher implements RepeaterLauncher {
private repeaterStarted: boolean = false;

constructor(
@inject(RuntimeDetector) private readonly runtimeDetector: RuntimeDetector,
@inject(VirtualScripts) private readonly virtualScripts: VirtualScripts,
@inject(RepeaterServer) private readonly repeaterServer: RepeaterServer,
@inject(StartupManager)
Expand Down Expand Up @@ -108,7 +110,12 @@ export class ServerRepeaterLauncher implements RepeaterLauncher {
private getRuntime(): DeploymentRuntime {
return {
version: this.info.version,
scriptsLoaded: !!this.virtualScripts.size
scriptsLoaded: !!this.virtualScripts.size,
os: this.runtimeDetector.os(),
arch: this.runtimeDetector.arch(),
docker: this.runtimeDetector.isInsideDocker(),
distribution: this.runtimeDetector.distribution(),
nodeVersion: this.runtimeDetector.nodeVersion()
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/Repeater/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export * from './DefaultRepeaterServer';
export * from './RepeaterLauncher';
export * from './RepeaterServer';
export * from './ServerRepeaterLauncher';
export * from './RuntimeDetector';
export * from './DefaultRuntimeDetector';

0 comments on commit 27bdacb

Please sign in to comment.