UNPKG

6.29 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.defaultOptions = undefined;
7exports.initCmd = initCmd;
8exports.assignZombieRC = assignZombieRC;
9exports.validateArgs = validateArgs;
10exports.readSwarmConfigRaw = readSwarmConfigRaw;
11exports.formatSwarmConfig = formatSwarmConfig;
12exports.readSwarmConfig = readSwarmConfig;
13exports.validateServices = validateServices;
14exports.readNodesConfig = readNodesConfig;
15exports.validateNodes = validateNodes;
16exports.querySwarmNodes = querySwarmNodes;
17exports.detectDuplicateFingerprints = detectDuplicateFingerprints;
18exports.extractFingerprint = extractFingerprint;
19exports.extractServices = extractServices;
20
21var _fs = require('fs');
22
23var _fs2 = _interopRequireDefault(_fs);
24
25var _request = require('request');
26
27var _request2 = _interopRequireDefault(_request);
28
29var _async = require('async');
30
31var _async2 = _interopRequireDefault(_async);
32
33var _jsYaml = require('js-yaml');
34
35var _jsYaml2 = _interopRequireDefault(_jsYaml);
36
37var _object = require('object.assign');
38
39var _object2 = _interopRequireDefault(_object);
40
41var _zombieServiceFormat = require('@zombiec0rn/zombie-service-format');
42
43var _zombieServiceFormat2 = _interopRequireDefault(_zombieServiceFormat);
44
45var _zombieNodeFormat = require('@zombiec0rn/zombie-node-format');
46
47var _zombieNodeFormat2 = _interopRequireDefault(_zombieNodeFormat);
48
49var _ora = require('ora');
50
51var _ora2 = _interopRequireDefault(_ora);
52
53var _route = require('./route');
54
55var route = _interopRequireWildcard(_route);
56
57var _mdns2 = require('./mdns');
58
59var mdns = _interopRequireWildcard(_mdns2);
60
61function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
62
63function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
64
65// NOTE:
66// `initCmd` needs to be called whenever mdns is involved.
67// It creates a `route` for mdns packets -> interface
68// and hooks up listeners to remove this route when app exits.
69function initCmd(args) {
70 // Prevent app from closing immediately
71 process.stdin.resume();
72 // exitHandler
73 function exitHandler(err) {
74 route.del(args, function () {
75 console.error(err);
76 process.exit();
77 });
78 }
79
80 // Call exitHandler on exit
81 process.on('exit', exitHandler);
82 process.on('SIGINT', exitHandler);
83 process.on('uncaughtException', exitHandler);
84
85 // Add route
86 route.add(args);
87}
88
89function assignZombieRC(args) {
90 var rc = {};
91 try {
92 rc = _jsYaml2.default.safeLoad(_fs2.default.readFileSync('.zombierc'));
93 } catch (e) {
94 if (e.code != 'ENOENT') throw e;
95 }
96 (0, _object2.default)(rc, args); // Overwrite passed args
97 (0, _object2.default)(args, rc); // Assign non-overwritten to args
98}
99
100var defaultOptions = [{
101 name: 'interface',
102 help: 'Which interface to use (required)'
103}];
104exports.defaultOptions = defaultOptions;
105function validateArgs(args) {
106 if (!args.interface) {
107 console.log('Missing required argument `interface`. Exiting...');
108 process.exit(1);
109 }
110}
111
112function readSwarmConfigRaw(path) {
113 try {
114 return _jsYaml2.default.safeLoad(_fs2.default.readFileSync(path));
115 } catch (e) {
116 throw e;
117 process.exit(1);
118 }
119}
120
121function formatSwarmConfig(config) {
122 var defaultServiceConfig = config.services.default || {};
123 config.services = Object.keys(config.services).filter(function (k) {
124 return k != 'default';
125 }).map(function (k) {
126 var serviceConfig = config.services[k];
127 serviceConfig.id = k;
128 return (0, _object2.default)({}, config.services[k], defaultServiceConfig);
129 });
130 return config;
131}
132
133function readSwarmConfig(path) {
134 var raw = readSwarmConfigRaw(path);
135 var formatted = formatSwarmConfig(raw);
136 return formatted;
137}
138
139function validateServices(services) {
140 services.forEach(function (s) {
141 // TODO: Move to scheduler.validateServices !?
142 // scheduler needs to export validateServices & validateNodes ??
143 if (!s.memory) throw new Error('Missing memory - ' + s.id);
144 if (!s.cpu || typeof s.cpu != 'number') throw new Error('Missing cpu - ' + s.id);
145 });
146 return _zombieServiceFormat2.default.validate(services);
147}
148
149function readNodesConfig(path) {
150 return JSON.parse(_fs2.default.readFileSync(path));
151}
152
153function validateNodes(nodes) {
154 return _zombieNodeFormat2.default.validate(nodes);
155}
156
157function querySwarmNodes(callback, args, queryTime) {
158 queryTime = queryTime || 5000;
159 var _mdns = mdns.default(args);
160 var spinner = new _ora2.default({ text: 'Looking for swarm nodes on ' + args.interface + '...' });
161 spinner.start();
162 mdns.onResponse(_mdns, function (answers) {
163 _async2.default.map(answers, function (a, cb) {
164 (0, _request2.default)('http://' + a.data + ':8901', function (err, res, body) {
165 if (res.statusCode != 200) return cb(err, a);
166 var info = JSON.parse(body);
167 info.ip = a.data;
168 cb(err, info);
169 });
170 }, function (err, nodes) {
171 _mdns.destroy();
172 spinner.stop();
173 if (err) {
174 console.error(err);
175 process.exit(1);
176 }
177 if (args.swarm) {
178 nodes = nodes.filter(function (n) {
179 return n.swarm == args.swarm;
180 });
181 }
182 if (nodes.length == 0) {
183 console.log('No swarm nodes found on ' + args.interface + ' ¯_(ツ)_/¯');
184 process.exit(0);
185 }
186 callback(nodes);
187 });
188 }, queryTime);
189 mdns.query(_mdns);
190}
191
192function detectDuplicateFingerprints(services) {
193 return services.filter(function (s) {
194 return s.fingerprint;
195 }).map(function (s) {
196 return s.fingerprint;
197 }).filter(function (fp, i, arr) {
198 var arrIndex = arr.indexOf(fp);
199 return arrIndex >= 0 && arrIndex != i;
200 });
201}
202
203function extractFingerprint(service) {
204 var fingerprint = undefined;
205 if (service.env) {
206 service.env.forEach(function (e) {
207 if (e.indexOf('ZOMBIE_SWARM_FINGERPRINT') == 0) {
208 fingerprint = e.split('=')[1];
209 }
210 });
211 }
212 return fingerprint;
213}
214
215function extractServices(node) {
216 return (node.services || []).map(function (s) {
217 s.host = node;
218 s.fingerprint = extractFingerprint(s);
219 return s;
220 });
221}
\No newline at end of file