1 | #!/usr/bin/env node
|
2 |
|
3 | var fs = require('fs')
|
4 | , exec = require('child_process').exec
|
5 | , cwd = process.cwd()
|
6 | , path = require('path')
|
7 | , kernel = require('../kernel/kernel.js')
|
8 | , usage =
|
9 |
|
10 | '\n' +
|
11 | 'Usage\t: lemonade [options] config-file.js\n' +
|
12 | 'Options\t: \n' +
|
13 | ' --help,-h' + '\t\tthis message\n' +
|
14 | ' --version,-v' + '\t\tlemonade version\n' +
|
15 | ' --watch-changes,-w' + '\twatch for changes in the app dir;\n' +
|
16 | '\t\t\tgracefully restart when a file changes\n' +
|
17 | ' --rotate-logs,-r' + '\trotate logs at given interval (default 1day)\n' +
|
18 | ' --debug,-d' + '\t\tdebug mode, extra output in all logfiles\n' +
|
19 | ' --quiet,-q' + '\t\tminimum output (disables daemon logs)\n';
|
20 |
|
21 |
|
22 | if (process.argv[2] === 'install') {
|
23 | exec(
|
24 | 'cp -rv ' + __dirname + '/../app/* ' + cwd,
|
25 | function (error, stdout, stderr) {
|
26 | if (!error) {
|
27 | console.log('Install completed');
|
28 | } else {
|
29 | console.log(error, stderr);
|
30 | }
|
31 | }
|
32 | );
|
33 | } else {
|
34 | |
35 |
|
36 |
|
37 | for (var key in process.argv) {
|
38 | var eqpos = process.argv[key].indexOf('=');
|
39 | if (eqpos !== -1) {
|
40 | var option = process.argv[key].substring(0, eqpos)
|
41 | , value = process.argv[key].substring(eqpos + 1);
|
42 | } else {
|
43 | var option = process.argv[key]
|
44 | , value = null;
|
45 | }
|
46 | switch (option) {
|
47 | case '--help' :
|
48 | case '-h' :
|
49 | console.log(usage);
|
50 | process.exit(0);
|
51 | break;
|
52 | case '--version' :
|
53 | case '-v' :
|
54 | console.log(kernel.prototype.version);
|
55 | process.exit(0);
|
56 | break;
|
57 | case '--watch-changes' :
|
58 | case '-w' :
|
59 | var watch = true;
|
60 | break;
|
61 | case '--rotate-logs' :
|
62 | case '-r' :
|
63 | var rotatelogs = true
|
64 | , rotatehour = value || 3
|
65 | break;
|
66 | case '--debug' :
|
67 | case '-d' :
|
68 | if (typeof loglevel !== 'undefined') {
|
69 | console.log('Cannot use -q and -d together');
|
70 | process.exit(1);
|
71 | }
|
72 | var loglevel = kernel.prototype.LOGLEVEL_DEBUG;
|
73 | break;
|
74 | case '--quiet' :
|
75 | case '-q' :
|
76 | if (typeof loglevel !== 'undefined') {
|
77 | console.log('Cannot use -q and -d together');
|
78 | process.exit(1);
|
79 | }
|
80 | var loglevel = kernel.prototype.LOGLEVEL_QUIET;
|
81 | break;
|
82 | }
|
83 | }
|
84 | if (typeof loglevel === 'undefined') {
|
85 | var loglevel = kernel.prototype.LOGLEVEL_NORMAL;
|
86 | }
|
87 | var configfile = process.argv.pop();
|
88 | |
89 |
|
90 |
|
91 | if (fs.existsSync(cwd + '/' + configfile)) {
|
92 | var config = require(cwd + '/' + configfile)
|
93 | appdir = path.dirname(configfile);
|
94 | process.chdir(appdir);
|
95 | } else {
|
96 | console.log('Missing or invalid configuration file');
|
97 | console.log(usage);
|
98 | process.exit(1);
|
99 | }
|
100 | |
101 |
|
102 |
|
103 | var start = function() {
|
104 | return new kernel(
|
105 | config.config
|
106 | ,config.boot
|
107 | ,config.run
|
108 | ,config.shutdown
|
109 | ,loglevel
|
110 | );
|
111 | }, krnlobj = start();
|
112 | |
113 |
|
114 |
|
115 |
|
116 | if (typeof watch !== 'undefined' && watch) {
|
117 | var md5sum, listen,
|
118 | watchintv = setInterval(function() {
|
119 | if (!listen) {
|
120 | listen = true;
|
121 | krnlobj.on(kernel.prototype.OFFLINE, function() {
|
122 | krnlobj = start();
|
123 | listen = false;
|
124 | });
|
125 | }
|
126 | exec('ls -alR . | md5sum | sed s/[^a-zA-Z0-9]//g', function(err, stdout, stderr) {
|
127 | if (!err) {
|
128 | if (md5sum && md5sum !== stdout) {
|
129 | krnlobj.shutdown('appdir changed, rebooting');
|
130 | }
|
131 | md5sum = stdout;
|
132 | } else {
|
133 | console.log(err, stderr);
|
134 | }
|
135 | });
|
136 | }, 1000);
|
137 | krnlobj.log('watching changes in appdir - ' + krnlobj.utility.ansi('green', 'ok'));
|
138 | }
|
139 | |
140 |
|
141 |
|
142 |
|
143 | if (typeof rotatelogs !== 'undefined' && rotatelogs && rotatehour) {
|
144 | var rotateintv = setInterval(function() {
|
145 | var now = new Date();
|
146 | if (now.getHours() === rotatehour && krnlobj.config && now.getTime() - lastrun.getTime() > onehour) {
|
147 | lastrun = new Date();
|
148 | if (!fs.existsSync(krnlobj.config.logpath + '/archive')) {
|
149 | fs.mkdirSync(krnlobj.config.logpath + '/archive');
|
150 | krnlobj.log('creating archive logdir - ' + krnlobj.utility.ansi('green', 'ok'));
|
151 | }
|
152 | exec(
|
153 | 'cd ' + krnlobj.config.logpath + ' && ' +
|
154 | 'find *.log -print0 | xargs -0 -I {} mv {} ./archive/ && ' +
|
155 | 'cd ./archive && tar -czf "$(date --date=\'yesterday\' \'+%Y-%m-%d\').tgz" *.log && ' +
|
156 | 'rm *.log'
|
157 | , function (err, stdout, stderr) {
|
158 | if (err) {
|
159 | krnlobj.error(
|
160 | new Error(err.message || err + ';' + stderr)
|
161 | );
|
162 | } else {
|
163 | krnlobj.log('rotating logs - ' + krnlobj.utility.ansi('green', 'ok'));
|
164 | }
|
165 | }
|
166 | );
|
167 | }
|
168 | }, 60000), lastrun = new Date(), onehour = 1000 * 60 * 60;
|
169 | krnlobj.log('looking for logs to rotate (@' + rotatehour + ':00)- ' + krnlobj.utility.ansi('green', 'ok'));
|
170 | }
|
171 | |
172 |
|
173 |
|
174 | var shutdown = function() {
|
175 | krnlobj.removeAllListeners(kernel.prototype.OFFLINE);
|
176 | krnlobj.shutdown('got term signal, going down');
|
177 | if (watchintv) {
|
178 | clearInterval(watchintv);
|
179 | }
|
180 | if (rotateintv) {
|
181 | clearInterval(rotateintv);
|
182 | }
|
183 | };
|
184 | process.once('SIGTERM', shutdown);
|
185 | process.once('SIGINT', shutdown);
|
186 | } |
\ | No newline at end of file |