@pixlcore/xyrun 1.0.2 → 1.0.4
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/README.md +7 -1
- package/main.js +42 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ To use xyRun in a xyOps Event Plugin, make sure you set the Plugin's `runner` pr
|
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- Handles monitoring
|
|
11
|
+
- Handles monitoring processes, network connections, CPU and memory usage of remote jobs, and passing those metrics back to xyOps.
|
|
12
12
|
- Handles input files by creating a temporary directory for you job and pre-downloading all files from the xyOps master server.
|
|
13
13
|
- Handles output files by intercepting the `files` message and uploading them directly to the xyOps master server.
|
|
14
14
|
|
|
@@ -53,6 +53,12 @@ Then wrap your remote command with a `xyrun` prefix:
|
|
|
53
53
|
ssh user@target xyrun node /path/to/your-script.js
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
# Script Mode
|
|
57
|
+
|
|
58
|
+
When no sub-command is specified on the CLI, xyRun will look inside the job JSON data (passed in via STDIN) for a parameter named `script`. If this is found, it is quickly written out to a temp file, made executable (775), and that is what it launches. It is assumed that the provided `script` will contain a proper [Shebang](https://en.wikipedia.org/wiki/Shebang_%28Unix%29) line.
|
|
59
|
+
|
|
60
|
+
This allows xyRun to act as a "Remote Shell Plugin" for certain xyOps jobs that require it.
|
|
61
|
+
|
|
56
62
|
# Development
|
|
57
63
|
|
|
58
64
|
You can install the source code by using [Git](https://en.wikipedia.org/wiki/Git) ([Node.js](https://nodejs.org/) is also required):
|
package/main.js
CHANGED
|
@@ -131,8 +131,30 @@ const app = {
|
|
|
131
131
|
var child = null;
|
|
132
132
|
var worker = {};
|
|
133
133
|
|
|
134
|
+
// setup environment for child
|
|
134
135
|
var child_args = process.argv.slice(2);
|
|
135
136
|
var child_cmd = child_args.shift();
|
|
137
|
+
var child_opts = {
|
|
138
|
+
env: Object.assign( {}, process.env, job.secrets || {} )
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
child_opts.env['XYOPS'] = 'runner-' + pkg.version;
|
|
142
|
+
child_opts.env['JOB_ID'] = job.id;
|
|
143
|
+
child_opts.env['JOB_NOW'] = job.now;
|
|
144
|
+
|
|
145
|
+
if (!child_cmd && job.params && job.params.script) {
|
|
146
|
+
// no direct command specified, but user wants a "script" executed from the job params
|
|
147
|
+
var script_file = Path.join( job.cwd, 'xyops-script-temp-' + job.id + '.sh' );
|
|
148
|
+
child_cmd = Path.resolve(script_file);
|
|
149
|
+
child_args = [];
|
|
150
|
+
|
|
151
|
+
// quickly write out script file and make it executable
|
|
152
|
+
Tools.mkdirpSync( job.cwd, { mode: 0o777 } );
|
|
153
|
+
fs.writeFileSync( script_file, job.params.script.replace(/\r\n/g, "\n"), { mode: 0o775 } );
|
|
154
|
+
|
|
155
|
+
// set the cwd to the job cwd, as it's a more controlled environment
|
|
156
|
+
child_opts.cwd = job.cwd;
|
|
157
|
+
}
|
|
136
158
|
|
|
137
159
|
if (!child_cmd) {
|
|
138
160
|
// no command!
|
|
@@ -157,11 +179,6 @@ const app = {
|
|
|
157
179
|
|
|
158
180
|
console.log( "Running command: " + child_cmd, child_args );
|
|
159
181
|
|
|
160
|
-
// setup environment for child
|
|
161
|
-
var child_opts = {
|
|
162
|
-
env: Object.assign( {}, process.env )
|
|
163
|
-
};
|
|
164
|
-
|
|
165
182
|
// get uid / gid info for child env vars
|
|
166
183
|
if (!this.platform.windows) {
|
|
167
184
|
child_opts.uid = job.uid || process.getuid();
|
|
@@ -207,6 +224,16 @@ const app = {
|
|
|
207
224
|
child_opts.gid = parseInt( child_opts.gid );
|
|
208
225
|
}
|
|
209
226
|
|
|
227
|
+
// add plugin params as env vars, expand $INLINE vars
|
|
228
|
+
if (job.params) {
|
|
229
|
+
for (var key in job.params) {
|
|
230
|
+
child_opts.env[ key.replace(/\W+/g, '_') ] =
|
|
231
|
+
(''+job.params[key]).replace(/\$(\w+)/g, function(m_all, m_g1) {
|
|
232
|
+
return (m_g1 in child_opts.env) ? child_opts.env[m_g1] : '';
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
210
237
|
// windows additions
|
|
211
238
|
if (this.platform.windows) {
|
|
212
239
|
child_opts.windowsHide = true;
|
|
@@ -337,7 +364,7 @@ const app = {
|
|
|
337
364
|
if (job.kill === 'none') {
|
|
338
365
|
// kill none, just unref and finish
|
|
339
366
|
worker.child.unref();
|
|
340
|
-
this.
|
|
367
|
+
this.finishJob();
|
|
341
368
|
return;
|
|
342
369
|
}
|
|
343
370
|
|
|
@@ -465,6 +492,15 @@ const app = {
|
|
|
465
492
|
|
|
466
493
|
if (!job.files || !job.files.length || !Tools.isaArray(job.files)) return callback();
|
|
467
494
|
|
|
495
|
+
if (!job.base_url) {
|
|
496
|
+
console.error("Error: Cannot upload files: Missing 'base_url' property in job data.");
|
|
497
|
+
return callback();
|
|
498
|
+
}
|
|
499
|
+
if (!job.auth_token) {
|
|
500
|
+
console.error("Error: Cannot upload files: Missing 'auth_token' property in job data.");
|
|
501
|
+
return callback();
|
|
502
|
+
}
|
|
503
|
+
|
|
468
504
|
async.eachSeries( job.files,
|
|
469
505
|
function(file, callback) {
|
|
470
506
|
var filename = Path.basename(file.filename || file.path).replace(/[^\w\-\+\.\,\s\(\)\[\]\{\}\'\"\!\&\^\%\$\#\@\*\?\~]+/g, '_');
|