@pixlcore/xyrun 1.0.1 → 1.0.3

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.
Files changed (3) hide show
  1. package/README.md +7 -1
  2. package/main.js +39 -17
  3. 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 procesess, network connections, CPU and memory usage of remote jobs, and passing those metrics back to xyOps.
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
@@ -16,6 +16,8 @@ const pkg = require('./package.json');
16
16
  const noop = function() {};
17
17
  const async = Tools.async;
18
18
 
19
+ process.title = "xyRun";
20
+
19
21
  const app = {
20
22
 
21
23
  activeJobs: {},
@@ -129,8 +131,26 @@ const app = {
129
131
  var child = null;
130
132
  var worker = {};
131
133
 
134
+ // setup environment for child
132
135
  var child_args = process.argv.slice(2);
133
136
  var child_cmd = child_args.shift();
137
+ var child_opts = {
138
+ env: Object.assign( {}, process.env )
139
+ };
140
+
141
+ if (!child_cmd && job.params && job.params.script) {
142
+ // no direct command specified, but user wants a "script" executed from the job params
143
+ var script_file = Path.join( job.cwd, 'xyops-script-temp-' + job.id + '.sh' );
144
+ child_cmd = Path.resolve(script_file);
145
+ child_args = [];
146
+
147
+ // quickly write out script file and make it executable
148
+ Tools.mkdirpSync( job.cwd, { mode: 0o777 } );
149
+ fs.writeFileSync( script_file, job.params.script.replace(/\r\n/g, "\n"), { mode: 0o775 } );
150
+
151
+ // set the cwd to the job cwd, as it's a more controlled environment
152
+ child_opts.cwd = job.cwd;
153
+ }
134
154
 
135
155
  if (!child_cmd) {
136
156
  // no command!
@@ -155,11 +175,6 @@ const app = {
155
175
 
156
176
  console.log( "Running command: " + child_cmd, child_args );
157
177
 
158
- // setup environment for child
159
- var child_opts = {
160
- env: Object.assign( {}, process.env )
161
- };
162
-
163
178
  // get uid / gid info for child env vars
164
179
  if (!this.platform.windows) {
165
180
  child_opts.uid = job.uid || process.getuid();
@@ -335,7 +350,7 @@ const app = {
335
350
  if (job.kill === 'none') {
336
351
  // kill none, just unref and finish
337
352
  worker.child.unref();
338
- this.shutdown();
353
+ this.finishJob();
339
354
  return;
340
355
  }
341
356
 
@@ -436,9 +451,6 @@ const app = {
436
451
 
437
452
  if (!file.path) return; // sanity
438
453
 
439
- // prepend job cwd if path is not absolute
440
- if (!Path.isAbsolute(file.path)) file.path = Path.join(job.cwd, file.path);
441
-
442
454
  if (file.filename) {
443
455
  // if user specified a custom filename, then do not perform a glob
444
456
  to_upload.push(file);
@@ -463,9 +475,18 @@ const app = {
463
475
  // upload all job files (from user) if applicable
464
476
  var self = this;
465
477
  var final_files = [];
466
- var server_id = job.server;
478
+
467
479
  if (!job.files || !job.files.length || !Tools.isaArray(job.files)) return callback();
468
480
 
481
+ if (!job.base_url) {
482
+ console.error("Error: Cannot upload files: Missing 'base_url' property in job data.");
483
+ return callback();
484
+ }
485
+ if (!job.auth_token) {
486
+ console.error("Error: Cannot upload files: Missing 'auth_token' property in job data.");
487
+ return callback();
488
+ }
489
+
469
490
  async.eachSeries( job.files,
470
491
  function(file, callback) {
471
492
  var filename = Path.basename(file.filename || file.path).replace(/[^\w\-\+\.\,\s\(\)\[\]\{\}\'\"\!\&\^\%\$\#\@\*\?\~]+/g, '_');
@@ -503,7 +524,7 @@ const app = {
503
524
  filename: filename,
504
525
  path: json.key,
505
526
  size: json.size,
506
- server: server_id,
527
+ server: job.server,
507
528
  job: job.id
508
529
  });
509
530
 
@@ -567,8 +588,8 @@ const app = {
567
588
  return;
568
589
  }
569
590
 
570
- // update job data
571
- console.log( JSON.stringify({ xy: 1, procs: job.procs, conns: job.conns, cpu: job.cpu, mem: job.mem }) );
591
+ // update job data with stats in tow
592
+ console.log( JSON.stringify({ xy: 1, rpid: process.pid, procs: job.procs, conns: job.conns, cpu: job.cpu, mem: job.mem }) );
572
593
 
573
594
  self.jobTickInProgress = false;
574
595
  }
@@ -579,20 +600,21 @@ const app = {
579
600
  measureJobResources(job, pids) {
580
601
  // scan process list for all processes that are descendents of job pid
581
602
  delete job.procs;
603
+ var root_pid = process.pid;
582
604
 
583
- if (pids[ job.pid ]) {
605
+ if (pids[ root_pid ]) {
584
606
  // add all procs into job
585
607
  job.procs = {};
586
- job.procs[ job.pid ] = pids[ job.pid ];
608
+ job.procs[ root_pid ] = pids[ root_pid ];
587
609
 
588
- var info = pids[ job.pid ];
610
+ var info = pids[ root_pid ];
589
611
  var cpu = info.cpu;
590
612
  var mem = info.memRss;
591
613
 
592
614
  // also consider children of the child (up to 100 generations deep)
593
615
  var levels = 0;
594
616
  var family = {};
595
- family[ job.pid ] = 1;
617
+ family[ root_pid ] = 1;
596
618
 
597
619
  while (Tools.numKeys(family) && (++levels <= 100)) {
598
620
  for (var fpid in family) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixlcore/xyrun",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Remote job runner script for xyOps.",
5
5
  "author": "Joseph Huckaby <jhuckaby@pixlcore.com>",
6
6
  "homepage": "https://github.com/pixlcore/xyrun",