2013-12-23 04:22:54 +00:00
|
|
|
Promise = require 'bluebird'
|
2014-06-18 16:54:36 +00:00
|
|
|
_ = require 'lodash'
|
2013-12-23 04:22:54 +00:00
|
|
|
fs = Promise.promisifyAll require 'fs'
|
2014-06-18 16:54:36 +00:00
|
|
|
config = require './config'
|
|
|
|
mixpanel = require 'mixpanel'
|
2015-01-06 14:32:57 +00:00
|
|
|
networkCheck = require 'network-checker'
|
2015-02-27 19:22:42 +00:00
|
|
|
blink = require('blinking')(config.ledFile)
|
2015-03-17 20:40:57 +00:00
|
|
|
url = require 'url'
|
2014-04-28 10:56:17 +00:00
|
|
|
|
2014-12-10 18:38:37 +00:00
|
|
|
utils = exports
|
|
|
|
|
2014-10-14 09:21:19 +00:00
|
|
|
# Parses package.json and returns resin-supervisor's version
|
|
|
|
exports.supervisorVersion = require('../package.json').version
|
|
|
|
|
2014-06-18 19:10:33 +00:00
|
|
|
mixpanelClient = mixpanel.init(config.mixpanelToken)
|
2014-06-18 16:54:36 +00:00
|
|
|
|
|
|
|
exports.mixpanelProperties = mixpanelProperties =
|
|
|
|
username: require('/boot/config.json').username
|
|
|
|
|
2014-09-15 11:31:14 +00:00
|
|
|
exports.mixpanelTrack = (event, properties = {}) ->
|
2014-10-01 17:37:35 +00:00
|
|
|
# Allow passing in an error directly and having it assigned to the error property.
|
|
|
|
if properties instanceof Error
|
|
|
|
properties = error: properties
|
|
|
|
|
|
|
|
# If the properties has an error argument that is an Error object then it treats it nicely,
|
|
|
|
# rather than letting it become `{}`
|
|
|
|
if properties.error instanceof Error
|
|
|
|
properties.error =
|
|
|
|
message: properties.error.message
|
|
|
|
stack: properties.error.stack
|
|
|
|
|
2014-06-19 13:49:30 +00:00
|
|
|
console.log('Event:', event, JSON.stringify(properties))
|
2014-06-18 16:54:36 +00:00
|
|
|
# Mutation is bad, and it should feel bad
|
|
|
|
properties = _.assign(_.cloneDeep(properties), mixpanelProperties)
|
|
|
|
|
2014-06-18 19:10:33 +00:00
|
|
|
mixpanelClient.track(event, properties)
|
2014-07-11 14:57:49 +00:00
|
|
|
|
2014-12-17 17:54:49 +00:00
|
|
|
networkPattern =
|
|
|
|
blinks: 4
|
|
|
|
pause: 1000
|
2014-12-17 17:01:24 +00:00
|
|
|
|
2014-12-17 17:54:49 +00:00
|
|
|
exports.blink = blink
|
2015-03-17 20:40:57 +00:00
|
|
|
|
2015-08-26 14:27:26 +00:00
|
|
|
pauseConnectivityCheck = false
|
|
|
|
disableConnectivityCheck = false
|
2015-08-26 21:57:14 +00:00
|
|
|
|
2015-08-26 13:40:22 +00:00
|
|
|
# options: An object of net.connect options, with the addition of:
|
|
|
|
# timeout: 10s
|
|
|
|
checkHost = (options) ->
|
2015-08-27 15:28:15 +00:00
|
|
|
if disableConnectivityCheck or pauseConnectivityCheck
|
2015-08-26 13:40:22 +00:00
|
|
|
return true
|
2015-09-01 12:26:25 +00:00
|
|
|
else
|
|
|
|
return networkCheck.checkHost(options)
|
2015-08-26 13:40:22 +00:00
|
|
|
|
2015-08-26 21:57:14 +00:00
|
|
|
# Custom monitor that uses checkHost function above.
|
2015-08-26 13:40:22 +00:00
|
|
|
customMonitor = (options, fn) ->
|
|
|
|
networkCheck.monitor(checkHost, options, fn)
|
|
|
|
|
2015-08-26 14:27:26 +00:00
|
|
|
# pause: A Boolean to pause the connectivity checks
|
|
|
|
exports.pauseCheck = (pause) ->
|
|
|
|
pauseConnectivityCheck = pause
|
|
|
|
|
|
|
|
# disable: A Boolean to disable the connectivity checks
|
2015-08-26 13:40:22 +00:00
|
|
|
exports.disableCheck = (disable) ->
|
2015-08-26 14:27:26 +00:00
|
|
|
disableConnectivityCheck = disable
|
2015-08-26 13:40:22 +00:00
|
|
|
|
2015-08-26 21:57:14 +00:00
|
|
|
# Call back for inotify triggered when the VPN status is changed.
|
2015-08-27 15:28:15 +00:00
|
|
|
vpnStatusInotifyCallback = ->
|
|
|
|
fs.lstatAsync(config.vpnStatusPath + '/active')
|
2015-08-27 14:20:10 +00:00
|
|
|
.then ->
|
2015-08-27 15:28:15 +00:00
|
|
|
pauseConnectivityCheck = true
|
2015-08-27 14:20:10 +00:00
|
|
|
.catch ->
|
2015-08-27 15:28:15 +00:00
|
|
|
pauseConnectivityCheck = false
|
2015-08-26 21:57:14 +00:00
|
|
|
|
2015-08-27 20:19:20 +00:00
|
|
|
# Use the following to catch EEXIST errors
|
|
|
|
EEXIST = (err) -> err.code is 'EEXIST'
|
|
|
|
|
2014-12-17 17:01:24 +00:00
|
|
|
exports.connectivityCheck = _.once ->
|
2015-03-17 20:40:57 +00:00
|
|
|
parsedUrl = url.parse(config.apiEndpoint)
|
2015-08-27 15:28:15 +00:00
|
|
|
fs.mkdirAsync(config.vpnStatusPath)
|
2015-09-02 12:12:11 +00:00
|
|
|
.catch EEXIST, (err) ->
|
|
|
|
console.log('VPN status path exists.')
|
2015-08-27 14:20:10 +00:00
|
|
|
.then ->
|
2015-08-27 15:28:15 +00:00
|
|
|
fs.watch(config.vpnStatusPath, vpnStatusInotifyCallback)
|
2015-08-27 20:19:20 +00:00
|
|
|
|
2015-08-26 21:57:14 +00:00
|
|
|
# Manually trigger the call back to detect cases when VPN was switched on before the supervisor starts.
|
|
|
|
vpnStatusInotifyCallback()
|
2015-08-26 13:40:22 +00:00
|
|
|
customMonitor
|
2015-03-17 20:40:57 +00:00
|
|
|
host: parsedUrl.hostname
|
|
|
|
port: parsedUrl.port ? (if parsedUrl.protocol is 'https:' then 443 else 80)
|
2014-12-17 17:01:24 +00:00
|
|
|
interval: 10 * 1000
|
|
|
|
(connected) ->
|
|
|
|
if connected
|
2014-12-11 13:29:59 +00:00
|
|
|
console.log('Internet Connectivity: OK')
|
2014-12-17 17:11:54 +00:00
|
|
|
blink.pattern.stop()
|
2014-12-10 18:38:37 +00:00
|
|
|
else
|
2014-12-11 13:29:59 +00:00
|
|
|
console.log('Waiting for connectivity...')
|
2014-12-17 17:54:49 +00:00
|
|
|
blink.pattern.start(networkPattern)
|
2015-10-01 18:18:35 +00:00
|
|
|
|
|
|
|
exports.extendEnvVars = (env, uuid) ->
|
|
|
|
newEnv =
|
|
|
|
RESIN_DEVICE_UUID: uuid
|
|
|
|
RESIN: '1'
|
|
|
|
USER: 'root'
|
|
|
|
if env?
|
|
|
|
_.extend(newEnv, env)
|
|
|
|
return newEnv
|