Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50665 views
1
/*
2
* index.js: Top-level include for the systemv foreverd service adapter
3
*
4
* (C) 2010 Nodejitsu Inc.
5
* MIT LICENCE
6
*
7
*/
8
9
var fs = require('fs'),
10
util = require('util'),
11
path = require('path'),
12
spawn = require('child_process').spawn,
13
nssocket = require('nssocket'),
14
forever = require('../../../../forever'),
15
Adapter = require('../adapter');
16
17
//
18
// Classic init.d script adapter
19
// Sometimes called inittab, but its origin is called systemv
20
//
21
var SystemVAdapter = module.exports = function SystemVAdapter(service) {
22
Adapter.call(this, service);
23
this.daemonized = false;
24
};
25
26
util.inherits(SystemVAdapter, Adapter);
27
28
SystemVAdapter.prototype.install = function install(callback) {
29
//
30
// Copy the init.d script to the right location
31
// TODO Distribution fixes?
32
//
33
forever.config.set('root', path.join('/var', 'local', 'foreverd'));
34
var initdPath = path.join('/etc', 'init.d', 'foreverd'),
35
script,
36
target;
37
38
try {
39
fs.mkdirSync(forever.config.get('root'), '0777');
40
fs.mkdirSync(path.join(forever.config.get('root'), 'services'), '0777');
41
}
42
catch (e) {
43
if (e.code !== 'EEXIST') {
44
return callback && callback(e);
45
}
46
}
47
48
try {
49
script = fs.createReadStream(path.join(__dirname, 'foreverd'));
50
target = fs.createWriteStream(initdPath, { flags: 'w', mode: '0777' });
51
52
script.pipe(target);
53
script.on('end', function () {
54
var directories = fs.readdirSync('/etc');
55
directories.forEach(function (directory) {
56
var match = directory.match(/^rc(\d+)\.d$/),
57
killOrStart;
58
59
if (match) {
60
killOrStart = { 0: true, 1: true, 6: true }[match[1]] ? 'K' : 'S';
61
62
try {
63
fs.symlinkSync(initdPath, path.join('/etc', directory, killOrStart + '20foreverd'));
64
}
65
catch (e) {
66
if (e.code !== 'EEXIST') {
67
return callback && callback(e);
68
}
69
}
70
}
71
});
72
73
return callback && callback();
74
});
75
}
76
catch (e) {
77
if (e.code !== 'EEXIST') {
78
return callback && callback(e);
79
}
80
}
81
};
82
83
//
84
//
85
//
86
SystemVAdapter.prototype.load = function load(callback) {
87
forever.config.set('root', path.join('/var', 'local', 'foreverd'));
88
var serviceFiles = fs.readdirSync(path.join(forever.config.get('root'), 'services')),
89
services = [];
90
91
if (serviceFiles.length !== 0) {
92
serviceFiles.forEach(function loadServiceFiles(serviceFile, index) {
93
var serviceFilePath = path.join(forever.config.get('root'), 'services', serviceFile),
94
service = JSON.parse(fs.readFileSync(serviceFilePath)),
95
file = service.file,
96
options = service.options;
97
98
options.minUptime = 200;
99
services.push({
100
file: service.file,
101
options: service.options
102
});
103
});
104
}
105
106
callback(services);
107
};
108
109
SystemVAdapter.prototype.start = function start(callback) {
110
spawn('/etc/init.d/foreverd', ['start']);
111
return callback && callback();
112
};
113
114
SystemVAdapter.prototype.run = function run(callback) {
115
if (this.daemonized) {
116
return callback();
117
}
118
119
var self = this,
120
pidFilePath = path.join('/var', 'run', 'foreverd.pid'),
121
logFilePath = path.join('/var', 'log', 'foreverd');
122
123
process.on('exit', function removePIDFile() {
124
try {
125
fs.unlinkSync(pidFilePath);
126
}
127
catch (err) {
128
// we are exiting anyway. this may have some noexist error already
129
}
130
});
131
132
fs.open(logFilePath, 'w+', function serviceLogOpened(err, logFile) {
133
if (err) {
134
throw err;
135
}
136
137
self.service.startServer(function () {
138
try {
139
//
140
// TODO: Create a pseudo-daemon to replace this.
141
//
142
// daemon.start(logFile);
143
// daemon.lock(pidFilePath);
144
self.daemonized = true;
145
return callback && callback();
146
}
147
catch (err) {
148
console.error(err);
149
return callback && callback(err);
150
}
151
});
152
});
153
};
154
155
SystemVAdapter.prototype.add = function add(file, options, callback) {
156
forever.config.set('root', path.join('/var', 'local', 'foreverd'));
157
//
158
// Add descriptor to our service list
159
// this is just a json file in $root/services/*.json
160
//
161
var filePath, service = {
162
file: file,
163
options: options || {}
164
};
165
166
options.appendLog = true;
167
filePath = path.join(forever.config.get('root'), 'services', options.uid + '.json');
168
169
fs.writeFile(filePath, JSON.stringify(service), function (err) {
170
return callback && callback(err);
171
});
172
};
173
174
SystemVAdapter.prototype.list = function list(callback) {
175
forever.config.set('root', path.join('/var', 'local', 'foreverd'));
176
177
var sockPath = path.join(forever.config.get('root'), 'foreverd.sock'),
178
client;
179
180
client = dnode.connect(sockPath, function onConnect(remote, client) {
181
if (callback) {
182
callback(false, remote.applications);
183
}
184
185
client.end();
186
});
187
188
client.on('error', function onError(err) {
189
if (err.code === 'ECONNREFUSED') {
190
try {
191
fs.unlinkSync(fullPath);
192
}
193
catch (ex) { }
194
return callback && callback(false, []);
195
}
196
197
return callback && callback(err);
198
});
199
};
200