-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathporter.coffee
More file actions
134 lines (118 loc) · 3.71 KB
/
porter.coffee
File metadata and controls
134 lines (118 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
upnode = require 'upnode'
portfinder = require 'portfinder'
net = require 'net'
http = require 'http'
path = require 'path'
fs = require 'fs'
spawn = require('child_process').spawn
router = require './lib/router'
PORT = 7004
SECRET = process.env.PORTER_PASS ? 'o87asdoa87sa'
PIDPATH = path.resolve __dirname, '..', '..', 'pids'
router.setPIDPATH PIDPATH
try
fs.mkdirSync PIDPATH
nginx = null
cleanup = (err) ->
nginx.kill() if nginx?
throw err
butler =
host: process.env.BUTLER_HOST
port: process.env.BUTLER_PORT
secret: process.env.BUTLER_SECRET
droneName = process.env.DRONE_NAME
spawnNginx = ->
fs.readFile (path.join PIDPATH, 'porternginx.pid'), (err, data) ->
pid = data.toString() if data?
console.log "Killing stale nginx process with pid", pid if pid?
process.kill(pid) if pid?
nginx = spawn "nginx", ['-c', path.resolve(__dirname, 'nginx', 'nginx.conf')]
nginx.stdout.on 'data', (data) ->
console.log "Stdout from nginx:", data.toString()
nginx.stderr.on 'data', (data) ->
console.error "Stderr from nginx", data.toString()
nginx.on 'close', (code, signal) ->
console.log "nginx closed with code #{code} and signal #{signal}"
spawnNginx()
nginx.on 'error', (err) ->
console.error 'Error on nginx process', err
spawnNginx()
getRoutingTable = (remote) ->
return if process.env.PORTER_TESTING
opts =
hostname: remote.host
port: remote.port
path: "/routingTable"
auth: "porter:#{remote.secret}"
connection = http.get opts, (res) ->
cleanup new Error "Failed to get routing table, status: #{res.statusCode}" if res.statusCode isnt 200
responseText = ''
res.on 'data', (data) ->
responseText += data.toString()
res.on 'end', ->
routingTable = JSON.parse responseText
router.writeFile routingTable, (err) ->
cleanup err if err?
@socket.end()
.on "error", (e) ->
cleanup new Error e
connection.on 'socket', (socket) ->
socket.setTimeout(10 * 1000)
socket.on 'timeout', ->
cleanup new Error "getRoutingTable timeout"
checkin = (remote) ->
return if process.env.PORTER_TESTING
opts =
hostname: remote.host
port: remote.port
path: "/checkin/#{droneName}"
auth: "porter:#{remote.secret}"
connection = http.get opts, (res) ->
cleanup new Error "Checkin failed with status #{res.statusCode}" if res.statusCode != 200
console.log "Checked in with #{remote.host}:#{remote.port}"
@socket.end()
.on "error", (e) ->
cleanup new Error e
connection.on 'socket', (socket) ->
socket.setTimeout(10 * 1000)
socket.on 'timeout', ->
cleanup new Error "Checkin timeout"
listen = ->
server.listen PORT
checkin(butler)
getRoutingTable(butler)
setInterval ->
checkin(butler)
, 60 * 1000
router.writeFile {}, (err) ->
throw err if err?
spawnNginx()
authed =
port: (cb) ->
portfinder.getPort (err, port) ->
portfinder.basePort = port + 1
portfinder.basePort = 8000 if portfinder.basePort > 9000
cb err, port
updateRouting: (routes, cb) ->
router.writeFile routes, (err) ->
#kill is a misnomer, this instructs nginx to re-read it's configuration and gracefully retire it's workers. http://nginx.org/en/docs/control.html
nginx.kill 'SIGHUP' unless err?
cb err
server = upnode (client, conn) ->
@auth = (secret, cb) ->
return cb null, authed if secret == SECRET
cb 'DENIED'
checkPort = ->
tester = net.createServer()
tester.on 'error', (error) ->
console.log "Porter already running?"
setTimeout ->
checkPort()
, 10 * 1000
tester.listen PORT, ->
tester.close ->
listen()
checkPort()
console.log "Server listening on #{PORT}"
module.exports =
authed: authed