pinokiod 3.28.0 → 3.30.0
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.
- package/kernel/api/index.js +0 -1
- package/kernel/bin/caddy.js +2 -0
- package/kernel/index.js +22 -25
- package/kernel/peer.js +230 -28
- package/kernel/procs.js +1 -131
- package/kernel/prototype.js +0 -7
- package/kernel/router/index.js +7 -1
- package/kernel/shell.js +1 -1
- package/kernel/util.js +87 -1
- package/package.json +2 -1
- package/server/index.js +205 -112
- package/server/public/common.js +13 -12
- package/server/public/network.gif +0 -0
- package/server/public/opener.js +12 -11
- package/server/views/index.ejs +3 -0
- package/server/views/net.ejs +121 -47
- package/server/views/network.ejs +506 -25
package/kernel/api/index.js
CHANGED
package/kernel/bin/caddy.js
CHANGED
package/kernel/index.js
CHANGED
|
@@ -292,6 +292,7 @@ class Kernel {
|
|
|
292
292
|
}
|
|
293
293
|
async refresh(notify_peers) {
|
|
294
294
|
const ts = Date.now()
|
|
295
|
+
// console.time("Total " + ts)
|
|
295
296
|
let network_active = await this.network_active()
|
|
296
297
|
if (!network_active) {
|
|
297
298
|
return
|
|
@@ -307,23 +308,12 @@ class Kernel {
|
|
|
307
308
|
// 1. get the process list
|
|
308
309
|
// console.time("> 1. Proc Refresh"+ts)
|
|
309
310
|
await this.processes.refresh()
|
|
310
|
-
|
|
311
|
-
// diff check
|
|
312
|
-
let new_config = JSON.stringify(this.processes.info)
|
|
313
|
-
// if (this.old_config !== new_config) {
|
|
314
|
-
// console.log("Proc config has changed")
|
|
315
|
-
// console.log("old", this.old_config)
|
|
316
|
-
// console.log("new", new_config)
|
|
317
|
-
// } else {
|
|
318
|
-
// console.log("Proc config is the same")
|
|
319
|
-
// }
|
|
320
|
-
this.old_config = new_config
|
|
321
|
-
|
|
322
311
|
// console.timeEnd("> 1. Proc Refresh"+ts)
|
|
323
312
|
|
|
324
313
|
// 2. refresh peer info to reflect the proc info
|
|
325
314
|
// console.time("> 2. Peer Refresh"+ts)
|
|
326
|
-
await this.peer.refresh()
|
|
315
|
+
//await this.peer.refresh()
|
|
316
|
+
await this.peer.refresh_host(this.peer.host)
|
|
327
317
|
// console.timeEnd("> 2. Peer Refresh"+ts)
|
|
328
318
|
|
|
329
319
|
// 3. load custom routers from ~/pinokio/network
|
|
@@ -336,18 +326,6 @@ class Kernel {
|
|
|
336
326
|
await this.router.local()
|
|
337
327
|
// console.timeEnd("> 4. Router Local"+ts)
|
|
338
328
|
|
|
339
|
-
// 5. refresh peer info to reflect the updated router info
|
|
340
|
-
// console.time("> 5. Peer Refresh"+ts)
|
|
341
|
-
await this.peer.refresh()
|
|
342
|
-
// console.timeEnd("> 5. Peer Refresh"+ts)
|
|
343
|
-
|
|
344
|
-
// 6. tell peers to refresh
|
|
345
|
-
if (notify_peers) {
|
|
346
|
-
// console.time("> 6. Peer Notify Peers"+ts)
|
|
347
|
-
await this.peer.notify_peers()
|
|
348
|
-
// console.timeEnd("> 6. Peer Notify Peers"+ts)
|
|
349
|
-
}
|
|
350
|
-
|
|
351
329
|
// 7. update remote router
|
|
352
330
|
// console.time("> 7. Router Remote"+ts)
|
|
353
331
|
await this.router.remote()
|
|
@@ -355,14 +333,33 @@ class Kernel {
|
|
|
355
333
|
|
|
356
334
|
await this.router.custom_domain()
|
|
357
335
|
|
|
336
|
+
this.router.fallback()
|
|
337
|
+
|
|
358
338
|
// 8. update caddy config
|
|
359
339
|
// console.time("> 8. Router Update"+ts)
|
|
360
340
|
await this.router.update()
|
|
361
341
|
// console.timeEnd("> 8. Router Update"+ts)
|
|
362
342
|
|
|
343
|
+
// 6. tell peers to refresh
|
|
344
|
+
let changed
|
|
345
|
+
// console.time("> 9. notify if changed")
|
|
346
|
+
let new_config = JSON.stringify(await this.peer.current_host())
|
|
347
|
+
if (this.old_config !== new_config) {
|
|
348
|
+
console.log("Proc config has changed. update router.")
|
|
349
|
+
changed = true
|
|
350
|
+
} else {
|
|
351
|
+
// console.log("Proc config is the same")
|
|
352
|
+
changed = false
|
|
353
|
+
}
|
|
354
|
+
this.old_config = new_config
|
|
355
|
+
if (changed) {
|
|
356
|
+
await this.peer.notify_refresh()
|
|
357
|
+
}
|
|
358
|
+
// console.timeEnd("> 9. notify if changed")
|
|
363
359
|
// 9. announce self to the peer network
|
|
364
360
|
this.peer.announce()
|
|
365
361
|
}
|
|
362
|
+
// console.timeEnd("Total " + ts)
|
|
366
363
|
}
|
|
367
364
|
async clearLog(group) {
|
|
368
365
|
let relativePath = path.relative(this.homedir, group)
|
package/kernel/peer.js
CHANGED
|
@@ -7,11 +7,13 @@ class PeerDiscovery {
|
|
|
7
7
|
this.kernel = kernel
|
|
8
8
|
this.port = port;
|
|
9
9
|
this.message = Buffer.from(message);
|
|
10
|
+
this.kill_message = Buffer.from("kill")
|
|
10
11
|
this.interval = interval;
|
|
11
12
|
this.peers = new Set();
|
|
12
13
|
this.host = this._getLocalIPAddress()
|
|
13
14
|
this.default_port = 42000
|
|
14
15
|
this.peers.add(this.host)
|
|
16
|
+
this.router_info_cache = {}
|
|
15
17
|
// this.start();
|
|
16
18
|
}
|
|
17
19
|
stop() {
|
|
@@ -20,6 +22,17 @@ class PeerDiscovery {
|
|
|
20
22
|
this.socket.close()
|
|
21
23
|
}
|
|
22
24
|
}
|
|
25
|
+
async check_peers () {
|
|
26
|
+
for(let host of Array.from(this.peers)) {
|
|
27
|
+
if (this.host !== host) {
|
|
28
|
+
let result = await this._refresh(host)
|
|
29
|
+
if (!result) {
|
|
30
|
+
this.peers.delete(host)
|
|
31
|
+
delete this.info[host]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
23
36
|
announce() {
|
|
24
37
|
if (this.socket) {
|
|
25
38
|
this.socket.send(this.message, 0, this.message.length, this.port, '192.168.1.255');
|
|
@@ -69,11 +82,19 @@ class PeerDiscovery {
|
|
|
69
82
|
this.socket = dgram.createSocket('udp4');
|
|
70
83
|
this.socket.on('message', (msg, rinfo) => {
|
|
71
84
|
const ip = rinfo.address;
|
|
85
|
+
let str = msg.toString()
|
|
86
|
+
let kill_message = this.kill_message.toString()
|
|
87
|
+
if (str.startsWith(kill_message + " ") && this._isLocalLAN(ip)) {
|
|
88
|
+
let host = str.split(" ")[1]
|
|
89
|
+
console.log({ host })
|
|
90
|
+
this.kill(host)
|
|
91
|
+
}
|
|
72
92
|
if (msg.toString() === this.message.toString() && this._isLocalLAN(ip)) {
|
|
73
93
|
if (!this.peers.has(ip)) {
|
|
74
94
|
console.log(`Discovered peer: ${ip}`);
|
|
75
95
|
this.peers.add(ip);
|
|
76
|
-
this.refresh()
|
|
96
|
+
// this.refresh()
|
|
97
|
+
// this.notify_refresh()
|
|
77
98
|
}
|
|
78
99
|
}
|
|
79
100
|
});
|
|
@@ -114,6 +135,25 @@ class PeerDiscovery {
|
|
|
114
135
|
return null
|
|
115
136
|
}
|
|
116
137
|
}
|
|
138
|
+
async notify_refresh() {
|
|
139
|
+
// notify all peers of the current host info
|
|
140
|
+
if (this.info) {
|
|
141
|
+
let info = this.info[this.host]
|
|
142
|
+
for(let host of Array.from(this.peers)) {
|
|
143
|
+
if (this.host !== host) {
|
|
144
|
+
try {
|
|
145
|
+
let endpoint = `http://${host}:${this.default_port}/pinokio/peer/refresh`
|
|
146
|
+
let res = await axios.post(endpoint, info, {
|
|
147
|
+
timeout: 2000
|
|
148
|
+
})
|
|
149
|
+
return res.data
|
|
150
|
+
} catch (e) {
|
|
151
|
+
return null
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
117
157
|
async _broadcast(host) {
|
|
118
158
|
try {
|
|
119
159
|
let res = await axios.post(`http://${host}:${this.default_port}/pinokio/peer/refresh`, {
|
|
@@ -133,19 +173,194 @@ class PeerDiscovery {
|
|
|
133
173
|
return res
|
|
134
174
|
}
|
|
135
175
|
}
|
|
136
|
-
|
|
176
|
+
async proc_info(proc) {
|
|
177
|
+
let title
|
|
178
|
+
let description
|
|
179
|
+
let http_icon
|
|
180
|
+
let https_icon
|
|
181
|
+
let icon
|
|
182
|
+
let iconpath
|
|
183
|
+
let appname
|
|
184
|
+
if (proc.external_router) {
|
|
185
|
+
// try to get icons from pinokio
|
|
186
|
+
for(let router of proc.external_router) {
|
|
187
|
+
// replace the root domain: facefusion-pinokio.git.x.localhost => facefusion-pinokio.git
|
|
188
|
+
let pattern = `.${this.name}.localhost`
|
|
189
|
+
if (router.endsWith(pattern)) {
|
|
190
|
+
let name = router.replace(pattern, "")
|
|
191
|
+
appname = name
|
|
192
|
+
let api_path = this.kernel.path("api", name)
|
|
193
|
+
let exists = await this.kernel.exists(api_path)
|
|
194
|
+
if (exists) {
|
|
195
|
+
let meta = await this.kernel.api.meta(name)
|
|
196
|
+
if (meta.icon) {
|
|
197
|
+
icon = meta.icon
|
|
198
|
+
iconpath = meta.iconpath
|
|
199
|
+
}
|
|
200
|
+
if (meta.title) {
|
|
201
|
+
title = meta.title
|
|
202
|
+
}
|
|
203
|
+
if (meta.description) {
|
|
204
|
+
description = meta.description
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// if not an app running inside pinokio, try to fetch and infer the favicon
|
|
211
|
+
if (icon) {
|
|
212
|
+
http_icon = `http://${this.host}:42000${icon}`;
|
|
213
|
+
//https_icon = `https://${appname}.${this.name}.localhost/${iconpath}?raw=true`
|
|
214
|
+
https_icon = `https://pinokio.${this.name}.localhost/raw/${appname}/${iconpath}`
|
|
215
|
+
} else {
|
|
216
|
+
for(let protocol of ["https", "http"]) {
|
|
217
|
+
if (protocol === "https") {
|
|
218
|
+
if (proc.external_router.length > 0) {
|
|
219
|
+
let favicon = await this.kernel.favicon.get("https://" + proc.external_router[0])
|
|
220
|
+
if (favicon) {
|
|
221
|
+
https_icon = favicon
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
if (proc.external_ip) {
|
|
226
|
+
let favicon = await this.kernel.favicon.get("http://" + proc.external_ip)
|
|
227
|
+
if (favicon) {
|
|
228
|
+
http_icon = favicon
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
title, description, http_icon, https_icon, icon
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async router_info() {
|
|
239
|
+
try {
|
|
240
|
+
let processes = []
|
|
241
|
+
if (this.info[this.host]) {
|
|
242
|
+
let procs = this.info[this.host].proc
|
|
243
|
+
let router = this.info[this.host].router
|
|
244
|
+
let port_mapping = this.info[this.host].port_mapping
|
|
245
|
+
for(let proc of procs) {
|
|
246
|
+
let pid = proc.pid
|
|
247
|
+
let d = Date.now()
|
|
248
|
+
let chunks = proc.ip.split(":")
|
|
249
|
+
let internal_port = chunks[chunks.length-1]
|
|
250
|
+
let internal_host = chunks.slice(0, chunks.length-1).join(":")
|
|
251
|
+
let external_port = port_mapping[internal_port]
|
|
252
|
+
let merged
|
|
253
|
+
let external_ip
|
|
254
|
+
if (external_port) {
|
|
255
|
+
external_ip = `${this.host}:${external_port}`
|
|
256
|
+
}
|
|
257
|
+
let info = {
|
|
258
|
+
external_router: router[external_ip] || [],
|
|
259
|
+
internal_router: router[proc.ip] || [],
|
|
260
|
+
external_ip,
|
|
261
|
+
external_port: parseInt(external_port),
|
|
262
|
+
internal_port: parseInt(internal_port),
|
|
263
|
+
...proc,
|
|
264
|
+
}
|
|
265
|
+
let cached = this.router_info_cache[pid]
|
|
266
|
+
let cached_str = JSON.stringify(cached)
|
|
267
|
+
let info_str = JSON.stringify(info)
|
|
268
|
+
if (cached && cached_str === info_str) {
|
|
269
|
+
// nothing has changed. use the cached version
|
|
270
|
+
processes.push(cached)
|
|
271
|
+
} else {
|
|
272
|
+
// something has changed, refresh
|
|
273
|
+
let proc_info = await this.proc_info(info)
|
|
274
|
+
info = { ...proc_info, ...info }
|
|
275
|
+
this.router_info_cache[pid] = info
|
|
276
|
+
processes.push(info)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
processes.sort((a, b) => {
|
|
281
|
+
return b.external_port-a.external_port
|
|
282
|
+
})
|
|
283
|
+
return processes
|
|
284
|
+
} catch (e) {
|
|
285
|
+
console.log("ERROR", e)
|
|
286
|
+
return []
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async installed() {
|
|
290
|
+
let folders = await fs.promises.readdir(this.kernel.path("api"))
|
|
291
|
+
let installed = []
|
|
292
|
+
for(let folder of folders) {
|
|
293
|
+
let meta = await this.kernel.api.meta(folder)
|
|
294
|
+
/*
|
|
295
|
+
meta := {
|
|
296
|
+
title,
|
|
297
|
+
icon,
|
|
298
|
+
description,
|
|
299
|
+
}
|
|
300
|
+
*/
|
|
301
|
+
let http_icon = null
|
|
302
|
+
let https_icon = null
|
|
303
|
+
let http_href = null
|
|
304
|
+
let https_href = null
|
|
305
|
+
if (meta && !meta.init_required) {
|
|
306
|
+
if (meta.title) {
|
|
307
|
+
if (meta.icon) {
|
|
308
|
+
http_icon = `http://${this.host}:42000${meta.icon}`;
|
|
309
|
+
//https_icon = `https://${folder}.${this.name}.localhost/${meta.iconpath}?raw=true`
|
|
310
|
+
https_icon = `https://pinokio.${this.name}.localhost/raw/${folder}/${meta.iconpath}`
|
|
311
|
+
}
|
|
312
|
+
//https_href = `https://${folder}.${this.name}.localhost`
|
|
313
|
+
https_href = `https://pinokio.${this.name}.localhost/p/${folder}`
|
|
314
|
+
http_href = `http://${this.host}:42000/p/${folder}`
|
|
315
|
+
installed.push({
|
|
316
|
+
folder,
|
|
317
|
+
http_icon,
|
|
318
|
+
https_icon,
|
|
319
|
+
https_href,
|
|
320
|
+
http_href,
|
|
321
|
+
...meta
|
|
322
|
+
})
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return installed
|
|
327
|
+
}
|
|
328
|
+
async current_host() {
|
|
329
|
+
let d = Date.now()
|
|
330
|
+
let router_info = await this.router_info()
|
|
331
|
+
let installed = await this.installed()
|
|
137
332
|
return {
|
|
138
333
|
home: this.kernel.homedir,
|
|
139
334
|
arch: this.kernel.arch,
|
|
140
335
|
platform: this.kernel.platform,
|
|
141
|
-
name: this.
|
|
142
|
-
host: this.
|
|
336
|
+
name: this.name,
|
|
337
|
+
host: this.host,
|
|
143
338
|
port_mapping: this.kernel.router.port_mapping,
|
|
144
339
|
proc: this.kernel.processes.info,
|
|
145
340
|
router: this.kernel.router.published(),
|
|
341
|
+
router_info,
|
|
342
|
+
installed,
|
|
146
343
|
memory: this.kernel.memory
|
|
147
344
|
}
|
|
148
345
|
}
|
|
346
|
+
refresh_info(info) {
|
|
347
|
+
this.info[info.host] = info
|
|
348
|
+
}
|
|
349
|
+
async refresh_host(host) {
|
|
350
|
+
this.refreshing = true
|
|
351
|
+
if (!this.info) {
|
|
352
|
+
this.info = {}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
let info = await this._refresh(host)
|
|
356
|
+
if (info) {
|
|
357
|
+
this.info[host] = {
|
|
358
|
+
host,
|
|
359
|
+
...info
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
this.refreshing = false
|
|
363
|
+
}
|
|
149
364
|
// refresh peer info
|
|
150
365
|
async refresh(peers) {
|
|
151
366
|
// if (this.active) {
|
|
@@ -154,7 +369,9 @@ class PeerDiscovery {
|
|
|
154
369
|
if (peers) {
|
|
155
370
|
refresh_peers = peers
|
|
156
371
|
} else {
|
|
157
|
-
this.info
|
|
372
|
+
if (!this.info) {
|
|
373
|
+
this.info = {}
|
|
374
|
+
}
|
|
158
375
|
refresh_peers = Array.from(this.peers)
|
|
159
376
|
}
|
|
160
377
|
let peer_info = await Promise.all(refresh_peers.map((host) => {
|
|
@@ -167,6 +384,14 @@ class PeerDiscovery {
|
|
|
167
384
|
host: peer.host,
|
|
168
385
|
...peer
|
|
169
386
|
}
|
|
387
|
+
} else {
|
|
388
|
+
// let host = refresh_peers[i]
|
|
389
|
+
// console.log(`remove peer ${host}`)
|
|
390
|
+
// delete this.info[host]
|
|
391
|
+
// this.peers.delete(host)
|
|
392
|
+
// console.log("after removing")
|
|
393
|
+
// console.log("info", this.info)
|
|
394
|
+
// console.log("peers", this.peers)
|
|
170
395
|
}
|
|
171
396
|
}
|
|
172
397
|
this.refreshing = false
|
|
@@ -176,29 +401,6 @@ class PeerDiscovery {
|
|
|
176
401
|
_isLocalLAN(ip) {
|
|
177
402
|
return ip.startsWith('192.168.') || ip.startsWith('10.') || (ip.startsWith('172.') && is172Private(ip));
|
|
178
403
|
}
|
|
179
|
-
//_getLocalIPAddress() {
|
|
180
|
-
// const interfaces = os.networkInterfaces();
|
|
181
|
-
// for (const ifaceList of Object.values(interfaces)) {
|
|
182
|
-
// for (const iface of ifaceList) {
|
|
183
|
-
// console.log({ iface })
|
|
184
|
-
// if (iface.family === 'IPv4' && !iface.internal) {
|
|
185
|
-
// const ip = iface.address;
|
|
186
|
-
// if (
|
|
187
|
-
// ip.startsWith('10.') ||
|
|
188
|
-
// ip.startsWith('192.168.') ||
|
|
189
|
-
// (ip.startsWith('172.') && is172Private(ip))
|
|
190
|
-
// ) {
|
|
191
|
-
// return ip;
|
|
192
|
-
// }
|
|
193
|
-
// }
|
|
194
|
-
// }
|
|
195
|
-
// }
|
|
196
|
-
// return null;
|
|
197
|
-
// function is172Private(ip) {
|
|
198
|
-
// const secondOctet = parseInt(ip.split('.')[1], 10);
|
|
199
|
-
// return secondOctet >= 16 && secondOctet <= 31;
|
|
200
|
-
// }
|
|
201
|
-
//}
|
|
202
404
|
_getLocalIPAddress() {
|
|
203
405
|
const interfaces = os.networkInterfaces();
|
|
204
406
|
for (const ifaceList of Object.values(interfaces)) {
|
package/kernel/procs.js
CHANGED
|
@@ -10,28 +10,10 @@ const cls = isWin ? 'cls' : 'clear'
|
|
|
10
10
|
const net = require('net');
|
|
11
11
|
class Procs {
|
|
12
12
|
constructor (kernel) {
|
|
13
|
-
// console.log("Initializing procs")
|
|
14
13
|
this.kernel = kernel
|
|
15
14
|
this.cache = {}
|
|
16
15
|
}
|
|
17
16
|
async isHttp(port) {
|
|
18
|
-
//async isHttp(localAddress) {
|
|
19
|
-
// if (this.cache.hasOwnProperty(localAddress)) {
|
|
20
|
-
//// console.log("Use cached", localAddress)
|
|
21
|
-
// return this.cache[localAddress]
|
|
22
|
-
// }
|
|
23
|
-
// console.log("Not cached", localAddress)
|
|
24
|
-
//try {
|
|
25
|
-
// //await axios.head(`http://${localAddress}`, { timeout: 3000 });
|
|
26
|
-
// await axios.get(`http://${localAddress}`, { timeout: 3000 });
|
|
27
|
-
// this.cache[localAddress] = true
|
|
28
|
-
// return true;
|
|
29
|
-
//} catch (err) {
|
|
30
|
-
// console.log("HEAD ERROR",{ localAddress, err })
|
|
31
|
-
// this.cache[localAddress] = false
|
|
32
|
-
// return false;
|
|
33
|
-
//}
|
|
34
|
-
|
|
35
17
|
// ignore caddy
|
|
36
18
|
if (parseInt(port) === 2019) {
|
|
37
19
|
return false
|
|
@@ -79,7 +61,6 @@ class Procs {
|
|
|
79
61
|
})
|
|
80
62
|
}
|
|
81
63
|
emit(id, cmd) {
|
|
82
|
-
// console.log("emit", { id, cmd })
|
|
83
64
|
setTimeout(() => {
|
|
84
65
|
this.kernel.shell.emit({
|
|
85
66
|
emit: cmd + "\r\n" + cls,
|
|
@@ -88,7 +69,6 @@ class Procs {
|
|
|
88
69
|
}, 10)
|
|
89
70
|
}
|
|
90
71
|
async get_pids (stdout) {
|
|
91
|
-
// console.log("get_pids size", stdout.length)
|
|
92
72
|
const results = [];
|
|
93
73
|
let pids = new Set()
|
|
94
74
|
let s = stdout.trim()
|
|
@@ -153,11 +133,6 @@ class Procs {
|
|
|
153
133
|
ip = localAddress
|
|
154
134
|
}
|
|
155
135
|
|
|
156
|
-
// let isHttp = await this.isHttp(ip)
|
|
157
|
-
// if (!isHttp) continue;
|
|
158
|
-
|
|
159
|
-
//const portMatch = line.match(/:(\d+)\s/);
|
|
160
|
-
//const port = portMatch?.[1];
|
|
161
136
|
if (pids.has(pid+"/"+port)) continue;
|
|
162
137
|
pids.add(pid+"/"+port)
|
|
163
138
|
if (pid && port) results.push({ port, pid, ip });
|
|
@@ -166,14 +141,11 @@ class Procs {
|
|
|
166
141
|
}
|
|
167
142
|
}
|
|
168
143
|
}
|
|
169
|
-
// console.timeEnd("###### Line parsing")
|
|
170
|
-
// console.time("########## http_check")
|
|
171
144
|
const http_check = await Promise.all(results.map(({ port }) => {
|
|
172
145
|
return limit(() => {
|
|
173
146
|
return this.isHttp(port)
|
|
174
147
|
})
|
|
175
148
|
}))
|
|
176
|
-
// console.timeEnd("########## http_check")
|
|
177
149
|
let filtered = []
|
|
178
150
|
for(let i=0; i<http_check.length; i++) {
|
|
179
151
|
if (http_check[i]) {
|
|
@@ -184,53 +156,7 @@ class Procs {
|
|
|
184
156
|
}
|
|
185
157
|
getPortPidList(cb) {
|
|
186
158
|
const cmd = isWin ? 'netstat -ano -p tcp' : 'lsof -nP -iTCP -sTCP:LISTEN';
|
|
187
|
-
|
|
188
|
-
// if (this.portPidList) {
|
|
189
|
-
// cb(this.portPidList)
|
|
190
|
-
// return
|
|
191
|
-
// }
|
|
192
|
-
let id = "Procs.getPortPidList"
|
|
193
|
-
let sh = this.kernel.shell.get(id)
|
|
194
|
-
this.port_cb = cb
|
|
195
|
-
this.port_running = true
|
|
196
|
-
this.d2 = Date.now()
|
|
197
|
-
console.time("Shell"+this.d2)
|
|
198
|
-
if (sh) {
|
|
199
|
-
this.emit(id, cmd)
|
|
200
|
-
console.time("lsof" + this.d2);
|
|
201
|
-
} else {
|
|
202
|
-
this.kernel.exec({
|
|
203
|
-
id,
|
|
204
|
-
conda: {
|
|
205
|
-
skip: true,
|
|
206
|
-
},
|
|
207
|
-
onready: () => {
|
|
208
|
-
this.emit(id, cmd)
|
|
209
|
-
},
|
|
210
|
-
input: true
|
|
211
|
-
}, (e) => {
|
|
212
|
-
console.log(">>>>>> all e.state", e.state)
|
|
213
|
-
if (e.state && e.state.includes(cls)) {
|
|
214
|
-
if (this.port_running) {
|
|
215
|
-
console.timeEnd("Shell"+this.d2)
|
|
216
|
-
console.log("e.state", e.state)
|
|
217
|
-
this.port_running = false
|
|
218
|
-
this.newline(id)
|
|
219
|
-
let d = Date.now()
|
|
220
|
-
console.time("get_pids" + d)
|
|
221
|
-
this.get_pids(e.state).then((pids) => {
|
|
222
|
-
console.timeEnd("get_pids" + d)
|
|
223
|
-
this.portPidList = pids
|
|
224
|
-
this.port_cb(pids)
|
|
225
|
-
})
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}).then((result) => {
|
|
229
|
-
this.port_running = false
|
|
230
|
-
console.log("Exec Finished", {result})
|
|
231
|
-
})
|
|
232
|
-
}
|
|
233
|
-
*/
|
|
159
|
+
let d = Date.now()
|
|
234
160
|
exec(cmd, { maxBuffer: 10 * 1024 * 1024 }, async (err, stdout) => {
|
|
235
161
|
this.get_pids(stdout).then((pids) => {
|
|
236
162
|
cb(pids)
|
|
@@ -238,7 +164,6 @@ class Procs {
|
|
|
238
164
|
});
|
|
239
165
|
}
|
|
240
166
|
get_name(stdout) {
|
|
241
|
-
// console.log("get_name size", stdout.length)
|
|
242
167
|
const lines = stdout.trim().split('\n');
|
|
243
168
|
const map = {};
|
|
244
169
|
lines.forEach(line => {
|
|
@@ -265,7 +190,6 @@ class Procs {
|
|
|
265
190
|
let exists = this.port_map["" + pid]
|
|
266
191
|
if (!exists) {
|
|
267
192
|
cached = false
|
|
268
|
-
console.log("Didn't exist", { pid, port, exists })
|
|
269
193
|
break;
|
|
270
194
|
}
|
|
271
195
|
}
|
|
@@ -275,46 +199,6 @@ class Procs {
|
|
|
275
199
|
return
|
|
276
200
|
}
|
|
277
201
|
const cmd = isWin ? 'tasklist /fo csv /nh' : 'ps -Ao pid,comm';
|
|
278
|
-
/*
|
|
279
|
-
let id = "Procs.getPidToNameMap"
|
|
280
|
-
let sh = this.kernel.shell.get(id)
|
|
281
|
-
this.pid_cb = cb
|
|
282
|
-
this.pid_running = true
|
|
283
|
-
if (sh) {
|
|
284
|
-
this.emit(id, cmd)
|
|
285
|
-
} else {
|
|
286
|
-
this.kernel.exec({
|
|
287
|
-
id,
|
|
288
|
-
conda: {
|
|
289
|
-
skip: true,
|
|
290
|
-
},
|
|
291
|
-
onready: () => {
|
|
292
|
-
// console.log("ON READY")
|
|
293
|
-
this.emit(id, cmd)
|
|
294
|
-
},
|
|
295
|
-
input: true
|
|
296
|
-
}, async (e) => {
|
|
297
|
-
if (e.state && e.state.includes(cls)) {
|
|
298
|
-
if (this.pid_running) {
|
|
299
|
-
this.pid_running = false
|
|
300
|
-
this.newline(id)
|
|
301
|
-
// console.log("GET MAP")
|
|
302
|
-
let map = this.get_name(e.state)
|
|
303
|
-
if (!this.port_map) {
|
|
304
|
-
this.port_map = {}
|
|
305
|
-
}
|
|
306
|
-
for(let key in map) {
|
|
307
|
-
this.port_map[key] = map[key]
|
|
308
|
-
}
|
|
309
|
-
this.pid_cb(this.port_map)
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}).then((result) => {
|
|
313
|
-
this.pid_running = false
|
|
314
|
-
console.log("Exec Finished", {result})
|
|
315
|
-
})
|
|
316
|
-
}
|
|
317
|
-
*/
|
|
318
202
|
exec(cmd, { maxBuffer: 10 * 1024 * 1024 }, async (err, stdout) => {
|
|
319
203
|
let map = this.get_name(stdout)
|
|
320
204
|
if (!this.port_map) {
|
|
@@ -331,21 +215,8 @@ class Procs {
|
|
|
331
215
|
this.refreshing = true
|
|
332
216
|
let ts = Date.now()
|
|
333
217
|
let list = await new Promise((resolve, reject) => {
|
|
334
|
-
// console.time(">>>>>>>>GET PORTS " + ts)
|
|
335
|
-
// console.log("get ports")
|
|
336
218
|
this.getPortPidList((portPidList) => {
|
|
337
|
-
// console.log("done: get ports")
|
|
338
|
-
// console.log({ portPidList })
|
|
339
|
-
// console.timeEnd(">>>>>>>>GET PORTS " + ts)
|
|
340
|
-
// console.time(">>>>>>> GET PIDS " + ts)
|
|
341
|
-
// if there's any new port, run getPidToNameMap
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
// console.log("getPid")
|
|
345
219
|
this.getPidToNameMap(portPidList, (pidToName) => {
|
|
346
|
-
// console.log("done getPid")
|
|
347
|
-
|
|
348
|
-
// console.timeEnd(">>>>>>> GET PIDS " + ts)
|
|
349
220
|
let list = portPidList.map(({ port, pid, ip }) => {
|
|
350
221
|
const fullname = pidToName[pid] || 'Unknown';
|
|
351
222
|
const name = fullname.split(path.sep).pop()
|
|
@@ -357,7 +228,6 @@ class Procs {
|
|
|
357
228
|
return { port, pid , name, fullname, ip }
|
|
358
229
|
}
|
|
359
230
|
}).filter((x) => { return x })
|
|
360
|
-
// console.log("LIST", JSON.stringify(list, null, 2))
|
|
361
231
|
resolve(list)
|
|
362
232
|
})
|
|
363
233
|
})
|
package/kernel/prototype.js
CHANGED
|
@@ -77,15 +77,12 @@ class Proto {
|
|
|
77
77
|
await fs.promises.rm(this.kernel.path("prototype"), { recursive: true })
|
|
78
78
|
}
|
|
79
79
|
async create(req, ondata) {
|
|
80
|
-
console.log("REQ", req)
|
|
81
80
|
try {
|
|
82
81
|
let projectType = req.params.projectType
|
|
83
82
|
let startType = req.params.cliType || req.params.startType
|
|
84
|
-
console.log({ projectType, startType })
|
|
85
83
|
|
|
86
84
|
let cwd = req.cwd
|
|
87
85
|
let name = req.params.name
|
|
88
|
-
// let name = req.name
|
|
89
86
|
let payload = {}
|
|
90
87
|
payload.cwd = path.resolve(cwd, name)
|
|
91
88
|
payload.input = req.params
|
|
@@ -100,8 +97,6 @@ class Proto {
|
|
|
100
97
|
let mod_path = this.kernel.path("prototype/system", projectType, startType)
|
|
101
98
|
let mod = await this.kernel.require(mod_path)
|
|
102
99
|
|
|
103
|
-
console.log({ mod_path, projectType, startType })
|
|
104
|
-
|
|
105
100
|
await mod(payload, ondata, this.kernel)
|
|
106
101
|
|
|
107
102
|
// copy readme
|
|
@@ -120,7 +115,6 @@ class Proto {
|
|
|
120
115
|
}
|
|
121
116
|
}
|
|
122
117
|
async readme(proto) {
|
|
123
|
-
console.log("proto.readme", proto)
|
|
124
118
|
let readme_path = path.resolve(this.kernel.homedir, "prototype", proto, "README.md")
|
|
125
119
|
let readme
|
|
126
120
|
try {
|
|
@@ -128,7 +122,6 @@ class Proto {
|
|
|
128
122
|
} catch (e) {
|
|
129
123
|
readme = ""
|
|
130
124
|
}
|
|
131
|
-
console.log({ readme_path, readme })
|
|
132
125
|
return marked.parse(readme)
|
|
133
126
|
}
|
|
134
127
|
}
|