2020-07-21 13:20:51 +00:00
|
|
|
import {LocalPlugin} from 'app/common/plugin';
|
|
|
|
import {BaseComponent, createRpcLogger} from 'app/common/PluginInstance';
|
|
|
|
import {GristServer} from 'app/server/lib/GristServer';
|
|
|
|
import {ISandbox} from 'app/server/lib/ISandbox';
|
2022-07-04 14:14:55 +00:00
|
|
|
import log from 'app/server/lib/log';
|
2020-07-21 13:20:51 +00:00
|
|
|
import {IMsgCustom, IMsgRpcCall} from 'grain-rpc';
|
|
|
|
|
|
|
|
// TODO safePython component should be able to call other components function
|
|
|
|
// TODO calling a function on safePython component with a name that was not register chould fail
|
|
|
|
// gracefully.
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The safePython component used by a PluginInstance.
|
|
|
|
*
|
|
|
|
* It uses `NSandbox` implementation of rpc for calling methods within the sandbox.
|
|
|
|
*/
|
|
|
|
export class SafePythonComponent extends BaseComponent {
|
|
|
|
|
(core) Speed up and upgrade build.
Summary:
- Upgrades to build-related packages:
- Upgrade typescript, related libraries and typings.
- Upgrade webpack, eslint; add tsc-watch, node-dev, eslint_d.
- Build organization changes:
- Build webpack from original typescript, transpiling only; with errors still
reported by a background tsc watching process.
- Typescript-related changes:
- Reduce imports of AWS dependencies (very noticeable speedup)
- Avoid auto-loading global @types
- Client code is now built with isolatedModules flag (for safe transpilation)
- Use allowJs to avoid copying JS files manually.
- Linting changes
- Enhance Arcanist ESLintLinter to run before/after commands, and set up to use eslint_d
- Update eslint config, and include .eslintignore to avoid linting generated files.
- Include a bunch of eslint-prompted and eslint-generated fixes
- Add no-unused-expression rule to eslint, and fix a few warnings about it
- Other items:
- Refactor cssInput to avoid circular dependency
- Remove a bit of unused code, libraries, dependencies
Test Plan: No behavior changes, all existing tests pass. There are 30 tests fewer reported because `test_gpath.py` was removed (it's been unused for years)
Reviewers: paulfitz
Reviewed By: paulfitz
Subscribers: paulfitz
Differential Revision: https://phab.getgrist.com/D3498
2022-06-27 20:09:41 +00:00
|
|
|
private _sandbox?: ISandbox;
|
2020-07-21 13:20:51 +00:00
|
|
|
private _logMeta: log.ILogMeta;
|
|
|
|
|
|
|
|
// safe python component does not need pluginInstance.rpc because it is not possible to forward
|
|
|
|
// calls to other component from within python
|
2021-08-09 14:51:43 +00:00
|
|
|
constructor(_localPlugin: LocalPlugin,
|
|
|
|
private _tmpDir: string,
|
2020-07-21 13:20:51 +00:00
|
|
|
docName: string, private _server: GristServer,
|
2021-08-09 14:51:43 +00:00
|
|
|
rpcLogger = createRpcLogger(log, `PLUGIN ${_localPlugin.id} SafePython:`)) {
|
2020-07-21 13:20:51 +00:00
|
|
|
super(_localPlugin.manifest, rpcLogger);
|
|
|
|
this._logMeta = {plugin: _localPlugin.id, docId: docName};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* `SafePythonComponent` activation creates the Sandbox. Throws if the plugin has no `safePyton`
|
|
|
|
* components.
|
|
|
|
*/
|
|
|
|
protected async activateImplementation(): Promise<void> {
|
|
|
|
if (!this._tmpDir) {
|
|
|
|
throw new Error("Sanbox should have a tmpDir");
|
|
|
|
}
|
|
|
|
this._sandbox = this._server.create.NSandbox({
|
|
|
|
importMount: this._tmpDir,
|
|
|
|
logTimes: true,
|
|
|
|
logMeta: this._logMeta,
|
2022-09-02 14:02:34 +00:00
|
|
|
preferredPythonVersion: '3',
|
2020-07-21 13:20:51 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
protected async deactivateImplementation(): Promise<void> {
|
|
|
|
log.info('SafePython deactivating ...');
|
|
|
|
if (!this._sandbox) {
|
|
|
|
log.info(' sandbox is undefined');
|
|
|
|
}
|
|
|
|
if (this._sandbox) {
|
|
|
|
await this._sandbox.shutdown();
|
|
|
|
log.info('SafePython done deactivating the sandbox');
|
|
|
|
delete this._sandbox;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected doForwardCall(c: IMsgRpcCall): Promise<any> {
|
|
|
|
if (!this._sandbox) { throw new Error("Component should have be activated"); }
|
|
|
|
const {meth, iface, args} = c;
|
|
|
|
const funcName = meth === "invoke" ? iface : iface + "." + meth;
|
|
|
|
return this._sandbox.pyCall(funcName, ...args);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected doForwardMessage(c: IMsgCustom): Promise<any> {
|
|
|
|
throw new Error("Forwarding messages to python sandbox is not supported");
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|