server: properly send serverVersion across during call to getRemote

This commit is contained in:
Koushik Dutta
2023-01-02 20:22:56 -08:00
parent c15a12ae53
commit 227b287f1e
7 changed files with 24 additions and 18 deletions

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/server",
"version": "0.5.3",
"version": "0.5.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/server",
"version": "0.5.3",
"version": "0.5.4",
"license": "ISC",
"dependencies": {
"@ffmpeg-installer/ffmpeg": "^1.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/server",
"version": "0.5.3",
"version": "0.5.4",
"description": "",
"dependencies": {
"@ffmpeg-installer/ffmpeg": "^1.1.0",

View File

@@ -209,13 +209,15 @@ class PluginRemote:
systemState: Mapping[str, Mapping[str, SystemDeviceState]] = {}
nativeIds: Mapping[str, DeviceStorage] = {}
pluginId: str
hostInfo: Any
mediaManager: MediaManager
loop: AbstractEventLoop
consoles: Mapping[str, Future[Tuple[StreamReader, StreamWriter]]] = {}
def __init__(self, api, pluginId, loop: AbstractEventLoop):
def __init__(self, api, pluginId, hostInfo, loop: AbstractEventLoop):
self.api = api
self.pluginId = pluginId
self.hostInfo = hostInfo
self.loop = loop
self.__dict__['__proxy_oneway_methods'] = [
'notify',
@@ -463,8 +465,8 @@ async def async_main(loop: AbstractEventLoop):
peer.constructorSerializerMap[bytes] = 'Buffer'
peer.constructorSerializerMap[bytearray] = 'Buffer'
peer.params['print'] = print
peer.params['getRemote'] = lambda api, pluginId: PluginRemote(
api, pluginId, loop)
peer.params['getRemote'] = lambda api, pluginId, hostInfo: PluginRemote(
api, pluginId, hostInfo, loop)
async def get_update_stats():
update_stats = await peer.getParam('updateStats')

View File

@@ -8,6 +8,10 @@ export interface PluginLogger {
clearAlerts(): Promise<void>;
}
export interface PluginHostInfo {
serverVersion: string;
}
export interface PluginAPI {
setState(nativeId: ScryptedNativeId, key: string, value: any): Promise<void>;
onDevicesChanged(deviceManifest: DeviceManifest): Promise<void>;
@@ -154,7 +158,6 @@ export class PluginAPIProxy extends PluginAPIManagedListeners implements PluginA
}
export interface PluginRemoteLoadZipOptions {
serverVersion?: string;
/**
* The filename to load the script as. Use for debugger source mapping.
*/

View File

@@ -217,7 +217,7 @@ export class PluginHost {
logger.log('i', `loading ${this.pluginName}`);
logger.log('i', 'pid ' + this.worker?.pid);
const remotePromise = setupPluginRemote(this.peer, this.api, self.pluginId, () => this.scrypted.stateManager.getSystemState());
const remotePromise = setupPluginRemote(this.peer, this.api, self.pluginId, { serverVersion }, () => this.scrypted.stateManager.getSystemState());
const init = (async () => {
const remote = await remotePromise;
@@ -242,7 +242,6 @@ export class PluginHost {
try {
const isPython = runtime === 'python';
const loadZipOptions: PluginRemoteLoadZipOptions = {
serverVersion: serverVersion,
// if debugging, use a normalized path for sourcemap resolution, otherwise
// prefix with module path.
filename: isPython
@@ -396,7 +395,7 @@ export class PluginHost {
socket.on('close', kill);
socket.on('error', kill);
return setupPluginRemote(rpcPeer, api, null, () => this.scrypted.stateManager.getSystemState());
return setupPluginRemote(rpcPeer, api, null, { serverVersion }, () => this.scrypted.stateManager.getSystemState());
}
async createRpcPeer(duplex: Duplex) {
@@ -410,6 +409,6 @@ export class PluginHost {
};
duplex.on('close', kill);
return setupPluginRemote(rpcPeer, api, null, () => this.scrypted.stateManager.getSystemState());
return setupPluginRemote(rpcPeer, api, null, { serverVersion }, () => this.scrypted.stateManager.getSystemState());
}
}

View File

@@ -22,6 +22,8 @@ interface PluginStats {
memoryUsage: NodeJS.MemoryUsage;
}
const serverVersion = require('../../package.json').version;
export function startPluginRemote(pluginId: string, peerSend: (message: RpcMessage, reject?: (e: Error) => void, serializationContext?: any) => void) {
const peer = new RpcPeer('unknown', 'host', peerSend);
@@ -371,7 +373,7 @@ export function startPluginRemote(pluginId: string, peerSend: (message: RpcMessa
}
const forkApi = new PluginForkAPI(api);
const remote = await setupPluginRemote(threadPeer, forkApi, pluginId, () => systemManager.getSystemState());
const remote = await setupPluginRemote(threadPeer, forkApi, pluginId, { serverVersion }, () => systemManager.getSystemState());
forks.add(remote);
ntw.worker.on('exit', () => {
threadPeer.kill('worker exited');

View File

@@ -2,7 +2,7 @@ import { Device, DeviceManager, DeviceManifest, DeviceState, EndpointManager, Ev
import { RpcPeer, RPCResultError } from '../rpc';
import { AccessControls } from './acl';
import { BufferSerializer } from './buffer-serializer';
import { PluginAPI, PluginLogger, PluginRemote, PluginRemoteLoadZipOptions } from './plugin-api';
import { PluginAPI, PluginHostInfo, PluginLogger, PluginRemote, PluginRemoteLoadZipOptions } from './plugin-api';
import { createWebSocketClass, WebSocketConnectCallbacks, WebSocketConnection, WebSocketMethods, WebSocketSerializer } from './plugin-remote-websocket';
import { checkProperty } from './plugin-state-check';
import { SystemManagerImpl } from './system';
@@ -352,7 +352,7 @@ class StorageImpl implements Storage {
}
}
export async function setupPluginRemote(peer: RpcPeer, api: PluginAPI, pluginId: string, getSystemState: () => { [id: string]: { [property: string]: SystemDeviceState } }): Promise<PluginRemote> {
export async function setupPluginRemote(peer: RpcPeer, api: PluginAPI, pluginId: string, hostInfo: PluginHostInfo, getSystemState: () => { [id: string]: { [property: string]: SystemDeviceState } }): Promise<PluginRemote> {
try {
// the host/remote connection can be from server to plugin (node to node),
// core plugin to web (node to browser).
@@ -361,7 +361,7 @@ export async function setupPluginRemote(peer: RpcPeer, api: PluginAPI, pluginId:
if (!peer.constructorSerializerMap.get(Buffer))
peer.addSerializer(Buffer, 'Buffer', new BufferSerializer());
const getRemote = await peer.getParam('getRemote');
const remote = await getRemote(api, pluginId) as PluginRemote;
const remote = await getRemote(api, pluginId, hostInfo) as PluginRemote;
const accessControls: AccessControls = peer.tags.acl;
@@ -463,7 +463,7 @@ export function attachPluginRemote(peer: RpcPeer, options?: PluginRemoteAttachOp
let done: (scrypted: ScryptedStatic) => void;
const retPromise = new Promise<ScryptedStatic>(resolve => done = resolve);
peer.params.getRemote = async (api: PluginAPI, pluginId: string) => {
peer.params.getRemote = async (api: PluginAPI, pluginId: string, hostInfo: PluginHostInfo) => {
websocketSerializer.WebSocket = createWebSocketClass((connection, callbacks) => {
const { url } = connection;
if (url.startsWith('io://') || url.startsWith('ws://')) {
@@ -506,7 +506,8 @@ export function attachPluginRemote(peer: RpcPeer, options?: PluginRemoteAttachOp
log,
pluginHostAPI: api,
pluginRemoteAPI: undefined,
}
serverVersion: hostInfo?.serverVersion,
};
delete peer.params.getRemote;
@@ -637,7 +638,6 @@ export function attachPluginRemote(peer: RpcPeer, options?: PluginRemoteAttachOp
};
params.pluginRuntimeAPI = ret;
ret.serverVersion = zipOptions.serverVersion;
return options.onLoadZip(ret, params, packageJson, zipData, zipOptions);
},