mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-01 08:47:56 +00:00
network: implement a module to get IP addresses and check network connectivity
This module now uses the native node `os.networkInterfaces()` to retrieve the addresses, instead of the gosuper endpoint. We also add the very simple "blink" library that is also used by the Supervisor API. Signed-off-by: Pablo Carranza Velez <pablo@resin.io>
This commit is contained in:
parent
f77d3e1563
commit
93832d6540
2
src/lib/blink.coffee
Normal file
2
src/lib/blink.coffee
Normal file
@ -0,0 +1,2 @@
|
||||
constants = require './constants'
|
||||
module.exports = require('blinking')(constants.ledFile)
|
99
src/network.coffee
Normal file
99
src/network.coffee
Normal file
@ -0,0 +1,99 @@
|
||||
Promise = require 'bluebird'
|
||||
_ = require 'lodash'
|
||||
url = require 'url'
|
||||
networkCheck = require 'network-checker'
|
||||
os = require 'os'
|
||||
fs = Promise.promisifyAll(require('fs'))
|
||||
|
||||
constants = require './lib/constants'
|
||||
{ checkTruthy } = require './lib/validation'
|
||||
blink = require './lib/blink'
|
||||
|
||||
networkPattern =
|
||||
blinks: 4
|
||||
pause: 1000
|
||||
|
||||
pauseConnectivityCheck = false
|
||||
enableConnectivityCheck = true
|
||||
|
||||
# options: An object of net.connect options, with the addition of:
|
||||
# timeout: 10s
|
||||
checkHost = (options) ->
|
||||
if !enableConnectivityCheck or pauseConnectivityCheck
|
||||
return true
|
||||
else
|
||||
return networkCheck.checkHost(options)
|
||||
|
||||
# Custom monitor that uses checkHost function above.
|
||||
customMonitor = (options, fn) ->
|
||||
networkCheck.monitor(checkHost, options, fn)
|
||||
|
||||
# enable: A Boolean to enable/disable the connectivity checks
|
||||
exports.enableCheck = enableCheck = (enable) ->
|
||||
enableConnectivityCheck = enable
|
||||
|
||||
# Call back for inotify triggered when the VPN status is changed.
|
||||
vpnStatusInotifyCallback = ->
|
||||
fs.lstatAsync(constants.vpnStatusPath + '/active')
|
||||
.then ->
|
||||
pauseConnectivityCheck = true
|
||||
.catch ->
|
||||
pauseConnectivityCheck = false
|
||||
|
||||
# Use the following to catch EEXIST errors
|
||||
EEXIST = (err) -> err.code is 'EEXIST'
|
||||
|
||||
exports.startConnectivityCheck = _.once (apiEndpoint, enable) ->
|
||||
exports.enableConnectivityCheck(enable)
|
||||
if !apiEndpoint?
|
||||
console.log('No API endpoint specified, skipping connectivity check')
|
||||
return
|
||||
parsedUrl = url.parse(apiEndpoint)
|
||||
fs.mkdirAsync(constants.vpnStatusPath)
|
||||
.catch EEXIST, (err) ->
|
||||
console.log('VPN status path exists.')
|
||||
.then ->
|
||||
fs.watch(constants.vpnStatusPath, vpnStatusInotifyCallback)
|
||||
|
||||
# Manually trigger the call back to detect cases when VPN was switched on before the supervisor starts.
|
||||
vpnStatusInotifyCallback() if enable
|
||||
customMonitor
|
||||
host: parsedUrl.hostname
|
||||
port: parsedUrl.port ? (if parsedUrl.protocol is 'https:' then 443 else 80)
|
||||
interval: 10 * 1000
|
||||
(connected) ->
|
||||
if connected
|
||||
console.log('Internet Connectivity: OK')
|
||||
blink.pattern.stop()
|
||||
else
|
||||
console.log('Waiting for connectivity...')
|
||||
blink.pattern.start(networkPattern)
|
||||
|
||||
# Callback function to enable/disable tcp pings
|
||||
exports.enableConnectivityCheck = (val) ->
|
||||
enabled = checkTruthy(val) ? true
|
||||
enableCheck(enabled)
|
||||
console.log("Connectivity check enabled: #{enabled}")
|
||||
|
||||
exports.connectivityCheckEnabled = Promise.method ->
|
||||
return enableConnectivityCheck
|
||||
|
||||
exports.getIPAddresses = ->
|
||||
_.flatten(_.map(_.omitBy(os.networkInterfaces(), (interfaceFields, interfaceName) ->
|
||||
/(docker[0-9]+)|(rce[0-9]+)|(tun[0-9]+)|(resin-vpn)|(lo)/.test(interfaceName))
|
||||
, (validInterfaces) ->
|
||||
_.map(_.omitBy(validInterfaces, (a) -> a.family != 'IPv4' ), 'address'))
|
||||
)
|
||||
|
||||
exports.startIPAddressUpdate = do ->
|
||||
_lastIPValues = null
|
||||
return (callback, interval) ->
|
||||
getAndReportIP = ->
|
||||
ips = exports.getIPAddresses()
|
||||
if !_.isEmpty(_.xor(ips , _lastIPValues))
|
||||
_lastIPValues = ips
|
||||
callback(ips)
|
||||
setInterval( ->
|
||||
getAndReportIP()
|
||||
, interval)
|
||||
getAndReportIP()
|
Loading…
x
Reference in New Issue
Block a user