Skip to content
Browse files

some more magic

  • Loading branch information...
1 parent 36799e0 commit ca93834475c6707cd4b955712b1dfbb9603599ab @postwait postwait committed Aug 26, 2011
Showing with 115 additions and 7 deletions.
  1. +16 −0 README
  2. +77 −4 nad
  3. +14 −2 nad.8
  4. +7 −0 plugins/smartos/.index.json
  5. +1 −1 smf/nad.xml
View
16 README
@@ -0,0 +1,16 @@
+For running nad, man nad.
+
+These are the poor man's docs.
+
+nad will run scripts from the config directory; only from that
+and not subdirectories. The best practice it to write your scripts
+in subdirectories of the config dir and soft link to them to enable
+their execution.
+
+Some scripts distributed with nad need to be compiled (yes, they aren't
+actually scripts, they are elf executables). Since not all programs
+can be compiled on all platforms, you need to go build them as needed.
+There are makefiles, pick and choose.
+
+If you write a set of scripts/programs, you can describe them in a
+.index.json file and they will be reported on when you run nad -i.
View
81 nad
@@ -14,20 +14,22 @@ var fs = require('fs'),
http = require('http'),
url = require('url'),
spawn = require('child_process').spawn,
+ procre = /^(?!\.)([^\/]*?)(?:\..*)$/,
past_results = {},
scripts = {},
scripts_once = {},
creds = {},
- generation = 0;
+ generation = 0, do_index = false;
var configdir = '/etc/node-agent.d',
- port = 0,
+ port = 2609,
sslport = 0,
verify = false;
function help(err) {
console.log(process.argv[1] + "\n" +
"\t-h\t\tthis help message\n" +
+ "\t-i\t\toffline inventory\n" +
"\t-c <configdir>\tconfig dir\n" +
"\t-p <port>\tunsecured port\n" +
"\t-s <secureport>\tsecured port\n" +
@@ -38,17 +40,88 @@ function help(err) {
}
}
+function index(dir) {
+ try { process.chdir(dir); }
+ catch (e) {
+ console.log("Cannot use configdir: " + configdir);
+ console.log(e.message);
+ process.exit(-1);
+ }
+ var catalog = {}, active = {}, missing = {};
+
+ function build_catalog(dir) {
+ dir = dir || "";
+ try {
+ var c = fs.readFileSync("./" + dir + "/.index.json");
+ var j = JSON.parse(c);
+ catalog[dir] = j;
+ for(var script in j) {
+ try {
+ var info = fs.statSync("./" + dir + "/" + script);
+ if(!info.isFile() || !(info.mode & 0100)) throw Exception("");
+ } catch(e) { missing[dir + "/" + script] = true; }
+ }
+ } catch(e) { }
+ var files = fs.readdirSync("./" + dir);
+ for(var i=0; i<files.length; i++) {
+ var info = fs.statSync("./" + dir + "/" + files[i]);
+ if(info && info.isDirectory())
+ build_catalog(dir + (dir ? "/" : "") + files[i]);
+ }
+ }
+ build_catalog();
+ var files = fs.readdirSync(".");
+ var base = fs.realpathSync(".") + "/";
+ for(var i=0; i<files.length; i++) {
+ var m = procre.exec(files[i]);
+ if(!m) continue;
+ var info = fs.lstatSync(files[i]);
+ var realpath = files[i];
+ if(info.isSymbolicLink()) info = fs.statSync(files[i]);
+ if(info.isFile() && (info.mode & 0100)) {
+ var realpath = fs.realpathSync(files[i]);
+ if(realpath.indexOf(base) == 0)
+ realpath = realpath.substr(base.length);
+ active[realpath] = m[1];
+ }
+ }
+ for(var module in catalog) {
+ for(var script in catalog[module]) {
+ var m = procre.exec(script);
+ if(!m) console.log("! " + script + ": MALFORMED NAME");
+ else {
+ var file = module + "/" + script;
+ var desc = catalog[module][script];
+ var on = (file in active) ? "*" : " ";
+ if(file in missing) on = "!";
+ delete active[file];
+ console.log(on + " " +
+ module + "/" + m[1] + ": " + desc);
+ }
+ }
+ }
+ var first = true;
+ for(var file in active) {
+ if(first) { console.log("\n !!! Rogue scripts !!!"); first = false; }
+ console.log("* " + file + ": ???");
+ }
+}
+
for(var i=2; i<process.argv.length; i++) {
switch(process.argv[i]) {
case "-h": help(); process.exit(-1);
case "-c": configdir = process.argv[++i]; break;
+ case "-i": do_index = true; break;
case "-p": port = parseInt(process.argv[++i]); break;
case "-s": sslport = parseInt(process.argv[++i]); break;
case "-v": verify = true; break;
default: help("unknown argument: " + process.argv[i]);
}
}
-
+if(do_index) {
+ index(configdir);
+ process.exit(0);
+}
if(!port && !sslport) help("must specify at least one of -p and -s");
if(sslport) {
try {
@@ -93,7 +166,7 @@ function rescan_modules() {
generation++;
fs.readdir(configdir, function(err, files) {
for(var i = 0; i < files.length; i++) {
- var m = /^(?!\.)([^\/]*?)(?:\..*)$/.exec(files[i]);
+ var m = procre.exec(files[i]);
if(!m) continue;
var filename = configdir + "/" + files[i];
fs.unwatchFile(filename);
View
16 nad.8
@@ -3,7 +3,7 @@
nad \- node\-agent daemon
.SH SYNOPSIS
.B nad
-[\-h] [\-c configdir] [\-p port] [\-s sslport] [\-v]
+[\-h] [\-i] [\-c configdir] [\-p port] [\-s sslport] [\-v]
.SH DESCRIPTION
The node\-agent daemon provides a simple mechanism to expose
systems and application metrics to external onlookers. It
@@ -12,6 +12,15 @@ inventories all executable programs in
and executes them upon external request (via http or https)
and returns the results in JSON format.
.PP
+It is recommended that executable checks be stored in subdirectories
+of the
+.I configdir.
+Because those subdirectories are not scanned, those
+scripts will not be executed with an additional step. Those scripts
+that the administrator wishes activated can be soft linked directly
+within
+.I configdir.
+.PP
No arguments are accepted from the onlooker and thus no special
precautions must be taken handling/validating/sanitizing arguments.
.PP
@@ -31,11 +40,14 @@ returns the current active inventory of scripts.
\-h
Display the help text.
.TP
+\-i
+Display an inventory of plugins.
+.TP
\-c <configdir>
Sets the configuration directory (home of scripts and SSL credentials).
.TP
\-p <port>
-Sets the port on which the HTTP server shall listen.
+Sets the port on which the HTTP server shall listen. (default 2609).
.TP
\-s <sslport>
Sets the port on which the HTTPS server shall listen. If this option is
View
7 plugins/smartos/.index.json
@@ -0,0 +1,7 @@
+{
+ "aggcpu.elf": "aggregated statistics across all CPUs",
+ "cpu.sh": "statistics for each CPU",
+ "sdinfo.sh": "statistics for all disk devices on 'sd'",
+ "vminfo.sh": "statistics related to the virtual memory subsystem",
+ "zfsinfo.sh": "statistics for ZFS"
+}
View
2 smf/nad.xml
@@ -19,7 +19,7 @@
<envvar name='PATH' value='/usr/xpg4/bin:/usr/bin:/usr/sbin:/sbin:/usr/sfw/bin:/usr/local/bin:/opt/omni/bin'/>
</method_environment>
</method_context>
- <exec_method name='start' type='method' exec='/opt/omni/sbin/nad -c /opt/omni/etc/node-agent.d -p 8081' timeout_seconds='60'>
+ <exec_method name='start' type='method' exec='/opt/omni/sbin/nad -c /opt/omni/etc/node-agent.d' timeout_seconds='60'>
<method_context>
<method_credential user='nobody' group='other'/>
</method_context>

0 comments on commit ca93834

Please sign in to comment.
Something went wrong with that request. Please try again.