clavarium 0.2.381-next.1 → 0.2.383-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/deploy/online.mjs CHANGED
@@ -58,6 +58,8 @@ import { doctor, servedCert, DOCTOR_PATHS } from './doctor.mjs';
58
58
  export const PATHS = {
59
59
  access: '/var/lib/clavarium-relay-access',
60
60
  tunnel: '/var/lib/clavarium-tunnel',
61
+ tunnelUnit: TUNNEL_UNIT,
62
+ relayDone: '/var/lib/clavarium/update/relay-version',
61
63
  relayConf: '/etc/clavarium/relay.conf',
62
64
  updateConf: '/etc/clavarium/update.conf',
63
65
  unit: '/etc/systemd/system/clavarium.service',
@@ -207,6 +209,15 @@ export function readRelayConf(P = PATHS) {
207
209
  try { for (const line of readFileSync(P.relayConf, 'utf8').split('\n')) { const m = /^([A-Z_]+)=(.*)$/.exec(line.trim()); if (m) conf[m[1]] = m[2]; } } catch { return null; }
208
210
  return conf.HOST ? conf : null;
209
211
  }
212
+ /* The relay of a machine put online before relay.conf existed (07-11, found on a test machine): only
213
+ its tunnel unit says it. Read there, as the updater does (tunnel.mjs, relayOfUnit); never written back. */
214
+ export function relayOf(P = PATHS) {
215
+ const conf = readRelayConf(P);
216
+ if (conf) return conf;
217
+ let unit = null;
218
+ try { unit = relayOfUnit(readFileSync(P.tunnelUnit ?? TUNNEL_UNIT, 'utf8')); } catch { return null; }
219
+ return unit ? { HOST: unit.relay, PORT: unit.port } : null;
220
+ }
210
221
  function writeRelayConf(P, conf) {
211
222
  mkdirSync(join(P.relayConf, '..'), { recursive: true });
212
223
  writeFileSync(`${P.relayConf}.new`, `# The relay of this Clavarium. Written by clavarium online.\n${Object.entries(conf).map(([k, v]) => `${k}=${v}`).join('\n')}\n`, { mode: 0o644 });
@@ -243,6 +254,11 @@ export async function keepRelayCurrent(sys, P = PATHS, { done, unit = TUNNEL_UNI
243
254
  let last = '';
244
255
  try { last = readFileSync(done, 'utf8').trim(); } catch { /* never brought */ }
245
256
  if (last === version) return { state: 'current', version };
257
+ /* A new GENERATION of the relay program (0.1 -> 0.2: one relay for several homes, 07-11) is never brought
258
+ by the updater: the owner brings it once, `sudo clavarium relay update-relay`, when they want it.
259
+ Fixes within a generation still come by themselves. */
260
+ const gen = (v) => String(v).split('.').slice(0, 2).join('.');
261
+ if (gen(version) !== gen(last || '0.1.0')) return { state: 'held', version, why: `the relay program ${version} is a new generation: bring it with sudo clavarium relay update-relay` };
246
262
  const r = await keeper(sys, P, conf, ['update-relay', version]);
247
263
  if (r.code !== 0) {
248
264
  /* sys.run says { code, out, err } (realSys). */
@@ -662,7 +678,7 @@ function writeInvites(P, v) {
662
678
  }
663
679
  /* Only the principal adds homes: the machine that holds the relay's maintenance key, online. */
664
680
  function principal(P) {
665
- const conf = readRelayConf(P);
681
+ const conf = relayOf(P);
666
682
  if (!conf) throw new Refused('this machine has no relay (sudo clavarium online --relay HOST --domain NAME)');
667
683
  if (conf.ROLE === 'home') throw new Refused(`this machine is a home of the relay ${conf.HOST}: only its principal${conf.PRINCIPAL ? ` (${conf.PRINCIPAL})` : ''} adds or removes homes`);
668
684
  const domain = serverModeOf(P);
@@ -729,7 +745,7 @@ export async function joinWithCode(sys, P, given, key) {
729
745
 
730
746
  /* `sudo clavarium relay VERB` */
731
747
  export async function relayCommand(args, sys, P = PATHS) {
732
- const conf = readRelayConf(P);
748
+ const conf = relayOf(P);
733
749
  if (!conf) throw new Refused('this machine has no relay (sudo clavarium online --relay HOST --domain NAME)');
734
750
  const [verb, ...rest] = args;
735
751
  if (conf.ROLE === 'home') throw new Refused(`this machine is a home of the relay ${conf.HOST}: the relay is kept by its principal${conf.PRINCIPAL ? `, ${conf.PRINCIPAL}` : ''}`);
@@ -779,6 +795,8 @@ export async function relayCommand(args, sys, P = PATHS) {
779
795
  if (!/^\d{1,4}\.\d{1,4}\.\d{1,6}(-[0-9A-Za-z.-]{1,40})?$/.test(version ?? '')) throw new Bad('relay update-relay [X.Y.Z]');
780
796
  const r = await keeper(sys, P, conf, ['update-relay', version], { stream: true });
781
797
  if (r.code !== 0) throw new Failed(`the relay did not update (exit ${r.code})`);
798
+ /* Said to the updater (keepRelayCurrent): this generation is the owner's choice now, its fixes come by themselves. */
799
+ try { const done = P.relayDone ?? '/var/lib/clavarium/update/relay-version'; writeFileSync(`${done}.new`, `${version}\n`); renameSync(`${done}.new`, done); } catch { /* the updater asks again: no harm */ }
782
800
  return;
783
801
  }
784
802
  default: throw new Bad('usage: sudo clavarium relay status | repair | update-os [--reboot] | update-relay [X.Y.Z] | forget-setup-key | homes | invite NAME | add-home NAME --key KEY | remove-home NAME');
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "clavarium",
3
- "version": "0.2.381-next.1",
3
+ "version": "0.2.383-next.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "clavarium",
9
- "version": "0.2.381-next.1",
9
+ "version": "0.2.383-next.1",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@xterm/addon-fit": "^0.11.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clavarium",
3
- "version": "0.2.381-next.1",
3
+ "version": "0.2.383-next.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "A conversation is a VM with a terminal in it. Everything else is a folder.",
@@ -67,7 +67,7 @@ function timerLastRun() {
67
67
  }
68
68
  const firstLine = (text) => String(text ?? '').trim().split('\n').filter(Boolean).pop()?.replace(/^REFUSED: /, '').slice(0, 300) ?? '';
69
69
 
70
- const RELAY_STATES = ['none', 'no-key', 'current', 'brought', 'refused', 'failed'];
70
+ const RELAY_STATES = ['none', 'no-key', 'current', 'brought', 'refused', 'failed', 'held'];
71
71
 
72
72
  export class Updates {
73
73
  #host; #state; #conf; #version; #store; #alerts; #timer; #lastLook; #lastLookCache = { at: 0, value: null }; #clock; #noticeCache = { at: -Infinity, value: '' };
package/web/app.js CHANGED
@@ -7306,6 +7306,8 @@
7306
7306
  refused: () => ['Relay not kept up to date: it refuses this server\'s key', 'Once: sudo clavarium key on this server, then relay.sh again on the relay, with --key and --keeper-key.', true],
7307
7307
  'no-key': () => ['Relay not kept up to date: no maintenance key', 'sudo clavarium online --relay HOST sets one up.', true],
7308
7308
  failed: (r) => [`Relay update failed: ${r.why ?? 'unknown'} · tried again later`, '', true],
7309
+ /* 07-11: a new generation of the relay (several homes) waits for the owner, never brought by itself. */
7310
+ held: (r) => [`Relay ${r.version} ready, not installed`, 'When you want it: sudo clavarium relay update-relay', false],
7309
7311
  };
7310
7312
  const relayBox = $('updates-relay');
7311
7313
  relayBox.hidden = !relay || !RELAY_SAID[relay.state];