forked from robinpowered/bifrost
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rbn-pi.coffee
154 lines (126 loc) · 3.68 KB
/
rbn-pi.coffee
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# request = require 'request'
winston = require 'winston'
{EventEmitter} = require 'events'
# request = require 'request'
semver = require 'semver'
forever = require 'forever-monitor'
NPM = require 'npm'
config = require './config.json'
class Supervisor extends EventEmitter
constructor: ()->
@log.info 'Started supervisor!'
# Polling interval!
@interval = 300000 # 5 minutes
# Updating flag
@updating = false
# Packages
@packages = {}
# @loadPackages()
NPM.load (err, @npm) =>
# Start the script
@startRunning()
# Poll for new releases every once in a while
@watchReleases()
log: winston
# Gets the tag of the currently running os
getCurrentRelease: (packageName) ->
try
pjson = require "./node_modules/#{packageName}/package.json"
@packages[packageName].current = pjson.version
catch err
@log.error err
@log.warn "Package #{packageName} does not exist, so this must be the first run."
@packages[packageName].current = null
# Watches github for new releases
watchReleases: ->
# Check on an interval
setInterval =>
@checkOutdated()
, @interval
# Check for releases right away
# @checkOutdated()
# Gets the tag of the latest release
checkOutdated: ->
# run the npm outdated command to get a list of outdated packages
# check for any with the rbn prefix
# if found, do an npm update
@log.info 'checking for outdated packages...'
@npm.commands.outdated (err, outdated) =>
needsUpdate = false
unless err
# console.log outdated
for pack in outdated
# If name starts with rbn-
if pack[1][0...4] is 'rbn-'
console.log "#{pack[1]}: #{pack[3]} > #{pack[2]}"
# If version can update
if semver.valid(pack[2]) and semver.valid(pack[3]) and semver.gt(pack[3], pack[2])
# Needs an update!
needsUpdate = true
break
# Update if necessary
if needsUpdate
@update() unless @updating
else
@log.error err
update: ->
# Stop the current module if running
@log.info 'stopping current module...'
@stopRunning =>
@updating = true
# Update the npm modules
@npm.commands.update (err) =>
console.log err
unless err
@log.info "Updated successfully!"
@updating = false
@startRunning()
else
@log.error "Error updating"
console.log err
@updating = false
install: (callback=null) ->
# Install the module
@log.info 'installing!'
@updating = true
@npm.commands.install (err) =>
unless err
@log.info "Installed successfully!"
@startRunning()
@updating = false
callback()
else
@log.error "Error installing"
console.log err
@updating = false
stopRunning: (callback=null) ->
# Stop any running software.
# Kill with a stop code that allows the os to emit an "updating" event before exiting
@log.info 'stopping old os...'
if @running
emitter = @running.stop()
emitter.on 'stop', =>
@log.info 'stopped running successfully'
callback()
else
callback() if callback
startRunning: ->
# Start the software in the current directory
@log.info 'starting os...'
pjson = require "./node_modules/rbn-base/package.json"
startScript = pjson.main
if startScript
@running = new forever.Monitor "./node_modules/rbn-base/#{startScript}.js",
silent: false
command: 'node'
# Start/stop listeners
@running.on 'start', (process, data) =>
@log.info 'script started successfully!'
@emit 'startedRunning'
@running.on 'stop', =>
@emit 'stoppedRunning'
# Actually start the process
@running.start()
else
@log.error "No start script in package.json - make sure you have a {'scripts':{'start':'someScript.js'}}"
supervisor = new Supervisor config.NpmPackageName