pinokiod 3.8.23 → 3.8.25

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.
@@ -186,6 +186,7 @@ class Api {
186
186
  type: "disconnect"
187
187
  })
188
188
  console.timeEnd("stop 4")
189
+ await this.kernel.caddy.update()
189
190
  return true
190
191
  }
191
192
  async startScripts() {
@@ -1073,6 +1074,7 @@ class Api {
1073
1074
  })
1074
1075
  }
1075
1076
  }
1077
+ await this.kernel.caddy.update()
1076
1078
  } catch (e) {
1077
1079
  ondata({ raw: e.toString() })
1078
1080
  }
@@ -1,5 +1,4 @@
1
1
  const axios = require('axios')
2
- const selfsigned = require('selfsigned')
3
2
  const fs = require('fs')
4
3
 
5
4
  class Caddy {
@@ -44,273 +43,274 @@ class Caddy {
44
43
  })
45
44
  })
46
45
  }
47
- const config = {
48
- "apps": {
49
- "http": {
50
- "servers": {
51
- "main": {
52
- "listen": ["127.0.0.1:443"],
53
- "routes": [
54
- {
55
- "match": [{ "method": ["OPTIONS"] }],
56
- "handle": [
57
- {
58
- "handler": "headers",
59
- "response": {
60
- "set": {
61
- "Access-Control-Allow-Origin": ["*"],
62
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
63
- "Access-Control-Allow-Headers": ["*"],
64
- "Vary": ["Origin"]
65
- }
66
- }
67
- },
68
- {
69
- "handler": "static_response",
70
- "status_code": 204
71
- }
72
- ]
73
- },
74
- {
75
- "match": [{ "host": ["pinokio.localhost"] }],
76
- "handle": [
77
- {
78
- "handler": "reverse_proxy",
79
- "upstreams": [{ "dial": "127.0.0.1:42000" }]
80
- },
81
- {
82
- "handler": "headers",
83
- "response": {
84
- "set": {
85
- "Access-Control-Allow-Origin": ["*"],
86
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
87
- "Access-Control-Allow-Headers": ["*"],
88
- "Vary": ["Origin"]
89
- }
90
- }
91
- }
92
- ]
93
- },
94
- {
95
- "match": [{ "host": ["l.pinokio.localhost"] }],
96
- "handle": [
97
- {
98
- "handler": "reverse_proxy",
99
- "upstreams": [{ "dial": "127.0.0.1:1234" }]
100
- },
101
- {
102
- "handler": "headers",
103
- "response": {
104
- "set": {
105
- "Access-Control-Allow-Origin": ["*"],
106
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
107
- "Access-Control-Allow-Headers": ["*"],
108
- "Vary": ["Origin"]
109
- }
110
- }
111
- }
112
- ]
113
- },
114
- {
115
- "match": [{ "host": ["o.pinokio.localhost"] }],
116
- "handle": [
117
- {
118
- "handler": "reverse_proxy",
119
- "upstreams": [{ "dial": "127.0.0.1:11434" }]
120
- },
121
- {
122
- "handler": "headers",
123
- "response": {
124
- "set": {
125
- "Access-Control-Allow-Origin": ["*"],
126
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
127
- "Access-Control-Allow-Headers": ["*"],
128
- "Vary": ["Origin"]
129
- }
130
- }
131
- }
132
- ]
133
- },
134
- {
135
- "match": [{ "host": ["a.pinokio.localhost"] }],
136
- "handle": [
137
- {
138
- "handler": "reverse_proxy",
139
- "upstreams": [{ "dial": "127.0.0.1:7860" }]
140
- },
141
- {
142
- "handler": "headers",
143
- "response": {
144
- "set": {
145
- "Access-Control-Allow-Origin": ["*"],
146
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
147
- "Access-Control-Allow-Headers": ["*"],
148
- "Vary": ["Origin"]
149
- }
150
- }
151
- }
152
- ]
153
- },
154
- {
155
- "match": [{ "host": ["b.pinokio.localhost"] }],
156
- "handle": [
157
- {
158
- "handler": "reverse_proxy",
159
- "upstreams": [{ "dial": "127.0.0.1:7861" }]
160
- },
161
- {
162
- "handler": "headers",
163
- "response": {
164
- "set": {
165
- "Access-Control-Allow-Origin": ["*"],
166
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
167
- "Access-Control-Allow-Headers": ["*"],
168
- "Vary": ["Origin"]
169
- }
170
- }
171
- }
172
- ]
173
- },
174
- {
175
- "match": [{ "host": ["c.pinokio.localhost"] }],
176
- "handle": [
177
- {
178
- "handler": "reverse_proxy",
179
- "upstreams": [{ "dial": "127.0.0.1:7862" }]
180
- },
181
- {
182
- "handler": "headers",
183
- "response": {
184
- "set": {
185
- "Access-Control-Allow-Origin": ["*"],
186
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
187
- "Access-Control-Allow-Headers": ["*"],
188
- "Vary": ["Origin"]
189
- }
190
- }
191
- }
192
- ]
193
- }
194
- ]
195
- }
196
- }
197
- }
198
- }
199
- }
200
-
201
- const config2 = {
202
- "apps": {
203
- "http": {
204
- "servers": {
205
- "main": {
206
- "listen": [":443"],
207
- //"listen": [":80"],
208
- "handle_response": [
209
- {
210
- "handler": "headers",
211
- "headers": {
212
- "Access-Control-Allow-Origin": ["*"],
213
- "Access-Control-Allow-Methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"],
214
- "Access-Control-Allow-Headers": ["*"]
215
- }
216
- }
217
- ],
218
- "routes": [
219
- {
220
- "match": [{ "method": ["OPTIONS"] }],
221
- "handle": [
222
- {
223
- "handler": "static_response",
224
- "headers": {
225
- "Access-Control-Allow-Origin": ["*"],
226
- "Access-Control-Allow-Methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"],
227
- "Access-Control-Allow-Headers": ["*"]
228
- },
229
- "status_code": 204
230
- }
231
- ]
232
- },
233
- {
234
- "match": [{ "host": ["pinokio.localhost"] }],
235
- "handle": [
236
- {
237
- "handler": "reverse_proxy",
238
- "upstreams": [{ "dial": "localhost:42000" }]
239
- }
240
- ]
241
- },
242
- {
243
- "match": [{ "host": ["l.pinokio.localhost"] }],
244
- "handle": [
245
- {
246
- "handler": "reverse_proxy",
247
- "upstreams": [{ "dial": "localhost:1234" }]
248
- }
249
- ]
250
- },
251
- {
252
- "match": [{ "host": ["a.pinokio.localhost"] }],
253
- "handle": [
254
- {
255
- "handler": "reverse_proxy",
256
- "upstreams": [{ "dial": "localhost:7860" }]
257
- }
258
- ]
259
- },
260
- {
261
- "match": [{ "host": ["b.pinokio.localhost"] }],
262
- "handle": [
263
- {
264
- "handler": "reverse_proxy",
265
- "upstreams": [{ "dial": "localhost:7861" }]
266
- }
267
- ]
268
- },
269
- {
270
- "match": [{ "host": ["c.pinokio.localhost"] }],
271
- "handle": [
272
- {
273
- "handler": "reverse_proxy",
274
- "upstreams": [{ "dial": "localhost:7862" }]
275
- }
276
- ]
277
- }
278
- ]
279
- }
280
- }
281
- },
282
- // "tls": {
283
- // "automation": {
284
- // "policies": [
285
- // {
286
- // "subjects": [
287
- // "pinokio.localhost",
288
- // "a.pinokio.localhost",
289
- // "b.pinokio.localhost",
290
- // "c.pinokio.localhost"
291
- // ],
292
- // "issuers": [
293
- // {
294
- // "module": "internal"
295
- // }
296
- // ]
297
- // }
298
- // ]
46
+ await this.kernel.caddy.update()
47
+ // const config = {
48
+ // "apps": {
49
+ // "http": {
50
+ // "servers": {
51
+ // "main": {
52
+ // "listen": ["127.0.0.1:443"],
53
+ // "routes": [
54
+ // {
55
+ // "match": [{ "method": ["OPTIONS"] }],
56
+ // "handle": [
57
+ // {
58
+ // "handler": "headers",
59
+ // "response": {
60
+ // "set": {
61
+ // "Access-Control-Allow-Origin": ["*"],
62
+ // "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
63
+ // "Access-Control-Allow-Headers": ["*"],
64
+ // "Vary": ["Origin"]
65
+ // }
66
+ // }
67
+ // },
68
+ // {
69
+ // "handler": "static_response",
70
+ // "status_code": 204
71
+ // }
72
+ // ]
73
+ // },
74
+ // {
75
+ // "match": [{ "host": ["pinokio.localhost"] }],
76
+ // "handle": [
77
+ // {
78
+ // "handler": "reverse_proxy",
79
+ // "upstreams": [{ "dial": "127.0.0.1:42000" }]
80
+ // },
81
+ // {
82
+ // "handler": "headers",
83
+ // "response": {
84
+ // "set": {
85
+ // "Access-Control-Allow-Origin": ["*"],
86
+ // "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
87
+ // "Access-Control-Allow-Headers": ["*"],
88
+ // "Vary": ["Origin"]
89
+ // }
90
+ // }
91
+ // }
92
+ // ]
93
+ // },
94
+ // {
95
+ // "match": [{ "host": ["l.pinokio.localhost"] }],
96
+ // "handle": [
97
+ // {
98
+ // "handler": "reverse_proxy",
99
+ // "upstreams": [{ "dial": "127.0.0.1:1234" }]
100
+ // },
101
+ // {
102
+ // "handler": "headers",
103
+ // "response": {
104
+ // "set": {
105
+ // "Access-Control-Allow-Origin": ["*"],
106
+ // "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
107
+ // "Access-Control-Allow-Headers": ["*"],
108
+ // "Vary": ["Origin"]
109
+ // }
110
+ // }
111
+ // }
112
+ // ]
113
+ // },
114
+ // {
115
+ // "match": [{ "host": ["o.pinokio.localhost"] }],
116
+ // "handle": [
117
+ // {
118
+ // "handler": "reverse_proxy",
119
+ // "upstreams": [{ "dial": "127.0.0.1:11434" }]
120
+ // },
121
+ // {
122
+ // "handler": "headers",
123
+ // "response": {
124
+ // "set": {
125
+ // "Access-Control-Allow-Origin": ["*"],
126
+ // "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
127
+ // "Access-Control-Allow-Headers": ["*"],
128
+ // "Vary": ["Origin"]
129
+ // }
130
+ // }
131
+ // }
132
+ // ]
133
+ // },
134
+ // {
135
+ // "match": [{ "host": ["a.pinokio.localhost"] }],
136
+ // "handle": [
137
+ // {
138
+ // "handler": "reverse_proxy",
139
+ // "upstreams": [{ "dial": "127.0.0.1:7860" }]
140
+ // },
141
+ // {
142
+ // "handler": "headers",
143
+ // "response": {
144
+ // "set": {
145
+ // "Access-Control-Allow-Origin": ["*"],
146
+ // "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
147
+ // "Access-Control-Allow-Headers": ["*"],
148
+ // "Vary": ["Origin"]
149
+ // }
150
+ // }
151
+ // }
152
+ // ]
153
+ // },
154
+ // {
155
+ // "match": [{ "host": ["b.pinokio.localhost"] }],
156
+ // "handle": [
157
+ // {
158
+ // "handler": "reverse_proxy",
159
+ // "upstreams": [{ "dial": "127.0.0.1:7861" }]
160
+ // },
161
+ // {
162
+ // "handler": "headers",
163
+ // "response": {
164
+ // "set": {
165
+ // "Access-Control-Allow-Origin": ["*"],
166
+ // "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
167
+ // "Access-Control-Allow-Headers": ["*"],
168
+ // "Vary": ["Origin"]
169
+ // }
170
+ // }
171
+ // }
172
+ // ]
173
+ // },
174
+ // {
175
+ // "match": [{ "host": ["c.pinokio.localhost"] }],
176
+ // "handle": [
177
+ // {
178
+ // "handler": "reverse_proxy",
179
+ // "upstreams": [{ "dial": "127.0.0.1:7862" }]
180
+ // },
181
+ // {
182
+ // "handler": "headers",
183
+ // "response": {
184
+ // "set": {
185
+ // "Access-Control-Allow-Origin": ["*"],
186
+ // "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
187
+ // "Access-Control-Allow-Headers": ["*"],
188
+ // "Vary": ["Origin"]
189
+ // }
190
+ // }
191
+ // }
192
+ // ]
193
+ // }
194
+ // ]
195
+ // }
299
196
  // }
