iobroker.bee 0.2.3 → 0.2.5

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.
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NODE_VERDICT = exports.NODE_STATUS = void 0;
7
+ exports.majorOf = majorOf;
8
+ exports.nodeStep = nodeStep;
9
+ exports.serviceOf = serviceOf;
10
+ exports.nodeBlockers = nodeBlockers;
11
+ exports.engineConflicts = engineConflicts;
12
+ exports.readEngines = readEngines;
13
+ exports.nodeFacts = nodeFacts;
14
+ exports.nodeUnit = nodeUnit;
15
+ exports.launchNodeUpdate = launchNodeUpdate;
16
+ exports.unitActive = unitActive;
17
+ exports.readNodeStatus = readNodeStatus;
18
+ exports.readVerdict = readVerdict;
19
+ exports.writeVerdict = writeVerdict;
20
+ const node_child_process_1 = require("node:child_process");
21
+ const node_fs_1 = require("node:fs");
22
+ const promises_1 = require("node:fs/promises");
23
+ const node_path_1 = require("node:path");
24
+ const semver_1 = __importDefault(require("semver"));
25
+ const util_1 = require("./util");
26
+ /**
27
+ * Update of Node.js to the major line of the profile (DesiredProfile.node), only upwards.
28
+ *
29
+ * Node.js comes from the package nodejs of NodeSource, as the installer of ioBroker sets it up. The update
30
+ * stops ioBroker, so the agent cannot do it itself: it starts scripts/node-update.sh as root in a systemd
31
+ * unit of its own (sudo systemd-run, which the installer allows the user iobroker). After the restart the
32
+ * agent checks under the new Node.js that the instances that ran before run again and writes its verdict;
33
+ * without a positive verdict the script installs the old package again. Files in the data directory:
34
+ * node-status.json (script), node-verdict.json (agent), node-update.log.
35
+ */
36
+ exports.NODE_STATUS = 'node-status.json';
37
+ exports.NODE_VERDICT = 'node-verdict.json';
38
+ const NODE_SCRIPT = 'node-update.sh';
39
+ /** Major line of a version, e.g. 22 for "v22.11.0", "22" or "22.x" */
40
+ function majorOf(version) {
41
+ return semver_1.default.coerce(version ?? '')?.major || null;
42
+ }
43
+ /**
44
+ * The step that brings Node.js to the major line of the profile; null if it runs that line already, or a
45
+ * newer one (no downgrades)
46
+ *
47
+ * @param target DesiredProfile.node, e.g. "22"
48
+ * @param current process.version
49
+ */
50
+ function nodeStep(target, current) {
51
+ const want = majorOf(target);
52
+ const have = majorOf(current);
53
+ if (!want || !have || want <= have) {
54
+ return null;
55
+ }
56
+ return { action: 'node', from: current, to: String(want), status: 'pending' };
57
+ }
58
+ /**
59
+ * The systemd service ioBroker runs in, from /proc/self/cgroup, e.g. "iobroker.service"
60
+ *
61
+ * @param cgroup content of /proc/self/cgroup
62
+ */
63
+ function serviceOf(cgroup) {
64
+ return /\/system\.slice\/([^/\s]+\.service)/.exec(cgroup)?.[1] ?? null;
65
+ }
66
+ /** Reasons that block the update of Node.js; empty if it can run */
67
+ function nodeBlockers(f) {
68
+ if (f.platform !== 'linux') {
69
+ return ['nur unter Linux möglich'];
70
+ }
71
+ const errors = [];
72
+ if (!f.service) {
73
+ errors.push('ioBroker läuft nicht als systemd-Dienst');
74
+ }
75
+ if (!f.sudo) {
76
+ errors.push('kein sudo ohne Passwort für systemd-run (Installation mit --hardened?)');
77
+ }
78
+ if (!f.packaged || !f.source) {
79
+ errors.push('Node.js stammt nicht aus dem Paket nodejs von NodeSource');
80
+ }
81
+ else if (f.arch !== 'amd64' && f.arch !== 'arm64') {
82
+ errors.push(`NodeSource bietet für ${f.arch || 'diese Architektur'} kein Node.js an (nur amd64 und arm64)`);
83
+ }
84
+ if (f.held) {
85
+ errors.push('das Paket nodejs ist auf hold gesetzt');
86
+ }
87
+ if (!f.offDeviceBackup) {
88
+ errors.push('keine Sicherung außerhalb des Geräts (BackItUp)');
89
+ }
90
+ return errors;
91
+ }
92
+ /**
93
+ * Installed packages whose engines.node excludes the major line
94
+ *
95
+ * @param target major line, e.g. 22
96
+ * @param engines per package its version and engines.node
97
+ */
98
+ function engineConflicts(target, engines) {
99
+ const line = `^${target}.0.0`;
100
+ return Object.entries(engines)
101
+ .filter(([, e]) => !!e.node && !!semver_1.default.validRange(e.node) && !semver_1.default.intersects(e.node, line))
102
+ .map(([name, e]) => `${name}@${e.version} verlangt Node ${e.node}`);
103
+ }
104
+ /**
105
+ * Version and engines.node of installed packages iobroker.<name>
106
+ *
107
+ * @param cwd directory of ioBroker, e.g. /opt/iobroker
108
+ * @param names adapters, "js-controller" for the controller
109
+ */
110
+ function readEngines(cwd, names) {
111
+ const result = {};
112
+ for (const name of names) {
113
+ try {
114
+ const pkg = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(cwd, 'node_modules', `iobroker.${name}`, 'package.json'), 'utf8'));
115
+ const node = pkg.engines?.node;
116
+ result[name] = { version: String(pkg.version), ...(typeof node === 'string' ? { node } : {}) };
117
+ }
118
+ catch {
119
+ // not installed as a package of its own
120
+ }
121
+ }
122
+ return result;
123
+ }
124
+ function run(cmd, args, timeout = 15_000) {
125
+ return new Promise(resolve => {
126
+ (0, node_child_process_1.execFile)(cmd, args, { timeout, windowsHide: true }, (error, stdout, stderr) => resolve({ ok: !error, out: String(stdout).trim(), err: String(stderr).trim() || error?.message || '' }));
127
+ });
128
+ }
129
+ const isRoot = () => process.getuid?.() === 0;
130
+ /** Root runs systemd-run itself, everybody else with sudo -n */
131
+ function asRoot(args) {
132
+ return isRoot() ? [args[0], args.slice(1)] : ['sudo', ['-n', ...args]];
133
+ }
134
+ function realpath(path) {
135
+ try {
136
+ return (0, node_fs_1.realpathSync)(path);
137
+ }
138
+ catch {
139
+ return null;
140
+ }
141
+ }
142
+ const SOURCES = ['/etc/apt/sources.list.d/nodesource.sources', '/etc/apt/sources.list.d/nodesource.list'];
143
+ /**
144
+ * Looks at this system
145
+ *
146
+ * @param offDeviceBackup Inventory.backup.offDevice
147
+ */
148
+ async function nodeFacts(offDeviceBackup) {
149
+ const facts = {
150
+ platform: process.platform,
151
+ service: null,
152
+ sudo: false,
153
+ arch: null,
154
+ packaged: false,
155
+ source: false,
156
+ held: false,
157
+ offDeviceBackup,
158
+ };
159
+ if (process.platform !== 'linux') {
160
+ return facts;
161
+ }
162
+ const binary = realpath(process.execPath);
163
+ const [cgroup, sudo, arch, owner, held] = await Promise.all([
164
+ (0, promises_1.readFile)('/proc/self/cgroup', 'utf8').catch(() => ''),
165
+ run(...asRoot(['systemd-run', '--version'])),
166
+ run('dpkg', ['--print-architecture']),
167
+ binary ? run('dpkg', ['-S', binary]) : Promise.resolve({ ok: false, out: '', err: '' }),
168
+ run('apt-mark', ['showhold', 'nodejs']),
169
+ ]);
170
+ facts.service = serviceOf(cgroup);
171
+ facts.sudo = sudo.ok;
172
+ facts.arch = arch.ok ? arch.out : null;
173
+ facts.packaged = !!binary && binary === realpath('/usr/bin/node') && owner.ok && owner.out.startsWith('nodejs:');
174
+ facts.source = SOURCES.some(f => (0, node_fs_1.existsSync)(f) && /deb\.nodesource\.com\/node_\d+\.x/.test((0, node_fs_1.readFileSync)(f, 'utf8')));
175
+ facts.held = held.ok && held.out.split('\n').some(l => l.trim() === 'nodejs');
176
+ return facts;
177
+ }
178
+ /** Name of the systemd unit for an update of Node.js */
179
+ function nodeUnit(now = Date.now()) {
180
+ return `bee-node-${now}`;
181
+ }
182
+ /**
183
+ * Starts scripts/node-update.sh as root in a unit of its own. It stops ioBroker, so this process ends soon.
184
+ *
185
+ * @param o what to start
186
+ * @param o.dir data directory of the agent
187
+ * @param o.target major line
188
+ * @param o.service systemd service of ioBroker
189
+ * @param o.unit name of the unit, see nodeUnit
190
+ * @param o.waitSeconds how long the script waits for the verdict of the agent
191
+ */
192
+ async function launchNodeUpdate(o) {
193
+ await (0, promises_1.rm)((0, node_path_1.join)(o.dir, exports.NODE_STATUS), { force: true });
194
+ await (0, promises_1.rm)((0, node_path_1.join)(o.dir, exports.NODE_VERDICT), { force: true });
195
+ // a copy: the package of the agent may change while the script runs
196
+ const script = (0, node_path_1.join)(o.dir, NODE_SCRIPT);
197
+ await (0, promises_1.copyFile)((0, node_path_1.join)(__dirname, '..', '..', 'scripts', NODE_SCRIPT), script);
198
+ const r = await run(...asRoot([
199
+ 'systemd-run',
200
+ `--unit=${o.unit}`,
201
+ '--collect',
202
+ '--quiet',
203
+ `--description=ioBroker.bee: Node.js ${o.target}`,
204
+ '/bin/bash',
205
+ script,
206
+ o.dir,
207
+ o.target,
208
+ o.service,
209
+ String(o.waitSeconds),
210
+ ]));
211
+ if (!r.ok) {
212
+ throw new Error(`systemd-run: ${r.err || r.out || 'fehlgeschlagen'}`);
213
+ }
214
+ }
215
+ /** Whether the unit of the script is still there (it is removed when the script ends) */
216
+ async function unitActive(unit) {
217
+ return (await run('systemctl', ['is-active', '--quiet', unit])).ok;
218
+ }
219
+ function readNodeStatus(dir) {
220
+ return (0, util_1.readJson)((0, node_path_1.join)(dir, exports.NODE_STATUS));
221
+ }
222
+ /** Whether the agent already gave its verdict to the script, and which */
223
+ async function readVerdict(dir) {
224
+ return (0, util_1.readJson)((0, node_path_1.join)(dir, exports.NODE_VERDICT));
225
+ }
226
+ /**
227
+ * The verdict of the agent under the new Node.js. On one line: the script reads it with grep and sed.
228
+ *
229
+ * @param dir data directory of the agent
230
+ * @param ok the instances run, the script keeps the new Node.js
231
+ * @param reason otherwise why, the script goes back to the old one
232
+ */
233
+ async function writeVerdict(dir, ok, reason = '') {
234
+ const file = (0, node_path_1.join)(dir, exports.NODE_VERDICT);
235
+ const data = ok ? { ok: true } : { ok: false, reason: reason.replace(/["\\\r\n]/g, ' ').slice(0, 400) };
236
+ await (0, promises_1.writeFile)(`${file}.tmp`, `${JSON.stringify(data)}\n`);
237
+ await (0, promises_1.rename)(`${file}.tmp`, file);
238
+ }
239
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/lib/node.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ exports.computePlan = computePlan;
8
8
  exports.rollbackPlan = rollbackPlan;
9
9
  exports.checkDependencies = checkDependencies;
10
10
  const semver_1 = __importDefault(require("semver"));
11
+ const node_1 = require("./node");
11
12
  const util_1 = require("./util");
12
13
  /** Adapters installed locally that are neither in the profile, tolerated, nor scheduled for removal */
13
14
  function foreignAdapters(desired, installed) {
@@ -23,7 +24,7 @@ function foreignAdapters(desired, installed) {
23
24
  .sort();
24
25
  }
25
26
  /**
26
- * Steps to reach the profile. The agent (bee) is always updated last.
27
+ * Steps to reach the profile. Node.js comes first, the agent (bee) always last.
27
28
  *
28
29
  * @param desired desired state of the server
29
30
  * @param installed installed versions
@@ -31,8 +32,9 @@ function foreignAdapters(desired, installed) {
31
32
  * @param from where the adapters were installed from (installedFrom); with a package of the server and the
32
33
  * same version installed from somewhere else, the package is installed once more (a build that kept
33
34
  * the version number). Only given as long as that was not tried yet for this job.
35
+ * @param node the running Node.js (process.version); with it a step to the major line of the profile
34
36
  */
35
- function computePlan(desired, installed, selfName = 'bee', from) {
37
+ function computePlan(desired, installed, selfName = 'bee', from, node) {
36
38
  const steps = [];
37
39
  if (!desired.profile) {
38
40
  return steps;
@@ -63,12 +65,15 @@ function computePlan(desired, installed, selfName = 'bee', from) {
63
65
  }
64
66
  // removals first (frees space), then installs/updates alphabetically, the agent last
65
67
  const rank = (s) => (s.adapter === selfName ? 2 : s.action === 'remove' ? 0 : 1);
66
- return steps.sort((a, b) => rank(a) - rank(b) || a.adapter.localeCompare(b.adapter));
68
+ steps.sort((a, b) => rank(a) - rank(b) || a.adapter.localeCompare(b.adapter));
69
+ // Node.js before everything else: the new versions may need it
70
+ const step = node ? (0, node_1.nodeStep)(desired.profile.node, node) : null;
71
+ return step ? [step, ...steps] : steps;
67
72
  }
68
- /** Steps that restore the previous state after a failed rollout (reverse order) */
73
+ /** Steps that restore the previous state after a failed rollout (reverse order); Node.js stays */
69
74
  function rollbackPlan(steps) {
70
75
  return steps
71
- .filter(s => s.action !== 'backup' && s.status === 'ok')
76
+ .filter(s => s.action !== 'backup' && s.action !== 'node' && s.status === 'ok')
72
77
  .reverse()
73
78
  .map(s => {
74
79
  if (s.action === 'install') {
@@ -90,6 +95,12 @@ function rollbackPlan(steps) {
90
95
  * Checks the dependencies of all target versions against the state after the plan
91
96
  * (io-package.json dependencies, globalDependencies and engines.node of the target version).
92
97
  *
98
+ * @param desired desired state of the server
99
+ * @param installed installed versions
100
+ * @param env versions on the system
101
+ * @param env.jsController installed js-controller
102
+ * @param env.node running Node.js
103
+ * @param env.nodeMajor the major line the plan brings Node.js to before the adapters
93
104
  * @returns list of violations; empty if everything fits
94
105
  */
95
106
  function checkDependencies(desired, installed, env) {
@@ -108,8 +119,15 @@ function checkDependencies(desired, installed, env) {
108
119
  if (installed[name] === a.version) {
109
120
  continue;
110
121
  }
111
- if (a.node && semver_1.default.validRange(a.node) && !semver_1.default.satisfies(env.node, a.node)) {
112
- errors.push(`${name}@${a.version} verlangt Node ${a.node}, installiert ist ${env.node}`);
122
+ if (a.node && semver_1.default.validRange(a.node)) {
123
+ if (env.nodeMajor) {
124
+ if (!semver_1.default.intersects(a.node, `^${env.nodeMajor}.0.0`)) {
125
+ errors.push(`${name}@${a.version} verlangt Node ${a.node}, geplant ist Node ${env.nodeMajor}`);
126
+ }
127
+ }
128
+ else if (!semver_1.default.satisfies(env.node, a.node)) {
129
+ errors.push(`${name}@${a.version} verlangt Node ${a.node}, installiert ist ${env.node}`);
130
+ }
113
131
  }
114
132
  for (const dep of [...(a.dependencies || []), ...(a.globalDependencies || [])]) {
115
133
  for (const [depName, range] of Object.entries(dep)) {
@@ -1 +1 @@
1
- {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/lib/planner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/lib/planner.ts"],"names":[],"mappings":"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"}
@@ -57,6 +57,13 @@ async function preflight(input) {
57
57
  if (input.dependencyErrors.length) {
58
58
  return { ok: false, kind: 'block', reason: `Abhängigkeiten: ${input.dependencyErrors.join('; ')}` };
59
59
  }
60
+ if (input.nodeErrors?.errors.length) {
61
+ return {
62
+ ok: false,
63
+ kind: 'block',
64
+ reason: `Update auf Node.js ${input.nodeErrors.target} nicht möglich: ${input.nodeErrors.errors.join('; ')}`,
65
+ };
66
+ }
60
67
  const free = await freeDiskMb(input.diskPath);
61
68
  if (free !== null && free < input.minFreeMb) {
62
69
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/lib/preflight.ts"],"names":[],"mappings":";;AA4CA,0BAyBC;AAED,gCAOC;AAED,8BAoCC;AApHD,+CAA0C;AAC1C,iCAAkC;AAgClC,SAAS,MAAM,CAAC,KAAa;IACzB,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,MAAM,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAgB,OAAO,CAAC,MAA2B,EAAE,EAAY,EAAE,QAAgB;IAC/E,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,GAAG,GAAY,MAAM,CAAC;IAC1B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAClF,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1D,GAAG,GAAG,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,GAAG,CAAC;IAC9D,CAAC;IACD,QAAQ,EAAE,EAAE,CAAC;QACT,KAAK,IAAI;YACL,OAAO,GAAG,IAAI,GAAG,CAAC;QACtB,KAAK,IAAI;YACL,OAAO,GAAG,IAAI,GAAG,CAAC;QACtB,KAAK,GAAG;YACJ,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,KAAK,IAAI;YACL,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;QACtC,KAAK,GAAG;YACJ,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,KAAK,IAAI;YACL,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;QACtC;YACI,OAAO,KAAK,CAAC;IACrB,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,IAAY;IACzC,IAAI,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,IAAA,iBAAM,EAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,KAAqB;IACjD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;IAClH,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;QAChC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IACxG,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAC1C,OAAO;YACH,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,sBAAsB,IAAI,aAAa,KAAK,CAAC,SAAS,iDAAiD;SAClH,CAAC;IACN,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAA,eAAQ,EAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACrF,OAAO;YACH,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,mCAAmC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,GAAG;SACvF,CAAC;IACN,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACb,SAAS;QACb,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC;QACnC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,wBAAwB,EAAE,CAAC;QACjF,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,KAAK,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACzG,CAAC;IACL,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/lib/preflight.ts"],"names":[],"mappings":";;AA8CA,0BAyBC;AAED,gCAOC;AAED,8BA2CC;AA7HD,+CAA0C;AAC1C,iCAAkC;AAkClC,SAAS,MAAM,CAAC,KAAa;IACzB,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,MAAM,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAgB,OAAO,CAAC,MAA2B,EAAE,EAAY,EAAE,QAAgB;IAC/E,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,GAAG,GAAY,MAAM,CAAC;IAC1B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAClF,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1D,GAAG,GAAG,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,GAAG,CAAC;IAC9D,CAAC;IACD,QAAQ,EAAE,EAAE,CAAC;QACT,KAAK,IAAI;YACL,OAAO,GAAG,IAAI,GAAG,CAAC;QACtB,KAAK,IAAI;YACL,OAAO,GAAG,IAAI,GAAG,CAAC;QACtB,KAAK,GAAG;YACJ,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,KAAK,IAAI;YACL,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;QACtC,KAAK,GAAG;YACJ,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,KAAK,IAAI;YACL,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;QACtC;YACI,OAAO,KAAK,CAAC;IACrB,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,IAAY;IACzC,IAAI,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,IAAA,iBAAM,EAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,KAAqB;IACjD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;IAClH,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;QAChC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IACxG,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO;YACH,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,sBAAsB,KAAK,CAAC,UAAU,CAAC,MAAM,mBAAmB,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAC/G,CAAC;IACN,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAC1C,OAAO;YACH,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,sBAAsB,IAAI,aAAa,KAAK,CAAC,SAAS,iDAAiD;SAClH,CAAC;IACN,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAA,eAAQ,EAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACrF,OAAO;YACH,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,mCAAmC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,GAAG;SACvF,CAAC;IACN,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACb,SAAS;QACb,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC;QACnC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,wBAAwB,EAAE,CAAC;QACjF,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,KAAK,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACzG,CAAC;IACL,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
@@ -20,7 +20,7 @@
20
20
  * WebSocket to TUNNEL_PATH of the server and carries the connections of the browser (see tunnel.ts).
21
21
  */
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.TERMINAL_JOB_STATES = exports.TUNNEL_PATH = exports.ACCESS_KINDS = exports.INSTANCE_ID = exports.MAX_COMMENT_LENGTH = exports.PROTOCOL_VERSION = void 0;
23
+ exports.TERMINAL_JOB_STATES = exports.TUNNEL_PATH = exports.ACCESS_KINDS = exports.MAX_LOG_UPLOAD_BYTES = exports.INSTANCE_ID = exports.MAX_COMMENT_LENGTH = exports.PROTOCOL_VERSION = void 0;
24
24
  exports.deviceTopic = deviceTopic;
25
25
  exports.controlTopic = controlTopic;
26
26
  exports.normalizeComment = normalizeComment;
@@ -63,6 +63,8 @@ function parseOsPackage(line) {
63
63
  }
64
64
  /** Instance id as the commands accept it, e.g. "javascript.0" */
65
65
  exports.INSTANCE_ID = /^[a-z0-9][a-z0-9_-]*\.\d{1,4}$/;
66
+ /** Largest log file the agent uploads, compressed (nginx in front of the server allows 52 MB) */
67
+ exports.MAX_LOG_UPLOAD_BYTES = 50 * 1024 * 1024;
66
68
  exports.ACCESS_KINDS = ['admin', 'vis', 'console'];
67
69
  /** WebSocket path of the tunnel endpoint on the server */
68
70
  exports.TUNNEL_PATH = '/tunnel';
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/lib/protocol.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAMH,kCAEC;AAED,oCAEC;AASD,4CAWC;AAkHD,wCAMC;AAtJY,QAAA,gBAAgB,GAAG,CAAC,CAAC;AAIlC,SAAgB,WAAW,CAAC,QAAgB,EAAE,QAAgB,EAAE,KAAY;IACxE,OAAO,SAAS,QAAQ,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;AACpD,CAAC;AAED,SAAgB,YAAY,CAAC,QAAgB;IACzC,OAAO,SAAS,QAAQ,UAAU,CAAC;AACvC,CAAC;AAED,kFAAkF;AACrE,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEtC;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,CAAC,GAAG,KAAK;SACV,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC;SACzB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,0BAAkB,CAAC;SAC5B,IAAI,EAAE,CAAC;IACZ,OAAO,CAAC,IAAI,SAAS,CAAC;AAC1B,CAAC;AA8GD;;;GAGG;AACH,SAAgB,cAAc,CAAC,IAAY;IACvC,MAAM,CAAC,GAAG,uEAAuE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpG,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,iEAAiE;AACpD,QAAA,WAAW,GAAG,gCAAgC,CAAC;AAwG/C,QAAA,YAAY,GAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAetE,0DAA0D;AAC7C,QAAA,WAAW,GAAG,SAAS,CAAC;AAyBxB,QAAA,mBAAmB,GAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/lib/protocol.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAMH,kCAEC;AAED,oCAEC;AASD,4CAWC;AAkHD,wCAMC;AAtJY,QAAA,gBAAgB,GAAG,CAAC,CAAC;AAIlC,SAAgB,WAAW,CAAC,QAAgB,EAAE,QAAgB,EAAE,KAAY;IACxE,OAAO,SAAS,QAAQ,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;AACpD,CAAC;AAED,SAAgB,YAAY,CAAC,QAAgB;IACzC,OAAO,SAAS,QAAQ,UAAU,CAAC;AACvC,CAAC;AAED,kFAAkF;AACrE,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEtC;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,CAAC,GAAG,KAAK;SACV,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC;SACzB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,0BAAkB,CAAC;SAC5B,IAAI,EAAE,CAAC;IACZ,OAAO,CAAC,IAAI,SAAS,CAAC;AAC1B,CAAC;AA8GD;;;GAGG;AACH,SAAgB,cAAc,CAAC,IAAY;IACvC,MAAM,CAAC,GAAG,uEAAuE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpG,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,iEAAiE;AACpD,QAAA,WAAW,GAAG,gCAAgC,CAAC;AAe5D,iGAAiG;AACpF,QAAA,oBAAoB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AA4GxC,QAAA,YAAY,GAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAetE,0DAA0D;AAC7C,QAAA,WAAW,GAAG,SAAS,CAAC;AAyBxB,QAAA,mBAAmB,GAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC"}
package/build/main.js CHANGED
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const utils = __importStar(require("@iobroker/adapter-core"));
40
40
  const node_fs_1 = require("node:fs");
41
+ const promises_1 = require("node:fs/promises");
41
42
  const node_os_1 = __importDefault(require("node:os"));
42
43
  const node_path_1 = require("node:path");
43
44
  const commands_1 = require("./lib/commands");
@@ -46,6 +47,8 @@ const instances_1 = require("./lib/instances");
46
47
  const enrollment_1 = require("./lib/enrollment");
47
48
  const inventory_1 = require("./lib/inventory");
48
49
  const jobs_1 = require("./lib/jobs");
50
+ const logs_1 = require("./lib/logs");
51
+ const node_1 = require("./lib/node");
49
52
  const packages_1 = require("./lib/packages");
50
53
  const planner_1 = require("./lib/planner");
51
54
  const preflight_1 = require("./lib/preflight");
@@ -54,6 +57,15 @@ const remote_1 = require("./lib/remote");
54
57
  const transport_1 = require("./lib/transport");
55
58
  const tunnel_1 = require("./lib/tunnel");
56
59
  const util_1 = require("./lib/util");
60
+ /** Host of the broker for the status, e.g. "bee.iobroker.click" */
61
+ function hostOf(url) {
62
+ try {
63
+ return new URL(url || '').hostname || 'der Flottenverwaltung';
64
+ }
65
+ catch {
66
+ return 'der Flottenverwaltung';
67
+ }
68
+ }
57
69
  class BeeAdapter extends utils.Adapter {
58
70
  dataDir = '';
59
71
  creds = null;
@@ -73,6 +85,7 @@ class BeeAdapter extends utils.Adapter {
73
85
  reconciling = false;
74
86
  /** A command of the fleet management is being carried out (one at a time) */
75
87
  commandRunning = false;
88
+ logUploading = false;
76
89
  lastWaitReason = '';
77
90
  unloading = false;
78
91
  /** Open remote access sessions by session id */
@@ -108,6 +121,16 @@ class BeeAdapter extends utils.Adapter {
108
121
  instancesOf: adapter => this.instancesOf(adapter),
109
122
  errorsSince: (ts, adapters) => this.errorLog.filter(e => e.ts >= ts && adapters.some(a => e.from.startsWith(`${a}.`))),
110
123
  onFinished: (job, result) => this.onJobFinished(job, result),
124
+ running: async () => (await this.instancesOf()).filter(i => i.alive).map(i => i.id),
125
+ launchNode: async (target, unit, waitSeconds) => {
126
+ const service = (0, node_1.serviceOf)(await (0, promises_1.readFile)('/proc/self/cgroup', 'utf8').catch(() => ''));
127
+ if (!service) {
128
+ throw new Error('ioBroker läuft nicht als systemd-Dienst');
129
+ }
130
+ this.log.warn(`Node.js is updated to ${target}: ioBroker (${service}) restarts (fleet management)`);
131
+ await (0, node_1.launchNodeUpdate)({ dir: this.dataDir, target, service, unit, waitSeconds });
132
+ },
133
+ unitActive: unit => (0, node_1.unitActive)(unit),
111
134
  });
112
135
  await this.jobs.load();
113
136
  await this.jobs.setHalt(!!this.control?.halt);
@@ -217,7 +240,7 @@ class BeeAdapter extends utils.Adapter {
217
240
  async onConnected() {
218
241
  this.log.info('Connected to beekeeper');
219
242
  await this.setState('info.connection', true, true);
220
- await this.setState('info.status', 'Verbunden', true);
243
+ await this.setState('info.status', `Verbunden mit ${hostOf(this.creds?.mqttUrl)}`, true);
221
244
  await this.heartbeat();
222
245
  await this.sendInventory(true);
223
246
  // results produced while offline
@@ -262,12 +285,77 @@ class BeeAdapter extends utils.Adapter {
262
285
  else if (msg.ref && (msg.cmd === 'instance' || msg.cmd === 'restart' || msg.cmd === 'osUpgrade')) {
263
286
  await this.runCommand(msg);
264
287
  }
288
+ else if (msg.ref && msg.cmd === 'logList') {
289
+ // only reads: also during a job or another command
290
+ await this.logListCommand(msg.ref);
291
+ }
292
+ else if (msg.ref && msg.cmd === 'logFetch') {
293
+ // may take minutes on a mobile connection: the other messages go on meanwhile
294
+ void this.logFetchCommand(msg.ref, msg.by || 'Flottenverwaltung', msg.logFetch);
295
+ }
265
296
  }
266
297
  // ------------------------------------------------------------------ commands of the fleet management
267
- async reply(ref, state, message) {
268
- const msg = { v: protocol_1.PROTOCOL_VERSION, ts: Date.now(), ref, state, ...(message ? { message } : {}) };
298
+ async reply(ref, state, message, files) {
299
+ const msg = {
300
+ v: protocol_1.PROTOCOL_VERSION,
301
+ ts: Date.now(),
302
+ ref,
303
+ state,
304
+ ...(message ? { message } : {}),
305
+ ...(files ? { files } : {}),
306
+ };
269
307
  await this.transport?.publish('reply', msg);
270
308
  }
309
+ /** Directories of the log files of ioBroker (file transports of iobroker.json) */
310
+ logDirs() {
311
+ let config = null;
312
+ try {
313
+ config = utils.getConfig();
314
+ }
315
+ catch (e) {
316
+ this.log.debug(`iobroker.json not readable: ${e.message}`);
317
+ }
318
+ return (0, logs_1.logDirs)(config, (0, node_path_1.join)(utils.controllerDir, '..', '..'));
319
+ }
320
+ async logListCommand(ref) {
321
+ try {
322
+ const files = await (0, logs_1.listLogFiles)(this.logDirs());
323
+ await this.reply(ref, 'done', `${files.length} Log-Dateien`, files);
324
+ }
325
+ catch (e) {
326
+ await this.reply(ref, 'error', e.message);
327
+ }
328
+ }
329
+ /** Uploads a log file to the own server, one at a time */
330
+ async logFetchCommand(ref, by, req) {
331
+ try {
332
+ if (this.logUploading) {
333
+ throw new Error('Es wird schon eine Log-Datei übertragen');
334
+ }
335
+ if (!req || typeof req.url !== 'string' || typeof req.ticket !== 'string') {
336
+ throw new Error('Unvollständige Anfrage');
337
+ }
338
+ if (!(0, packages_1.trustedPackageUrl)(req.url, [this.config.enrollUrl, this.creds?.mqttUrl || ''])) {
339
+ throw new Error(`${req.url} gehört nicht zum Flottenserver`);
340
+ }
341
+ const file = await (0, logs_1.findLogFile)(this.logDirs(), req.file);
342
+ if (!file) {
343
+ throw new Error(`Log-Datei ${String(req.file)} gibt es nicht`);
344
+ }
345
+ this.logUploading = true;
346
+ this.log.info(`Log file ${req.file} is uploaded on request of ${by} (fleet management)`);
347
+ await this.reply(ref, 'running', `${req.file} wird komprimiert übertragen`);
348
+ const bytes = await (0, logs_1.uploadLog)(file, req.url, req.ticket, (0, transport_1.trustedCas)(this.creds?.ca || ''));
349
+ await this.reply(ref, 'done', `${req.file}: ${(bytes / 1024 / 1024).toFixed(1)} MB übertragen`);
350
+ }
351
+ catch (e) {
352
+ this.log.warn(`Log file ${String(req?.file)} for ${by}: ${e.message}`);
353
+ await this.reply(ref, 'error', e.message);
354
+ }
355
+ finally {
356
+ this.logUploading = false;
357
+ }
358
+ }
271
359
  /** Sends the inventory again a while after a command, when the instances show its effect */
272
360
  inventorySoon() {
273
361
  for (const ms of [5_000, 30_000]) {
@@ -502,7 +590,8 @@ class BeeAdapter extends utils.Adapter {
502
590
  await this.setState('info.remoteAccess', active.length > 0, true);
503
591
  await this.setState('info.remoteAccessBy', active
504
592
  .map(t => `${remote_1.ACCESS_LABEL[t.kind]}${t.instance ? ` (${t.instance})` : ''}${this.shellText(t)}: ${t.by}, ${t.purpose} (bis ${new Date(t.expiresAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })})`)
505
- .join('; '), true);
593
+ // in the settings an empty value would show the label alone
594
+ .join('; ') || 'keiner', true);
506
595
  }
507
596
  // ------------------------------------------------------------------ inventory and heartbeat
508
597
  async inventory() {
@@ -603,10 +692,16 @@ class BeeAdapter extends utils.Adapter {
603
692
  this.errorLog.splice(0, this.errorLog.length - 500);
604
693
  }
605
694
  }
695
+ /**
696
+ * Enabled instances with a process of their own on this host and whether they run
697
+ *
698
+ * @param adapter only of this adapter; missing: all
699
+ */
606
700
  async instancesOf(adapter) {
701
+ const prefix = adapter ? `system.adapter.${adapter}.` : 'system.adapter.';
607
702
  const res = await this.getObjectViewAsync('system', 'instance', {
608
- startkey: `system.adapter.${adapter}.`,
609
- endkey: `system.adapter.${adapter}.香`,
703
+ startkey: prefix,
704
+ endkey: `${prefix}香`,
610
705
  });
611
706
  const list = [];
612
707
  for (const row of res.rows) {
@@ -717,7 +812,7 @@ class BeeAdapter extends utils.Adapter {
717
812
  const from = this.persisted.results[key] === 'done'
718
813
  ? undefined
719
814
  : Object.fromEntries(Object.entries(inv.software.adapters).map(([n, a]) => [n, a.installedFrom]));
720
- const plan = (0, planner_1.computePlan)(d, installed, this.name, from);
815
+ const plan = (0, planner_1.computePlan)(d, installed, this.name, from, process.version);
721
816
  await this.setState('info.onTarget', plan.length === 0, true);
722
817
  if (d.mode === 'self') {
723
818
  // self-managed: no automatic rollout, only a hint about the new state
@@ -752,6 +847,7 @@ class BeeAdapter extends utils.Adapter {
752
847
  }
753
848
  // drift after an earlier success (e.g. manual change): converge again
754
849
  delete this.persisted.results[key];
850
+ const nodeTarget = plan.find(s => s.action === 'node')?.to ?? undefined;
755
851
  const pf = await (0, preflight_1.preflight)({
756
852
  now: new Date(),
757
853
  halted: !!this.control?.halt,
@@ -768,7 +864,11 @@ class BeeAdapter extends utils.Adapter {
768
864
  dependencyErrors: (0, planner_1.checkDependencies)(d, installed, {
769
865
  jsController: inv.software.jsController,
770
866
  node: process.version,
867
+ nodeMajor: nodeTarget ? Number(nodeTarget) : undefined,
771
868
  }),
869
+ nodeErrors: nodeTarget
870
+ ? { target: nodeTarget, errors: await this.nodeErrors(nodeTarget, inv, plan) }
871
+ : undefined,
772
872
  });
773
873
  if (!pf.ok) {
774
874
  if (pf.kind === 'block') {
@@ -805,6 +905,22 @@ class BeeAdapter extends utils.Adapter {
805
905
  await this.report('preflight', `${plan.length} Schritte geplant, Vorprüfung bestanden`, plan);
806
906
  await this.jobs.start(d, plan, this.config.backupBeforeUpdate !== false, files);
807
907
  }
908
+ /**
909
+ * Why Node.js cannot go to the major line: the system, and installed packages that exclude it
910
+ * (those the plan changes are checked with their new version by checkDependencies)
911
+ *
912
+ * @param target major line
913
+ * @param inv inventory
914
+ * @param plan steps of the job
915
+ */
916
+ async nodeErrors(target, inv, plan) {
917
+ const changed = new Set(plan.map(s => s.adapter));
918
+ const names = ['js-controller', ...Object.keys(inv.software.adapters).filter(n => !changed.has(n))];
919
+ return [
920
+ ...(0, node_1.nodeBlockers)(await (0, node_1.nodeFacts)(inv.backup.offDevice)),
921
+ ...(0, node_1.engineConflicts)(Number(target), (0, node_1.readEngines)((0, node_path_1.join)(utils.controllerDir, '..', '..'), names)),
922
+ ];
923
+ }
808
924
  // ------------------------------------------------------------------ states, notifications
809
925
  async updateInfoStates() {
810
926
  await this.setState('info.deviceId', this.creds?.deviceId || '', true);