@andersbakken/fisk 3.5.7 → 3.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,150 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const option = require("@jhanssen/options")("fisk/proxy", require('minimist')(process.argv.slice(2)));
4
- const WebSocket = require('ws');
5
-
6
- let scheduler = option("scheduler", "ws://localhost:8097");
7
- if (scheduler.indexOf('://') == -1)
8
- scheduler = "ws://" + scheduler;
9
- if (!/:[0-9]+$/.exec(scheduler))
10
- scheduler += ":8097";
11
- console.log("scheduler is", scheduler);
12
-
13
- let server;
14
- const port = option.int("port", 8099);
15
- let tasks = {};
16
- function handleConnection(ws, req)
17
- {
18
- // console.log("got req", req.headers, req.url);
19
-
20
- if (req.url != "/compile") {
21
- console.log("Bad request", req.url);
22
- ws.close();
23
- return;
24
- }
25
-
26
- if (!req.headers["x-fisk-job-id"]) {
27
- try {
28
- // console.log(req.headers);
29
- let headers = {};
30
- for (let key in req.headers) {
31
- if (/^x-fisk-/.exec(key)) {
32
- headers[key] = req.headers[key];
33
- }
34
- }
35
- let proxyWs = new WebSocket(`${scheduler}${req.url}`, { headers: headers });
36
- proxyWs.on("error", err => { console.error("Got error", err.message); });
37
- proxyWs.on("message", msg => {
38
- // console.log("Got message", msg);
39
- const message = JSON.parse(msg);
40
- if (message.type == "builder" && message.ip) {
41
- let copy = JSON.parse(msg);
42
- let ip = req.connection.remoteAddress;
43
- if (ip.substr(0, 7) == "::ffff:") {
44
- ip = ip.substr(7);
45
- }
46
- copy.ip = ip;
47
- copy.port = port;
48
- // console.log("sending copy", copy);
49
- tasks[copy.id] = { ws: ws, builderIp: message.ip, builderPort: message.port };
50
- ws.send(JSON.stringify(copy));
51
- } else {
52
- ws.send(msg);
53
- }
54
- });
55
- proxyWs.on("close", () => {
56
- // console.log("Got close");
57
- proxyWs = undefined;
58
- if (ws)
59
- ws.close();
60
- });
61
- let pendingMessages = [];
62
- proxyWs.on("open", () => {
63
- // console.log("got open");
64
- pendingMessages.forEach(msg => { proxyWs.send(msg); });
65
- pendingMessages = undefined;
66
- });
67
- ws.on("close", () => {
68
- // console.log("Client closed");
69
- ws = undefined;
70
- if (proxyWs)
71
- proxyWs.close();
72
- });
73
- ws.on("message", msg => {
74
- // console.log("Got message from client", msg);
75
- if (pendingMessages) {
76
- pendingMessages.push(msg);
77
- } else {
78
- proxyWs.send(msg);
79
- }
80
- });
81
- } catch (err) {
82
- console.log("Got error", err.toString());
83
- ws.close();
84
- }
85
- } else {
86
- let id = parseInt(req.headers["x-fisk-job-id"]);
87
- let task = tasks[id];
88
- delete tasks[id];
89
- let headers = {};
90
- let pendingMessages = [];
91
- for (let key in req.headers) {
92
- if (/^x-fisk-/.exec(key)) {
93
- headers[key] = req.headers[key];
94
- }
95
- }
96
- let proxyWs = new WebSocket(`ws://${task.builderIp}:${task.builderPort}/compile`, { headers: headers });
97
- proxyWs.on("close", () => {
98
- // console.log("Got close 2");
99
- proxyWs = undefined;
100
- if (ws)
101
- ws.close();
102
- });
103
- proxyWs.on("open", () => {
104
- // console.log("got open 2");
105
- // console.log("got open");
106
- pendingMessages.forEach(msg => { proxyWs.send(msg); });
107
- pendingMessages = undefined;
108
- });
109
-
110
- ws.on("close", () => {
111
- // console.log("Client closed 2");
112
- ws = undefined;
113
- if (proxyWs)
114
- proxyWs.close();
115
- });
116
- ws.on("message", msg => {
117
- // console.log("Got message from client 2", msg, !!pendingMessages);
118
- if (pendingMessages) {
119
- pendingMessages.push(msg);
120
- } else {
121
- proxyWs.send(msg);
122
- }
123
- });
124
-
125
- proxyWs.on("message", msg => {
126
- // console.log("Got message from builder", msg);
127
- ws.send(msg);
128
- });
129
-
130
- console.log("Now to connect to the builder");
131
- // ws.on("close", () => {
132
- // console.log("Client 2 closed");
133
- // });
134
- // ws.on("message", msg => {
135
- // console.log("Got message 2 from client", msg);
136
- // });
137
- }
138
- }
139
-
140
- function listen()
141
- {
142
- server = new WebSocket.Server({
143
- port: port,
144
- backlog: option.int("backlog", 50)
145
- });
146
- console.log("listening on", server.options.port);
147
- server.on("connection", handleConnection);
148
- }
149
-
150
- listen();
@@ -1,144 +0,0 @@
1
- const fs = require('fs');
2
-
3
- class Database {
4
- constructor(path) {
5
- this.path = path;
6
- this.busy = false;
7
- this.queue = [];
8
- }
9
-
10
- get(record) {
11
- return new Promise((resolve, reject) => {
12
- // console.log("Reader promise", record, this.busy, this.queue);
13
- const perform = () => {
14
- // console.log("perform called for read");
15
- return this._read().then(records => {
16
- this.finishedOperation();
17
- resolve(records ? records[record] : undefined);
18
- }).catch(err => {
19
- reject(err);
20
- this.finishedOperation();
21
- });
22
- };
23
- if (this.busy) {
24
- this.queue.push(perform);
25
- } else {
26
- this.busy = true;
27
- perform();
28
- }
29
- });
30
- }
31
-
32
- set(...keyValuePairs) {
33
- return new Promise((resolve, reject) => {
34
- const perform = () => {
35
- return this._read().then(records => {
36
- if (!records)
37
- records = {};
38
- for (let i=0; i<keyValuePairs.length; i+=2)
39
- records[keyValuePairs[i]] = keyValuePairs[i + 1];
40
-
41
- fs.writeFile(this.path + ".tmp", JSON.stringify(records) + "\n", err => {
42
- if (err) {
43
- reject(err);
44
- } else {
45
- fs.rename(this.path + ".tmp", this.path, (err) => {
46
- if (err) {
47
- reject(new Error(`Failed to rename ${this.path}.tmp to ${this.path} ${err}`));
48
- } else {
49
- resolve();
50
- }
51
- });
52
- }
53
- this.finishedOperation();
54
- });
55
- }).catch(err => {
56
- reject(err);
57
- this.finishedOperation();
58
- });
59
- };
60
-
61
- if (this.busy) {
62
- this.queue.push(perform);
63
- } else {
64
- this.busy = true;
65
- perform();
66
- }
67
- });
68
- }
69
-
70
- _read() {
71
- return new Promise((resolve, reject) => {
72
- fs.readFile(this.path, (err, data) => {
73
- // console.log("got read", err, data);
74
- if (err) {
75
- if (err.code == "ENOENT") {
76
- resolve({});
77
- } else {
78
- reject(err);
79
- }
80
- } else {
81
- if (!data) {
82
- resolve({});
83
- } else {
84
- try {
85
- resolve(JSON.parse(data));
86
- } catch (err) {
87
- fs.renameSync(this.path, this.path + ".error");
88
- reject(new Error(`Failed to parse JSON from file: ${this.path} ${err}`));
89
- }
90
- }
91
- }
92
- });
93
- });
94
- }
95
-
96
- finishedOperation() {
97
- // console.log("finishedOperation", this.queue.length);
98
- if (this.queue.length) {
99
- const func = this.queue.splice(0, 1)[0];
100
- func();
101
- } else {
102
- this.busy = false;
103
- }
104
- }
105
- }
106
-
107
- const db = new Database("fisk.2");
108
- // db.get("ball").
109
- // then(result => {
110
- // console.log("read ball", result);
111
- // if (!result)
112
- // result = [];
113
- // result.push(result.length);
114
- // return db.set("ball", result).then(val => {
115
- // console.log("set 1", val);
116
- // }).catch(err => {
117
- // console.log("set 1 err", err);
118
- // });
119
-
120
- // return db.set("ball2", result).then(val => {
121
- // console.log("set 2", val);
122
- // }).catch(err => {
123
- // console.log("set 2 err", err);
124
- // });
125
-
126
- // return db.set("ball3", result).then(val => {
127
- // console.log("set 3", val);
128
- // }).catch(err => {
129
- // console.log("set 3 err", err);
130
- // });
131
- // }).then(val => {
132
-
133
- // }).catch(err => {
134
-
135
- // });
136
-
137
- // db.set("a", 1).then(a => console.log("got a", a)).catch(err => console.error("a error", err));
138
- // db.set("a", 2).then(a => console.log("got b", a)).catch(err => console.error("b error", err));
139
- // db.set("a", 3).then(a => console.log("got c", a)).catch(err => console.error("c error", err));
140
- // db.get("a").then(a => console.log("read a", a)).catch(err => {
141
- // console.error("got err", err);
142
- // });
143
-
144
- module.exports = Database;
@@ -1,386 +0,0 @@
1
- const fs = require('fs-extra');
2
- const path = require('path');
3
- const child_process = require('child_process');
4
- const mktemp = require('mktemp');
5
-
6
- function untarFile(archive, file, encoding)
7
- {
8
- return new Promise((resolve, reject) => {
9
- mktemp.createDir("/tmp/fisk_env_infoXXXX").then(tmpdir => {
10
- child_process.exec(`tar -zxf "${archive}" ${file}`, { cwd: tmpdir }, (err, stdout, stderr) => {
11
- if (err) {
12
- reject(err);
13
- return;
14
- }
15
- fs.readFile(path.join(tmpdir, file), encoding || "utf8", (err, data) => {
16
- try {
17
- fs.removeSync(tmpdir);
18
- } catch (e) {
19
- console.error("Got an error removing the temp dir", tmpdir);
20
- }
21
- if (err) {
22
- reject(err);
23
- } else {
24
- resolve(data);
25
- }
26
- });
27
- });
28
- });
29
- });
30
- }
31
-
32
- class Environment {
33
- constructor(path, hash, system, originalPath) {
34
- this.path = path;
35
- this.hash = hash;
36
- this.system = system;
37
- this.originalPath = originalPath;
38
- this.info = undefined;
39
- try {
40
- this.size = fs.statSync(path).size;
41
- } catch (err) {
42
- }
43
- console.log("Created environment", JSON.stringify(this), originalPath);
44
- }
45
-
46
- toString() {
47
- return JSON.stringify(this, null, 4);
48
- }
49
-
50
- get file() {
51
- return `${this.hash}_${this.system}.tar.gz`;
52
- }
53
-
54
- canRun(system) {
55
- switch (system) {
56
- case 'Linux i686':
57
- case 'Darwin i686': // ### this is not really a thing
58
- return this.system == system;
59
- case 'Linux x86_64':
60
- return !!/^Linux /.exec(this.system);
61
- case 'Darwin x86_64':
62
- return !!/^Darwin /.exec(this.system);
63
- default:
64
- console.error("Unknown system", system);
65
- return false;
66
- }
67
- }
68
- }
69
-
70
- class File {
71
- constructor(path, hash) {
72
- this._fd = fs.openSync(path, "w");
73
- this._pending = [];
74
- this._writing = false;
75
-
76
- this.path = path;
77
- this.hash = hash;
78
- this.system = undefined;
79
- this.originalPath = undefined;
80
- }
81
-
82
- toString() {
83
- return JSON.stringify(this, null, 4);
84
- }
85
-
86
- save(data) {
87
- if (!this._fd)
88
- throw new Error(`No fd for ${this.path}`);
89
- return new Promise((resolve, reject) => {
90
- this._pending.push({ data: data, resolve: resolve, reject: reject });
91
- if (!this._writing) {
92
- this._writing = true;
93
- this._write();
94
- }
95
- });
96
- }
97
-
98
- discard() {
99
- if (!this._fd)
100
- throw new Error(`No fd for ${this.path}`);
101
- fs.closeSync(this._fd);
102
- fs.unlinkSync(this.path);
103
- }
104
-
105
- close() {
106
- if (!this._fd)
107
- throw new Error(`No fd for ${this.path}`);
108
- fs.closeSync(this._fd);
109
- this._fd = undefined;
110
- }
111
-
112
- _write() {
113
- const pending = this._pending.shift();
114
- fs.write(this._fd, pending.data).then(() => {
115
- pending.resolve();
116
-
117
- if (this._pending.length > 0) {
118
- process.nextTick(() => { this._write(); });
119
- } else {
120
- this._writing = false;
121
- }
122
- }).catch(e => {
123
- fs.closeSync(this._fd);
124
- this._fd = undefined;
125
- pending.reject(e);
126
- this._clearPending(e);
127
- });
128
- }
129
-
130
- _clearPending(e) {
131
- if (!this._pending)
132
- return;
133
-
134
- for (let i = 0; i < this._pending.length; ++i) {
135
- this._pending[i].reject(e);
136
- }
137
- this._pending = undefined;
138
- }
139
- }
140
-
141
- class LinkProperties {
142
- constructor(args, blacklist) {
143
- this.arguments = args || [];
144
- this.blacklist = blacklist || [];
145
- }
146
-
147
- toString() {
148
- return JSON.stringify(this, null, 4);
149
- }
150
- };
151
-
152
- class Links {
153
- constructor() {
154
- this._targets = {};
155
- }
156
-
157
- toString() {
158
- return JSON.stringify(this, null, 4);
159
- }
160
-
161
- get targets() {
162
- return this._targets;
163
- }
164
-
165
- toObject() {
166
- return this._targets;
167
- }
168
-
169
- contains(targetHash) {
170
- return targetHash in this._targets;
171
- }
172
-
173
- arguments(targetHash) {
174
- const ret = this._targets[targetHash];
175
- return ret ? ret.arguments : [];
176
- }
177
-
178
- blacklist(targetHash) {
179
- const ret = this._targets[targetHash];
180
- return ret ? ret.blacklist : [];
181
- }
182
-
183
- set(targetHash, args, blacklist) {
184
- this._targets[targetHash] = new LinkProperties(args, blacklist);
185
- }
186
-
187
- unset(targetHash) {
188
- delete this._targets[targetHash];
189
- }
190
-
191
- get targetHashes() {
192
- return Object.keys(this._targets);
193
- }
194
-
195
- get size() {
196
- return Object.keys(this._targets).length;
197
- }
198
- };
199
-
200
- const environments = {
201
- _data: {}, // key: hash, value: class Environment
202
- _links: {}, // key: srcHash, value: class Links { targetHash, LinkProperties { arguments, blacklist } }
203
- _path: undefined,
204
- _db: undefined,
205
-
206
- load(db, p) {
207
- this._db = db;
208
- return db.get("links").then(links => {
209
- if (links) {
210
- for (var srcHash in links) {
211
- let targets = links[srcHash];
212
- let data = environments._links[srcHash] = new Links();
213
- for (let target in targets) {
214
- let obj = targets[target];
215
- data.set(target, obj.arguments, obj.blacklist);
216
- }
217
- }
218
- }
219
- return new Promise((resolve, reject) => {
220
- fs.stat(p).then(st => {
221
- if (st.isDirectory()) {
222
- // we're good
223
- environments._path = p;
224
- fs.readdir(p).then(files => {
225
- let promises = [];
226
- files.forEach(e => {
227
- if (e.length == 47 && e.indexOf(".tar.gz", 40) == 40) {
228
- const tarFile = path.join(p, e);
229
- const hash = e.substr(0, 40);
230
- let env = new Environment(tarFile);
231
- promises.push(untarFile(tarFile, "etc/compiler_info").then(data => {
232
- const idx = data.indexOf('\n');
233
- const info = JSON.parse(data.substr(0, idx));
234
- env.system = info.system;
235
- env.originalPath = info.originalPath;
236
- env.info = data.substr(idx + 1);
237
- environments._data[hash] = env;
238
- }).catch(err => {
239
- console.error("Failed to extract compiler_info", err);
240
- }));
241
- }
242
- });
243
- Promise.all(promises).then(() => {
244
- resolve();
245
- });
246
-
247
- // setTimeout(() => {
248
- // // console.log(JSON.stringify(environments._links, null, 4));
249
- // environments.link("28CD22DF1176120F63EC463E095F13D4330194D7", "177EF462A7AEC31C26502F5833A92B51C177C01B", [], []);
250
- // }, 1000);
251
- });
252
- } else {
253
- reject(`Can't use path ${p}`);
254
- }
255
- }).catch(e => {
256
- if ("code" in e && e.code == "ENOENT") {
257
- // make the directory
258
- fs.mkdirp(p, err => {
259
- if (err) {
260
- reject(`Can't make directory ${p}: ${e.message}`);
261
- return;
262
- }
263
- // we're good
264
- environments._path = p;
265
- resolve();
266
- });
267
- } else {
268
- reject(`Can't make directory ${p}: ${e.message}`);
269
- }
270
- });
271
- });
272
- });
273
- },
274
-
275
-
276
- prepare(environment) {
277
- if (environment.hash in environments._data)
278
- return undefined;
279
- fs.mkdirpSync(environments._path);
280
- return new File(path.join(environments._path, `${environment.hash}.tar.gz`), environment.hash);
281
- },
282
-
283
- complete(file) {
284
- return new Promise((resolve, reject) => {
285
- untarFile(file.path, "etc/compiler_info").then(data => {
286
- let env = new Environment(file.path, file.hash);
287
- const idx = data.indexOf('\n');
288
- const info = JSON.parse(data.substr(0, idx));
289
- env.system = info.system;
290
- env.originalPath = info.originalPath;
291
- env.info = data.substr(idx + 1);
292
- environments._data[file.hash] = env;
293
- resolve();
294
- });
295
- });
296
- },
297
-
298
- hasEnvironment(hash) {
299
- return hash in environments._data;
300
- },
301
-
302
- compatibleEnvironments(srcHash) {
303
- let compatible = [];
304
- if (srcHash in environments._data)
305
- compatible.push(srcHash);
306
- // console.log("checking", srcHash, environments._links);
307
- let data = environments._links[srcHash];
308
- if (data)
309
- return compatible.concat(data.targetHashes);
310
- return compatible;
311
- },
312
-
313
- extraArgs(srcHash, targetHash) {
314
- let data = environments._links[srcHash];
315
- if (data) {
316
- return data.arguments(targetHash);
317
- }
318
- return [];
319
- },
320
-
321
- link(srcHash, targetHash, args, blacklist) {
322
- let data = environments._links[srcHash];
323
- if (!data)
324
- data = environments._links[srcHash] = new Links();
325
- data.set(targetHash, args, blacklist);
326
- return this.syncLinks();
327
- },
328
-
329
- unlink(srcHash, targetHash) {
330
- if (!srcHash) {
331
- for (let src in environments._links) {
332
- let targets = environments._links[src];
333
- targets.unset(targetHash);
334
- if (!targets.size) {
335
- delete environments._links[src];
336
- }
337
- }
338
- } else if (!targetHash) {
339
- delete environments._links[srcHash];
340
- } else {
341
- let targets = environments._links[srcHash];
342
- targets.unset(targetHash);
343
- if (!targets.size) {
344
- delete environments._links[srcHash];
345
- }
346
- }
347
- return this.syncLinks();
348
- },
349
-
350
- get environments() {
351
- return environments._data;
352
- },
353
-
354
- environment(hash) {
355
- if (!(hash in environments._data))
356
- return undefined;
357
- return environments._data[hash];
358
- },
359
-
360
- linksInfo() {
361
- let obj = {};
362
- for (let srcHash in this._links) {
363
- obj[srcHash] = this._links[srcHash].targets;
364
- }
365
- return obj;
366
- },
367
-
368
- syncLinks() {
369
- return this._db.set("links", this.linksInfo());
370
- },
371
-
372
- remove(hash) { // ### this should be promisified
373
- try {
374
- fs.removeSync(environments._data[hash].path);
375
- delete environments._data[hash];
376
- this.unlink(hash);
377
- this.unlink(undefined, hash);
378
- this.syncLinks();
379
- } catch (err) {
380
- console.error("Failed to remove environment", environments._data[hash].path, err);
381
- return;
382
- }
383
- }
384
- };
385
-
386
- module.exports = environments;