smart-home-engine 1.34.3 → 1.35.0
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/dist/web/assets/{index-BtBtSJng.js → index-DfNXDuwc.js} +110 -108
- package/dist/web/assets/{index-CXLA5efM.css → index-DwaZ1Sfz.css} +1 -1
- package/dist/web/assets/{tsMode-CFhaNPy5.js → tsMode-DS17PuxG.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/service/she-servicectl +19 -3
- package/src/lib/services-host.js +1 -1
- package/src/web/services-api.js +40 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{m as O}from"./monaco-langs-DKJI_o9J.js";import{t as I}from"./index-
|
|
1
|
+
import{m as O}from"./monaco-langs-DKJI_o9J.js";import{t as I}from"./index-DfNXDuwc.js";/*!-----------------------------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
|
|
4
4
|
* Released under the MIT license
|
package/dist/web/index.html
CHANGED
|
@@ -172,10 +172,10 @@
|
|
|
172
172
|
}
|
|
173
173
|
})();
|
|
174
174
|
</script>
|
|
175
|
-
<script type="module" crossorigin src="/assets/index-
|
|
175
|
+
<script type="module" crossorigin src="/assets/index-DfNXDuwc.js"></script>
|
|
176
176
|
<link rel="modulepreload" crossorigin href="/assets/monaco-langs-DKJI_o9J.js">
|
|
177
177
|
<link rel="stylesheet" crossorigin href="/assets/monaco-langs-DyX1CsEw.css">
|
|
178
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
178
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DwaZ1Sfz.css">
|
|
179
179
|
</head>
|
|
180
180
|
<body>
|
|
181
181
|
<div id="app"></div>
|
package/package.json
CHANGED
package/service/she-servicectl
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
# she-servicectl schema <adapter>
|
|
25
25
|
# she-servicectl install <adapter> <instance> (options as KEY=VALUE lines on stdin)
|
|
26
26
|
# she-servicectl uninstall <adapter> <instance>
|
|
27
|
-
# she-servicectl npm <adapter> version|origin|install|update
|
|
27
|
+
# she-servicectl npm <adapter> version|origin|install|update|uninstall [--purge] (uninstall: package, template unit; --purge also /etc and /var/lib)
|
|
28
28
|
# she-servicectl files <adapter> <instance> JSON listing of /etc/<adapter>/ and /var/lib/<adapter>/<instance>/
|
|
29
29
|
# she-servicectl file <adapter> <instance> read|write <path> a file inside those two directories (write: content on stdin)
|
|
30
30
|
# she-servicectl asset <adapter> <relpath> a file shipped in the adapter package (example, schema)
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
set -eu
|
|
42
42
|
|
|
43
|
-
VERSION=
|
|
43
|
+
VERSION=9
|
|
44
44
|
BROKER_ENV=/etc/mqtt-interfaces/broker.env
|
|
45
45
|
UNIT_DIR=/etc/systemd/system
|
|
46
46
|
|
|
@@ -599,9 +599,25 @@ cmd_teardown() {
|
|
|
599
599
|
}
|
|
600
600
|
|
|
601
601
|
cmd_npm() {
|
|
602
|
-
[ $# -
|
|
602
|
+
[ $# -ge 2 ] || die "usage: npm <adapter> version|origin|install|update|uninstall [--purge]"
|
|
603
603
|
need_adapter "$1"
|
|
604
604
|
case "$2" in
|
|
605
|
+
uninstall)
|
|
606
|
+
# the package and what it left behind; instances must be gone (she removes them first)
|
|
607
|
+
if [ -n "$(ls "/etc/$1"/*.env 2>/dev/null)" ]; then die "instances of $1 still exist — uninstall them first"; fi
|
|
608
|
+
npm=$(adapter_npm "$1")
|
|
609
|
+
node=$(adapter_node "$1")
|
|
610
|
+
PATH="$(dirname "$node"):$PATH" "$npm" uninstall -g "$1" --no-audit --no-fund 2>&1 || true
|
|
611
|
+
dir=$(adapter_dir "$1" 2>/dev/null || true)
|
|
612
|
+
if [ -n "$dir" ] && [ -d "$dir" ]; then case "$dir" in */node_modules/"$1") rm -rf "$dir"; printf 'removed %s\n' "$dir" ;; esac; fi
|
|
613
|
+
[ -L "/usr/local/bin/$1" ] && [ ! -e "/usr/local/bin/$1" ] && rm -f "/usr/local/bin/$1"
|
|
614
|
+
if [ -f "$UNIT_DIR/$1@.service" ]; then rm -f "$UNIT_DIR/$1@.service"; systemctl daemon-reload; printf 'removed %s\n' "$UNIT_DIR/$1@.service"; fi
|
|
615
|
+
if [ "${3:-}" = "--purge" ]; then
|
|
616
|
+
for d in "/etc/$1" "/var/lib/$1"; do [ -d "$d" ] && rm -rf "$d" && printf 'removed %s\n' "$d"; done
|
|
617
|
+
else
|
|
618
|
+
for d in "/etc/$1" "/var/lib/$1"; do [ -d "$d" ] && rmdir "$d" 2>/dev/null && printf 'removed empty %s\n' "$d"; done
|
|
619
|
+
fi
|
|
620
|
+
printf '%s uninstalled\n' "$1" ;;
|
|
605
621
|
version) adapter_version "$1"; printf '\n' ;;
|
|
606
622
|
origin) adapter_origin "$1"; printf '\n' ;;
|
|
607
623
|
install|update)
|
package/src/lib/services-host.js
CHANGED
|
@@ -26,7 +26,7 @@ const { execFile, spawn } = require('child_process');
|
|
|
26
26
|
const sshDeploy = require('./ssh-deploy');
|
|
27
27
|
|
|
28
28
|
const HELPER = '/usr/local/bin/she-servicectl';
|
|
29
|
-
const HELPER_VERSION =
|
|
29
|
+
const HELPER_VERSION = 9; // must match VERSION in service/she-servicectl
|
|
30
30
|
/** Default identity for services.hosts[].ssh — one key for all managed hosts (I5). */
|
|
31
31
|
const DEFAULT_SERVICES_IDENTITY = '~/.she/ssh/services_id_ed25519';
|
|
32
32
|
/** The helper as shipped with this she version (copied to remote hosts by the deploy route). */
|
package/src/web/services-api.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* POST /she/services/hosts/:host/adapters/:adapter/update { force? } → npm install -g, restart instances
|
|
19
19
|
* POST /she/services/hosts/:host/units/:adapter/:instance/:action start|stop|restart|enable|disable
|
|
20
20
|
* DELETE /she/services/hosts/:host/units/:adapter/:instance <adapter> --uninstall
|
|
21
|
+
* POST /she/services/hosts/:host/adapters/:adapter/uninstall every instance (--uninstall, dynsec identity), then the package, /etc and /var/lib
|
|
21
22
|
* GET /she/services/hosts/:host/units/:adapter/:instance/logs journal tail (?n=)
|
|
22
23
|
* POST /she/services/hosts/:host/units/:adapter/:instance/logs/follow start/renew a journal follower (serviceLog WS)
|
|
23
24
|
* DELETE /she/services/hosts/:host/units/:adapter/:instance/logs/follow stop it
|
|
@@ -885,22 +886,52 @@ router.post('/hosts/:host/units/:adapter/:instance/:action', async (req, res) =>
|
|
|
885
886
|
});
|
|
886
887
|
|
|
887
888
|
// DELETE /she/services/hosts/:host/units/:adapter/:instance — uninstall
|
|
889
|
+
/** <adapter> --uninstall --name <instance> on the host, plus the instance's dynsec identity if it has one. */
|
|
890
|
+
async function uninstallInstance(entry, adapter, instance) {
|
|
891
|
+
stopFollower(followKey(entry.driver.name, adapter, instance));
|
|
892
|
+
let dynsecClient = null;
|
|
893
|
+
try {
|
|
894
|
+
dynsecClient = parseEnvFile((await entry.driver.exec(['env', adapter, instance, 'read'])).stdout)[DYNSEC_MARKER] || null;
|
|
895
|
+
} catch {
|
|
896
|
+
/* no env file */
|
|
897
|
+
}
|
|
898
|
+
const { stdout } = await entry.driver.exec(['uninstall', adapter, instance], { timeout: 60000 });
|
|
899
|
+
if (dynsecClient) await deleteInstanceCredentials(dynsecClient);
|
|
900
|
+
return { output: stdout, dynsecRemoved: Boolean(dynsecClient) };
|
|
901
|
+
}
|
|
902
|
+
|
|
888
903
|
router.delete('/hosts/:host/units/:adapter/:instance', async (req, res) => {
|
|
889
904
|
const entry = resolve(req, res, { adapter: true, instance: true });
|
|
890
905
|
if (!entry) return;
|
|
891
906
|
if (req.params.instance === LEGACY) return res.status(400).json({ error: 'a legacy unit is not uninstalled from here — migrate it to an instance first', code: 'LEGACY' });
|
|
892
907
|
try {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
908
|
+
res.json({ ok: true, ...(await uninstallInstance(entry, req.params.adapter, req.params.instance)) });
|
|
909
|
+
} catch (err) {
|
|
910
|
+
hostError(res, err);
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
// POST /she/services/hosts/:host/adapters/:adapter/uninstall — the adapter with all its instances
|
|
915
|
+
router.post('/hosts/:host/adapters/:adapter/uninstall', async (req, res) => {
|
|
916
|
+
const entry = resolve(req, res, { adapter: true });
|
|
917
|
+
if (!entry) return;
|
|
918
|
+
const adapter = req.params.adapter;
|
|
919
|
+
try {
|
|
920
|
+
const list = parseList((await entry.driver.exec(['list'])).stdout);
|
|
921
|
+
if ((list.legacy || []).some((l) => l.adapter === adapter)) {
|
|
922
|
+
return res.status(409).json({ error: `${adapter} still runs as a pre-core unit (${adapter}.service) — migrate or stop it by hand first`, code: 'LEGACY' });
|
|
923
|
+
}
|
|
924
|
+
const instances = (list.instances || []).filter((i) => i.adapter === adapter).map((i) => i.instance);
|
|
925
|
+
const removed = [];
|
|
926
|
+
for (const instance of instances) {
|
|
927
|
+
await uninstallInstance(entry, adapter, instance);
|
|
928
|
+
removed.push(instance);
|
|
899
929
|
}
|
|
900
|
-
const { stdout } = await entry.driver.exec(['
|
|
901
|
-
|
|
902
|
-
res.json({ ok: true,
|
|
930
|
+
const { stdout } = await entry.driver.exec(['npm', adapter, 'uninstall', '--purge'], { timeout: 120000 });
|
|
931
|
+
invalidateHosts();
|
|
932
|
+
res.json({ ok: true, removedInstances: removed, output: stdout });
|
|
903
933
|
} catch (err) {
|
|
934
|
+
invalidateHosts();
|
|
904
935
|
hostError(res, err);
|
|
905
936
|
}
|
|
906
937
|
});
|