pinokiod 3.8.29 → 3.8.31

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/caddy.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const axios = require('axios')
2
2
  const path = require('path')
3
+ const Util = require('./util')
3
4
  class Caddy {
4
5
  constructor(kernel) {
5
6
  this.kernel = kernel
@@ -86,7 +87,7 @@ class Caddy {
86
87
  }
87
88
  }
88
89
  }
89
- peers_locals(payload) {
90
+ async peers_locals(payload) {
90
91
  let peers = this.kernel.peer.get()
91
92
  for(let ip of peers) {
92
93
  let account = this.kernel.peer.account(ip)
@@ -101,12 +102,42 @@ class Caddy {
101
102
  if (val.startsWith("http")) {
102
103
  val = val.replace(/https?:\/\//, '')
103
104
 
105
+
104
106
  // replace 127,0.0.1 or localhost with the 192.168 address
105
107
  val = val.replace(/localhost|127\.0\.0\.1/g, ip)
106
108
  let api_path = path.resolve(this.kernel.peer.homedir(ip), "api")
107
109
  let rel_path = path.relative(api_path, script_path)
108
110
  let name = rel_path.split(path.sep)[0]
109
111
  console.log({ api_path, rel_path, name, val })
112
+
113
+
114
+ // create a proxy proxy
115
+ // - get next available port and expose
116
+ payload.apps.http.servers.main.routes.push({
117
+ "match": [{
118
+ "host": [":PORT_PLACEHOLDER_" + val],
119
+ }],
120
+ "handle": [
121
+ {
122
+ "handler": "reverse_proxy",
123
+ "upstreams": [{ "dial": val }]
124
+ },
125
+ {
126
+ "handler": "headers",
127
+ "response": {
128
+ "set": {
129
+ "Access-Control-Allow-Origin": ["*"],
130
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
131
+ "Access-Control-Allow-Headers": ["*"],
132
+ "Vary": ["Origin"]
133
+ }
134
+ }
135
+ }
136
+ ]
137
+ })
138
+
139
+
140
+ // proxy proxy => proxy
110
141
  if (key === "url") {
111
142
  let url = `${name}.${account}.localhost`.toLowerCase()
112
143
  this.mapping[val] = url
@@ -117,7 +148,7 @@ class Caddy {
117
148
  "handle": [
118
149
  {
119
150
  "handler": "reverse_proxy",
120
- "upstreams": [{ "dial": val }]
151
+ "upstreams": [{ "dial": ":PORT_PLACEHOLDER_" + val }]
121
152
  },
122
153
  {
123
154
  "handler": "headers",
@@ -140,7 +171,7 @@ class Caddy {
140
171
  "handle": [
141
172
  {
142
173
  "handler": "reverse_proxy",
143
- "upstreams": [{ "dial": val }]
174
+ "upstreams": [{ "dial": ":PORT_PLACEHOLDER_" + val }]
144
175
  },
145
176
  {
146
177
  "handler": "headers",
@@ -232,39 +263,85 @@ class Caddy {
232
263
  async peers_procs (payload) {
233
264
  console.log("####### procs", payload)
234
265
  let list = this.kernel.peer.get()
266
+ console.log(">> peers list", list)
235
267
  for(let ip of list) {
236
268
  let account = this.kernel.peer.account(ip)
269
+ console.log({ account })
237
270
 
238
271
  // caddy_mapping := { IP => HTTPS_DOMAIN }
239
272
  let caddy_mapping = this.kernel.peer.caddy(ip)
240
- for(let app_ip in caddy_mapping) {
241
- let https_domain = caddy_mapping[app_ip]
242
- let remote_app_ip = app_ip.replace(/localhost|127\.0\.0\.1/g, ip)
273
+ console.log({ caddy_mapping })
274
+ for(let internal_ip in caddy_mapping) {
275
+ let INTERNAL_PORT = internal_ip.split(":")[1]
276
+ let https_domain = caddy_mapping[internal_ip]
277
+ // let remote_app_ip = app_ip.replace(/localhost|127\.0\.0\.1/g, ip)
278
+ // console.log({ https_domain, app_ip, ip })
243
279
  // https_domain <port>.localhost
244
- let url = https_domain.replace(/\.localhost$/, '') + `${account}.localhost`
245
- this.mapping[remote_app_ip] = url
246
- payload.apps.http.servers.main.routes.push({
247
- "match": [{
248
- "host": [url],
249
- }],
250
- "handle": [
251
- {
252
- "handler": "reverse_proxy",
253
- "upstreams": [{ "dial": remote_app_ip }]
254
- },
255
- {
256
- "handler": "headers",
257
- "response": {
258
- "set": {
259
- "Access-Control-Allow-Origin": ["*"],
260
- "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
261
- "Access-Control-Allow-Headers": ["*"],
262
- "Vary": ["Origin"]
280
+ // let re = new RegExp(ip)
281
+
282
+ // insert the $account value right before the last part (1234.localhost => 1234.x.localhost)
283
+ let chunks = https_domain.split(".")
284
+ if (chunks.length === 2) {
285
+ chunks.splice(chunks.length - 1, 0, account)
286
+
287
+
288
+ let namespaced_url = chunks.join(".")
289
+
290
+ const exposed_url = ip + ":" + INTERNAL_PORT
291
+ console.log({ namespaced_url, https_domain, exposed_url, internal_ip })
292
+ this.mapping[internal_ip] = namespaced_url
293
+
294
+
295
+ // create a proxy proxy
296
+ // 1. create an exposed port listening on 0.0.0.0
297
+ // 2. the exposed port points to the internal ip
298
+ payload.apps.http.servers[":" + INTERNAL_PORT] = {
299
+ "listen": [":PORT_PLACEHOLDER_" + INTERNAL_PORT],
300
+ "routes": [{
301
+ "handle": [
302
+ {
303
+ "handler": "reverse_proxy",
304
+ "upstreams": [{ "dial": internal_ip }]
305
+ },
306
+ {
307
+ "handler": "headers",
308
+ "response": {
309
+ "set": {
310
+ "Access-Control-Allow-Origin": ["*"],
311
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
312
+ "Access-Control-Allow-Headers": ["*"],
313
+ "Vary": ["Origin"]
314
+ }
315
+ }
316
+ }
317
+ ]
318
+ }]
319
+ }
320
+
321
+ // 1. point proxy URL to the 127.0.0.1:EXPOSED_PORT
322
+ payload.apps.http.servers.main.routes.push({
323
+ "match": [{
324
+ "host": [namespaced_url],
325
+ }],
326
+ "handle": [
327
+ {
328
+ "handler": "reverse_proxy",
329
+ "upstreams": [{ "dial": ip + ":PORT_PLACEHOLDER_" + INTERNAL_PORT }]
330
+ },
331
+ {
332
+ "handler": "headers",
333
+ "response": {
334
+ "set": {
335
+ "Access-Control-Allow-Origin": ["*"],
336
+ "Access-Control-Allow-Methods": ["GET, POST, OPTIONS, PUT, DELETE"],
337
+ "Access-Control-Allow-Headers": ["*"],
338
+ "Vary": ["Origin"]
339
+ }
263
340
  }
264
341
  }
265
- }
266
- ]
267
- })
342
+ ]
343
+ })
344
+ }
268
345
  }
269
346
  }
270
347
  return payload
@@ -331,10 +408,23 @@ class Caddy {
331
408
  // localhost local variables
332
409
  payload = this.locals(payload)
333
410
  // peers local variables
334
- payload = this.peers_locals(payload)
411
+ payload = await this.peers_locals(payload)
335
412
 
336
413
  payload = await this.procs(payload)
337
- payload = this.peers_procs(payload)
414
+ payload = await this.peers_procs(payload)
415
+
416
+
417
+ // replace :PORT_PLACEHOLDER with available ports
418
+
419
+ const jsonString = JSON.stringify(payload)
420
+ const matches = jsonString.match(/:PORT_PLACEHOLDER/g);
421
+ const count = matches ? matches.length : 0;
422
+
423
+ if (count > 0) {
424
+ let ports = await this.kernel.ports(count)
425
+ console.log({ count, ports })
426
+ payload = Util.fill_object(payload, /PORT_PLACEHOLDER_.+/, ports)
427
+ }
338
428
 
339
429
  return payload
340
430
  }
package/kernel/index.js CHANGED
@@ -212,6 +212,18 @@ class Kernel {
212
212
  return portfinder.getPortPromise({ port: 42003 })
213
213
  }
214
214
  }
215
+ ports(count) {
216
+ // get "count" number of available ports
217
+ return new Promise((resolve, reject) => {
218
+ portfinder.getPorts(count, { port: 42003 }, (err, ports) => {
219
+ if (err) {
220
+ reject(err)
221
+ } else {
222
+ resolve(ports)
223
+ }
224
+ })
225
+ })
226
+ }
215
227
  path(...args) {
216
228
  return path.resolve(this.homedir, ...args)
217
229
  }
package/kernel/peer.js CHANGED
@@ -34,10 +34,16 @@ class PeerDiscovery {
34
34
  if (msg.toString() === this.message.toString() && this._isLocalLAN(ip)) {
35
35
  if (!this.peers.has(ip)) {
36
36
  this.peers.add(ip);
37
- axios.get(`http://${ip}:42000/pinokio/mem`).then((res) => {
38
- this.data[ip] = res.data
39
- })
40
- console.log(`Discovered peer: ${ip}`);
37
+ let interval = setInterval(() => {
38
+ axios.get(`http://${ip}:42000/pinokio/mem`).then((res) => {
39
+ console.log("axios", res.data)
40
+ this.data[ip] = res.data
41
+ if (res.data.caddy) {
42
+ console.log(`Discovered peer: ${ip}`);
43
+ // clearInterval(interval)
44
+ }
45
+ })
46
+ }, 1000)
41
47
  }
42
48
  }
43
49
  });
package/kernel/util.js CHANGED
@@ -307,6 +307,34 @@ const update_env = async (filepath, changes) => {
307
307
  }, normalizeEOL(env));
308
308
  await fs.promises.writeFile(filepath, newval)
309
309
  };
310
+ function fill_object(obj, pattern, list) {
311
+ const map = {};
312
+ let index = 0;
313
+
314
+ function recurse(value) {
315
+ if (typeof value === 'string') {
316
+ return value.replace(pattern, (match) => {
317
+ if (!(match in map)) {
318
+ if (index >= list.length) throw new Error("Not enough items provided");
319
+ map[match] = list[index++];
320
+ }
321
+ return map[match];
322
+ });
323
+ } else if (Array.isArray(value)) {
324
+ return value.map(recurse);
325
+ } else if (value && typeof value === 'object') {
326
+ const newObj = {};
327
+ for (const [k, v] of Object.entries(value)) {
328
+ newObj[k] = recurse(v);
329
+ }
330
+ return newObj;
331
+ }
332
+ return value;
333
+ }
334
+
335
+ return recurse(obj);
336
+ }
337
+
310
338
  module.exports = {
311
- parse_env, log_path, api_path, update_env, parse_env_detail, openfs, port_running, du, is_port_available, find_python, find_venv
339
+ parse_env, log_path, api_path, update_env, parse_env_detail, openfs, port_running, du, is_port_available, find_python, find_venv, fill_object
312
340
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.8.29",
3
+ "version": "3.8.31",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {