| 
									
										
										
										
											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 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; |