pinokiod 3.8.92 → 3.8.94
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/bin/caddy.js +1 -270
- package/kernel/index.js +31 -7
- package/kernel/loader.js +8 -0
- package/kernel/peer.js +77 -84
- package/kernel/router/index.js +1 -1
- package/kernel/shell.js +15 -6
- package/kernel/shells.js +6 -2
- package/kernel/tree-kill.js +165 -0
- package/package.json +1 -2
- package/server/index.js +69 -54
- package/server/views/network.ejs +179 -5
package/kernel/bin/caddy.js
CHANGED
|
@@ -15,7 +15,7 @@ class Caddy {
|
|
|
15
15
|
let response = await axios.get('http://127.0.0.1:2019/config/')
|
|
16
16
|
return true
|
|
17
17
|
} catch (e) {
|
|
18
|
-
console.log(e)
|
|
18
|
+
console.log(e.message)
|
|
19
19
|
return false
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -34,7 +34,6 @@ class Caddy {
|
|
|
34
34
|
message: `caddy run --watch`,
|
|
35
35
|
path: this.kernel.homedir,
|
|
36
36
|
}, (e) => {
|
|
37
|
-
console.log("[CADDY] " + e.cleaned)
|
|
38
37
|
if (!resolved) {
|
|
39
38
|
if (/endpoint started/i.test(e.cleaned)) {
|
|
40
39
|
console.log("######### match")
|
|
@@ -46,273 +45,6 @@ class Caddy {
|
|
|
46
45
|
})
|
|
47
46
|
this.kernel.refresh(true)
|
|
48
47
|
}
|
|
49
|
-
// const config = {
|
|
50
|
-
// "apps": {
|
|
51
|
-
// "http": {
|
|
52
|
-
// "servers": {
|
|
53
|
-
// "main": {
|
|
54
|
-
// "listen": ["127.0.0.1:443"],
|
|
55
|
-
// "routes": [
|
|
56
|
-
// {
|
|
57
|
-
// "match": [{ "method": ["OPTIONS"] }],
|
|
58
|
-
// "handle": [
|
|
59
|
-
// {
|
|
60
|
-
// "handler": "headers",
|
|
61
|
-
// "response": {
|
|
62
|
-
// "set": {
|
|
63
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
64
|
-
// "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
|
|
65
|
-
// "Access-Control-Allow-Headers": ["*"],
|
|
66
|
-
// "Vary": ["Origin"]
|
|
67
|
-
// }
|
|
68
|
-
// }
|
|
69
|
-
// },
|
|
70
|
-
// {
|
|
71
|
-
// "handler": "static_response",
|
|
72
|
-
// "status_code": 204
|
|
73
|
-
// }
|
|
74
|
-
// ]
|
|
75
|
-
// },
|
|
76
|
-
// {
|
|
77
|
-
// "match": [{ "host": ["pinokio.localhost"] }],
|
|
78
|
-
// "handle": [
|
|
79
|
-
// {
|
|
80
|
-
// "handler": "reverse_proxy",
|
|
81
|
-
// "upstreams": [{ "dial": "127.0.0.1:42000" }]
|
|
82
|
-
// },
|
|
83
|
-
// {
|
|
84
|
-
// "handler": "headers",
|
|
85
|
-
// "response": {
|
|
86
|
-
// "set": {
|
|
87
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
88
|
-
// "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
|
|
89
|
-
// "Access-Control-Allow-Headers": ["*"],
|
|
90
|
-
// "Vary": ["Origin"]
|
|
91
|
-
// }
|
|
92
|
-
// }
|
|
93
|
-
// }
|
|
94
|
-
// ]
|
|
95
|
-
// },
|
|
96
|
-
// {
|
|
97
|
-
// "match": [{ "host": ["l.pinokio.localhost"] }],
|
|
98
|
-
// "handle": [
|
|
99
|
-
// {
|
|
100
|
-
// "handler": "reverse_proxy",
|
|
101
|
-
// "upstreams": [{ "dial": "127.0.0.1:1234" }]
|
|
102
|
-
// },
|
|
103
|
-
// {
|
|
104
|
-
// "handler": "headers",
|
|
105
|
-
// "response": {
|
|
106
|
-
// "set": {
|
|
107
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
108
|
-
// "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
|
|
109
|
-
// "Access-Control-Allow-Headers": ["*"],
|
|
110
|
-
// "Vary": ["Origin"]
|
|
111
|
-
// }
|
|
112
|
-
// }
|
|
113
|
-
// }
|
|
114
|
-
// ]
|
|
115
|
-
// },
|
|
116
|
-
// {
|
|
117
|
-
// "match": [{ "host": ["o.pinokio.localhost"] }],
|
|
118
|
-
// "handle": [
|
|
119
|
-
// {
|
|
120
|
-
// "handler": "reverse_proxy",
|
|
121
|
-
// "upstreams": [{ "dial": "127.0.0.1:11434" }]
|
|
122
|
-
// },
|
|
123
|
-
// {
|
|
124
|
-
// "handler": "headers",
|
|
125
|
-
// "response": {
|
|
126
|
-
// "set": {
|
|
127
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
128
|
-
// "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
|
|
129
|
-
// "Access-Control-Allow-Headers": ["*"],
|
|
130
|
-
// "Vary": ["Origin"]
|
|
131
|
-
// }
|
|
132
|
-
// }
|
|
133
|
-
// }
|
|
134
|
-
// ]
|
|
135
|
-
// },
|
|
136
|
-
// {
|
|
137
|
-
// "match": [{ "host": ["a.pinokio.localhost"] }],
|
|
138
|
-
// "handle": [
|
|
139
|
-
// {
|
|
140
|
-
// "handler": "reverse_proxy",
|
|
141
|
-
// "upstreams": [{ "dial": "127.0.0.1:7860" }]
|
|
142
|
-
// },
|
|
143
|
-
// {
|
|
144
|
-
// "handler": "headers",
|
|
145
|
-
// "response": {
|
|
146
|
-
// "set": {
|
|
147
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
148
|
-
// "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
|
|
149
|
-
// "Access-Control-Allow-Headers": ["*"],
|
|
150
|
-
// "Vary": ["Origin"]
|
|
151
|
-
// }
|
|
152
|
-
// }
|
|
153
|
-
// }
|
|
154
|
-
// ]
|
|
155
|
-
// },
|
|
156
|
-
// {
|
|
157
|
-
// "match": [{ "host": ["b.pinokio.localhost"] }],
|
|
158
|
-
// "handle": [
|
|
159
|
-
// {
|
|
160
|
-
// "handler": "reverse_proxy",
|
|
161
|
-
// "upstreams": [{ "dial": "127.0.0.1:7861" }]
|
|
162
|
-
// },
|
|
163
|
-
// {
|
|
164
|
-
// "handler": "headers",
|
|
165
|
-
// "response": {
|
|
166
|
-
// "set": {
|
|
167
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
168
|
-
// "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
|
|
169
|
-
// "Access-Control-Allow-Headers": ["*"],
|
|
170
|
-
// "Vary": ["Origin"]
|
|
171
|
-
// }
|
|
172
|
-
// }
|
|
173
|
-
// }
|
|
174
|
-
// ]
|
|
175
|
-
// },
|
|
176
|
-
// {
|
|
177
|
-
// "match": [{ "host": ["c.pinokio.localhost"] }],
|
|
178
|
-
// "handle": [
|
|
179
|
-
// {
|
|
180
|
-
// "handler": "reverse_proxy",
|
|
181
|
-
// "upstreams": [{ "dial": "127.0.0.1:7862" }]
|
|
182
|
-
// },
|
|
183
|
-
// {
|
|
184
|
-
// "handler": "headers",
|
|
185
|
-
// "response": {
|
|
186
|
-
// "set": {
|
|
187
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
188
|
-
// "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
|
|
189
|
-
// "Access-Control-Allow-Headers": ["*"],
|
|
190
|
-
// "Vary": ["Origin"]
|
|
191
|
-
// }
|
|
192
|
-
// }
|
|
193
|
-
// }
|
|
194
|
-
// ]
|
|
195
|
-
// }
|
|
196
|
-
// ]
|
|
197
|
-
// }
|
|
198
|
-
// }
|
|
199
|
-
// }
|
|
200
|
-
// }
|
|
201
|
-
// }
|
|
202
|
-
//
|
|
203
|
-
// const config2 = {
|
|
204
|
-
// "apps": {
|
|
205
|
-
// "http": {
|
|
206
|
-
// "servers": {
|
|
207
|
-
// "main": {
|
|
208
|
-
// "listen": [":443"],
|
|
209
|
-
// //"listen": [":80"],
|
|
210
|
-
// "handle_response": [
|
|
211
|
-
// {
|
|
212
|
-
// "handler": "headers",
|
|
213
|
-
// "headers": {
|
|
214
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
215
|
-
// "Access-Control-Allow-Methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"],
|
|
216
|
-
// "Access-Control-Allow-Headers": ["*"]
|
|
217
|
-
// }
|
|
218
|
-
// }
|
|
219
|
-
// ],
|
|
220
|
-
// "routes": [
|
|
221
|
-
// {
|
|
222
|
-
// "match": [{ "method": ["OPTIONS"] }],
|
|
223
|
-
// "handle": [
|
|
224
|
-
// {
|
|
225
|
-
// "handler": "static_response",
|
|
226
|
-
// "headers": {
|
|
227
|
-
// "Access-Control-Allow-Origin": ["*"],
|
|
228
|
-
// "Access-Control-Allow-Methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"],
|
|
229
|
-
// "Access-Control-Allow-Headers": ["*"]
|
|
230
|
-
// },
|
|
231
|
-
// "status_code": 204
|
|
232
|
-
// }
|
|
233
|
-
// ]
|
|
234
|
-
// },
|
|
235
|
-
// {
|
|
236
|
-
// "match": [{ "host": ["pinokio.localhost"] }],
|
|
237
|
-
// "handle": [
|
|
238
|
-
// {
|
|
239
|
-
// "handler": "reverse_proxy",
|
|
240
|
-
// "upstreams": [{ "dial": "localhost:42000" }]
|
|
241
|
-
// }
|
|
242
|
-
// ]
|
|
243
|
-
// },
|
|
244
|
-
// {
|
|
245
|
-
// "match": [{ "host": ["l.pinokio.localhost"] }],
|
|
246
|
-
// "handle": [
|
|
247
|
-
// {
|
|
248
|
-
// "handler": "reverse_proxy",
|
|
249
|
-
// "upstreams": [{ "dial": "localhost:1234" }]
|
|
250
|
-
// }
|
|
251
|
-
// ]
|
|
252
|
-
// },
|
|
253
|
-
// {
|
|
254
|
-
// "match": [{ "host": ["a.pinokio.localhost"] }],
|
|
255
|
-
// "handle": [
|
|
256
|
-
// {
|
|
257
|
-
// "handler": "reverse_proxy",
|
|
258
|
-
// "upstreams": [{ "dial": "localhost:7860" }]
|
|
259
|
-
// }
|
|
260
|
-
// ]
|
|
261
|
-
// },
|
|
262
|
-
// {
|
|
263
|
-
// "match": [{ "host": ["b.pinokio.localhost"] }],
|
|
264
|
-
// "handle": [
|
|
265
|
-
// {
|
|
266
|
-
// "handler": "reverse_proxy",
|
|
267
|
-
// "upstreams": [{ "dial": "localhost:7861" }]
|
|
268
|
-
// }
|
|
269
|
-
// ]
|
|
270
|
-
// },
|
|
271
|
-
// {
|
|
272
|
-
// "match": [{ "host": ["c.pinokio.localhost"] }],
|
|
273
|
-
// "handle": [
|
|
274
|
-
// {
|
|
275
|
-
// "handler": "reverse_proxy",
|
|
276
|
-
// "upstreams": [{ "dial": "localhost:7862" }]
|
|
277
|
-
// }
|
|
278
|
-
// ]
|
|
279
|
-
// }
|
|
280
|
-
// ]
|
|
281
|
-
// }
|
|
282
|
-
// }
|
|
283
|
-
// },
|
|
284
|
-
//// "tls": {
|
|
285
|
-
//// "automation": {
|
|
286
|
-
//// "policies": [
|
|
287
|
-
//// {
|
|
288
|
-
//// "subjects": [
|
|
289
|
-
//// "pinokio.localhost",
|
|
290
|
-
//// "a.pinokio.localhost",
|
|
291
|
-
//// "b.pinokio.localhost",
|
|
292
|
-
//// "c.pinokio.localhost"
|
|
293
|
-
//// ],
|
|
294
|
-
//// "issuers": [
|
|
295
|
-
//// {
|
|
296
|
-
//// "module": "internal"
|
|
297
|
-
//// }
|
|
298
|
-
//// ]
|
|
299
|
-
//// }
|
|
300
|
-
//// ]
|
|
301
|
-
//// }
|
|
302
|
-
//// }
|
|
303
|
-
// }
|
|
304
|
-
// }
|
|
305
|
-
//
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
// console.log("Make request to caddy", config)
|
|
310
|
-
// let response = await axios.post('http://127.0.0.1:2019/load', config, {
|
|
311
|
-
// headers: { 'Content-Type': 'application/json' }
|
|
312
|
-
// }).catch((e) => {
|
|
313
|
-
// console.log("EEEEEEEEEEEEE", e)
|
|
314
|
-
// })
|
|
315
|
-
// console.log("Caddy Response", { response })
|
|
316
48
|
}
|
|
317
49
|
async install(req, ondata, kernel, id) {
|
|
318
50
|
await this.kernel.bin.exec({
|
|
@@ -328,7 +60,6 @@ class Caddy {
|
|
|
328
60
|
path: this.kernel.homedir,
|
|
329
61
|
}, (e) => {
|
|
330
62
|
resolve()
|
|
331
|
-
console.log("[CADDY] " + e.cleaned)
|
|
332
63
|
if (!resolved) {
|
|
333
64
|
if (/endpoint started/i.test(e.cleaned)) {
|
|
334
65
|
console.log("######### match")
|
package/kernel/index.js
CHANGED
|
@@ -33,6 +33,7 @@ const Proto = require('./prototype')
|
|
|
33
33
|
const Router = require("./router")
|
|
34
34
|
const Procs = require('./procs')
|
|
35
35
|
const Peer = require('./peer')
|
|
36
|
+
const kill = require('./tree-kill');
|
|
36
37
|
const VARS = {
|
|
37
38
|
pip: {
|
|
38
39
|
install: {
|
|
@@ -79,16 +80,16 @@ class Kernel {
|
|
|
79
80
|
this.jsdom = jsdom
|
|
80
81
|
this.exposed = {}
|
|
81
82
|
this.envs = {}
|
|
82
|
-
this.info = new Info(this)
|
|
83
|
-
this.pipe = new Pipe(this)
|
|
84
|
-
this.proto = new Proto(this)
|
|
85
|
-
this.processes = new Procs()
|
|
86
|
-
this.kv = new KV(this)
|
|
87
|
-
this.cloudflare = new Cloudflare()
|
|
83
|
+
// this.info = new Info(this)
|
|
84
|
+
// this.pipe = new Pipe(this)
|
|
85
|
+
// this.proto = new Proto(this)
|
|
86
|
+
// this.processes = new Procs()
|
|
87
|
+
// this.kv = new KV(this)
|
|
88
|
+
// this.cloudflare = new Cloudflare()
|
|
89
|
+
// this.peer = new Peer()
|
|
88
90
|
this.shellpath = shellPath.sync()
|
|
89
91
|
|
|
90
92
|
|
|
91
|
-
this.peer = new Peer()
|
|
92
93
|
}
|
|
93
94
|
/*
|
|
94
95
|
kernel.env() => return the system environment
|
|
@@ -480,12 +481,35 @@ class Kernel {
|
|
|
480
481
|
}
|
|
481
482
|
}
|
|
482
483
|
async init(options) {
|
|
484
|
+
|
|
483
485
|
let home = this.store.get("home")
|
|
484
486
|
|
|
485
487
|
// reset shells if they exist
|
|
488
|
+
console.log("KERNEL INIT")
|
|
486
489
|
if (this.shell) {
|
|
490
|
+
console.log("> shell reset")
|
|
487
491
|
this.shell.reset()
|
|
488
492
|
}
|
|
493
|
+
if (this.peer) {
|
|
494
|
+
console.log("> peer stop")
|
|
495
|
+
this.peer.stop()
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// kill all processes just in case
|
|
499
|
+
await new Promise((resolve, reject) => {
|
|
500
|
+
kill(process.pid, 'SIGKILL', () => {
|
|
501
|
+
console.log("child procs killed for", process.pid)
|
|
502
|
+
resolve()
|
|
503
|
+
});
|
|
504
|
+
})
|
|
505
|
+
|
|
506
|
+
this.info = new Info(this)
|
|
507
|
+
this.pipe = new Pipe(this)
|
|
508
|
+
this.proto = new Proto(this)
|
|
509
|
+
this.processes = new Procs()
|
|
510
|
+
this.kv = new KV(this)
|
|
511
|
+
this.cloudflare = new Cloudflare()
|
|
512
|
+
this.peer = new Peer()
|
|
489
513
|
|
|
490
514
|
this.homedir = home
|
|
491
515
|
|
package/kernel/loader.js
CHANGED
|
@@ -6,6 +6,14 @@ const clearModule = require('clear-module');
|
|
|
6
6
|
|
|
7
7
|
class Loader {
|
|
8
8
|
async load(_path) {
|
|
9
|
+
|
|
10
|
+
let exists = await new Promise(r=>fs.access(_path, fs.constants.F_OK, e => r(!e)))
|
|
11
|
+
if (!exists) {
|
|
12
|
+
console.log(`[load] ${_path} does not exist`)
|
|
13
|
+
return { resolved: null }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
9
17
|
let resolved
|
|
10
18
|
let dirname
|
|
11
19
|
let extension = path.extname(_path)
|
package/kernel/peer.js
CHANGED
|
@@ -1,80 +1,69 @@
|
|
|
1
1
|
const dgram = require('dgram');
|
|
2
2
|
const axios = require('axios');
|
|
3
3
|
const os = require('os')
|
|
4
|
+
const Environment = require("./environment")
|
|
4
5
|
class PeerDiscovery {
|
|
5
6
|
constructor(port = 41234, message = 'ping', interval = 1000) {
|
|
6
7
|
this.port = port;
|
|
7
8
|
this.message = Buffer.from(message);
|
|
8
9
|
this.interval = interval;
|
|
9
10
|
this.peers = new Set();
|
|
10
|
-
this.name = os.userInfo().username
|
|
11
11
|
this.host = this._getLocalIPAddress()
|
|
12
12
|
this.default_port = 42000
|
|
13
13
|
// this.start();
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!this.peers.has(ip)) {
|
|
25
|
-
console.log(`Discovered peer: ${ip}`);
|
|
26
|
-
this.peers.add(ip);
|
|
27
|
-
this.refresh()
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
});
|
|
15
|
+
stop() {
|
|
16
|
+
if (this.socket) {
|
|
17
|
+
console.log("peer stop")
|
|
18
|
+
clearInterval(this.interval)
|
|
19
|
+
this.socket.close()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async start(kernel) {
|
|
23
|
+
let env = await Environment.get(kernel.homedir)
|
|
31
24
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.
|
|
25
|
+
// by default expose to the local network
|
|
26
|
+
this.active = false
|
|
27
|
+
// if PINOKIO_NETWORK_SHARE is 0 or false, turn it off
|
|
28
|
+
if (env && env.PINOKIO_NETWORK_ACTIVE && (env.PINOKIO_NETWORK_ACTIVE==="1" || env.PINOKIO_NETWORK_ACTIVE.toLowerCase()==="true")) {
|
|
29
|
+
this.active = true
|
|
30
|
+
}
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
this.name = os.userInfo().username
|
|
33
|
+
if (env && env.PINOKIO_NETWORK_NAME && env.PINOKIO_NETWORK_NAME.length > 0) {
|
|
34
|
+
this.name = env.PINOKIO_NETWORK_NAME
|
|
35
|
+
}
|
|
42
36
|
|
|
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
|
-
// this.refresh([peer])
|
|
74
|
-
// }
|
|
75
|
-
// }
|
|
76
|
-
}, this.interval);
|
|
77
|
-
});
|
|
37
|
+
if (this.active) {
|
|
38
|
+
// Listen for incoming pings
|
|
39
|
+
console.log("kernel.peer start")
|
|
40
|
+
this.socket = dgram.createSocket('udp4');
|
|
41
|
+
this.socket.on('message', (msg, rinfo) => {
|
|
42
|
+
console.log("peer message", { msg, rinfo })
|
|
43
|
+
const ip = rinfo.address;
|
|
44
|
+
console.log({rinfo})
|
|
45
|
+
if (msg.toString() === this.message.toString() && this._isLocalLAN(ip)) {
|
|
46
|
+
if (!this.peers.has(ip)) {
|
|
47
|
+
console.log(`Discovered peer: ${ip}`);
|
|
48
|
+
this.peers.add(ip);
|
|
49
|
+
this.refresh()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Enable broadcast
|
|
55
|
+
console.log("binding socket")
|
|
56
|
+
this.socket.bind(this.port, () => {
|
|
57
|
+
console.log("socket bound")
|
|
58
|
+
this.socket.setBroadcast(true);
|
|
59
|
+
|
|
60
|
+
// Send broadcast pings every interval
|
|
61
|
+
this.interval = setInterval(() => {
|
|
62
|
+
console.log("send message to peers")
|
|
63
|
+
this.socket.send(this.message, 0, this.message.length, this.port, '255.255.255.255');
|
|
64
|
+
}, this.interval);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
78
67
|
}
|
|
79
68
|
async _refresh(host) {
|
|
80
69
|
try {
|
|
@@ -99,35 +88,39 @@ class PeerDiscovery {
|
|
|
99
88
|
}
|
|
100
89
|
// notify peers to refresh my info
|
|
101
90
|
async notify_peers() {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
91
|
+
if (this.active) {
|
|
92
|
+
let res = await Promise.all(Array.from(this.peers).map((host) => {
|
|
93
|
+
return this._broadcast(host)
|
|
94
|
+
}))
|
|
95
|
+
return res
|
|
96
|
+
}
|
|
106
97
|
}
|
|
107
98
|
// refresh peer info
|
|
108
99
|
async refresh(peers) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
let
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
100
|
+
if (this.active) {
|
|
101
|
+
let refresh_peers
|
|
102
|
+
if (peers) {
|
|
103
|
+
refresh_peers = peers
|
|
104
|
+
} else {
|
|
105
|
+
this.info = {}
|
|
106
|
+
refresh_peers = Array.from(this.peers)
|
|
107
|
+
}
|
|
108
|
+
let peer_info = await Promise.all(refresh_peers.map((host) => {
|
|
109
|
+
return this._refresh(host)
|
|
110
|
+
}))
|
|
111
|
+
console.log({ peer_info })
|
|
112
|
+
for(let i=0; i<peer_info.length; i++) {
|
|
113
|
+
let peer = peer_info[i]
|
|
114
|
+
if (peer) {
|
|
115
|
+
this.info[peer.host] = {
|
|
116
|
+
host: peer.host,
|
|
117
|
+
...peer
|
|
118
|
+
}
|
|
126
119
|
}
|
|
127
120
|
}
|
|
121
|
+
console.log("REFRESH", this.info)
|
|
122
|
+
return this.info
|
|
128
123
|
}
|
|
129
|
-
console.log("REFRESH", this.info)
|
|
130
|
-
return this.info
|
|
131
124
|
}
|
|
132
125
|
_isLocalLAN(ip) {
|
|
133
126
|
return ip.startsWith('192.168.');
|
package/kernel/router/index.js
CHANGED
|
@@ -198,7 +198,7 @@ class Router {
|
|
|
198
198
|
let response = await axios.post('http://127.0.0.1:2019/load', this.config, {
|
|
199
199
|
headers: { 'Content-Type': 'application/json' }
|
|
200
200
|
}).catch((e) => {
|
|
201
|
-
console.log("EEEEEEEEEEEEE", e)
|
|
201
|
+
console.log("EEEEEEEEEEEEE", e.message)
|
|
202
202
|
})
|
|
203
203
|
console.log("Caddy Response", { response })
|
|
204
204
|
}
|
package/kernel/shell.js
CHANGED
|
@@ -2,7 +2,7 @@ const { Terminal } = require('xterm-headless');
|
|
|
2
2
|
const { SerializeAddon } = require("xterm-addon-serialize");
|
|
3
3
|
const sanitize = require("sanitize-filename");
|
|
4
4
|
const YAML = require('yaml')
|
|
5
|
-
const kill = require('tree-kill');
|
|
5
|
+
const kill = require('./tree-kill');
|
|
6
6
|
const fastq = require('fastq')
|
|
7
7
|
const { v4: uuidv4 } = require('uuid');
|
|
8
8
|
const os = require('os');
|
|
@@ -251,6 +251,7 @@ class Shell {
|
|
|
251
251
|
this.ondata({ raw: `\r\n████\r\n██ Starting Shell ${this.id}\r\n` })
|
|
252
252
|
|
|
253
253
|
|
|
254
|
+
this.params = params
|
|
254
255
|
|
|
255
256
|
// 3. path => path can be http, relative, absolute
|
|
256
257
|
this.path = params.path
|
|
@@ -258,6 +259,7 @@ class Shell {
|
|
|
258
259
|
// automatically add self to the shells registry
|
|
259
260
|
this.kernel.shell.add(this)
|
|
260
261
|
|
|
262
|
+
|
|
261
263
|
if (params.sudo) {
|
|
262
264
|
let options = {
|
|
263
265
|
name: "Pinokio",
|
|
@@ -977,23 +979,30 @@ class Shell {
|
|
|
977
979
|
this.queue.killAndDrain()
|
|
978
980
|
if (this.ptyProcess) {
|
|
979
981
|
if (cb) {
|
|
980
|
-
console.log("tree kill", this.ptyProcess.pid)
|
|
981
982
|
kill(this.ptyProcess.pid, 'SIGKILL', () => {
|
|
983
|
+
console.log("child procs killed for", this.ptyProcess.pid)
|
|
982
984
|
this.ptyProcess.kill()
|
|
983
985
|
this.ptyProcess = undefined
|
|
986
|
+
// automatically remove the shell from this.kernel.shells
|
|
987
|
+
this.kernel.shell.rm(this.id)
|
|
988
|
+
this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
|
|
984
989
|
cb()
|
|
985
990
|
});
|
|
986
991
|
} else {
|
|
987
|
-
console.log("tree kill", this.ptyProcess.pid)
|
|
988
992
|
kill(this.ptyProcess.pid, 'SIGKILL');
|
|
993
|
+
console.log("child procs killed for", this.ptyProcess.pid)
|
|
989
994
|
this.ptyProcess.kill()
|
|
990
995
|
this.ptyProcess = undefined
|
|
996
|
+
// automatically remove the shell from this.kernel.shells
|
|
997
|
+
this.kernel.shell.rm(this.id)
|
|
998
|
+
this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
|
|
991
999
|
}
|
|
1000
|
+
} else {
|
|
1001
|
+
// // automatically remove the shell from this.kernel.shells
|
|
1002
|
+
this.kernel.shell.rm(this.id)
|
|
1003
|
+
this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
|
|
992
1004
|
}
|
|
993
1005
|
|
|
994
|
-
// automatically remove the shell from this.kernel.shells
|
|
995
|
-
this.kernel.shell.rm(this.id)
|
|
996
|
-
this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
|
|
997
1006
|
|
|
998
1007
|
}
|
|
999
1008
|
log() {
|
package/kernel/shells.js
CHANGED
|
@@ -362,7 +362,7 @@ class Shells {
|
|
|
362
362
|
let info = this.shells.map((s) => {
|
|
363
363
|
return { id: s.id, group: s.group, cmd: s.cmd }
|
|
364
364
|
})
|
|
365
|
-
if (this.shells) {
|
|
365
|
+
if (this.shells && this.shells.length > 0) {
|
|
366
366
|
let shells = []
|
|
367
367
|
for(let i=0; i<this.shells.length; i++) {
|
|
368
368
|
shells.push(this.shells[i])
|
|
@@ -381,6 +381,11 @@ class Shells {
|
|
|
381
381
|
shell.kill("", true)
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
|
+
} else {
|
|
385
|
+
console.log("no shells running")
|
|
386
|
+
if (cb) {
|
|
387
|
+
cb()
|
|
388
|
+
}
|
|
384
389
|
}
|
|
385
390
|
}
|
|
386
391
|
kill(request, message) {
|
|
@@ -448,7 +453,6 @@ class Shells {
|
|
|
448
453
|
}
|
|
449
454
|
}
|
|
450
455
|
rm(id) {
|
|
451
|
-
console.log("SHELL RM", id)
|
|
452
456
|
for(let i=0; i<this.shells.length; i++) {
|
|
453
457
|
let shell = this.shells[i]
|
|
454
458
|
if (shell.id === id) {
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var childProcess = require('child_process');
|
|
4
|
+
var spawn = childProcess.spawn;
|
|
5
|
+
var exec = childProcess.exec;
|
|
6
|
+
var execSync = childProcess.execSync;
|
|
7
|
+
|
|
8
|
+
module.exports = function (pid, signal, callback) {
|
|
9
|
+
if (typeof signal === 'function' && callback === undefined) {
|
|
10
|
+
callback = signal;
|
|
11
|
+
signal = undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pid = parseInt(pid);
|
|
15
|
+
if (Number.isNaN(pid)) {
|
|
16
|
+
if (callback) {
|
|
17
|
+
return callback(new Error("pid must be a number"));
|
|
18
|
+
} else {
|
|
19
|
+
throw new Error("pid must be a number");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var tree = {};
|
|
24
|
+
var pidsToProcess = {};
|
|
25
|
+
tree[pid] = [];
|
|
26
|
+
pidsToProcess[pid] = 1;
|
|
27
|
+
|
|
28
|
+
switch (process.platform) {
|
|
29
|
+
case 'win32':
|
|
30
|
+
exec('taskkill /pid ' + pid + ' /T /F', callback);
|
|
31
|
+
break;
|
|
32
|
+
case 'darwin':
|
|
33
|
+
buildProcessTreeMacOS(pid, tree, pidsToProcess, function () {
|
|
34
|
+
killAll(tree, signal, callback);
|
|
35
|
+
});
|
|
36
|
+
break;
|
|
37
|
+
// case 'sunos':
|
|
38
|
+
// buildProcessTreeSunOS(pid, tree, pidsToProcess, function () {
|
|
39
|
+
// killAll(tree, signal, callback);
|
|
40
|
+
// });
|
|
41
|
+
// break;
|
|
42
|
+
default: // Linux
|
|
43
|
+
buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
|
|
44
|
+
return spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid]);
|
|
45
|
+
}, function () {
|
|
46
|
+
killAll(tree, signal, callback);
|
|
47
|
+
});
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
function killAll (tree, signal, callback) {
|
|
53
|
+
var killed = {};
|
|
54
|
+
try {
|
|
55
|
+
Object.keys(tree).forEach(function (pid) {
|
|
56
|
+
tree[pid].forEach(function (pidpid) {
|
|
57
|
+
if (!killed[pidpid]) {
|
|
58
|
+
killPid(pidpid, signal);
|
|
59
|
+
killed[pidpid] = 1;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// exception: if the pid is the current process,
|
|
63
|
+
// kill all subprocesses, but do NOT kill the current process
|
|
64
|
+
if (String(pid) === String(process.pid)) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
if (!killed[pid]) {
|
|
68
|
+
killPid(pid, signal);
|
|
69
|
+
killed[pid] = 1;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
} catch (err) {
|
|
73
|
+
if (callback) {
|
|
74
|
+
return callback(err);
|
|
75
|
+
} else {
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (callback) {
|
|
80
|
+
return callback();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function killPid(pid, signal) {
|
|
85
|
+
try {
|
|
86
|
+
process.kill(parseInt(pid, 10), signal);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
if (err.code !== 'ESRCH') throw err;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesList, cb) {
|
|
94
|
+
var ps = spawnChildProcessesList(parentPid);
|
|
95
|
+
var allData = '';
|
|
96
|
+
ps.stdout.on('data', function (data) {
|
|
97
|
+
var data = data.toString('ascii');
|
|
98
|
+
allData += data;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
var onClose = function (code) {
|
|
102
|
+
delete pidsToProcess[parentPid];
|
|
103
|
+
|
|
104
|
+
if (code != 0) {
|
|
105
|
+
// no more parent processes
|
|
106
|
+
if (Object.keys(pidsToProcess).length == 0) {
|
|
107
|
+
cb();
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
allData.match(/\d+/g).forEach(function (pid) {
|
|
113
|
+
pid = parseInt(pid, 10);
|
|
114
|
+
tree[parentPid].push(pid);
|
|
115
|
+
tree[pid] = [];
|
|
116
|
+
pidsToProcess[pid] = 1;
|
|
117
|
+
buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb);
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
ps.on('close', onClose);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function buildProcessTreeMacOS(parentPid, tree, pidsToProcess, cb) {
|
|
125
|
+
try {
|
|
126
|
+
let stdout = '';
|
|
127
|
+
try {
|
|
128
|
+
stdout = execSync('pgrep -P ' + parentPid, {
|
|
129
|
+
encoding: 'utf8',
|
|
130
|
+
timeout: 2000,
|
|
131
|
+
maxBuffer: 1024 * 1024
|
|
132
|
+
});
|
|
133
|
+
} catch (execError) {
|
|
134
|
+
if (execError.status !== 1) {
|
|
135
|
+
throw execError;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
delete pidsToProcess[parentPid];
|
|
140
|
+
|
|
141
|
+
const childPids = stdout.trim().split('\n').filter(Boolean);
|
|
142
|
+
|
|
143
|
+
if (childPids.length === 0) {
|
|
144
|
+
if (Object.keys(pidsToProcess).length === 0) {
|
|
145
|
+
cb();
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
childPids.forEach(function(pidStr) {
|
|
151
|
+
const pid = parseInt(pidStr, 10);
|
|
152
|
+
if (!isNaN(pid)) {
|
|
153
|
+
tree[parentPid].push(pid);
|
|
154
|
+
tree[pid] = [];
|
|
155
|
+
pidsToProcess[pid] = 1;
|
|
156
|
+
buildProcessTreeMacOS(pid, tree, pidsToProcess, cb);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
} catch (err) {
|
|
160
|
+
delete pidsToProcess[parentPid];
|
|
161
|
+
if (Object.keys(pidsToProcess).length === 0) {
|
|
162
|
+
cb();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinokiod",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.94",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -59,7 +59,6 @@
|
|
|
59
59
|
"sudo-prompt-programfiles-x86": "^9.2.10",
|
|
60
60
|
"symlink-dir": "^5.2.1",
|
|
61
61
|
"systeminformation": "^5.18.4",
|
|
62
|
-
"tree-kill": "^1.2.2",
|
|
63
62
|
"uuid": "^9.0.0",
|
|
64
63
|
"wait-on": "^7.2.0",
|
|
65
64
|
"which": "^5.0.0",
|
package/server/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
|
+
const kill = require('../kernel/tree-kill');
|
|
2
3
|
const portfinder = require('portfinder-cp');
|
|
3
4
|
const proxy = require('express-http-proxy-cp');
|
|
4
5
|
const sudo = require("sudo-prompt-programfiles-x86");
|
|
@@ -2256,6 +2257,8 @@ class Server {
|
|
|
2256
2257
|
}
|
|
2257
2258
|
}
|
|
2258
2259
|
// initialize kernel
|
|
2260
|
+
|
|
2261
|
+
|
|
2259
2262
|
await this.kernel.init({ port: this.port})
|
|
2260
2263
|
|
|
2261
2264
|
|
|
@@ -2678,31 +2681,6 @@ class Server {
|
|
|
2678
2681
|
}
|
|
2679
2682
|
}
|
|
2680
2683
|
console.log({ peers_info })
|
|
2681
|
-
|
|
2682
|
-
// if (this.kernel.processes.info) {
|
|
2683
|
-
// console.log("proc info", this.kernel.processes.info)
|
|
2684
|
-
// list = this.kernel.processes.info.map((item) => {
|
|
2685
|
-
// console.log("item", item)
|
|
2686
|
-
// console.log("item.ip", item.ip)
|
|
2687
|
-
// let internal_port = item.ip.split(":")[1]
|
|
2688
|
-
// let external_port = this.kernel.router.port_mapping[internal_port]
|
|
2689
|
-
// if (external_port) {
|
|
2690
|
-
// let external_ip = `${this.kernel.peer.host}:${external_port}`
|
|
2691
|
-
// console.log({ internal_port, external_port, external_ip })
|
|
2692
|
-
// return {
|
|
2693
|
-
// //proxy: this.kernel.caddy.mapping[item.ip] || [],
|
|
2694
|
-
// router: info[this.kernel.peer.host][external_ip] || [],
|
|
2695
|
-
// external_ip,
|
|
2696
|
-
// ...item
|
|
2697
|
-
// }
|
|
2698
|
-
// } else {
|
|
2699
|
-
// return {
|
|
2700
|
-
// router: [],
|
|
2701
|
-
// ...item
|
|
2702
|
-
// }
|
|
2703
|
-
// }
|
|
2704
|
-
// })
|
|
2705
|
-
// }
|
|
2706
2684
|
|
|
2707
2685
|
let peers = []
|
|
2708
2686
|
for(let host in peers_info) {
|
|
@@ -2714,20 +2692,6 @@ class Server {
|
|
|
2714
2692
|
router: `https://pinokio.${peer_info.name}.localhost/proxy`
|
|
2715
2693
|
})
|
|
2716
2694
|
}
|
|
2717
|
-
|
|
2718
|
-
// let peers = this.kernel.peer.get()
|
|
2719
|
-
// peers = peers.map((x) => {
|
|
2720
|
-
// let account = this.kernel.peer.account(x)
|
|
2721
|
-
// let domain = `https://pinokio.${account}.localhost`
|
|
2722
|
-
// let proxy_page = `https://pinokio.${account}.localhost/proxy`
|
|
2723
|
-
// return {
|
|
2724
|
-
// ip: x,
|
|
2725
|
-
// account,
|
|
2726
|
-
// domain,
|
|
2727
|
-
// proxy_page
|
|
2728
|
-
// }
|
|
2729
|
-
// })
|
|
2730
|
-
|
|
2731
2695
|
let live_proxies = this.kernel.api.proxies["/proxy"]
|
|
2732
2696
|
if (!live_proxies) live_proxies = []
|
|
2733
2697
|
let proxies = []
|
|
@@ -2799,6 +2763,8 @@ class Server {
|
|
|
2799
2763
|
ip: this.kernel.peer.current_ip,
|
|
2800
2764
|
peers,
|
|
2801
2765
|
list,
|
|
2766
|
+
name: this.kernel.peer.name,
|
|
2767
|
+
active: this.kernel.peer.active,
|
|
2802
2768
|
port_mapping: this.kernel.router.port_mapping,
|
|
2803
2769
|
// port_mapping: this.kernel.caddy.port_mapping,
|
|
2804
2770
|
// ip_mapping: this.kernel.caddy.ip_mapping,
|
|
@@ -3905,6 +3871,36 @@ class Server {
|
|
|
3905
3871
|
console.log({ requirements_pending })
|
|
3906
3872
|
res.json({ requirements_pending })
|
|
3907
3873
|
}))
|
|
3874
|
+
this.app.get("/check_peer", ex((req, res) => {
|
|
3875
|
+
if (this.kernel.peer.active) {
|
|
3876
|
+
// if network is active, return success only if the router is up for all of its peers (including itself)
|
|
3877
|
+
console.log({ peer_info: this.kernel.peer.info })
|
|
3878
|
+
let ready = true
|
|
3879
|
+
if (this.kernel.peer.info) {
|
|
3880
|
+
for(let host in this.kernel.peer.info) {
|
|
3881
|
+
let info = this.kernel.peer.info[host]
|
|
3882
|
+
if (info.router && Object.keys(info.router).length > 0) {
|
|
3883
|
+
ready = true
|
|
3884
|
+
} else {
|
|
3885
|
+
ready = false
|
|
3886
|
+
break;
|
|
3887
|
+
}
|
|
3888
|
+
}
|
|
3889
|
+
} else {
|
|
3890
|
+
ready = false;
|
|
3891
|
+
}
|
|
3892
|
+
console.log({ info: this.kernel.peer.info, ready })
|
|
3893
|
+
if (ready) {
|
|
3894
|
+
res.json({ success: true })
|
|
3895
|
+
} else {
|
|
3896
|
+
res.json({ success: false })
|
|
3897
|
+
}
|
|
3898
|
+
} else {
|
|
3899
|
+
// if network is not active, return success immediately (just checking if the server is up)
|
|
3900
|
+
console.log("this.kernel.router.published()")
|
|
3901
|
+
res.json({ success: true })
|
|
3902
|
+
}
|
|
3903
|
+
}))
|
|
3908
3904
|
this.app.get("/check", ex((req, res) => {
|
|
3909
3905
|
res.json({ success: true })
|
|
3910
3906
|
}))
|
|
@@ -3912,6 +3908,16 @@ class Server {
|
|
|
3912
3908
|
console.log("post /restart")
|
|
3913
3909
|
this.start({ debug: this.debug, browser: this.browser })
|
|
3914
3910
|
}))
|
|
3911
|
+
this.app.post("/network", ex(async (req, res) => {
|
|
3912
|
+
if (this.kernel.homedir) {
|
|
3913
|
+
let fullpath = path.resolve(this.kernel.homedir, "ENVIRONMENT")
|
|
3914
|
+
await Util.update_env(fullpath, req.body)
|
|
3915
|
+
res.json({ success: true })
|
|
3916
|
+
} else {
|
|
3917
|
+
res.json({ error: "homedir doesn't exist" })
|
|
3918
|
+
}
|
|
3919
|
+
}))
|
|
3920
|
+
|
|
3915
3921
|
this.app.post("/config", ex(async (req, res) => {
|
|
3916
3922
|
try {
|
|
3917
3923
|
await this.setConfig(req.body)
|
|
@@ -3933,24 +3939,33 @@ class Server {
|
|
|
3933
3939
|
})
|
|
3934
3940
|
});
|
|
3935
3941
|
process.on('SIGINT', () => {
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
} else {
|
|
3942
|
+
//if (this.kernel && this.kernel.shell) {
|
|
3943
|
+
// console.log("shell reset")
|
|
3944
|
+
// this.kernel.shell.reset(() => {
|
|
3945
|
+
// process.exit()
|
|
3946
|
+
// })
|
|
3947
|
+
//} else {
|
|
3948
|
+
// process.exit()
|
|
3949
|
+
//}
|
|
3950
|
+
kill(process.pid, 'SIGKILL', () => {
|
|
3951
|
+
console.log("child procs killed for", process.pid)
|
|
3942
3952
|
process.exit()
|
|
3943
|
-
}
|
|
3953
|
+
});
|
|
3944
3954
|
})
|
|
3955
|
+
|
|
3945
3956
|
process.on('SIGTERM', () => {
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
this.kernel.shell.reset(() => {
|
|
3949
|
-
process.exit()
|
|
3950
|
-
})
|
|
3951
|
-
} else {
|
|
3957
|
+
// if (this.kernel && this.kernel.shell) {
|
|
3958
|
+
// console.log("shell reset")
|
|
3959
|
+
// this.kernel.shell.reset(() => {
|
|
3960
|
+
// process.exit()
|
|
3961
|
+
// })
|
|
3962
|
+
// } else {
|
|
3963
|
+
// process.exit()
|
|
3964
|
+
// }
|
|
3965
|
+
kill(process.pid, 'SIGKILL', () => {
|
|
3966
|
+
console.log("child procs killed for", process.pid)
|
|
3952
3967
|
process.exit()
|
|
3953
|
-
}
|
|
3968
|
+
});
|
|
3954
3969
|
})
|
|
3955
3970
|
// process.on('exit', () => {
|
|
3956
3971
|
// console.log("exit Event")
|
|
@@ -3974,7 +3989,7 @@ class Server {
|
|
|
3974
3989
|
server: this.listening
|
|
3975
3990
|
});
|
|
3976
3991
|
})
|
|
3977
|
-
this.kernel.peer.start()
|
|
3992
|
+
this.kernel.peer.start(this.kernel)
|
|
3978
3993
|
|
|
3979
3994
|
|
|
3980
3995
|
}
|
package/server/views/network.ejs
CHANGED
|
@@ -156,7 +156,9 @@ body.dark .browser-options-row {
|
|
|
156
156
|
padding: 0;
|
|
157
157
|
font-size: 50px;
|
|
158
158
|
letter-spacing: -1px;
|
|
159
|
+
/*
|
|
159
160
|
text-align: center;
|
|
161
|
+
*/
|
|
160
162
|
text-transform: capitalize;
|
|
161
163
|
}
|
|
162
164
|
.header-label-sub h1 {
|
|
@@ -181,7 +183,6 @@ body.dark .browser-options-row {
|
|
|
181
183
|
box-sizing: border-box;
|
|
182
184
|
}
|
|
183
185
|
.container {
|
|
184
|
-
margin-top: 20px;
|
|
185
186
|
display: grid;
|
|
186
187
|
grid-template-columns: repeat(<%=list.length%>, 1fr);
|
|
187
188
|
}
|
|
@@ -194,8 +195,10 @@ body.dark .browser-options-row {
|
|
|
194
195
|
box-sizing: border-box;
|
|
195
196
|
}
|
|
196
197
|
.desc {
|
|
198
|
+
/*
|
|
197
199
|
text-align:center;
|
|
198
|
-
|
|
200
|
+
*/
|
|
201
|
+
padding: 10px 0;
|
|
199
202
|
}
|
|
200
203
|
.container-row table {
|
|
201
204
|
width: 100%;
|
|
@@ -222,6 +225,105 @@ td:first-child, th:first-child {
|
|
|
222
225
|
font-size: 14px;
|
|
223
226
|
padding: 2px;
|
|
224
227
|
}
|
|
228
|
+
|
|
229
|
+
.config {
|
|
230
|
+
background: rgba(0,0,0,0.9);
|
|
231
|
+
color: white;
|
|
232
|
+
padding: 30px;
|
|
233
|
+
text-align: left;
|
|
234
|
+
}
|
|
235
|
+
.config-header {
|
|
236
|
+
}
|
|
237
|
+
.config-body {
|
|
238
|
+
display: flex;
|
|
239
|
+
align-items: flex-end;
|
|
240
|
+
}
|
|
241
|
+
.config .btn {
|
|
242
|
+
font-size: 16px;
|
|
243
|
+
font-weight: bold;
|
|
244
|
+
width: 100px;
|
|
245
|
+
background: royalblue;
|
|
246
|
+
flex-shrink: 0;
|
|
247
|
+
}
|
|
248
|
+
.config-row {
|
|
249
|
+
padding: 10px 20px 0 0;
|
|
250
|
+
}
|
|
251
|
+
.config-row .label {
|
|
252
|
+
padding-bottom: 5px;
|
|
253
|
+
font-weight: bold;
|
|
254
|
+
}
|
|
255
|
+
.config-row input[type=text] {
|
|
256
|
+
padding: 7px;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.switcher {
|
|
260
|
+
position: relative;
|
|
261
|
+
display: inline-block;
|
|
262
|
+
width: 60px;
|
|
263
|
+
height: 34px;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.switcher input {
|
|
267
|
+
opacity: 0;
|
|
268
|
+
width: 0;
|
|
269
|
+
height: 0;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.slider {
|
|
273
|
+
position: absolute;
|
|
274
|
+
cursor: pointer;
|
|
275
|
+
top: 0;
|
|
276
|
+
left: 0;
|
|
277
|
+
right: 0;
|
|
278
|
+
bottom: 0;
|
|
279
|
+
background-color: #ccc;
|
|
280
|
+
-webkit-transition: .4s;
|
|
281
|
+
transition: .4s;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.slider:before {
|
|
285
|
+
position: absolute;
|
|
286
|
+
content: "";
|
|
287
|
+
height: 26px;
|
|
288
|
+
width: 26px;
|
|
289
|
+
left: 4px;
|
|
290
|
+
bottom: 4px;
|
|
291
|
+
background-color: white;
|
|
292
|
+
-webkit-transition: .4s;
|
|
293
|
+
transition: .4s;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
input:checked + .slider {
|
|
297
|
+
/*
|
|
298
|
+
background-color: #2196F3;
|
|
299
|
+
*/
|
|
300
|
+
background-color: royalblue;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
input:focus + .slider {
|
|
304
|
+
box-shadow: 0 0 1px #2196F3;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
input:checked + .slider:before {
|
|
308
|
+
-webkit-transform: translateX(26px);
|
|
309
|
+
-ms-transform: translateX(26px);
|
|
310
|
+
transform: translateX(26px);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* Rounded sliders */
|
|
314
|
+
.slider.round {
|
|
315
|
+
border-radius: 34px;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.slider.round:before {
|
|
319
|
+
border-radius: 50%;
|
|
320
|
+
}
|
|
321
|
+
.loading {
|
|
322
|
+
text-align: center;
|
|
323
|
+
padding: 50px;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
225
327
|
@media only screen and (max-width: 480px) {
|
|
226
328
|
.btn2 {
|
|
227
329
|
padding: 5px;
|
|
@@ -254,8 +356,30 @@ td:first-child, th:first-child {
|
|
|
254
356
|
</h1>
|
|
255
357
|
</header>
|
|
256
358
|
<main>
|
|
257
|
-
<div class='
|
|
258
|
-
|
|
359
|
+
<div class='config'>
|
|
360
|
+
<div class='config-header'>
|
|
361
|
+
<div class='header-label'><i class='fa-solid fa-wifi'></i> Network</div>
|
|
362
|
+
<div class='desc'>Serve Pinokio, installed apps, and even external apps to any device on the same network.</div>
|
|
363
|
+
</div>
|
|
364
|
+
<div class='config-body'>
|
|
365
|
+
<div class='config-row'>
|
|
366
|
+
<div class='label'>Network Name</div>
|
|
367
|
+
<input id='name' type='text' value="<%=name%>">
|
|
368
|
+
</div>
|
|
369
|
+
<div class='config-row'>
|
|
370
|
+
<div class='label'>Network Share</div>
|
|
371
|
+
<label class="switcher">
|
|
372
|
+
<input id='active' type="checkbox" <%=active ? 'checked' : ''%>>
|
|
373
|
+
<span class="slider"></span>
|
|
374
|
+
</label>
|
|
375
|
+
</div>
|
|
376
|
+
<div class='flexible'></div>
|
|
377
|
+
<button class='btn save'>Save</button>
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
<div class='loading hidden'>
|
|
381
|
+
<i class="fa-solid fa-circle-notch fa-spin"></i> Stand by. Do not close this window..
|
|
382
|
+
</div>
|
|
259
383
|
<!--
|
|
260
384
|
<div class='header-container'>
|
|
261
385
|
<div class='header-label-sub'><i class="fa-solid fa-podcast"></i> Local Network</div>
|
|
@@ -393,8 +517,57 @@ td:first-child, th:first-child {
|
|
|
393
517
|
</div>
|
|
394
518
|
</main>
|
|
395
519
|
<script>
|
|
396
|
-
document.querySelector("
|
|
520
|
+
document.querySelector("main").addEventListener("click", async (e) => {
|
|
397
521
|
let target
|
|
522
|
+
|
|
523
|
+
if (e.target.classList.contains("save")) {
|
|
524
|
+
target = e.target
|
|
525
|
+
} else {
|
|
526
|
+
target = e.target.closest(".save")
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (target) {
|
|
530
|
+
let body = {
|
|
531
|
+
PINOKIO_NETWORK_NAME: document.querySelector("#name").value,
|
|
532
|
+
PINOKIO_NETWORK_ACTIVE: (document.querySelector("#active").checked ? "1": "0")
|
|
533
|
+
}
|
|
534
|
+
console.log(body)
|
|
535
|
+
debugger
|
|
536
|
+
let r = await fetch("/network", {
|
|
537
|
+
method: "post",
|
|
538
|
+
headers: { "Content-Type": "application/json" },
|
|
539
|
+
body: JSON.stringify(body)
|
|
540
|
+
}).then((res) => {
|
|
541
|
+
return res.json()
|
|
542
|
+
})
|
|
543
|
+
if (r.success) {
|
|
544
|
+
//alert("Successfully updated the pinokio home to " + val)
|
|
545
|
+
document.querySelector(".loading").classList.remove("hidden")
|
|
546
|
+
document.querySelector(".save").classList.add("hidden")
|
|
547
|
+
fetch("/restart", {
|
|
548
|
+
method: "post"
|
|
549
|
+
}, () => {
|
|
550
|
+
})
|
|
551
|
+
setInterval(async () => {
|
|
552
|
+
try {
|
|
553
|
+
let res = await fetch("/check_peer").then((res) => {
|
|
554
|
+
return res.json()
|
|
555
|
+
})
|
|
556
|
+
if (res.success) {
|
|
557
|
+
document.querySelector(".loading").classList.add("hidden")
|
|
558
|
+
location.href = location.href
|
|
559
|
+
}
|
|
560
|
+
} catch (e) {
|
|
561
|
+
console.log(e)
|
|
562
|
+
}
|
|
563
|
+
}, 1000)
|
|
564
|
+
} else if (r.error) {
|
|
565
|
+
alert(r.error)
|
|
566
|
+
location.href = location.href
|
|
567
|
+
}
|
|
568
|
+
return
|
|
569
|
+
}
|
|
570
|
+
|
|
398
571
|
if (e.target.classList.contains("stop")) {
|
|
399
572
|
target = e.target
|
|
400
573
|
} else {
|
|
@@ -467,6 +640,7 @@ document.querySelector(".container").addEventListener("click", async (e) => {
|
|
|
467
640
|
})
|
|
468
641
|
}
|
|
469
642
|
|
|
643
|
+
|
|
470
644
|
})
|
|
471
645
|
if (document.querySelector("#back")) {
|
|
472
646
|
document.querySelector("#back").addEventListener("click", (e) => {
|