-
Notifications
You must be signed in to change notification settings - Fork 74
/
index.js
188 lines (158 loc) · 4.65 KB
/
index.js
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
var path = require('path')
var fs = require('fs')
var menubar = require('menubar')
var ms = require('ms')
var Mongroup = require('mongroup')
var mkdir = require('mkdirp').sync
var debug = require('debug')('monu')
var shell = require('shell')
var dialog = require('dialog')
// try to fix the $PATH on OS X
require('fix-path')()
// use current user env (https://github.com/sindresorhus/shell-path/issues/7)
try {
process.env = require('user-env')()
} catch (e) {}
var Server = require('electron-rpc/server')
var app = new Server()
var opts = {dir: __dirname, icon: path.join(__dirname, 'images', 'Icon.png')}
var menu = menubar(opts)
var conf
process.on('uncaughtException', function (err) {
dialog.showErrorBox('Uncaught Exception: ' + err.message, err.stack || '')
menu.app.quit()
})
menu.on('ready', function ready () {
conf = loadConfig()
var canQuit = false
menu.app.on('will-quit', function tryQuit (e) {
if (canQuit) return true
menu.window = undefined
e.preventDefault()
})
// start all once
start([], function started (err) {
if (err) return console.log('error starting processes: ' + err.message)
console.log('started all processes')
})
menu.on('show', function show () {
app.configure(menu.window.webContents)
app.send('show')
})
app.on('terminate', function terminate (ev) {
canQuit = true
menu.app.terminate()
})
app.on('open-dir', function openDir (ev) {
shell.showItemInFolder(path.join(conf.exec.cwd, 'config.json'))
})
app.on('open-logs-dir', function openLogsDir (req) {
shell.showItemInFolder(path.join(conf.logs, req.body.name + '.log'))
})
app.on('get-all', function getAll (req, next) {
next(null, getProcessesStatus())
})
app.on('get-one', function getOne (req, next) {
next(null, getProcessStatus(req.body.name))
})
app.on('task', function task (req, next) {
if (req.body.task === 'startAll') start([], updateAll)
if (req.body.task === 'stopAll') stop([], req.body.signal, updateAll)
if (req.body.task === 'restartAll') restart([], updateAll)
if (req.body.task === 'start') start([req.body.name], updateSingle)
if (req.body.task === 'stop') stop([req.body.name], req.body.signal, updateSingle)
if (req.body.task === 'restart') restart([req.body.name], updateSingle)
function updateAll (err) {
if (err) throw err
next(null, getProcessesStatus())
}
function updateSingle (err) {
if (err) throw err
next(null, getProcessStatus(req.body.name))
}
})
})
function loadConfig () {
var dir = path.join(menu.app.getPath('userData'), 'data')
var configFile = dir + '/config.json'
var conf, data
try {
data = fs.readFileSync(configFile)
} catch (e) {
if (e.code === 'ENOENT') {
mkdir(dir)
fs.writeFileSync(configFile, fs.readFileSync(__dirname + '/config.json'))
return loadConfig()
} else {
throw e
}
}
try {
conf = JSON.parse(data.toString())
} catch (e) {
var code = dialog.showMessageBox({
message: 'Invalid configuration file\nCould not parse JSON',
detail: e.stack,
buttons: ['Reload Config', 'Exit app']
})
if (code === 0) {
return loadConfig()
} else {
menu.app.quit()
return
}
}
conf.exec = {cwd: dir}
conf.logs = path.resolve(path.join(dir, conf.logs || 'logs'))
conf.pids = path.resolve(path.join(dir, conf.pids || 'pids'))
mkdir(conf.logs)
mkdir(conf.pids)
conf.mon = path.join(__dirname, 'mon')
return conf
}
function getProcessStatus (procName) {
var procs = getProcessesStatus()
return procs.filter(function filter (proc) {
return proc.name === procName
})[0]
}
function getProcessesStatus () {
debug('reload config, get proc status...')
conf = loadConfig()
var group = new Mongroup(conf)
var procs = group.procs
return procs.map(function each (proc) {
var uptime, state = proc.state()
if (state === 'alive') uptime = ms(Date.now() - proc.mtime(), { long: true })
var item = {
cmd: proc.cmd,
name: proc.name,
state: state,
pid: proc.pid,
uptime: uptime ? uptime : undefined
}
return item
})
}
function restart (procs, cb) {
stop(procs, 'SIGQUIT', function onstop (err1) {
start(procs, function onstart (err2) {
if (cb) cb(err1 || err2)
})
})
}
function start (procs, cb) {
var group = new Mongroup(conf)
group.start(procs, function onstart (err) {
if (err) return cb(err)
cb()
})
}
function stop (procs, signal, cb) {
if (!signal) signal = 'SIGQUIT'
var group = new Mongroup(conf)
group.stop(procs, signal, function onstop (err) {
if (!err || err.code === 'ENOENT') return cb()
cb(err)
})
}