iobroker.bee 0.2.0 → 0.2.3

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/README.md CHANGED
@@ -25,7 +25,7 @@ Fleet agent for ioBroker. It connects a delivered ioBroker system (in a house, a
25
25
 
26
26
  If the owner installs adapters that are not part of the profile, the agent reports them, stops automatic updates and informs the owner via an ioBroker notification. The fleet manager sees the installation in the deviation list and can bring it back to managed mode (removing the own adapters or tolerating them as exceptions).
27
27
 
28
- ### Remote access to admin and vis-2
28
+ ### Remote access to admin, vis-2 and the console
29
29
 
30
30
  A technician of the fleet manager can open admin or vis-2 of the system from the fleet management, without ioBroker.pro and without open ports on the device:
31
31
 
@@ -35,11 +35,22 @@ A technician of the fleet manager can open admin or vis-2 of the system from the
35
35
 
36
36
  The owner can switch off each kind in the tab *Remote access*; the agent then refuses the session and the fleet management shows why. Running sessions are visible in `info.remoteAccess`. After a connection loss the agent reconnects until the session expires, also across restarts of the adapter. The server ends the session early when the technician ends it or the device is revoked.
37
37
 
38
+ **Console.** Off until the owner allows it (*Allow the console*), and only on Linux with `script` of util-linux (part of every Debian). Then every terminal the technician opens in the browser is a login shell on this system, as the user ioBroker runs as (usually `iobroker`), started in the ioBroker directory. No native module: `script` gives the shell a pseudo terminal, `stty` sets the size of its window. At most 4 shells per session; when the session or the connection ends, the shells get SIGHUP. `info.remoteAccessBy` shows how many shells are open. Whatever the shell may do beyond the rights of that user belongs in a sudo allow list for single commands, not in a general sudo. Note that the list the ioBroker installer writes (`/etc/sudoers.d/iobroker`) contains `apt`, `apt-get` and `dpkg` without password, which makes the console effectively root on a standard installation. Systems installed with `--hardened` have no sudo; there the OS updates below do not work either.
39
+
40
+ ### Commands from the fleet management
41
+
42
+ From the asset detail a technician (permission `operate`) can start, stop and restart instances on this host, restart ioBroker, and install updates of operating system packages. The agent answers on the topic `reply`; the fleet management logs who did what.
43
+
44
+ - Instances: the same way admin does it, through the instance object (`common.enabled`, or rewriting it for a restart). Only instances of this host; `bee` itself can be restarted but not stopped from afar.
45
+ - Restart of ioBroker: host command `restartController` of js-controller.
46
+ - OS updates: js-controller (6 and newer, Linux) lists upgradeable packages (`apt list --upgradeable`) on every update of the repository, admin triggers that daily, and writes them to `system.host.<host>.osPackageUpdates`. The agent reports this list in the inventory, together with `/var/run/reboot-required`, and on request passes the chosen packages to the host command `upgradeOsPackages`, which runs apt (with sudo if ioBroker does not run as root). Packages that js-controller did not list are refused.
47
+ - Nothing of this while a job (update) is running, and one command at a time.
48
+
38
49
  ## Configuration
39
50
 
40
51
  | Tab | Setting | Meaning |
41
52
  | --- | --- | --- |
42
- | Enrollment | Enrollment URL, token | from the factory image or the fleet manager; the token is stored encrypted |
53
+ | Enrollment | Enrollment URL, token | from the factory image or the fleet manager; the URL is preset to `https://bee.iobroker.click`, the token is stored encrypted |
43
54
  | | comment | free text shown in the fleet management next to the installation, e.g. `Womo Mercedes KA-1525`; sent on enrollment and with the inventory. It helps to recognize the installation but proves nothing: the identity is the device certificate |
44
55
  | Maintenance window | start, end | daily window for updates, may span midnight (e.g. 22:00–05:00) |
45
56
  | | conditions | table of `state operator value`, e.g. `victron.0.soc >= 50`, `modem.0.roaming == false`, `presence.0.home == false` |
@@ -48,6 +59,7 @@ The owner can switch off each kind in the tab *Remote access*; the agent then re
48
59
  | | observation after update, start timeout | verification of a rollout |
49
60
  | | backup before every update | only disable for tests |
50
61
  | Remote access | allow admin, allow vis-2 | whether the fleet manager may open the interface remotely (both allowed by default) |
62
+ | | allow the console | a shell on this system for the fleet manager (off by default, Linux only) |
51
63
 
52
64
  ## States
53
65
 
@@ -66,7 +78,7 @@ Files in `iobroker-data/bee.0/`: `device.json` (certificate and key, mode 0600),
66
78
 
67
79
  ## Not in this version
68
80
 
69
- Platform updates of js-controller and Node.js (with a systemd watchdog outside ioBroker), vis-2 project distribution, remote console (PTY), signed artifacts. See the concept of the beekeeper project.
81
+ Platform updates of js-controller and Node.js (with a systemd watchdog outside ioBroker), vis-2 project distribution, recording of console sessions, signed artifacts. See the concept of the beekeeper project.
70
82
 
71
83
  ## Development
72
84
 
@@ -80,6 +92,17 @@ npm test # unit tests of planner, preflight and diff
80
92
 
81
93
  ## Changelog
82
94
 
95
+ ### 0.2.3 (2026-11-10)
96
+
97
+ - Instances that run as a web extension inside a web instance (`common.webExtension` and `native.webInstance`, e.g. mcp) have no process of their own; they count as running when their web instance runs, as in admin. Before, the fleet management showed them as not running, and the check after an update of such an adapter would have rolled it back.
98
+ - Instances of adapters that only bring files for web (`common.onlyWWW`, e.g. material) have no process either: no longer reported as not running, not checked after an update, no commands.
99
+
100
+ ### 0.2.2 (2026-11-10)
101
+
102
+ - Console: a shell on this system for the fleet management, in the browser of the technician; off unless the owner allows it, Linux with `script` (util-linux) only
103
+ - Enrollment URL preset to `https://bee.iobroker.click` (new instances)
104
+ - Commands from the fleet management: start, stop and restart instances, restart ioBroker, install OS updates listed by js-controller (6 and newer)
105
+
83
106
  ### 0.2.0 (2026-11-10)
84
107
 
85
108
  - Remote access to admin and vis-2 through a tunnel to the fleet server, switchable per kind by the owner
@@ -21,7 +21,7 @@
21
21
  "enrollUrl": {
22
22
  "type": "text",
23
23
  "label": { "en": "Enrollment URL", "de": "Enrollment-URL" },
24
- "placeholder": "https://beekeeper.example.com",
24
+ "placeholder": "https://bee.iobroker.click",
25
25
  "xs": 12,
26
26
  "sm": 12,
27
27
  "md": 6,
@@ -73,8 +73,8 @@
73
73
  "hdr3": {
74
74
  "type": "staticText",
75
75
  "text": {
76
- "en": "Service staff of the fleet management can open admin or vis-2 of this system from afar, without ioBroker.pro and without open ports: on request, this adapter connects to the fleet server for the duration of the access. Every access is logged with person and purpose, and is shown below while it lasts. Changing these settings ends running accesses.",
77
- "de": "Servicepersonal der Flottenverwaltung kann admin oder vis-2 dieses Systems aus der Ferne öffnen, ohne ioBroker.pro und ohne offene Ports: auf Anforderung verbindet sich dieser Adapter für die Dauer des Zugriffs mit dem Flottenserver. Jeder Zugriff wird mit Person und Zweck protokolliert und unten angezeigt, solange er läuft. Eine Änderung dieser Einstellungen beendet laufende Zugriffe."
76
+ "en": "Service staff of the fleet management can open admin or vis-2 of this system from afar, without ioBroker.pro and without open ports: on request, this adapter connects to the fleet server for the duration of the access. Every access is logged with person and purpose, and is shown below while it lasts. Changing these settings ends running accesses. The console is off until you allow it here.",
77
+ "de": "Servicepersonal der Flottenverwaltung kann admin oder vis-2 dieses Systems aus der Ferne öffnen, ohne ioBroker.pro und ohne offene Ports: auf Anforderung verbindet sich dieser Adapter für die Dauer des Zugriffs mit dem Flottenserver. Jeder Zugriff wird mit Person und Zweck protokolliert und unten angezeigt, solange er läuft. Eine Änderung dieser Einstellungen beendet laufende Zugriffe. Die Konsole ist aus, bis Sie sie hier erlauben."
78
78
  },
79
79
  "xs": 12,
80
80
  "sm": 12,
@@ -109,6 +109,20 @@
109
109
  "lg": 6,
110
110
  "xl": 6
111
111
  },
112
+ "allowConsole": {
113
+ "type": "checkbox",
114
+ "label": { "en": "Allow the console (a shell on this system)", "de": "Konsole erlauben (Shell auf diesem System)" },
115
+ "help": {
116
+ "en": "Only Linux. The shell runs as the user of ioBroker: full access to ioBroker, its data and, depending on the setup, to the system",
117
+ "de": "Nur Linux. Die Shell läuft als Nutzer von ioBroker: voller Zugriff auf ioBroker, seine Daten und, je nach Einrichtung, auf das System"
118
+ },
119
+ "newLine": true,
120
+ "xs": 12,
121
+ "sm": 12,
122
+ "md": 6,
123
+ "lg": 6,
124
+ "xl": 6
125
+ },
112
126
  "_remoteAccessBy": {
113
127
  "type": "state",
114
128
  "oid": "info.remoteAccessBy",
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ACTION_DONE = exports.REBOOT_REQUIRED = void 0;
4
+ exports.supportedCommands = supportedCommands;
5
+ exports.osUpdatesFrom = osUpdatesFrom;
6
+ exports.instanceRefusal = instanceRefusal;
7
+ exports.chooseOsPackages = chooseOsPackages;
8
+ const protocol_1 = require("./protocol");
9
+ const instances_1 = require("./instances");
10
+ const util_1 = require("./util");
11
+ /**
12
+ * Commands of the fleet management to this system: start, stop or restart an instance (as admin does it,
13
+ * through the instance object), restart ioBroker, upgrade packages of the operating system. The last two
14
+ * are done by js-controller (host commands restartController and upgradeOsPackages); the agent only passes
15
+ * them on, and only packages js-controller listed itself as upgradeable.
16
+ */
17
+ /** Exists on Debian and Ubuntu when an update asks for a reboot of the system */
18
+ exports.REBOOT_REQUIRED = '/var/run/reboot-required';
19
+ /** What this system can do: OS updates need Linux and js-controller 6 (it lists them and runs apt) */
20
+ function supportedCommands(jsController, platform = process.platform) {
21
+ const commands = ['instance', 'restart'];
22
+ if (platform === 'linux' && jsController && (0, util_1.compareVersions)(jsController, '6.0.0') >= 0) {
23
+ commands.push('osUpgrade');
24
+ }
25
+ return commands;
26
+ }
27
+ /**
28
+ * OS updates from the state system.host.<host>.osPackageUpdates, which js-controller writes on every update
29
+ * of the repository: a JSON list of lines of `apt list --upgradeable`. Undefined if there is no such state.
30
+ *
31
+ * @param state the state of js-controller
32
+ * @param rebootRequired whether the system asks for a reboot
33
+ */
34
+ function osUpdatesFrom(state, rebootRequired) {
35
+ if (!state || typeof state.val !== 'string') {
36
+ return undefined;
37
+ }
38
+ let lines;
39
+ try {
40
+ lines = JSON.parse(state.val);
41
+ }
42
+ catch {
43
+ return undefined;
44
+ }
45
+ if (!Array.isArray(lines)) {
46
+ return undefined;
47
+ }
48
+ const packages = lines
49
+ .filter((l) => typeof l === 'string')
50
+ .map(protocol_1.parseOsPackage)
51
+ .filter((p) => !!p);
52
+ return { packages, checkedAt: state.ts || null, rebootRequired };
53
+ }
54
+ /**
55
+ * Why a command for an instance is not carried out, or null.
56
+ *
57
+ * @param id instance, e.g. "javascript.0"
58
+ * @param action start, stop or restart
59
+ * @param own the instance of the agent itself (bee.0)
60
+ * @param obj the object system.adapter.<id>
61
+ * @param host the host of the agent
62
+ */
63
+ function instanceRefusal(id, action, own, obj, host) {
64
+ if (typeof id !== 'string' || !protocol_1.INSTANCE_ID.test(id)) {
65
+ return `Ungültige Instanz ${String(id)}`;
66
+ }
67
+ if (action !== 'start' && action !== 'stop' && action !== 'restart') {
68
+ return `Unbekannte Aktion ${String(action)}`;
69
+ }
70
+ if (!obj || obj.type !== 'instance') {
71
+ return `Instanz ${id} gibt es auf dem Gerät nicht`;
72
+ }
73
+ if (obj.common.host !== host) {
74
+ return `Instanz ${id} gehört zum Host ${obj.common.host}, nicht zu ${host}`;
75
+ }
76
+ if ((0, instances_1.onlyWww)(obj)) {
77
+ return `${id} hat keinen eigenen Prozess (nur Dateien für web)`;
78
+ }
79
+ if (id === own && action === 'stop') {
80
+ return 'bee stoppen trennt die Anlage von der Flottenverwaltung; das geht nur am Gerät';
81
+ }
82
+ if (action === 'restart' && !obj.common.enabled) {
83
+ return `Instanz ${id} ist ausgeschaltet; starten statt neu starten`;
84
+ }
85
+ const web = (0, instances_1.webExtensionOf)(obj);
86
+ if (action === 'restart' && web) {
87
+ // web ignores a write of the object that changes nothing
88
+ return `${id} läuft als Erweiterung in ${(0, instances_1.webText)(web)} und hat keinen eigenen Prozess; dafür ${(0, instances_1.webText)(web)} neu starten`;
89
+ }
90
+ return null;
91
+ }
92
+ exports.ACTION_DONE = {
93
+ start: 'gestartet',
94
+ stop: 'gestoppt',
95
+ restart: 'neu gestartet',
96
+ };
97
+ /** The packages of a request that js-controller listed, or the names it did not list */
98
+ function chooseOsPackages(listed, wanted) {
99
+ const names = Array.isArray(wanted) ? wanted.filter((n) => typeof n === 'string') : [];
100
+ return {
101
+ packages: listed.filter(p => names.includes(p.name)),
102
+ unknown: names.filter(n => !listed.some(p => p.name === n)),
103
+ };
104
+ }
105
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/lib/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,218 @@
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.MAX_SHELLS = void 0;
7
+ exports.findScript = findScript;
8
+ exports.loginShell = loginShell;
9
+ exports.consoleUser = consoleUser;
10
+ exports.parentOf = parentOf;
11
+ exports.startShell = startShell;
12
+ const node_child_process_1 = require("node:child_process");
13
+ const node_fs_1 = require("node:fs");
14
+ const node_os_1 = __importDefault(require("node:os"));
15
+ const tunnel_1 = require("./tunnel");
16
+ /**
17
+ * Console of the remote access: a shell on this system for one terminal in the browser of the technician.
18
+ * Each stream of the tunnel is one shell. No native module: `script` of util-linux (on every Debian) gives the
19
+ * shell a pseudo terminal, and `stty` sets the size of its window. Only Linux, and only when the owner allows it.
20
+ */
21
+ /** Shells per access session at the same time */
22
+ exports.MAX_SHELLS = 4;
23
+ /** `script` of util-linux, null if this system has none (then there is no console) */
24
+ function findScript() {
25
+ if (process.platform !== 'linux') {
26
+ return null;
27
+ }
28
+ return ['/usr/bin/script', '/bin/script'].find(p => (0, node_fs_1.existsSync)(p)) ?? null;
29
+ }
30
+ function findStty() {
31
+ return ['/usr/bin/stty', '/bin/stty'].find(p => (0, node_fs_1.existsSync)(p)) ?? 'stty';
32
+ }
33
+ /** A shell to log in with; the one of a service user is often nologin, so not taken from /etc/passwd */
34
+ function loginShell(env = process.env) {
35
+ return ([env.SHELL, '/bin/bash', '/bin/sh'].find(s => !!s && !/(nologin|false)$/.test(s) && (0, node_fs_1.existsSync)(s)) ?? '/bin/sh');
36
+ }
37
+ /** The user the shell runs as: the user of ioBroker */
38
+ function consoleUser() {
39
+ try {
40
+ return node_os_1.default.userInfo().username;
41
+ }
42
+ catch {
43
+ return String(process.getuid?.() ?? '');
44
+ }
45
+ }
46
+ /** Parent process id from /proc/<pid>/stat; the name in parentheses may contain spaces and parentheses */
47
+ function parentOf(stat) {
48
+ const rest = stat.slice(stat.lastIndexOf(')') + 2).split(' ');
49
+ return parseInt(rest[1], 10);
50
+ }
51
+ /** The child of `script` (the shell) and the terminal it reads from, e.g. /dev/pts/3 */
52
+ function findTerminal(scriptPid) {
53
+ for (const entry of (0, node_fs_1.readdirSync)('/proc')) {
54
+ if (!/^\d+$/.test(entry)) {
55
+ continue;
56
+ }
57
+ try {
58
+ if (parentOf((0, node_fs_1.readFileSync)(`/proc/${entry}/stat`, 'utf8')) === scriptPid) {
59
+ const tty = (0, node_fs_1.readlinkSync)(`/proc/${entry}/fd/0`);
60
+ if (tty.startsWith('/dev/pts/')) {
61
+ return { pid: parseInt(entry, 10), tty };
62
+ }
63
+ }
64
+ }
65
+ catch {
66
+ // the process ended meanwhile, or is not ours
67
+ }
68
+ }
69
+ return null;
70
+ }
71
+ function signalGroup(pid, signal) {
72
+ if (!pid) {
73
+ return;
74
+ }
75
+ try {
76
+ process.kill(-pid, signal);
77
+ }
78
+ catch {
79
+ // already gone
80
+ }
81
+ }
82
+ /**
83
+ * Runs one shell for a stream of the tunnel until one of both ends.
84
+ *
85
+ * @param stream stream of the tunnel, carrying console messages (see tunnel.ts)
86
+ * @param opts working directory, logger and who opened it
87
+ */
88
+ function startShell(stream, opts) {
89
+ const script = findScript();
90
+ if (!script) {
91
+ stream.end((0, tunnel_1.consoleMessage)(tunnel_1.CONSOLE.EXIT, Buffer.from('keine Konsole auf diesem System')));
92
+ return;
93
+ }
94
+ const shell = loginShell();
95
+ const home = (() => {
96
+ try {
97
+ return node_os_1.default.userInfo().homedir;
98
+ }
99
+ catch {
100
+ return opts.cwd;
101
+ }
102
+ })();
103
+ // a fresh login environment instead of the one of the adapter process
104
+ const env = {
105
+ HOME: home,
106
+ USER: consoleUser(),
107
+ LOGNAME: consoleUser(),
108
+ SHELL: shell,
109
+ PATH: process.env.PATH || '/usr/local/bin:/usr/bin:/bin',
110
+ LANG: process.env.LANG || 'C.UTF-8',
111
+ TERM: 'xterm-256color',
112
+ COLORTERM: 'truecolor',
113
+ };
114
+ // detached: own process group, so that the end reaches everything started in it
115
+ const child = (0, node_child_process_1.spawn)(script, ['-qfec', `exec ${shell} -l`, '/dev/null'], {
116
+ cwd: (0, node_fs_1.existsSync)(opts.cwd) ? opts.cwd : home,
117
+ env,
118
+ detached: true,
119
+ stdio: ['pipe', 'pipe', 'pipe'],
120
+ });
121
+ let terminal = null;
122
+ let size = null;
123
+ let ended = false;
124
+ let killTimer = null;
125
+ const applySize = () => {
126
+ if (terminal && size) {
127
+ // the kernel tells the shell (SIGWINCH)
128
+ (0, node_child_process_1.execFile)(findStty(), ['-F', terminal.tty, 'cols', String(size.cols), 'rows', String(size.rows)], err => {
129
+ if (err) {
130
+ opts.log.debug(`Console: stty: ${err.message}`);
131
+ }
132
+ });
133
+ }
134
+ };
135
+ // the shell needs a moment until it runs on its terminal
136
+ let tries = 0;
137
+ const lookup = setInterval(() => {
138
+ if (ended || terminal || ++tries > 60 || !child.pid) {
139
+ clearInterval(lookup);
140
+ return;
141
+ }
142
+ terminal = findTerminal(child.pid);
143
+ if (terminal) {
144
+ clearInterval(lookup);
145
+ applySize();
146
+ }
147
+ }, 50);
148
+ const stop = () => {
149
+ // nobody waits for a drain any more: read the pipes to their end, or the end of the shell is never seen
150
+ child.stdout?.resume();
151
+ child.stderr?.resume();
152
+ if (killTimer || ended) {
153
+ return;
154
+ }
155
+ // hang up: the shell and what runs in its foreground get SIGHUP, as when an SSH connection drops
156
+ signalGroup(terminal?.pid, 'SIGHUP');
157
+ signalGroup(child.pid, 'SIGHUP');
158
+ killTimer = setTimeout(() => {
159
+ signalGroup(terminal?.pid, 'SIGKILL');
160
+ signalGroup(child.pid, 'SIGKILL');
161
+ }, 3000);
162
+ };
163
+ const forward = (chunk) => {
164
+ if (stream.destroyed || !stream.writable) {
165
+ // the browser is gone, the shell is being hung up: drop what it still writes
166
+ return;
167
+ }
168
+ if (!stream.write((0, tunnel_1.consoleMessage)(tunnel_1.CONSOLE.DATA, chunk))) {
169
+ // the browser is slow: hold the shell back
170
+ child.stdout?.pause();
171
+ child.stderr?.pause();
172
+ stream.once('drain', () => {
173
+ child.stdout?.resume();
174
+ child.stderr?.resume();
175
+ });
176
+ }
177
+ };
178
+ child.stdout?.on('data', forward);
179
+ child.stderr?.on('data', forward);
180
+ child.stdin?.on('error', () => { });
181
+ const reader = new tunnel_1.ConsoleReader((type, payload) => {
182
+ if (type === tunnel_1.CONSOLE.DATA) {
183
+ child.stdin?.write(payload);
184
+ }
185
+ else if (type === tunnel_1.CONSOLE.RESIZE && payload.length >= 4) {
186
+ const clamp = (n) => Math.max(1, Math.min(1000, n));
187
+ size = { cols: clamp(payload.readUInt16BE(0)), rows: clamp(payload.readUInt16BE(2)) };
188
+ applySize();
189
+ }
190
+ });
191
+ stream.on('data', (chunk) => {
192
+ if (!reader.push(chunk)) {
193
+ stream.destroy(new Error('invalid console message'));
194
+ }
195
+ });
196
+ stream.on('end', stop);
197
+ stream.on('close', stop);
198
+ stream.on('error', stop);
199
+ child.on('error', err => {
200
+ opts.log.warn(`Console: ${err.message}`);
201
+ stop();
202
+ });
203
+ child.on('close', (code, signal) => {
204
+ ended = true;
205
+ clearInterval(lookup);
206
+ if (killTimer) {
207
+ clearTimeout(killTimer);
208
+ }
209
+ const result = signal ? signal : String(code ?? '');
210
+ if (!stream.destroyed && stream.writable) {
211
+ stream.end((0, tunnel_1.consoleMessage)(tunnel_1.CONSOLE.EXIT, Buffer.from(result)));
212
+ }
213
+ opts.log.info(`Console of ${opts.by} ended (${result})`);
214
+ opts.onEnd?.(result);
215
+ });
216
+ opts.log.info(`Console: shell ${shell} as ${consoleUser()} started for ${opts.by}`);
217
+ }
218
+ //# sourceMappingURL=console.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/lib/console.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ /**
3
+ * Whether an instance runs. Most instances have a process of their own and report it in
4
+ * system.adapter.<id>.alive. An adapter with a web extension that is set to run inside a web instance
5
+ * (common.webExtension and native.webInstance, the rule of admin) has no process of its own: its alive
6
+ * stays false while it runs inside web. It runs when its web instance runs ("*": any of them) and it does
7
+ * not report the opposite in its state info.extension.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.webExtensionOf = webExtensionOf;
11
+ exports.instanceRunning = instanceRunning;
12
+ exports.onlyWww = onlyWww;
13
+ exports.webText = webText;
14
+ /**
15
+ * The web instance an instance runs in as a web extension, e.g. "web.0", "*" for every web instance;
16
+ * undefined if it has a process of its own.
17
+ *
18
+ * @param obj the object system.adapter.<id>
19
+ */
20
+ function webExtensionOf(obj) {
21
+ const web = obj.native?.webInstance;
22
+ if (obj.common.mode !== 'daemon' ||
23
+ !obj.common.enabled ||
24
+ !obj.common.webExtension ||
25
+ typeof web !== 'string' ||
26
+ !web) {
27
+ return undefined;
28
+ }
29
+ return web.replace(/^system\.adapter\./, '');
30
+ }
31
+ /**
32
+ * Whether an instance runs, also as a web extension.
33
+ *
34
+ * @param obj the object system.adapter.<id>
35
+ * @param readState reads a foreign state
36
+ * @param webInstances the enabled web instances, e.g. ["web.0"]; only asked for "*"
37
+ */
38
+ async function instanceRunning(obj, readState, webInstances) {
39
+ const web = webExtensionOf(obj);
40
+ if (!web) {
41
+ return !!(await readState(`${obj._id}.alive`))?.val;
42
+ }
43
+ const id = obj._id.replace(/^system\.adapter\./, '');
44
+ if ((await readState(`${id}.info.extension`))?.val === false) {
45
+ return false;
46
+ }
47
+ for (const w of web === '*' ? await webInstances() : [web]) {
48
+ if ((await readState(`system.adapter.${w}.alive`))?.val) {
49
+ return true;
50
+ }
51
+ }
52
+ return false;
53
+ }
54
+ /**
55
+ * An adapter that only brings files for web (common.onlyWWW, e.g. material): js-controller starts no
56
+ * process for it, except for the old vis.
57
+ *
58
+ * @param obj the object system.adapter.<id>
59
+ */
60
+ function onlyWww(obj) {
61
+ return !!obj.common.onlyWWW && obj.common.name !== 'vis';
62
+ }
63
+ /** "web.0", or "web" for every web instance */
64
+ function webText(web) {
65
+ return web === '*' ? 'web' : web;
66
+ }
67
+ //# sourceMappingURL=instances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instances.js","sourceRoot":"","sources":["../../src/lib/instances.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAUH,wCAYC;AASD,0CAmBC;AAQD,0BAEC;AAGD,0BAEC;AA7DD;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,GAA4B;IACvD,MAAM,GAAG,GAAI,GAAG,CAAC,MAA8C,EAAE,WAAW,CAAC;IAC7E,IACI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ;QAC5B,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;QACnB,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY;QACxB,OAAO,GAAG,KAAK,QAAQ;QACvB,CAAC,GAAG,EACN,CAAC;QACC,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,eAAe,CACjC,GAA4B,EAC5B,SAAsB,EACtB,YAAqC;IAErC,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,OAAO,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;IACxD,CAAC;IACD,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,EAAE,GAAG,KAAK,KAAK,EAAE,CAAC;QAC3D,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,OAAO,CAAC,GAA4B;IAChD,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;AAC7D,CAAC;AAED,+CAA+C;AAC/C,SAAgB,OAAO,CAAC,GAAW;IAC/B,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;AACrC,CAAC"}
@@ -11,6 +11,7 @@ exports.installedVersions = installedVersions;
11
11
  const node_child_process_1 = require("node:child_process");
12
12
  const promises_1 = require("node:fs/promises");
13
13
  const node_os_1 = __importDefault(require("node:os"));
14
+ const instances_1 = require("./instances");
14
15
  /**
15
16
  * Collects the inventory of this ioBroker system. Versions and system data only;
16
17
  * no measured values of the end customer (data minimization).
@@ -90,14 +91,25 @@ async function collectInventory(adapter, opts) {
90
91
  });
91
92
  const instances = {};
92
93
  let offDevice = false;
94
+ // web instances on any host, for extensions that run in every one of them
95
+ const webInstances = () => Promise.resolve(instanceRows.rows
96
+ .map(r => r.value)
97
+ .filter(o => o?.common.name === 'web' && o.common.enabled)
98
+ .map(o => o._id.replace(/^system\.adapter\./, '')));
93
99
  for (const row of instanceRows.rows) {
94
100
  const obj = row.value;
95
101
  if (!obj || obj.common.host !== adapter.host) {
96
102
  continue;
97
103
  }
98
104
  const id = obj._id.replace(/^system\.adapter\./, '');
99
- const alive = await adapter.getForeignStateAsync(`${obj._id}.alive`);
100
- instances[id] = { enabled: !!obj.common.enabled, alive: !!alive?.val, mode: obj.common.mode };
105
+ const web = (0, instances_1.webExtensionOf)(obj);
106
+ instances[id] = {
107
+ enabled: !!obj.common.enabled,
108
+ alive: await (0, instances_1.instanceRunning)(obj, sid => adapter.getForeignStateAsync(sid), webInstances),
109
+ mode: obj.common.mode,
110
+ ...(web ? { webInstance: web } : {}),
111
+ ...((0, instances_1.onlyWww)(obj) ? { onlyWWW: true } : {}),
112
+ };
101
113
  if (obj.common.name === 'backitup' && obj.common.enabled) {
102
114
  const native = obj.native;
103
115
  offDevice ||= OFF_DEVICE_KEYS.some(k => native[k] === true);
@@ -1 +1 @@
1
- {"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../src/lib/inventory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../src/lib/inventory.ts"],"names":[],"mappings":";;;;;AAyCA,4BAOC;AAED,4BAOC;AAED,wCAGC;AAaD,4CA+EC;AAGD,8CAEC;AA/JD,2DAA8C;AAC9C,+CAAoD;AACpD,sDAAyB;AACzB,2CAAuE;AAGvE;;;GAGG;AAEH,KAAK,UAAU,QAAQ,CAAC,IAAY;IAChC,IAAI,CAAC;QACD,OAAO,CAAC,MAAM,IAAA,mBAAQ,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED,KAAK,UAAU,MAAM;IACjB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,OAAO,IAAI,6BAA6B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,iBAAE,CAAC,IAAI,EAAE,IAAI,iBAAE,CAAC,OAAO,EAAE,EAAE,IAAI,iBAAE,CAAC,OAAO,EAAE,EAAE,CAAC;AACvE,CAAC;AAED,IAAI,UAAU,GAAkB,IAAI,CAAC;AACrC,KAAK,UAAU,MAAM;IACjB,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACtB,UAAU,GAAG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YACrC,IAAA,6BAAQ,EACJ,iBAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAC7C,CAAC,IAAI,CAAC,EACN,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE,EACrD,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CACrD,CAAC;QACN,CAAC,CAAC,CAAC;IACP,CAAC;IACD,OAAO,UAAU,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,qFAAqF;AAC9E,KAAK,UAAU,QAAQ;IAC1B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,IAAY;IACvC,IAAI,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,IAAA,iBAAM,EAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,cAAc;IAChC,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,uCAAuC,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,gEAAgE;AAChE,MAAM,eAAe,GAAG;IACpB,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,oBAAoB;IACpB,iBAAiB;IACjB,eAAe;IACf,aAAa;CAChB,CAAC;AAEK,KAAK,UAAU,gBAAgB,CAClC,OAAyB,EACzB,IAA6F;IAE7F,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE;QACtE,QAAQ,EAAE,iBAAiB;QAC3B,MAAM,EAAE,kBAAkB;KAC7B,CAAC,CAAC;IACH,MAAM,QAAQ,GAAqC,EAAE,CAAC;IACtD,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;QACjC,IAAI,MAAM,EAAE,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;gBACpB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3E,CAAC;QACN,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC,QAAQ,EAAE,UAAU,EAAE;QACxE,QAAQ,EAAE,iBAAiB;QAC3B,MAAM,EAAE,kBAAkB;KAC7B,CAAC,CAAC;IACH,MAAM,SAAS,GAAsC,EAAE,CAAC;IACxD,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,0EAA0E;IAC1E,MAAM,YAAY,GAAG,GAAsB,EAAE,CACzC,OAAO,CAAC,OAAO,CACX,YAAY,CAAC,IAAI;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAA4C,CAAC;SACxD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;SACzD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,CAC1D,CAAC;IACN,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,GAAG,CAAC,KAA4C,CAAC;QAC7D,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;YAC3C,SAAS;QACb,CAAC;QACD,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,IAAA,0BAAc,EAAC,GAAG,CAAC,CAAC;QAChC,SAAS,CAAC,EAAE,CAAC,GAAG;YACZ,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;YAC7B,KAAK,EAAE,MAAM,IAAA,2BAAe,EAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC;YACzF,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;YACrB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpC,GAAG,CAAC,IAAA,mBAAO,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAiC,CAAC;YACrD,SAAS,KAAK,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAChE,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,eAAe,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,yBAAyB,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,iBAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;IAE3G,OAAO;QACH,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,iBAAE,CAAC,QAAQ,EAAE;QACvC,QAAQ,EAAE;YACN,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,IAAI,EAAE;YACrD,IAAI,EAAE,OAAO,CAAC,OAAO;YACrB,GAAG,EAAE,MAAM,MAAM,EAAE;YACnB,QAAQ;YACR,SAAS;SACZ;QACD,MAAM,EAAE;YACJ,QAAQ,EAAE,iBAAE,CAAC,QAAQ,EAAE;YACvB,IAAI,EAAE,iBAAE,CAAC,IAAI,EAAE;YACf,EAAE,EAAE,MAAM,MAAM,EAAE;YAClB,MAAM,EAAE,iBAAE,CAAC,OAAO,EAAE;YACpB,KAAK;YACL,QAAQ,EAAE,iBAAE,CAAC,QAAQ,EAAE;YACvB,SAAS,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;SAC9B;QACD,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,SAAS,EAAE;KAC5D,CAAC;AACN,CAAC;AAED,mDAAmD;AACnD,SAAgB,iBAAiB,CAAC,GAAc;IAC5C,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACrG,CAAC"}
@@ -9,8 +9,9 @@
9
9
  * fleet/<tenant>/<device>/state device -> server heartbeat, online flag (also Last Will)
10
10
  * fleet/<tenant>/<device>/inventory device -> server full inventory or diff to the last one
11
11
  * fleet/<tenant>/<device>/result device -> server progress and result of reconciliation
12
+ * fleet/<tenant>/<device>/reply device -> server progress and result of a command (JobMessage.ref)
12
13
  * fleet/<tenant>/<device>/desired server -> device desired state, RETAINED
13
- * fleet/<tenant>/<device>/job server -> device one-shot requests (resync, refresh)
14
+ * fleet/<tenant>/<device>/job server -> device one-shot requests (resync, refresh, tunnel, commands)
14
15
  * fleet/<tenant>/control server -> device fleet-wide control (emergency stop), RETAINED
15
16
  *
16
17
  * Payloads are JSON, gzip-compressed. Receivers accept plain JSON as well.
@@ -19,10 +20,11 @@
19
20
  * WebSocket to TUNNEL_PATH of the server and carries the connections of the browser (see tunnel.ts).
20
21
  */
21
22
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.TERMINAL_JOB_STATES = exports.TUNNEL_PATH = exports.ACCESS_KINDS = exports.MAX_COMMENT_LENGTH = exports.PROTOCOL_VERSION = void 0;
23
+ exports.TERMINAL_JOB_STATES = exports.TUNNEL_PATH = exports.ACCESS_KINDS = exports.INSTANCE_ID = exports.MAX_COMMENT_LENGTH = exports.PROTOCOL_VERSION = void 0;
23
24
  exports.deviceTopic = deviceTopic;
24
25
  exports.controlTopic = controlTopic;
25
26
  exports.normalizeComment = normalizeComment;
27
+ exports.parseOsPackage = parseOsPackage;
26
28
  exports.PROTOCOL_VERSION = 1;
27
29
  function deviceTopic(tenantId, deviceId, topic) {
28
30
  return `fleet/${tenantId}/${deviceId}/${topic}`;
@@ -48,7 +50,20 @@ function normalizeComment(value) {
48
50
  .trim();
49
51
  return s || undefined;
50
52
  }
51
- exports.ACCESS_KINDS = ['admin', 'vis'];
53
+ /**
54
+ * Parses a line of `apt list --upgradeable`, e.g.
55
+ * "openssl/stable-security 3.0.15-1~deb12u1 arm64 [upgradable from: 3.0.14-1~deb12u2]"
56
+ */
57
+ function parseOsPackage(line) {
58
+ const m = /^([a-z0-9][a-z0-9+.-]*)\/\S*\s+(\S+)(?:.*\[[^\]:]*:\s*([^\]\s]+)\])?/i.exec(line.trim());
59
+ if (!m) {
60
+ return null;
61
+ }
62
+ return { name: m[1], version: m[2], ...(m[3] ? { from: m[3] } : {}) };
63
+ }
64
+ /** Instance id as the commands accept it, e.g. "javascript.0" */
65
+ exports.INSTANCE_ID = /^[a-z0-9][a-z0-9_-]*\.\d{1,4}$/;
66
+ exports.ACCESS_KINDS = ['admin', 'vis', 'console'];
52
67
  /** WebSocket path of the tunnel endpoint on the server */
53
68
  exports.TUNNEL_PATH = '/tunnel';
54
69
  exports.TERMINAL_JOB_STATES = ['done', 'blocked'];