dcp-worker 4.1.1 → 4.2.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.
- package/.gitlab-ci.yml +1 -3
- package/bin/dcp-evaluator-manager +33 -15
- package/bin/dcp-evaluator-start +149 -119
- package/bin/dcp-task-probe +20 -11
- package/bin/dcp-worker +698 -578
- package/lib/blessed-components/log.js +10 -0
- package/lib/check-scheduler-version.js +3 -2
- package/lib/consts.js +25 -0
- package/lib/loggers.js +256 -0
- package/lib/node-version-check.js +4 -2
- package/lib/pidfile.js +88 -4
- package/lib/reports.js +95 -0
- package/lib/show.js +54 -0
- package/lib/{remote-console.js → telnetd.js} +32 -19
- package/lib/utils.js +112 -9
- package/lib/web-console.js +178 -0
- package/lib/web-iface.js +128 -0
- package/lib/{dashboard-tui.js → worker-consoles/dashboard-console.js} +167 -57
- package/lib/worker-consoles/index.js +44 -0
- package/lib/worker-consoles/none-console.js +23 -0
- package/lib/worker-consoles/stdio-console.js +70 -0
- package/lib/worker-info.js +29 -20
- package/lib/worker-loggers/event-log.js +24 -26
- package/lib/worker-loggers/logfile.js +73 -65
- package/lib/worker-loggers/syslog.js +145 -43
- package/package.json +6 -4
- package/{bin/publish-docs.sh → publish-docs.sh} +1 -1
- package/tests/worker-with-no-options.simple +35 -13
- package/tests/worker-with-options.simple +65 -18
- package/lib/startWorkerLogger.js +0 -138
- package/lib/worker-loggers/console.js +0 -74
- package/lib/worker-loggers/dashboard.js +0 -76
package/.gitlab-ci.yml
CHANGED
|
@@ -149,11 +149,9 @@ publish_docs:
|
|
|
149
149
|
AWS_REGION: 'us-east-1'
|
|
150
150
|
TECHDOCS_S3_BUCKET_NAME: 'backstage.distributive.network'
|
|
151
151
|
ENTITY_NAMESPACE: 'default'
|
|
152
|
-
stage: deploy
|
|
153
|
-
needs: []
|
|
154
152
|
image: registry.gitlab.com/distributed-compute-protocol/backstage-ci-image:latest
|
|
155
153
|
script:
|
|
156
|
-
-
|
|
154
|
+
- ./publish-docs.sh
|
|
157
155
|
cache:
|
|
158
156
|
- key:
|
|
159
157
|
prefix: node-modules
|
|
@@ -41,8 +41,8 @@ var lastConnectionMs = 0;
|
|
|
41
41
|
const defaultPrefix = '/usr';
|
|
42
42
|
const daemonConfig = {
|
|
43
43
|
net: new URL('tcpip://localhost:9000/'),
|
|
44
|
-
proc:
|
|
45
|
-
argv: [ '-s', '--prefix', `${path.resolve(defaultPrefix)}/` ],
|
|
44
|
+
proc: process.argv[0],
|
|
45
|
+
argv: [ require.resolve('./dcp-evaluator-start'), '-s', '--prefix', `${path.resolve(defaultPrefix)}/` ],
|
|
46
46
|
pidfile: pidfile.getDefaultPidFilename,
|
|
47
47
|
limits: {
|
|
48
48
|
loadavgType: 'short',
|
|
@@ -65,9 +65,10 @@ function usage()
|
|
|
65
65
|
DCP Evaluator Monitor - Copyright (c) 2022-2024 Distributive Corp.
|
|
66
66
|
Released under the terms of the MIT License.
|
|
67
67
|
|
|
68
|
-
Usage: ${process.argv[0]} [-h | --help] [--prefix=<dir>] [--pts=<dir>]
|
|
68
|
+
Usage: ${process.argv[0]} [-h | --help] [--prefix=<dir>] [--pts=<dir>]
|
|
69
69
|
[--disable-monitor=<session|screensaver|signal>] [-i <timeout>]
|
|
70
|
-
[-p port] [-
|
|
70
|
+
[-p port] [-H hostname]
|
|
71
|
+
[-a] [-l | --max-load=<number>] [-r | --rate=<number>] [-L]
|
|
71
72
|
[-s | --signal=[name or number][,<toggle|quick>]]
|
|
72
73
|
[-T | --loadavg-type=<short,medium,long,random>]
|
|
73
74
|
[-f | --pidfile=</path/to/file.pid>]
|
|
@@ -75,6 +76,7 @@ Usage: ${process.argv[0]} [-h | --help] [--prefix=<dir>] [--pts=<dir>] [-a]
|
|
|
75
76
|
Where:
|
|
76
77
|
-i sets the idle timeout in seconds for tty sessions (${daemonConfig.session.idleTimeout}s)
|
|
77
78
|
-p specifies the port to listen on for dcpsaw: worker connections (${daemonConfig.net.port})
|
|
79
|
+
-H specifies the address to listen on for dcpsaw: worker connections (${daemonConfig.net.port})
|
|
78
80
|
--prefix specifies the directory where the DCP evaluator package was installed
|
|
79
81
|
--pidfile specifies an alternate location for the pid file (currently ${daemonConfig.pidfile})
|
|
80
82
|
--pts specifies the location of the system's pseudo terminal (${ptsDir})
|
|
@@ -110,7 +112,7 @@ async function listenForConnections(config)
|
|
|
110
112
|
if (config.net.hostname === 'localhost')
|
|
111
113
|
hostaddr = '::';
|
|
112
114
|
else
|
|
113
|
-
hostaddr = await dns.promises.lookup(config.net.hostname, { family: 4 });
|
|
115
|
+
hostaddr = (await dns.promises.lookup(config.net.hostname, { family: 4 })).address || config.net.hostname;
|
|
114
116
|
|
|
115
117
|
server.on('error', (error) => {
|
|
116
118
|
delete error.stack;
|
|
@@ -367,7 +369,7 @@ async function dbusScreenSaverMonitor()
|
|
|
367
369
|
console.warn('Warning: could not open dbus session to any screensaver, tried', screensaverList);
|
|
368
370
|
return;
|
|
369
371
|
}
|
|
370
|
-
|
|
372
|
+
|
|
371
373
|
try
|
|
372
374
|
{
|
|
373
375
|
// Note this is almost guranteed to fail if (GNOME is installed + you're accessing it not on GNOME,
|
|
@@ -524,7 +526,8 @@ function odRequire(moduleId)
|
|
|
524
526
|
/* Main program entry point */
|
|
525
527
|
async function main()
|
|
526
528
|
{
|
|
527
|
-
const parser = new getopt.BasicParser('h(help)P:(prefix)d:(disable-monitor)l:(max-load)r:(rate)
|
|
529
|
+
const parser = new getopt.BasicParser('h(help)P:(prefix)H:p:d:(disable-monitor)l:(max-load)r:(rate)'
|
|
530
|
+
+ 'Li:as:(signal)T:(loadavg-type)f:(pidfile)', process.argv);
|
|
528
531
|
var option;
|
|
529
532
|
|
|
530
533
|
if (dcpConfig.evaluator.listen)
|
|
@@ -601,6 +604,12 @@ async function main()
|
|
|
601
604
|
break;
|
|
602
605
|
}
|
|
603
606
|
|
|
607
|
+
case 'H':
|
|
608
|
+
{
|
|
609
|
+
daemonConfig.net.hostname = option.optarg;
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
|
|
604
613
|
case 'l':
|
|
605
614
|
{
|
|
606
615
|
daemonConfig.limits.maxLoad = Number(option.optarg);
|
|
@@ -660,11 +669,20 @@ async function main()
|
|
|
660
669
|
}
|
|
661
670
|
|
|
662
671
|
/* Initialize dcp-client to use only local resources before launching the main function */
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
}
|
|
672
|
+
try {
|
|
673
|
+
require('dcp-client').init({
|
|
674
|
+
programName: 'dcp-worker',
|
|
675
|
+
parseArgv: false,
|
|
676
|
+
dcpConfig: {
|
|
677
|
+
scheduler: { configLocation: false },
|
|
678
|
+
bundle: { location: false },
|
|
679
|
+
}
|
|
680
|
+
}).then(main);
|
|
681
|
+
}
|
|
682
|
+
catch(error)
|
|
683
|
+
{
|
|
684
|
+
if (error.name === 'SyntaxError')
|
|
685
|
+
console.error(`Unable to initialize dcp-client - Node.js version too old? (SyntaxError: ${error.message})`);
|
|
686
|
+
else
|
|
687
|
+
throw error;
|
|
688
|
+
}
|
package/bin/dcp-evaluator-start
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
3
|
* @file dcp-evaluator-start
|
|
4
|
-
* @author
|
|
5
|
-
*
|
|
6
|
-
* @date
|
|
4
|
+
* @author Wes Garland, wes@distributive.network
|
|
5
|
+
* Brandon Christie, brandon@distributive.network
|
|
6
|
+
* @date Feb 2021, June 2024
|
|
7
7
|
*
|
|
8
8
|
* This script starts a DCP Evaluator. It acts as a facade which takes a standardized command-line
|
|
9
9
|
* interface and spawns the selected evaluator type with the correct corresponding options. Evaluator
|
|
10
10
|
* support files (eg. those used to implement the host environment and sandboxes) are loaded from the
|
|
11
|
-
* dcp-client module or
|
|
12
|
-
* sandbox-definitions.json which is generated during a dcp-client build.
|
|
11
|
+
* dcp-client module or its dependencies, and which of those files to use are specified by the
|
|
12
|
+
* sandbox-definitions.json, which is generated during a dcp-client build.
|
|
13
13
|
*/
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
@@ -19,103 +19,144 @@ function panic(...argv)
|
|
|
19
19
|
process.exit(1);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function main()
|
|
22
|
+
function main()
|
|
23
|
+
{
|
|
23
24
|
const { clearLine, cursorTo } = require('readline');
|
|
25
|
+
const { BasicParser } = require('posix-getopt');
|
|
26
|
+
const { expandPath } = require('dcp/utils');
|
|
24
27
|
const path = require('path');
|
|
28
|
+
const pidfile = require('../lib/pidfile')
|
|
25
29
|
const dcpConfig = require('dcp/dcp-config');
|
|
26
30
|
const dcpClientDir = path.dirname(require.resolve('dcp-client'));
|
|
27
|
-
const
|
|
28
|
-
|
|
31
|
+
const parser = new BasicParser(
|
|
32
|
+
'h(help)P:(prefix)p:(port)s(stdio)e:(evaluator)r:(rEvaluator)\u1000:(sandbox-libexec-dir)' +
|
|
33
|
+
'\u1001:(sandbox-definitions)t:(sandbox-type)D(dump)T(dump-types)F(dump-files)J(json)v(verbose)' +
|
|
34
|
+
'f:(pidfile)d:(logLevel)',
|
|
35
|
+
process.argv
|
|
36
|
+
);
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
alias: ['s'],
|
|
46
|
-
desc: 'Use stdio pipeline (eg for inetd) instead of tcp port',
|
|
47
|
-
type: 'boolean',
|
|
48
|
-
default: false,
|
|
49
|
-
})
|
|
50
|
-
.option('evaluator', {
|
|
51
|
-
alias: ['e'],
|
|
52
|
-
desc: 'Path to evaluator (default: prefix/bin/dcp-evaluator)',
|
|
53
|
-
})
|
|
54
|
-
.option('rEvaluator', {
|
|
55
|
-
alias: ['r'],
|
|
56
|
-
desc: 'Path to evaluator as a module identitifer',
|
|
57
|
-
})
|
|
58
|
-
.option('sandbox-libexec-dir', {
|
|
59
|
-
desc: 'Location of sandbox setup files',
|
|
60
|
-
default: path.resolve(dcpClientDir, 'libexec', 'sandbox'),
|
|
61
|
-
})
|
|
62
|
-
.option('sandbox-definitions', {
|
|
63
|
-
desc: 'Index of sandbox setup files for different evaluator/sandbox types',
|
|
64
|
-
default: path.resolve(dcpClientDir, 'generated', 'sandbox-definitions.json'),
|
|
65
|
-
})
|
|
66
|
-
.option('sandbox-type', {
|
|
67
|
-
alias: ['t'],
|
|
68
|
-
desc: 'Type of evaluator/sandbox',
|
|
69
|
-
default: 'native'
|
|
70
|
-
})
|
|
71
|
-
.option('dump', {
|
|
72
|
-
alias: ['D'],
|
|
73
|
-
desc: 'Dump configuration to stdout and exit',
|
|
74
|
-
})
|
|
75
|
-
.option('dump-types', {
|
|
76
|
-
alias: ['T'],
|
|
77
|
-
desc: 'Dump list of known sandbox types to stdout and exit',
|
|
78
|
-
})
|
|
79
|
-
.option('dump-files', {
|
|
80
|
-
alias: ['F'],
|
|
81
|
-
desc: 'Dump list of startup files which would be passed to the evaluator and exit',
|
|
82
|
-
})
|
|
83
|
-
.option('json', {
|
|
84
|
-
alias: ['J'],
|
|
85
|
-
desc: 'Dump in JSON format',
|
|
86
|
-
})
|
|
87
|
-
.option('verbose', {
|
|
88
|
-
alias: ['v'],
|
|
89
|
-
desc: 'Generate verbose output',
|
|
90
|
-
})
|
|
91
|
-
.option('pidFile', {
|
|
92
|
-
alias: ['f'],
|
|
93
|
-
describe: `create a .pid file; value overrides default location (${defaultPidFileName})`,
|
|
94
|
-
})
|
|
95
|
-
.options('debugLogLevel', {
|
|
96
|
-
alias: ['d'],
|
|
97
|
-
desc: 'Log level for evaluator output (emerg, alert, crit, error, warn, notice, info, debug)',
|
|
98
|
-
})
|
|
99
|
-
.epilogue("To pass arguments to the evaluator, make sure to separate your arguments with a '--'. For example: 'dcp-evaluator-start -p 9000 -- --options=--max-old-space-size=2048'")
|
|
100
|
-
.wrap(process.stdout.columns || 80)
|
|
101
|
-
.strict()
|
|
102
|
-
.argv;
|
|
38
|
+
const options = {
|
|
39
|
+
prefix: path.resolve(path.dirname(process.argv[1]), '..'),
|
|
40
|
+
port: Number(dcpConfig.evaluator.listen.port),
|
|
41
|
+
sandboxLibexecDir: path.resolve(dcpClientDir, 'libexec', 'sandbox'),
|
|
42
|
+
sandboxDefinitions: path.resolve(dcpClientDir, 'generated', 'sandbox-definitions.json'),
|
|
43
|
+
sandboxType: 'native',
|
|
44
|
+
evaluator: path.join('bin', 'dcp-evaluator'), /* resolved against prefix later */
|
|
45
|
+
verbose: 0,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
function help() {
|
|
49
|
+
const binName = path.basename(__filename);
|
|
50
|
+
console.log(`
|
|
51
|
+
${binName} - Evaluator frontend
|
|
52
|
+
Copyright (c) 2021-2025, Distributive Corp. Released under the terms of the MIT License.
|
|
103
53
|
|
|
104
|
-
|
|
105
|
-
|
|
54
|
+
Usage: ${binName} [options...]
|
|
55
|
+
Options:
|
|
56
|
+
-h, --help Display this help and exit
|
|
57
|
+
--prefix= Path under which native components are installed;
|
|
58
|
+
default is ${options.prefix}
|
|
59
|
+
-p, --port= Port to listen on; default is ${options.port}
|
|
60
|
+
-s, --stdio Use stdio pipeline (eg for inetd) instead of tcp
|
|
61
|
+
-t, --sandbox-type= Type of evaluator/sandbox; default is ${options.sandboxType}
|
|
62
|
+
-e, --evaluator= Path to evaluator; default is
|
|
63
|
+
${options.prefix}/bin/dcp-evaluator
|
|
64
|
+
-m, --evaluator-module= Path to evaluator as a module identitifer
|
|
65
|
+
--sandbox-definitions= JSON file defining the sandbox setup files for the
|
|
66
|
+
different evaluator/sandbox types; default is
|
|
67
|
+
${options.sandboxDefinitions}
|
|
68
|
+
--sandbox-libexec-dir= Location of sandbox setup files; default is
|
|
69
|
+
${options.sandboxLibexecDir}
|
|
70
|
+
-D, --dump Dump configuration to stdout and exit
|
|
71
|
+
-T, --dump-types Dump list of known sandbox types to stdout and exit
|
|
72
|
+
-F, --dump-files Dump list of startup files which would be passed
|
|
73
|
+
to the evaluator and exit
|
|
74
|
+
-J, --json Dump in JSON format
|
|
75
|
+
-v, --verbose Generate verbose output
|
|
76
|
+
-f, --pidfile= create a .pid file; default is
|
|
77
|
+
${pidfile.getDefaultPidFileName(dcpConfig.worker.pidfile)}
|
|
78
|
+
-d, --log-level= Select minimum log level for evaluator output
|
|
79
|
+
(debug, info, notice, warn, error, crit, alert, emerg)
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
106
82
|
|
|
107
|
-
|
|
108
|
-
|
|
83
|
+
for (let opthnd; (opthnd = parser.getopt()) !== undefined; /* while loop */)
|
|
84
|
+
{
|
|
85
|
+
let option;
|
|
109
86
|
|
|
110
|
-
|
|
87
|
+
/* To fake long-only-opts, we use short opts >= \u1000), and present only the long opt below */
|
|
88
|
+
if (opthnd.option < '\u1000')
|
|
89
|
+
option = opthnd.option;
|
|
90
|
+
else
|
|
91
|
+
option = (Object.entries(parser.gop_aliases).filter(longShort => longShort[1] === opthnd.option)[0] || ['?'])[0];
|
|
92
|
+
|
|
93
|
+
switch (option)
|
|
94
|
+
{
|
|
95
|
+
case '?':
|
|
96
|
+
process.exit(1);
|
|
97
|
+
break;
|
|
98
|
+
case 'h':
|
|
99
|
+
help();
|
|
100
|
+
process.exit(0);
|
|
101
|
+
break;
|
|
102
|
+
case 'P':
|
|
103
|
+
options.prefix = opthnd.optarg;
|
|
104
|
+
break;
|
|
105
|
+
case 'p':
|
|
106
|
+
options.port = opthnd.optarg;
|
|
107
|
+
break;
|
|
108
|
+
case 's':
|
|
109
|
+
options.stdio = true;
|
|
110
|
+
options.port = false;
|
|
111
|
+
break;
|
|
112
|
+
case 'e':
|
|
113
|
+
options.evaluator = expandPath(opthnd.optarg);
|
|
114
|
+
break;
|
|
115
|
+
case 'm':
|
|
116
|
+
options.evaluator = require.resolve(opthnd.optarg);
|
|
117
|
+
break;
|
|
118
|
+
case 't':
|
|
119
|
+
options.sandboxType = opthnd.optarg;
|
|
120
|
+
break;
|
|
121
|
+
case 'l':
|
|
122
|
+
options.sandboxLibexecDir = expandPath(opthnd.optarg);
|
|
123
|
+
break;
|
|
124
|
+
case 'J':
|
|
125
|
+
options.json = true;
|
|
126
|
+
break;
|
|
127
|
+
case 'f':
|
|
128
|
+
pidfile.write(expandPath(opthnd.optarg));
|
|
129
|
+
break;
|
|
130
|
+
case 'sandbox-definitions':
|
|
131
|
+
options.sandboxDefinitions = expandPath(opthnd.optarg);
|
|
132
|
+
break;
|
|
133
|
+
case 'T':
|
|
134
|
+
{
|
|
135
|
+
const dump = Object.keys(require(options.sandboxDefinitions));
|
|
136
|
+
console.log(options.json ? JSON.stringify(dump) : dump);
|
|
137
|
+
process.exit(0);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case 'D':
|
|
141
|
+
options.dump = true;
|
|
142
|
+
break;
|
|
143
|
+
case 'F':
|
|
144
|
+
options.dumpFiles = true;
|
|
145
|
+
break;
|
|
146
|
+
case 'v':
|
|
147
|
+
options.verbose++;
|
|
148
|
+
break;
|
|
149
|
+
default:
|
|
150
|
+
throw new Error(`unhandled option '${option}'`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
options.evaluatorOptions = process.argv.slice(parser.optind()); /* after --, pass to evaluator as-is */
|
|
155
|
+
|
|
156
|
+
const sandboxSetupDefs = require(options.sandboxDefinitions)[options.sandboxType];
|
|
111
157
|
if (!sandboxSetupDefs)
|
|
112
158
|
panic(`Invalid sandbox type: ${options.sandboxType}`);
|
|
113
159
|
|
|
114
|
-
if (options.rEvaluator)
|
|
115
|
-
evaluator = require.resolve(options.rEvaluator);
|
|
116
|
-
else
|
|
117
|
-
evaluator = path.resolve(options.evaluator);
|
|
118
|
-
|
|
119
160
|
let args = []; /* Command-line arguments to pass to evaluator */
|
|
120
161
|
let files = []; /* Startup files passed to evaluator as supplementary arguments */
|
|
121
162
|
|
|
@@ -123,7 +164,7 @@ function main() {
|
|
|
123
164
|
args = args.concat(['-p', options.port]);
|
|
124
165
|
|
|
125
166
|
/* Decode log-level parameters and translate as appropriate for the type of evaluator in use */
|
|
126
|
-
if (options.
|
|
167
|
+
if (options.logLevel || options.logLevel === 0)
|
|
127
168
|
{
|
|
128
169
|
switch(options.sandboxType)
|
|
129
170
|
{
|
|
@@ -143,22 +184,22 @@ function main() {
|
|
|
143
184
|
'notice': 5,
|
|
144
185
|
'info': 6,
|
|
145
186
|
'debug': 7,
|
|
146
|
-
}[options.
|
|
187
|
+
}[options.logLevel];
|
|
147
188
|
|
|
148
|
-
if (typeof level === 'undefined' && (!isNaN(Number(options.
|
|
189
|
+
if (typeof level === 'undefined' && (!isNaN(Number(options.logLevel))))
|
|
149
190
|
{
|
|
150
191
|
console.warn('Warning: numeric log levels are deprecated');
|
|
151
|
-
level = Number(options.
|
|
192
|
+
level = Number(options.logLevel);
|
|
152
193
|
}
|
|
153
194
|
|
|
154
195
|
if (typeof level === 'undefined')
|
|
155
|
-
panic(`unknown debug log level ${options.
|
|
196
|
+
panic(`unknown debug log level ${options.logLevell}`);
|
|
156
197
|
|
|
157
198
|
args = args.concat('-d', level);
|
|
158
199
|
break;
|
|
159
200
|
}
|
|
160
201
|
case 'node':
|
|
161
|
-
process.env.DCP_DEBUG_EVALUATOR = options.
|
|
202
|
+
process.env.DCP_DEBUG_EVALUATOR = options.logLevel;
|
|
162
203
|
break;
|
|
163
204
|
default:
|
|
164
205
|
panic(`debug log level not supported for ${options.sandboxType} evaluators`);
|
|
@@ -167,8 +208,8 @@ function main() {
|
|
|
167
208
|
}
|
|
168
209
|
|
|
169
210
|
/* Pass options after -- as evaluator-specific options */
|
|
170
|
-
if (options.
|
|
171
|
-
args = args.concat(options.
|
|
211
|
+
if (options.evaluatorOptions.length > 0)
|
|
212
|
+
args = args.concat(options.evaluatorOptions);
|
|
172
213
|
|
|
173
214
|
/* Definitions in the JSON file are either in the sandboxLibexecDir, or pathed
|
|
174
215
|
* via normal CommonJS (node_modules) rules. The syntax for detecting which must
|
|
@@ -183,15 +224,16 @@ function main() {
|
|
|
183
224
|
|
|
184
225
|
if (options.dump) {
|
|
185
226
|
if (options.json) {
|
|
186
|
-
console.log(JSON.stringify({evaluator, files, args, options}));
|
|
227
|
+
console.log(JSON.stringify({ evaluator: options.evaluator, files, args, options }));
|
|
187
228
|
} else {
|
|
188
|
-
console.log('Evaluator command:', [evaluator].concat(files).concat(args).join(' '));
|
|
229
|
+
console.log('Evaluator command:', [path.resolve(options.prefix, options.evaluator)].concat(files).concat(args).join(' '));
|
|
189
230
|
console.log('Options:', options);
|
|
190
231
|
}
|
|
191
232
|
process.exit(0);
|
|
192
233
|
}
|
|
193
234
|
|
|
194
|
-
if (options.dumpFiles)
|
|
235
|
+
if (options.dumpFiles)
|
|
236
|
+
{
|
|
195
237
|
let dump = files;
|
|
196
238
|
|
|
197
239
|
if (options.json)
|
|
@@ -200,15 +242,6 @@ function main() {
|
|
|
200
242
|
process.exit(0);
|
|
201
243
|
}
|
|
202
244
|
|
|
203
|
-
if (options.dumpTypes) {
|
|
204
|
-
let dump = Object.keys(require(options.sandboxDefinitions));
|
|
205
|
-
|
|
206
|
-
if (options.json)
|
|
207
|
-
dump = JSON.stringify(dump);
|
|
208
|
-
console.log(dump);
|
|
209
|
-
process.exit(0);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
245
|
if (!options.stdio && options.sandboxType === 'node') {
|
|
213
246
|
if (process.env.I_WANT_AN_INSECURE_DCP_WORKER !== 'badly') {
|
|
214
247
|
console.warn('***\x07 WARNING: Node evaluator is not suitable for production work - ^C to abort');
|
|
@@ -225,8 +258,8 @@ function main() {
|
|
|
225
258
|
|
|
226
259
|
if (!options.stdio) {
|
|
227
260
|
console.log('Starting DCP Evaluator -- ');
|
|
228
|
-
console.log('. Evaluator program at:\t\t',
|
|
229
|
-
console.log('. Listening on: \t\t',
|
|
261
|
+
console.log('. Evaluator program at:\t\t', options.evaluator);
|
|
262
|
+
console.log('. Listening on: \t\t', options.port);
|
|
230
263
|
console.log('. Worker environment type:\t', options.sandboxType);
|
|
231
264
|
console.log('. Worker environment: \t');
|
|
232
265
|
files.forEach(f => {
|
|
@@ -235,15 +268,12 @@ function main() {
|
|
|
235
268
|
console.log('');
|
|
236
269
|
}
|
|
237
270
|
|
|
238
|
-
if (options.pidFile)
|
|
239
|
-
require('../lib/pidfile').write(options.pidFile);
|
|
240
|
-
|
|
241
271
|
if (options.verbose) {
|
|
242
272
|
console.log('. cwd:', path.join(options.prefix));
|
|
243
|
-
console.log('. run:', [evaluator].concat(files).concat(args).map(a => `"${a}"`).join(' '));
|
|
273
|
+
console.log('. run:', [options.evaluator].concat(files).concat(args).map(a => `"${a}"`).join(' '));
|
|
244
274
|
}
|
|
245
275
|
|
|
246
|
-
const child = require('child_process').spawn(evaluator, files.concat(args), {
|
|
276
|
+
const child = require('child_process').spawn(options.evaluator, files.concat(args), {
|
|
247
277
|
cwd: path.join(options.prefix),
|
|
248
278
|
windowsHide: true,
|
|
249
279
|
stdio: ['inherit', 'inherit', 'inherit'],
|
package/bin/dcp-task-probe
CHANGED
|
@@ -102,7 +102,7 @@ Examples (bash syntax):
|
|
|
102
102
|
- # dcp-task-probe --merge 'minimumWage={"CPU":1,"GPU":3}' -c
|
|
103
103
|
Options:
|
|
104
104
|
-h | --help show this help and exit
|
|
105
|
-
-C | --
|
|
105
|
+
-C | --showConfig [dot.path] show derived worker configuration instead of requesting a task
|
|
106
106
|
-v | --version increase verbosity (show job info)
|
|
107
107
|
-H | --hostname= set evaluator hostname (for capability probing)
|
|
108
108
|
-p | --port= set evaluator port number (for capability probing)
|
|
@@ -272,13 +272,13 @@ function cpuCommaGpu(str)
|
|
|
272
272
|
/**
|
|
273
273
|
* Parse and process command-line options. Most options result in changes to the running dcpConfig;
|
|
274
274
|
* other options are reflected in the returned object:
|
|
275
|
-
* -
|
|
275
|
+
* - showConfig
|
|
276
276
|
* - workerId
|
|
277
277
|
*/
|
|
278
278
|
async function processOptions(workerConfig)
|
|
279
279
|
{
|
|
280
280
|
const opts = { verbose: 0 };
|
|
281
|
-
const parser = new getopt.BasicParser('h(help)C(
|
|
281
|
+
const parser = new getopt.BasicParser('h(help)C(showConfig)S:(set)M:(merge)a:(allowedOrigins)'
|
|
282
282
|
+ 'c:(cores)u:(utilization)m:(maxSandboxes)w:(workerId)'
|
|
283
283
|
+ 'j:(job)g:(computeGroup)G(leaveGlobalGroup)'
|
|
284
284
|
+ 'H:(hostname)p:(port)r(replay)l(load)i(input)o(output)'
|
|
@@ -302,8 +302,18 @@ async function processOptions(workerConfig)
|
|
|
302
302
|
break;
|
|
303
303
|
|
|
304
304
|
case 'C':
|
|
305
|
-
|
|
305
|
+
{
|
|
306
|
+
/* no direct support for optional arguments in posix-getopt; dig into internals */
|
|
307
|
+
const nextArg = parser.gop_argv[parser.gop_optind];
|
|
308
|
+
if (nextArg?.[0] === '-')
|
|
309
|
+
opts.showConfig === ''; /* defined but empty - match yargs behaviour */
|
|
310
|
+
else
|
|
311
|
+
{
|
|
312
|
+
opts.showConfig = nextArg;
|
|
313
|
+
parser.gop_optind++;
|
|
314
|
+
}
|
|
306
315
|
break;
|
|
316
|
+
}
|
|
307
317
|
|
|
308
318
|
case 'v':
|
|
309
319
|
opts.verbose += 1;
|
|
@@ -338,7 +348,7 @@ async function processOptions(workerConfig)
|
|
|
338
348
|
break;
|
|
339
349
|
|
|
340
350
|
case 'G':
|
|
341
|
-
workerConfig.
|
|
351
|
+
workerConfig.leaveGlobalGroup = true;
|
|
342
352
|
break;
|
|
343
353
|
|
|
344
354
|
case 'H':
|
|
@@ -462,7 +472,7 @@ function readWorkerSnapshot()
|
|
|
462
472
|
|
|
463
473
|
if (!readWorkerSnapshot.cache)
|
|
464
474
|
{
|
|
465
|
-
const serializer = dcpConfig.worker.requestSnapshot.endsWith('kvin') ? require('kvin').KVIN : JSON;
|
|
475
|
+
const serializer = dcpConfig.worker.requestSnapshot.endsWith('kvin') ? require('dcp/internal/kvin').KVIN : JSON;
|
|
466
476
|
debug('dcp-task-probe')('loading snapshot', detailedView(dcpConfig.worker.requestSnapshot));
|
|
467
477
|
readWorkerSnapshot.cache = serializer.parse(fs.readFileSync(dcpConfig.worker.requestSnapshot));
|
|
468
478
|
}
|
|
@@ -609,12 +619,11 @@ async function main()
|
|
|
609
619
|
await probeEvaluator(initialWorkerConfig);
|
|
610
620
|
const dummyWorker = new (require('dcp/worker').DistributiveWorker)(initialWorkerConfig, function FakeSandboxConstructor(){});
|
|
611
621
|
|
|
612
|
-
if (opts.
|
|
622
|
+
if (opts.hasOwnProperty('showConfig'))
|
|
613
623
|
{
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
process.exit(0);
|
|
624
|
+
const val = opts.showConfig ? eval(`dummyWorker.config.${opts.showConfig}`) : dummyWorker.config;
|
|
625
|
+
console.log(JSON.stringify(val, null, 2));
|
|
626
|
+
process.exit();
|
|
618
627
|
}
|
|
619
628
|
|
|
620
629
|
const { workerId, response, workerConfig } = await requestTask(dummyWorker, opts);
|