walnut.js/lib/spawn-caddy.js

160 lines
4.1 KiB
JavaScript
Raw Normal View History

2015-11-06 01:00:22 +00:00
'use strict';
2016-03-31 16:30:04 +00:00
function tplCaddyfile(caddyConf) {
var contents = [];
2016-03-31 16:30:04 +00:00
caddyConf.domains.forEach(function (hostname) {
var content = "";
2015-11-28 07:30:34 +00:00
var pagesname = hostname;
2015-11-19 22:13:20 +00:00
// TODO prefix
2016-03-31 16:30:04 +00:00
content += "https://" + hostname + " {\n"
+ " gzip\n"
+ " tls "
+ "/srv/walnut/certs/live/" + hostname + "/fullchain.pem "
+ "/srv/walnut/certs/live/" + hostname + "/privkey.pem\n"
;
2016-03-31 16:30:04 +00:00
if (caddyConf.locked) {
content += " root /srv/walnut/init.public/\n";
} else {
2016-03-31 16:30:04 +00:00
content += " root " + caddyConf.sitespath + "/" + pagesname + "/\n";
}
2015-11-28 07:30:34 +00:00
content +=
2016-03-31 16:30:04 +00:00
" proxy /api http://localhost:" + caddyConf.localPort.toString() + " {\n"
2015-11-14 04:25:12 +00:00
+ " proxy_header Host {host}\n"
+ " proxy_header X-Forwarded-Host {host}\n"
+ " proxy_header X-Forwarded-Proto {scheme}\n"
// # TODO internal
2015-11-14 04:25:12 +00:00
+ " }\n"
+ "}";
contents.push(content);
});
return contents.join('\n\n');
}
module.exports.tplCaddyfile = tplCaddyfile;
2016-03-31 16:30:04 +00:00
module.exports.create = function (caddyConf) {
2015-11-06 01:00:22 +00:00
var spawn = require('child_process').spawn;
2016-03-31 16:30:04 +00:00
var caddyBin = caddyConf.bin;
var caddyfilePath = caddyConf.conf;
2015-11-28 07:30:34 +00:00
// TODO put up a booting / lock screen on boot
// and wait for all to be grabbed from db
// NOTE caddy cannot yet support multiple roots
// (needed for example.com/appname instead of appname.example.com)
2015-11-06 01:00:22 +00:00
var caddy;
var fs = require('fs');
// TODO this should be expanded to include proxies a la proxydyn
2016-03-31 16:30:04 +00:00
function writeCaddyfile(caddyConf, cb) {
fs.readdir(caddyConf.sitespath, function (err, nodes) {
if (err) {
if (cb) {
cb(err);
2015-11-06 01:00:22 +00:00
return;
}
console.error('[writeCaddyFile] 0');
console.error(err.stack);
throw err;
}
2015-11-06 01:00:22 +00:00
2016-03-31 16:30:04 +00:00
caddyConf.domains = nodes.filter(function (node) {
return /\./.test(node) && !/(^\.)|([\/\:\\])/.test(node);
});
2015-11-06 01:00:22 +00:00
2016-03-31 16:30:04 +00:00
var contents = tplCaddyfile(caddyConf);
fs.writeFile(caddyfilePath, contents, 'utf8', function (err) {
if (err) {
if (cb) {
cb(err);
2015-11-06 01:00:22 +00:00
return;
}
console.error('[writeCaddyFile] 1');
console.error(err.stack);
throw err;
}
2015-11-06 01:00:22 +00:00
if (cb) { cb(null); }
2015-11-06 01:00:22 +00:00
});
});
}
2016-03-31 16:30:04 +00:00
function spawnCaddy(caddyConf, cb) {
2015-11-06 01:00:22 +00:00
console.log('[CADDY] start');
2016-03-31 16:30:04 +00:00
writeCaddyfile(caddyfilePath, function (err) {
if (err) {
console.error('[writeCaddyfile]');
console.error(err.stack);
throw err;
}
2015-11-06 01:00:22 +00:00
if (caddy) {
caddy.kill('SIGUSR1');
return caddy;
2015-11-06 01:00:22 +00:00
// TODO caddy.kill('SIGKILL'); if SIGTERM fails
// https://github.com/mholt/caddy/issues/107
// SIGUSR1
//caddy.kill('SIGTERM');
}
try {
require('child_process').execSync('killall caddy');
} catch(e) {
// ignore
// Command failed: killall caddy
// caddy: no process found
}
2016-03-31 16:30:04 +00:00
caddy = spawn(caddyBin, ['-conf', caddyfilePath], { stdio: ['ignore', 'pipe', 'pipe'] });
2015-11-06 01:00:22 +00:00
caddy.stdout.on('data', function (str) {
console.error('[Caddy]', str.toString('utf8'));
});
caddy.stderr.on('data', function (errstr) {
console.error('[Caddy]', errstr.toString('utf8'));
});
caddy.on('close', function (code, signal) {
// TODO catch if caddy doesn't exist
console.log('[Caddy]');
console.log(code, signal);
caddy = null;
setTimeout(function () {
2016-03-31 16:30:04 +00:00
spawnCaddy(caddyConf);
2015-11-06 01:00:22 +00:00
}, 1 * 1000);
});
try {
if ('function' === typeof cb) { cb(null, caddy); }
} catch(e) {
console.error('ERROR: [spawn-caddy.js]');
console.error(e.stack);
}
2015-11-06 01:00:22 +00:00
});
}
function sighup() {
if (caddy) {
caddy.kill('SIGUSR1');
return;
}
// sudo kill -s SIGUSR1 `cat caddy.pid`
fs.readFileAsync('/srv/walnut/caddy.pid', 'utf8').then(function (pid) {
console.log('[caddy] pid', pid);
caddy = spawn('/bin/kill', ['-s', 'SIGUSR1', pid]);
});
}
return {
spawn: spawnCaddy
2016-03-31 16:30:04 +00:00
, update: function (caddyConf) {
return writeCaddyfile(caddyConf, sighup);
2015-11-06 01:00:22 +00:00
}
, sighup: sighup
};
};