300
197
  // }
301
- }
302
- }
303
-
304
-
305
-
306
-
307
- console.log("Make request to caddy", config)
308
- let response = await axios.post('http://127.0.0.1:2019/load', config, {
309
- headers: { 'Content-Type': 'application/json' }
310
- }).catch((e) => {
311
- console.log("EEEEEEEEEEEEE", e)
312
- })
313
- console.log("Caddy Response", { response })
198
+ // }
199
+ // }
200
+ //
201
+ // const config2 = {
202
+ // "apps": {
203
+ // "http": {
204
+ // "servers": {
205
+ // "main": {
206
+ // "listen": [":443"],
207
+ // //"listen": [":80"],
208
+ // "handle_response": [
209
+ // {
210
+ // "handler": "headers",
211
+ // "headers": {
212
+ // "Access-Control-Allow-Origin": ["*"],
213
+ // "Access-Control-Allow-Methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"],
214
+ // "Access-Control-Allow-Headers": ["*"]
215
+ // }
216
+ // }
217
+ // ],
218
+ // "routes": [
219
+ // {
220
+ // "match": [{ "method": ["OPTIONS"] }],
221
+ // "handle": [
222
+ // {
223
+ // "handler": "static_response",
224
+ // "headers": {
225
+ // "Access-Control-Allow-Origin": ["*"],
226
+ // "Access-Control-Allow-Methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"],
227
+ // "Access-Control-Allow-Headers": ["*"]
228
+ // },
229
+ // "status_code": 204
230
+ // }
231
+ // ]
232
+ // },
233
+ // {
234
+ // "match": [{ "host": ["pinokio.localhost"] }],
235
+ // "handle": [
236
+ // {
237
+ // "handler": "reverse_proxy",
238
+ // "upstreams": [{ "dial": "localhost:42000" }]
239
+ // }
240
+ // ]
241
+ // },
242
+ // {
243
+ // "match": [{ "host": ["l.pinokio.localhost"] }],
244
+ // "handle": [
245
+ // {
246
+ // "handler": "reverse_proxy",
247
+ // "upstreams": [{ "dial": "localhost:1234" }]
248
+ // }
249
+ // ]
250
+ // },
251
+ // {
252
+ // "match": [{ "host": ["a.pinokio.localhost"] }],
253
+ // "handle": [
254
+ // {
255
+ // "handler": "reverse_proxy",
256
+ // "upstreams": [{ "dial": "localhost:7860" }]
257
+ // }
258
+ // ]
259
+ // },
260
+ // {
261
+ // "match": [{ "host": ["b.pinokio.localhost"] }],
262
+ // "handle": [
263
+ // {
264
+ // "handler": "reverse_proxy",
265
+ // "upstreams": [{ "dial": "localhost:7861" }]
266
+ // }
267
+ // ]
268
+ // },
269
+ // {
270
+ // "match": [{ "host": ["c.pinokio.localhost"] }],
271
+ // "handle": [
272
+ // {
273
+ // "handler": "reverse_proxy",
274
+ // "upstreams": [{ "dial": "localhost:7862" }]
275
+ // }
276
+ // ]
277
+ // }
278
+ // ]
279
+ // }
280
+ // }
281
+ // },
282
+ //// "tls": {
283
+ //// "automation": {
284
+ //// "policies": [
285
+ //// {
286
+ //// "subjects": [
287
+ //// "pinokio.localhost",
288
+ //// "a.pinokio.localhost",
289
+ //// "b.pinokio.localhost",
290
+ //// "c.pinokio.localhost"
291
+ //// ],
292
+ //// "issuers": [
293
+ //// {
294
+ //// "module": "internal"
295
+ //// }
296
+ //// ]
297
+ //// }
298
+ //// ]
299
+ //// }
300
+ //// }
301
+ // }
302
+ // }
303
+ //
304
+ //
305
+ //
306
+ //
307
+ // console.log("Make request to caddy", config)
308
+ // let response = await axios.post('http://127.0.0.1:2019/load', config, {
309
+ // headers: { 'Content-Type': 'application/json' }
310
+ // }).catch((e) => {
311
+ // console.log("EEEEEEEEEEEEE", e)
312
+ // })
313
+ // console.log("Caddy Response", { response })
314
314
  }
