2015-11-06 01:00:22 +00:00
|
|
|
'use strict';
|
|
|
|
|
2015-11-06 11:05:32 +00:00
|
|
|
function tplCaddyfile(conf) {
|
|
|
|
var contents = [];
|
|
|
|
|
|
|
|
conf.domains.forEach(function (hostname) {
|
|
|
|
var content = "";
|
|
|
|
|
2015-11-19 22:13:20 +00:00
|
|
|
// TODO prefix
|
2015-11-06 11:05:32 +00:00
|
|
|
content+= "https://" + hostname + " {\n"
|
|
|
|
+ " gzip\n"
|
|
|
|
+ " tls "
|
|
|
|
+ "/srv/walnut/certs/live/" + hostname + "/fullchain.pem "
|
|
|
|
+ "/srv/walnut/certs/live/" + hostname + "/privkey.pem\n"
|
|
|
|
;
|
|
|
|
|
|
|
|
if (conf.locked) {
|
|
|
|
content += " root /srv/walnut/init.public/\n";
|
|
|
|
} else {
|
|
|
|
content += " root /srv/walnut/sites-enabled/" + hostname + "/\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
content +=
|
2015-11-14 04:25:12 +00:00
|
|
|
" proxy /api http://localhost:" + conf.localPort.toString() + " {\n"
|
|
|
|
+ " proxy_header Host {host}\n"
|
|
|
|
+ " proxy_header X-Forwarded-Host {host}\n"
|
|
|
|
+ " proxy_header X-Forwarded-Proto {scheme}\n"
|
2015-11-06 11:05:32 +00:00
|
|
|
// # TODO internal
|
2015-11-14 04:25:12 +00:00
|
|
|
+ " }\n"
|
2015-11-06 11:05:32 +00:00
|
|
|
+ "}";
|
|
|
|
|
|
|
|
contents.push(content);
|
|
|
|
});
|
|
|
|
|
|
|
|
return contents.join('\n\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports.tplCaddyfile = tplCaddyfile;
|
|
|
|
module.exports.create = function (config) {
|
2015-11-06 01:00:22 +00:00
|
|
|
var spawn = require('child_process').spawn;
|
2015-11-06 11:05:32 +00:00
|
|
|
var caddypath = config.caddypath;
|
|
|
|
var caddyfilepath = config.caddyfilepath;
|
|
|
|
var sitespath = config.sitespath;
|
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
|
2015-11-06 11:05:32 +00:00
|
|
|
function writeCaddyfile(conf, cb) {
|
|
|
|
fs.readdir(sitespath, function (err, nodes) {
|
|
|
|
if (err) {
|
|
|
|
if (cb) {
|
|
|
|
cb(err);
|
2015-11-06 01:00:22 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-11-06 11:05:32 +00:00
|
|
|
console.error('[writeCaddyFile] 0');
|
|
|
|
console.error(err.stack);
|
|
|
|
throw err;
|
|
|
|
}
|
2015-11-06 01:00:22 +00:00
|
|
|
|
2015-11-06 11:05:32 +00:00
|
|
|
conf.domains = nodes.filter(function (node) {
|
|
|
|
return /\./.test(node) && !/(^\.)|([\/\:\\])/.test(node);
|
|
|
|
});
|
2015-11-06 01:00:22 +00:00
|
|
|
|
2015-11-06 11:05:32 +00:00
|
|
|
var contents = tplCaddyfile(conf);
|
|
|
|
fs.writeFile(caddyfilepath, contents, 'utf8', function (err) {
|
|
|
|
if (err) {
|
|
|
|
if (cb) {
|
|
|
|
cb(err);
|
2015-11-06 01:00:22 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-11-06 11:05:32 +00:00
|
|
|
console.error('[writeCaddyFile] 1');
|
|
|
|
console.error(err.stack);
|
|
|
|
throw err;
|
|
|
|
}
|
2015-11-06 01:00:22 +00:00
|
|
|
|
2015-11-06 11:05:32 +00:00
|
|
|
if (cb) { cb(null); }
|
2015-11-06 01:00:22 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-11-06 11:05:32 +00:00
|
|
|
function spawnCaddy(conf, cb) {
|
2015-11-06 01:00:22 +00:00
|
|
|
console.log('[CADDY] start');
|
2015-11-06 11:05:32 +00:00
|
|
|
writeCaddyfile(conf, 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');
|
2015-11-06 11:05:32 +00:00
|
|
|
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');
|
|
|
|
}
|
|
|
|
|
2015-11-06 11:05:32 +00:00
|
|
|
try {
|
|
|
|
require('child_process').execSync('killall caddy');
|
|
|
|
} catch(e) {
|
|
|
|
// ignore
|
|
|
|
// Command failed: killall caddy
|
|
|
|
// caddy: no process found
|
|
|
|
}
|
2015-11-06 01:00:22 +00:00
|
|
|
caddy = spawn(caddypath, ['-conf', caddyfilepath], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
|
|
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 () {
|
|
|
|
spawnCaddy(conf);
|
|
|
|
}, 1 * 1000);
|
|
|
|
});
|
|
|
|
|
2015-11-06 11:05:32 +00:00
|
|
|
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
|
|
|
|
, update: function (conf) {
|
2015-11-06 11:05:32 +00:00
|
|
|
return writeCaddyfile(conf, sighup);
|
2015-11-06 01:00:22 +00:00
|
|
|
}
|
|
|
|
, sighup: sighup
|
|
|
|
};
|
|
|
|
};
|