balena-supervisor/app.coffee

141 lines
3.8 KiB
CoffeeScript
Raw Normal View History

2013-07-18 10:40:35 +00:00
fs = require('fs')
async = require('async')
request = require('request')
2013-07-19 00:45:02 +00:00
posix = require('posix')
{exec, spawn} = require('child_process')
2013-07-18 10:40:35 +00:00
STATE_FILE = '/opt/ewa-client-bootstrap/state.json'
2013-07-18 10:40:35 +00:00
API_ENDPOINT = 'http://paras.rulemotion.com:1337'
2013-07-18 23:31:42 +00:00
HAKI_PATH = '/home/haki'
POLLING_INTERVAL = 30000
2013-07-18 10:40:35 +00:00
try
state = require(STATE_FILE)
2013-07-18 10:40:35 +00:00
catch e
console.error(e)
process.exit()
bootstrapTasks = [
2013-07-18 11:07:39 +00:00
# get config from extra partition
2013-07-18 10:40:35 +00:00
(callback) ->
try
callback(null, require('/mnt/config.json'))
catch error
callback(error)
2013-07-18 13:02:45 +00:00
# bootstrapping
2013-07-18 10:40:35 +00:00
(config, callback) ->
request.post("#{API_ENDPOINT}/associate", {
2013-07-18 23:31:42 +00:00
json:
user: config.id
2013-07-18 10:40:35 +00:00
}, (error, response, body) ->
if error
return callback(error)
2013-07-18 23:31:42 +00:00
if typeof body isnt 'object'
callback(body)
2013-07-18 10:40:35 +00:00
state.virgin = false
state.uuid = body.uuid
state.gitUrl = body.gitUrl
2013-07-18 10:40:35 +00:00
2013-07-18 11:07:39 +00:00
fs.writeFileSync('/etc/openvpn/ca.crt', body.ca)
fs.writeFileSync('/etc/openvpn/client.crt', body.cert)
fs.writeFileSync('/etc/openvpn/client.key', body.key)
fs.appendFileSync('/etc/openvpn/client.conf', "remote #{body.vpnhost} #{body.vpnport}")
2013-07-18 10:40:35 +00:00
callback(null)
)
]
2013-07-18 11:07:39 +00:00
hakiExec = (command, options, callback) ->
options.uid = posix.getpwnam('haki').uid
ps = spawn(process.env.SHELL, ['-c', command], options)
stdout = ''
stderr = ''
ps.stdout.on('data', (chunk) ->
stdout += chunk
)
ps.stderr.on('data', (chunk) ->
stderr += chunk
)
ps.on('exit', (error) -> callback(error, stdout, stderr))
ps.on('error', (error) -> callback(error, stdout, stderr))
2013-07-19 00:10:43 +00:00
2013-07-18 11:07:39 +00:00
stage1Tasks = [
# superuser tasks
2013-07-18 11:07:39 +00:00
(callback) -> async.waterfall(bootstrapTasks, callback)
(callback) -> fs.writeFileSync(STATE_FILE, JSON.stringify(state)) ; callback()
2013-07-18 11:07:39 +00:00
(callback) -> exec('systemctl start openvpn@client', callback)
(callback) -> exec('systemctl enable openvpn@client', callback)
# haki user tasks
(callback) -> hakiExec('mkdir hakiapp', cwd: '/home/haki', callback)
(callback) -> hakiExec('git init', cwd: '/home/haki/hakiapp', callback)
(callback) -> hakiExec("git remote add origin #{state.gitUrl}", cwd: '/home/haki/hakiapp', callback)
# done
(callback) -> console.log('Bootstrapped') ; callback()
2013-07-18 11:07:39 +00:00
]
2013-07-19 00:10:43 +00:00
updateRepo = (callback) ->
tasks1 = [
(callback) -> hakiExec('git pull origin master', cwd: '/home/haki/hakiapp', callback)
(stdout, stderr, callback) -> hakiExec('git rev-parse HEAD', cwd: '/home/haki/hakiapp', callback)
2013-07-19 00:10:43 +00:00
(stdout, stderr, callback) -> callback(null, stdout.trim())
]
tasks2 = [
2013-07-19 14:40:53 +00:00
(callback) ->
2013-07-19 16:40:18 +00:00
console.log("Checking for package.json")
if fs.existsSync('hakiapp/package.json')
console.log("Found, npm installing")
ps = spawn('sudo', ['-u', 'haki', 'npm', 'install'],
cwd: 'hakiapp'
stdio: [0, 1, 2]
)
ps.on('exit', callback)
ps.on('error', callback)
2013-07-19 14:40:53 +00:00
else
2013-07-19 16:40:18 +00:00
console.log("No package.json")
2013-07-19 14:40:53 +00:00
callback()
(callback) ->
2013-07-19 16:40:18 +00:00
console.log("Checking for Procfile")
if fs.existsSync('hakiapp/Procfile')
console.log("Found Procfile, starting app..")
ps = spawn('foreman', ['start'],
cwd: 'hakiapp'
stdio: [0, 1, 2]
uid: posix.getpwnam('haki').uid
)
ps.on('exit', callback)
ps.on('error', callback)
2013-07-19 14:40:53 +00:00
else
2013-07-19 16:40:18 +00:00
console.log("No Procfile found")
2013-07-19 14:40:53 +00:00
callback()
2013-07-19 00:10:43 +00:00
]
2013-07-19 00:10:43 +00:00
async.waterfall(tasks1, (error, hash) ->
2013-07-19 16:40:18 +00:00
console.log("Checking for new version..")
if hash isnt state.gitHead
2013-07-19 16:40:18 +00:00
console.log("New version found #{state.gitHead}->#{hash}")
state.gitHead = hash
fs.writeFileSync(STATE_FILE, JSON.stringify(state))
async.series(tasks2, (callback) -> setTimeout(callback, POLLING_INTERVAL))
2013-07-19 00:10:43 +00:00
else
2013-07-19 16:40:18 +00:00
console.log("No new version found")
setTimeout(callback, POLLING_INTERVAL)
2013-07-19 00:33:20 +00:00
)
2013-07-19 00:10:43 +00:00
stage2Tasks = [
(callback) -> async.forever(updateRepo, callback)
]
2013-07-18 23:31:42 +00:00
if state.virgin
2013-07-19 00:10:43 +00:00
tasks = stage1Tasks.concat(stage2Tasks)
else
tasks = stage2Tasks
async.series(tasks, (error, results) ->
if (error)
console.error(error)
)