315
315
  async install(req, ondata, kernel, id) {
316
316
  await this.kernel.bin.exec({
@@ -0,0 +1,193 @@
1
+ const axios = require('axios')
2
+ const path = require('path')
3
+ class Caddy {
4
+ constructor(kernel) {
5
+ this.kernel = kernel
6
+ }
7
+ async update() {
8
+ this.mapping = {}
9
+ let payload = await this.payload()
10
+ console.log("Make request to caddy", JSON.stringify(payload, null, 2))
11
+ let response = await axios.post('http://127.0.0.1:2019/load', payload, {
12
+ headers: { 'Content-Type': 'application/json' }
13
+ }).catch((e) => {
14
+ console.log("EEEEEEEEEEEEE", e)
15
+ })
16
+ console.log("Caddy Response", { response })
17
+ }
18
+ async procs (payload) {
19
+ console.log("####### procs", payload)
20
+ let list = this.kernel.processes.list
21
+ if (!list) {
22
+ list = await this.kernel.processes.refresh()
23
+ }
24
+ for(let item of list) {
25
+ let url = `${item.port}.localhost`
26
+ this.mapping[item.ip] = url
27
+ payload.apps.http.servers.main.routes.push({
28
+ "match": [{
29
+ "host": [url],
30
+ }],
31
+ "handle": [
32
+ {
33
+ "handler": "reverse_proxy",
34
+ "upstreams": [{ "dial": item.ip }]
35
+ },
36
+ {
37
+ "handler": "headers",
38
+ "response": {
39
+ "set": {
40
+ "Access-Control-Allow-Origin": ["*"],
41
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
42
+ "Access-Control-Allow-Headers": ["*"],
43
+ "Vary": ["Origin"]
44
+ }
45
+ }
46
+ }
47
+ ]
48
+ })
49
+ }
50
+ return payload
51
+ }
52
+ locals (payload) {
53
+ // construct Caddy update payload
54
+ let local = this.kernel.memory.local;
55
+ console.log({ local })
56
+ for(let script_path in local) {
57
+ let local_variables = local[script_path]
58
+ console.log({ local_variables })
59
+ for(let key in local_variables) {
60
+ let val = local_variables[key]
61
+ if (val.startsWith("http")) {
62
+ val = val.replace(/https?:\/\//, '')
63
+ let api_path = this.kernel.path("api")
64
+ let rel_path = path.relative(api_path, script_path)
65
+ let name = rel_path.split(path.sep)[0]
66
+ console.log({ api_path, rel_path, name, val })
67
+ if (key === "url") {
68
+ let url = `${name}.localhost`.toLowerCase()
69
+ this.mapping[val] = url
70
+ payload.apps.http.servers.main.routes.push({
71
+ "match": [{
72
+ "host": [url]
73
+ //"path": [`/local/${key}/${uri}/*`]
74
+ }],
75
+ "handle": [
76
+ //{
77
+ // "handler": "rewrite",
78
+ // "uri": "/"
79
+ //},
80
+ {
81
+ "handler": "reverse_proxy",
82
+ "upstreams": [{ "dial": val }]
83
+ },
84
+ {
85
+ "handler": "headers",
86
+ "response": {
87
+ "set": {
88
+ "Access-Control-Allow-Origin": ["*"],
89
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
90
+ "Access-Control-Allow-Headers": ["*"],
91
+ "Vary": ["Origin"]
92
+ }
93
+ }
94
+ }
95
+ ]
96
+ })
97
+ }
98
+ payload.apps.http.servers.main.routes.push({
99
+ "match": [{
100
+ "host": [`${key}.${name}.localhost`.toLowerCase()],
101
+ //"path": [`/local/${key}/${uri}/*`]
102
+ }],
103
+ "handle": [
104
+ //{
105
+ // "handler": "rewrite",
106
+ // "uri": "/"
107
+ //},
108
+ {
109
+ "handler": "reverse_proxy",
110
+ "upstreams": [{ "dial": val }]
111
+ },
112
+ {
113
+ "handler": "headers",
114
+ "response": {
115
+ "set": {
116
+ "Access-Control-Allow-Origin": ["*"],
117
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
118
+ "Access-Control-Allow-Headers": ["*"],
119
+ "Vary": ["Origin"]
120
+ }
121
+ }
122
+ }
123
+ ]
124
+ })
125
+ }
126
+ }
127
+ }
128
+ return payload
129
+ }
130
+ home () {
131
+ return {
132
+ "apps": {
133
+ "http": {
134
+ "servers": {
135
+ "main": {
136
+ //"listen": ["127.0.0.1:443"],
137
+ "listen": [":443"],
138
+ "routes": [
139
+ {
140
+ "match": [{ "method": ["OPTIONS"] }],
141
+ "handle": [
142
+ {
143
+ "handler": "headers",
144
+ "response": {
145
+ "set": {
146
+ "Access-Control-Allow-Origin": ["*"],
147
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
148
+ "Access-Control-Allow-Headers": ["*"],
149
+ "Vary": ["Origin"]
150
+ }
151
+ }
152
+ },
153
+ {
154
+ "handler": "static_response",
155
+ "status_code": 204
156
+ }
157
+ ]
158
+ },
159
+ {
160
+ "match": [{ "host": ["pinokio.localhost"] }],
161
+ "handle": [
162
+ {
163
+ "handler": "reverse_proxy",
164
+ "upstreams": [{ "dial": "127.0.0.1:42000" }]
165
+ },
166
+ {
167
+ "handler": "headers",
168
+ "response": {
169
+ "set": {
170
+ "Access-Control-Allow-Origin": ["*"],
171
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
172
+ "Access-Control-Allow-Headers": ["*"],
173
+ "Vary": ["Origin"]
174
+ }
175
+ }
176
+ }
177
+ ]
178
+ },
179
+ ]
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+ async payload () {
187
+ let payload = this.home()
188
+ payload = this.locals(payload)
189
+ payload = await this.procs(payload)
190
+ return payload
191
+ }
192
+ }
193
+ module.exports = Caddy
package/kernel/index.js CHANGED
@@ -30,6 +30,8 @@ const Pipe = require("../pipe")
30
30
  const Cloudflare = require('./api/cloudflare')
31
31
  const Store = require('./store')
32
32
  const Proto = require('./prototype')
33
+ const Caddy = require("./caddy")
34
+ const Procs = require('./procs')
33
35
  const VARS = {
34
36
  pip: {
35
37
  install: {
@@ -80,6 +82,7 @@ class Kernel {
80
82
  this.info = new Info(this)
81
83
  this.pipe = new Pipe(this)
82
84
  this.proto = new Proto(this)
85
+ this.processes = new Procs()
83
86
  this.kv = new KV(this)
84
87
  this.cloudflare = new Cloudflare()
85
88
  this.shellpath = shellPath.sync()
@@ -488,6 +491,7 @@ class Kernel {
488
491
  this.api = new Api(this)
489
492
  this.python = new Python(this)
490
493
  this.shell = new Shells(this)
494
+ this.caddy = new Caddy(this)
491
495
  this.system = system
492
496
  this.keys = {}
493
497
  this.memory = {
@@ -0,0 +1,113 @@
1
+ const os = require('os')
2
+ const path = require('path')
3
+ const { fork, exec } = require('child_process');
4
+ const platform = os.platform();
5
+ class Procs {
6
+ constructor () {
7
+ console.log("Initializing procs")
8
+ }
9
+ getPortPidList(callback) {
10
+ const isWin = platform === 'win32';
11
+ const cmd = isWin ? 'netstat -ano -p tcp' : 'lsof -nP -iTCP -sTCP:LISTEN';
12
+ exec(cmd, (err, stdout) => {
13
+ if (err) return callback(err);
14
+
15
+ const results = [];
16
+ let pids = new Set()
17
+ const lines = stdout.trim().split('\n');
18
+
19
+ lines.forEach(line => {
20
+ console.log({ line })
21
+ if (isWin) {
22
+ // Skip headers
23
+ if (!line.startsWith(' TCP')) return;
24
+ const parts = line.trim().split(/\s+/);
25
+ const [ , localAddress, , state, pid ] = parts;
26
+ if (pids.has(pid)) return;
27
+ pids.add(pid)
28
+ if (state !== 'LISTENING') return;
29
+ const chunks = localAddress.split(":")
30
+ const port = chunks.pop()
31
+ let ip = chunks.pop()
32
+ if (!ip || ip === "*") {
33
+ ip = "127.0.0.1:" + port
34
+ } else {
35
+ ip = localAddress
36
+ }
37
+ results.push({ port, pid, ip });
38
+ } else {
39
+ if (!/LISTEN/.test(line)) return;
40
+ const parts = line.trim().split(/\s+/);
41
+ const pid = parts[1];
42
+ if (pids.has(pid)) return;
43
+ pids.add(pid)
44
+
45
+ const match = line.match(/([^\s]+:\d+)\s/);
46
+ const localAddress = match?.[1];
47
+ const chunks = localAddress.split(":")
48
+ const port = chunks.pop()
49
+ let ip = chunks.pop()
50
+ if (!ip || ip === "*") {
51
+ ip = "127.0.0.1:" + port
52
+ } else {
53
+ ip = localAddress
54
+ }
55
+ //const portMatch = line.match(/:(\d+)\s/);
56
+ //const port = portMatch?.[1];
57
+ if (pid && port) results.push({ port, pid, ip });
58
+ }
59
+ });
60
+
61
+ callback(null, results);
62
+ });
63
+ }
64
+ getPidToNameMap(callback) {
65
+ const isWin = platform === 'win32';
66
+ const cmd = isWin ? 'tasklist /fo csv /nh' : 'ps -Ao pid,comm';
67
+ exec(cmd, (err, stdout) => {
68
+ if (err) return callback(err);
69
+ const lines = stdout.trim().split('\n');
70
+ const map = {};
71
+ lines.forEach(line => {
72
+ if (isWin) {
73
+ const [name, , , , pid] = line.split('","').map(s => s.replace(/(^"|"$)/g, ''));
74
+ map[pid] = name;
75
+ } else {
76
+ const [pid, ...nameParts] = line.trim().split(/\s+/);
77
+ map[pid] = nameParts.join(' ');
78
+ }
79
+ });
80
+ callback(null, map);
81
+ });
82
+ }
83
+ async refresh() {
84
+ console.time("Get list")
85
+ let list = await new Promise((resolve, reject) => {
86
+ this.getPortPidList((err, portPidList) => {
87
+ if (err) {
88
+ reject(err)
89
+ return
90
+ }
91
+
92
+ this.getPidToNameMap((err, pidToName) => {
93
+ if (err) {
94
+ reject(err)
95
+ return
96
+ }
97
+
98
+ let list = portPidList.map(({ port, pid, ip }) => {
99
+ const fullname = pidToName[pid] || 'Unknown';
100
+ const name = fullname.split(path.sep).pop()
101
+ return { port, pid , name, fullname, ip }
102
+ })
103
+ resolve(list)
104
+ });
105
+ });
106
+ })
107
+ console.log( { list } )
108
+ console.timeEnd("Get list")
109
+ this.list = list
110
+ return this.list
111
+ }
112
+ }
113
+ module.exports = Procs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.8.23",
3
+ "version": "3.8.25",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -54,7 +54,6 @@
54
54
  "random-useragent": "^0.5.0",
55
55
  "rimraf": "^5.0.0",
56
56
  "sanitize-filename": "^1.6.3",
57
- "selfsigned": "^2.4.1",
58
57
  "semver": "^7.5.4",
59
58
  "shell-path": "^2.0.0",
60
59
  "sudo-prompt-programfiles-x86": "^9.2.10",
package/server/index.js CHANGED
@@ -13,12 +13,13 @@ const cors = require('cors');
13
13
  const path = require("path")
14
14
  const fs = require('fs');
15
15
  const os = require('os')
16
- const { fork } = require('child_process');
16
+ const { fork, exec } = require('child_process');
17
17
  const semver = require('semver')
18
18
  const fse = require('fs-extra')
19
19
  const QRCode = require('qrcode')
20
20
  const axios = require('axios')
21
21
 
22
+
22
23
  const git = require('isomorphic-git')
23
24
  const http = require('isomorphic-git/http/node')
24
25
  const marked = require('marked')
@@ -2658,6 +2659,15 @@ class Server {
2658
2659
  })
2659
2660
  }))
2660
2661
  this.app.get("/proxy", ex(async (req, res) => {
2662
+ let list = await this.kernel.processes.refresh()
2663
+ list = list.map((item) => {
2664
+ return {
2665
+ proxy: this.kernel.caddy.mapping[item.ip],
2666
+ ...item
2667
+ }
2668
+ })
2669
+ await this.kernel.caddy.update()
2670
+
2661
2671
  let live_proxies = this.kernel.api.proxies["/proxy"]
2662
2672
  if (!live_proxies) live_proxies = []
2663
2673
  let proxies = []
@@ -2735,6 +2745,7 @@ class Server {
2735
2745
  }
2736
2746
  }
2737
2747
  res.render("proxy", {
2748
+ list,
2738
2749
  agent: this.agent,
2739
2750
  theme: this.theme,
2740
2751
  items: proxies,
@@ -82,6 +82,10 @@ header .runner {
82
82
  font-size: 14px;
83
83
  margin-bottom: 3px;
84
84
  }
85
+ .line.align-top h3.table-grid {
86
+ display: grid;
87
+ grid-template-columns: repeat(3, 1fr);
88
+ }
85
89
  .browser-options-row .btn.disabled {
86
90
  opacity: 0.7;
87
91
  }
@@ -157,7 +161,7 @@ body.dark .browser-options-row {
157
161
  }
158
162
  .container {
159
163
  display: grid;
160
- grid-template-columns: repeat(2, 1fr);
164
+ grid-template-columns: repeat(3, 1fr);
161
165
  }
162
166
  .dark .container-row {
163
167
  background: rgba(255, 255, 255, 0.04);
@@ -206,6 +210,25 @@ body.dark .browser-options-row {
206
210
  <div class='header-label'><i class='fa-solid fa-wifi'></i> Local Sharing</div>
207
211
  <div class='desc'>Serve Pinokio, installed apps, and even external apps to any device on the same network.</div>
208
212
  <div class='container'>
213
+ <div class='container-row'>
214
+ <div class='header-label-sub'><i class="fa-solid fa-microchip"></i> Apps</div>
215
+ <div class='line align-top'>
216
+ <h3 class='table-grid'>
217
+ <div class='col'>Name</div>
218
+ <div class='col'>Pid</div>
219
+ <div class='col'>Port</div>
220
+ </h3>
221
+ </div>
222
+ <% list.forEach((item) => { %>
223
+ <a target="_blank" href="https://<%=item.proxy%>" class='line align-top'>
224
+ <h3 class='table-grid'>
225
+ <div class='col'><%=item.name%></div>
226
+ <div class='col'><%=item.pid%></div>
227
+ <div class='col'><%=item.port%></div>
228
+ </h3>
229
+ </a>
230
+ <% }) %>
231
+ </div>
209
232
  <div class='container-row'>
210
233
  <div class='header-label-sub'><i class="fa-solid fa-microchip"></i> System Programs</div>
211
234
  <div class='line align-top'>