@iobroker/js-controller-cli 7.2.5 → 8.0.0-alpha.11-20261103-58da667b3
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/build/cjs/index.js +3 -3
- package/build/cjs/lib/_Types.d.ts +8 -1
- package/build/cjs/lib/cli/cliCert.d.ts +7 -4
- package/build/cjs/lib/cli/cliCert.js +10 -6
- package/build/cjs/lib/cli/cliCert.js.map +2 -2
- package/build/cjs/lib/cli/cliCommand.d.ts +63 -15
- package/build/cjs/lib/cli/cliCommand.js +8 -1
- package/build/cjs/lib/cli/cliCommand.js.map +2 -2
- package/build/cjs/lib/cli/cliCompact.d.ts +5 -2
- package/build/cjs/lib/cli/cliCompact.js +9 -2
- package/build/cjs/lib/cli/cliCompact.js.map +2 -2
- package/build/cjs/lib/cli/cliDebug.d.ts +5 -2
- package/build/cjs/lib/cli/cliDebug.js +8 -1
- package/build/cjs/lib/cli/cliDebug.js.map +2 -2
- package/build/cjs/lib/cli/cliHost.d.ts +13 -10
- package/build/cjs/lib/cli/cliHost.js +13 -5
- package/build/cjs/lib/cli/cliHost.js.map +2 -2
- package/build/cjs/lib/cli/cliLogs.d.ts +9 -3
- package/build/cjs/lib/cli/cliLogs.js +12 -1
- package/build/cjs/lib/cli/cliLogs.js.map +2 -2
- package/build/cjs/lib/cli/cliMessage.d.ts +2 -1
- package/build/cjs/lib/cli/cliMessage.js +5 -0
- package/build/cjs/lib/cli/cliMessage.js.map +2 -2
- package/build/cjs/lib/cli/cliObjects.d.ts +21 -18
- package/build/cjs/lib/cli/cliObjects.js +51 -33
- package/build/cjs/lib/cli/cliObjects.js.map +2 -2
- package/build/cjs/lib/cli/cliPlugin.d.ts +3 -3
- package/build/cjs/lib/cli/cliPlugin.js +6 -0
- package/build/cjs/lib/cli/cliPlugin.js.map +2 -2
- package/build/cjs/lib/cli/cliProcess.d.ts +17 -7
- package/build/cjs/lib/cli/cliProcess.js +77 -24
- package/build/cjs/lib/cli/cliProcess.js.map +3 -3
- package/build/cjs/lib/cli/cliStates.d.ts +7 -4
- package/build/cjs/lib/cli/cliStates.js +14 -6
- package/build/cjs/lib/cli/cliStates.js.map +2 -2
- package/build/cjs/lib/cli/cliTools.js +11 -0
- package/build/cjs/lib/cli/cliTools.js.map +1 -1
- package/build/cjs/lib/cli/messages.js +47 -46
- package/build/cjs/lib/cli/messages.js.map +1 -1
- package/build/cjs/lib/progressBar.d.ts +59 -0
- package/build/cjs/lib/progressBar.js +115 -0
- package/build/cjs/lib/progressBar.js.map +7 -0
- package/build/cjs/lib/setup/customError.d.ts +4 -0
- package/build/cjs/lib/setup/customError.js +7 -0
- package/build/cjs/lib/setup/customError.js.map +2 -2
- package/build/cjs/lib/setup/dbConnection.js +69 -64
- package/build/cjs/lib/setup/dbConnection.js.map +3 -3
- package/build/cjs/lib/setup/formatters.d.ts +4 -4
- package/build/cjs/lib/setup/formatters.js +5 -0
- package/build/cjs/lib/setup/formatters.js.map +2 -2
- package/build/cjs/lib/setup/multihostClient.js +6 -2
- package/build/cjs/lib/setup/multihostClient.js.map +1 -1
- package/build/cjs/lib/setup/pluginInfos.d.ts +5 -0
- package/build/cjs/lib/setup/pluginInfos.js +2 -0
- package/build/cjs/lib/setup/pluginInfos.js.map +2 -2
- package/build/cjs/lib/setup/setupBackup.d.ts +53 -0
- package/build/cjs/lib/setup/setupBackup.js +125 -14
- package/build/cjs/lib/setup/setupBackup.js.map +3 -3
- package/build/cjs/lib/setup/setupInstall.d.ts +81 -15
- package/build/cjs/lib/setup/setupInstall.js +307 -26
- package/build/cjs/lib/setup/setupInstall.js.map +2 -2
- package/build/cjs/lib/setup/setupLicense.d.ts +13 -0
- package/build/cjs/lib/setup/setupLicense.js +33 -2
- package/build/cjs/lib/setup/setupLicense.js.map +2 -2
- package/build/cjs/lib/setup/setupList.d.ts +55 -1
- package/build/cjs/lib/setup/setupList.js +78 -24
- package/build/cjs/lib/setup/setupList.js.map +3 -3
- package/build/cjs/lib/setup/setupMultihost.d.ts +7 -0
- package/build/cjs/lib/setup/setupMultihost.js +78 -11
- package/build/cjs/lib/setup/setupMultihost.js.map +3 -3
- package/build/cjs/lib/setup/setupPacketManager.d.ts +10 -0
- package/build/cjs/lib/setup/setupPacketManager.js +16 -6
- package/build/cjs/lib/setup/setupPacketManager.js.map +2 -2
- package/build/cjs/lib/setup/setupRepo.d.ts +19 -0
- package/build/cjs/lib/setup/setupRepo.js +141 -13
- package/build/cjs/lib/setup/setupRepo.js.map +2 -2
- package/build/cjs/lib/setup/setupSetup.d.ts +34 -0
- package/build/cjs/lib/setup/setupSetup.js +209 -35
- package/build/cjs/lib/setup/setupSetup.js.map +3 -3
- package/build/cjs/lib/setup/setupUpgrade.d.ts +13 -2
- package/build/cjs/lib/setup/setupUpgrade.js +72 -12
- package/build/cjs/lib/setup/setupUpgrade.js.map +2 -2
- package/build/cjs/lib/setup/setupUpload.d.ts +77 -1
- package/build/cjs/lib/setup/setupUpload.js +152 -9
- package/build/cjs/lib/setup/setupUpload.js.map +2 -2
- package/build/cjs/lib/setup/setupUsers.d.ts +44 -14
- package/build/cjs/lib/setup/setupUsers.js +330 -17
- package/build/cjs/lib/setup/setupUsers.js.map +2 -2
- package/build/cjs/lib/setup/setupVendor.d.ts +14 -1
- package/build/cjs/lib/setup/setupVendor.js +40 -8
- package/build/cjs/lib/setup/setupVendor.js.map +2 -2
- package/build/cjs/lib/setup/setupVisDebug.d.ts +16 -2
- package/build/cjs/lib/setup/setupVisDebug.js +41 -17
- package/build/cjs/lib/setup/setupVisDebug.js.map +3 -3
- package/build/cjs/lib/setup/utils.d.ts +1 -1
- package/build/cjs/lib/setup/utils.js +13 -9
- package/build/cjs/lib/setup/utils.js.map +3 -3
- package/build/cjs/lib/setup.d.ts +1 -1
- package/build/cjs/lib/setup.js +858 -1758
- package/build/cjs/lib/setup.js.map +3 -3
- package/build/esm/lib/_Types.d.ts +8 -1
- package/build/esm/lib/_Types.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCert.d.ts +7 -4
- package/build/esm/lib/cli/cliCert.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCert.js +6 -6
- package/build/esm/lib/cli/cliCert.js.map +1 -1
- package/build/esm/lib/cli/cliCommand.d.ts +63 -15
- package/build/esm/lib/cli/cliCommand.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCommand.js +4 -1
- package/build/esm/lib/cli/cliCommand.js.map +1 -1
- package/build/esm/lib/cli/cliCompact.d.ts +5 -2
- package/build/esm/lib/cli/cliCompact.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCompact.js +5 -2
- package/build/esm/lib/cli/cliCompact.js.map +1 -1
- package/build/esm/lib/cli/cliDebug.d.ts +5 -2
- package/build/esm/lib/cli/cliDebug.d.ts.map +1 -1
- package/build/esm/lib/cli/cliDebug.js +4 -1
- package/build/esm/lib/cli/cliDebug.js.map +1 -1
- package/build/esm/lib/cli/cliHost.d.ts +13 -10
- package/build/esm/lib/cli/cliHost.d.ts.map +1 -1
- package/build/esm/lib/cli/cliHost.js +8 -5
- package/build/esm/lib/cli/cliHost.js.map +1 -1
- package/build/esm/lib/cli/cliLogs.d.ts +9 -3
- package/build/esm/lib/cli/cliLogs.d.ts.map +1 -1
- package/build/esm/lib/cli/cliLogs.js +8 -1
- package/build/esm/lib/cli/cliLogs.js.map +1 -1
- package/build/esm/lib/cli/cliMessage.d.ts +2 -1
- package/build/esm/lib/cli/cliMessage.d.ts.map +1 -1
- package/build/esm/lib/cli/cliMessage.js +1 -0
- package/build/esm/lib/cli/cliMessage.js.map +1 -1
- package/build/esm/lib/cli/cliObjects.d.ts +21 -18
- package/build/esm/lib/cli/cliObjects.d.ts.map +1 -1
- package/build/esm/lib/cli/cliObjects.js +44 -38
- package/build/esm/lib/cli/cliObjects.js.map +1 -1
- package/build/esm/lib/cli/cliPlugin.d.ts +3 -3
- package/build/esm/lib/cli/cliPlugin.d.ts.map +1 -1
- package/build/esm/lib/cli/cliPlugin.js +1 -1
- package/build/esm/lib/cli/cliPlugin.js.map +1 -1
- package/build/esm/lib/cli/cliProcess.d.ts +17 -7
- package/build/esm/lib/cli/cliProcess.d.ts.map +1 -1
- package/build/esm/lib/cli/cliProcess.js +73 -12
- package/build/esm/lib/cli/cliProcess.js.map +1 -1
- package/build/esm/lib/cli/cliStates.d.ts +7 -4
- package/build/esm/lib/cli/cliStates.d.ts.map +1 -1
- package/build/esm/lib/cli/cliStates.js +6 -2
- package/build/esm/lib/cli/cliStates.js.map +1 -1
- package/build/esm/lib/progressBar.d.ts +59 -0
- package/build/esm/lib/progressBar.d.ts.map +1 -0
- package/build/esm/lib/progressBar.js +104 -0
- package/build/esm/lib/progressBar.js.map +1 -0
- package/build/esm/lib/setup/customError.d.ts +4 -0
- package/build/esm/lib/setup/customError.d.ts.map +1 -1
- package/build/esm/lib/setup/customError.js +3 -0
- package/build/esm/lib/setup/customError.js.map +1 -1
- package/build/esm/lib/setup/dbConnection.d.ts.map +1 -1
- package/build/esm/lib/setup/dbConnection.js +10 -13
- package/build/esm/lib/setup/dbConnection.js.map +1 -1
- package/build/esm/lib/setup/formatters.d.ts +4 -4
- package/build/esm/lib/setup/formatters.js +4 -4
- package/build/esm/lib/setup/pluginInfos.d.ts +5 -0
- package/build/esm/lib/setup/pluginInfos.d.ts.map +1 -1
- package/build/esm/lib/setup/pluginInfos.js +5 -0
- package/build/esm/lib/setup/pluginInfos.js.map +1 -1
- package/build/esm/lib/setup/setupBackup.d.ts +53 -0
- package/build/esm/lib/setup/setupBackup.d.ts.map +1 -1
- package/build/esm/lib/setup/setupBackup.js +132 -13
- package/build/esm/lib/setup/setupBackup.js.map +1 -1
- package/build/esm/lib/setup/setupInstall.d.ts +81 -15
- package/build/esm/lib/setup/setupInstall.d.ts.map +1 -1
- package/build/esm/lib/setup/setupInstall.js +334 -21
- package/build/esm/lib/setup/setupInstall.js.map +1 -1
- package/build/esm/lib/setup/setupLicense.d.ts +13 -0
- package/build/esm/lib/setup/setupLicense.d.ts.map +1 -1
- package/build/esm/lib/setup/setupLicense.js +31 -1
- package/build/esm/lib/setup/setupLicense.js.map +1 -1
- package/build/esm/lib/setup/setupList.d.ts +55 -1
- package/build/esm/lib/setup/setupList.d.ts.map +1 -1
- package/build/esm/lib/setup/setupList.js +61 -8
- package/build/esm/lib/setup/setupList.js.map +1 -1
- package/build/esm/lib/setup/setupMultihost.d.ts +7 -0
- package/build/esm/lib/setup/setupMultihost.d.ts.map +1 -1
- package/build/esm/lib/setup/setupMultihost.js +85 -6
- package/build/esm/lib/setup/setupMultihost.js.map +1 -1
- package/build/esm/lib/setup/setupPacketManager.d.ts +10 -0
- package/build/esm/lib/setup/setupPacketManager.d.ts.map +1 -1
- package/build/esm/lib/setup/setupPacketManager.js +9 -0
- package/build/esm/lib/setup/setupPacketManager.js.map +1 -1
- package/build/esm/lib/setup/setupRepo.d.ts +19 -0
- package/build/esm/lib/setup/setupRepo.d.ts.map +1 -1
- package/build/esm/lib/setup/setupRepo.js +164 -14
- package/build/esm/lib/setup/setupRepo.js.map +1 -1
- package/build/esm/lib/setup/setupSetup.d.ts +34 -0
- package/build/esm/lib/setup/setupSetup.d.ts.map +1 -1
- package/build/esm/lib/setup/setupSetup.js +218 -21
- package/build/esm/lib/setup/setupSetup.js.map +1 -1
- package/build/esm/lib/setup/setupUpgrade.d.ts +13 -2
- package/build/esm/lib/setup/setupUpgrade.d.ts.map +1 -1
- package/build/esm/lib/setup/setupUpgrade.js +70 -6
- package/build/esm/lib/setup/setupUpgrade.js.map +1 -1
- package/build/esm/lib/setup/setupUpload.d.ts +77 -1
- package/build/esm/lib/setup/setupUpload.d.ts.map +1 -1
- package/build/esm/lib/setup/setupUpload.js +164 -7
- package/build/esm/lib/setup/setupUpload.js.map +1 -1
- package/build/esm/lib/setup/setupUsers.d.ts +44 -14
- package/build/esm/lib/setup/setupUsers.d.ts.map +1 -1
- package/build/esm/lib/setup/setupUsers.js +346 -14
- package/build/esm/lib/setup/setupUsers.js.map +1 -1
- package/build/esm/lib/setup/setupVendor.d.ts +14 -1
- package/build/esm/lib/setup/setupVendor.d.ts.map +1 -1
- package/build/esm/lib/setup/setupVendor.js +33 -2
- package/build/esm/lib/setup/setupVendor.js.map +1 -1
- package/build/esm/lib/setup/setupVisDebug.d.ts +16 -2
- package/build/esm/lib/setup/setupVisDebug.d.ts.map +1 -1
- package/build/esm/lib/setup/setupVisDebug.js +39 -14
- package/build/esm/lib/setup/setupVisDebug.js.map +1 -1
- package/build/esm/lib/setup/utils.d.ts +1 -1
- package/build/esm/lib/setup/utils.d.ts.map +1 -1
- package/build/esm/lib/setup/utils.js +2 -4
- package/build/esm/lib/setup/utils.js.map +1 -1
- package/build/esm/lib/setup.d.ts +1 -1
- package/build/esm/lib/setup.d.ts.map +1 -1
- package/build/esm/lib/setup.js +959 -1910
- package/build/esm/lib/setup.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +14 -14
|
@@ -6,25 +6,30 @@
|
|
|
6
6
|
* MIT License
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
|
-
import { tools, EXIT_CODES } from '@iobroker/js-controller-common';
|
|
10
|
-
import fs from 'fs-extra';
|
|
11
9
|
import path from 'node:path';
|
|
12
|
-
import semver from 'semver';
|
|
13
10
|
import child_process from 'node:child_process';
|
|
14
|
-
import axios from 'axios';
|
|
15
11
|
import { URL } from 'node:url';
|
|
12
|
+
import { createRequire } from 'node:module';
|
|
13
|
+
import axios from 'axios';
|
|
14
|
+
import fs from 'fs-extra';
|
|
15
|
+
import semver from 'semver';
|
|
16
|
+
import { tools, EXIT_CODES } from '@iobroker/js-controller-common';
|
|
16
17
|
import { Upload } from '../../lib/setup/setupUpload.js';
|
|
17
18
|
import { PacketManager } from '../../lib/setup/setupPacketManager.js';
|
|
18
19
|
import { getRepository } from '../../lib/setup/utils.js';
|
|
19
20
|
import { IoBrokerError } from '../../lib/setup/customError.js';
|
|
21
|
+
import { dbConnect } from '../../lib/setup/dbConnection.js';
|
|
22
|
+
import * as CLITools from '../../lib/cli/cliTools.js';
|
|
20
23
|
import { SYSTEM_ADAPTER_PREFIX } from '@iobroker/js-controller-common-db/constants';
|
|
21
|
-
import { createRequire } from 'node:module';
|
|
22
24
|
// eslint-disable-next-line unicorn/prefer-module
|
|
23
25
|
const require = createRequire(import.meta.url || `file://${__filename}`);
|
|
24
26
|
const hostname = tools.getHostName();
|
|
25
27
|
const osPlatform = process.platform;
|
|
26
28
|
/** Note: this is duplicated in preinstallCheck */
|
|
27
29
|
const RECOMMENDED_NPM_VERSION = 8;
|
|
30
|
+
/**
|
|
31
|
+
* CLI command to install and download adapters and create their instances
|
|
32
|
+
*/
|
|
28
33
|
export class Install {
|
|
29
34
|
isRootOnUnix;
|
|
30
35
|
objects;
|
|
@@ -34,6 +39,9 @@ export class Install {
|
|
|
34
39
|
tarballRegex;
|
|
35
40
|
upload;
|
|
36
41
|
packetManager;
|
|
42
|
+
/**
|
|
43
|
+
* @param options The states/objects clients, CLI parameters and the process-exit callback
|
|
44
|
+
*/
|
|
37
45
|
constructor(options) {
|
|
38
46
|
this.isRootOnUnix = typeof process.getuid === 'function' && process.getuid() === 0;
|
|
39
47
|
options = options || {};
|
|
@@ -88,7 +96,7 @@ export class Install {
|
|
|
88
96
|
if (!options || typeof options !== 'object') {
|
|
89
97
|
options = {};
|
|
90
98
|
}
|
|
91
|
-
stoppedList
|
|
99
|
+
stoppedList ||= [];
|
|
92
100
|
let sources;
|
|
93
101
|
if (!repoUrlOrRepo || !tools.isObject(repoUrlOrRepo)) {
|
|
94
102
|
sources = await getRepository({ repoName: repoUrlOrRepo, objects: this.objects });
|
|
@@ -465,7 +473,7 @@ export class Install {
|
|
|
465
473
|
obj.from = `system.host.${hostname}.cli`;
|
|
466
474
|
obj.ts = Date.now();
|
|
467
475
|
try {
|
|
468
|
-
await this.objects.
|
|
476
|
+
await this.objects.extendObject(obj._id, obj);
|
|
469
477
|
}
|
|
470
478
|
catch (err) {
|
|
471
479
|
console.error(`host.${hostname} error setObject ${obj._id} ${err.message}`);
|
|
@@ -479,8 +487,8 @@ export class Install {
|
|
|
479
487
|
* Installs given adapter
|
|
480
488
|
*
|
|
481
489
|
* @param adapter The adapter name
|
|
482
|
-
* @param repoUrl
|
|
483
|
-
* @param _installCount
|
|
490
|
+
* @param repoUrl Optional repository URL to install the adapter from
|
|
491
|
+
* @param _installCount Internal recursion counter limiting the number of dependency installs
|
|
484
492
|
*/
|
|
485
493
|
async installAdapter(adapter, repoUrl, _installCount) {
|
|
486
494
|
_installCount = _installCount || 0;
|
|
@@ -547,6 +555,11 @@ export class Install {
|
|
|
547
555
|
await this.upload.upgradeAdapterObjects(adapter);
|
|
548
556
|
return adapter;
|
|
549
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Install the OS packages required by an adapter
|
|
560
|
+
*
|
|
561
|
+
* @param osDependencies The OS dependencies declared by the adapter, keyed by platform
|
|
562
|
+
*/
|
|
550
563
|
async installOSPackages(osDependencies) {
|
|
551
564
|
if (osPlatform in osDependencies) {
|
|
552
565
|
try {
|
|
@@ -560,6 +573,12 @@ export class Install {
|
|
|
560
573
|
}
|
|
561
574
|
}
|
|
562
575
|
}
|
|
576
|
+
/**
|
|
577
|
+
* Run the custom install script of an adapter if it defines one
|
|
578
|
+
*
|
|
579
|
+
* @param adapter The adapter name
|
|
580
|
+
* @param config The adapter object containing the install configuration
|
|
581
|
+
*/
|
|
563
582
|
async callInstallOfAdapter(adapter, config) {
|
|
564
583
|
if (config.common.install) {
|
|
565
584
|
// Install node modules
|
|
@@ -815,10 +834,10 @@ export class Install {
|
|
|
815
834
|
/**
|
|
816
835
|
* Enumerate all instances of an adapter
|
|
817
836
|
*
|
|
818
|
-
* @param knownObjIDs
|
|
819
|
-
* @param notDeleted
|
|
820
|
-
* @param adapter
|
|
821
|
-
* @param instance
|
|
837
|
+
* @param knownObjIDs Accumulator of object IDs found so far
|
|
838
|
+
* @param notDeleted Accumulator of object IDs that must not be deleted
|
|
839
|
+
* @param adapter The adapter name
|
|
840
|
+
* @param instance Optional instance number to restrict the search to
|
|
822
841
|
*/
|
|
823
842
|
async _enumerateAdapterInstances(knownObjIDs, notDeleted, adapter, instance) {
|
|
824
843
|
if (!notDeleted) {
|
|
@@ -868,9 +887,9 @@ export class Install {
|
|
|
868
887
|
/**
|
|
869
888
|
* Enumerate all meta objects of an adapter
|
|
870
889
|
*
|
|
871
|
-
* @param knownObjIDs
|
|
872
|
-
* @param adapter
|
|
873
|
-
* @param metaFilesToDelete
|
|
890
|
+
* @param knownObjIDs Accumulator of object IDs found so far
|
|
891
|
+
* @param adapter The adapter name
|
|
892
|
+
* @param metaFilesToDelete Accumulator of meta files that should be deleted
|
|
874
893
|
*/
|
|
875
894
|
async _enumerateAdapterMeta(knownObjIDs, adapter, metaFilesToDelete) {
|
|
876
895
|
try {
|
|
@@ -1077,9 +1096,9 @@ export class Install {
|
|
|
1077
1096
|
/**
|
|
1078
1097
|
* Enumerate all state IDs of an adapter (or instance)
|
|
1079
1098
|
*
|
|
1080
|
-
* @param knownStateIDs
|
|
1081
|
-
* @param adapter
|
|
1082
|
-
* @param instance
|
|
1099
|
+
* @param knownStateIDs Accumulator of state IDs found so far
|
|
1100
|
+
* @param adapter The adapter name
|
|
1101
|
+
* @param instance Optional instance number to restrict the search to
|
|
1083
1102
|
*/
|
|
1084
1103
|
async _enumerateAdapterStates(knownStateIDs, adapter, instance) {
|
|
1085
1104
|
for (const pattern of [
|
|
@@ -1108,8 +1127,8 @@ export class Install {
|
|
|
1108
1127
|
/**
|
|
1109
1128
|
* delete WWW pages, objects and meta files
|
|
1110
1129
|
*
|
|
1111
|
-
* @param adapter
|
|
1112
|
-
* @param metaFilesToDelete
|
|
1130
|
+
* @param adapter The adapter name
|
|
1131
|
+
* @param metaFilesToDelete The meta files that should be deleted
|
|
1113
1132
|
*/
|
|
1114
1133
|
async _deleteAdapterFiles(adapter, metaFilesToDelete) {
|
|
1115
1134
|
// special files, which are not meta (vis widgets), combined with meta object ids
|
|
@@ -1277,6 +1296,7 @@ export class Install {
|
|
|
1277
1296
|
// remove adapter from custom
|
|
1278
1297
|
await this._removeCustomFromObjects([adapter]);
|
|
1279
1298
|
await _uninstallNpm();
|
|
1299
|
+
await this._removePythonEnvironment(adapter);
|
|
1280
1300
|
}
|
|
1281
1301
|
else {
|
|
1282
1302
|
// we are not allowed to delete the last instance if another instance depends on us
|
|
@@ -1296,11 +1316,15 @@ export class Install {
|
|
|
1296
1316
|
await this._deleteAdapterFiles(adapter, metaFilesToDelete);
|
|
1297
1317
|
await this._deleteAdapterObjects(knownObjectIDs);
|
|
1298
1318
|
await this._deleteAdapterStates(knownStateIDs);
|
|
1319
|
+
// this path removes the instance objects itself instead of going through deleteInstance,
|
|
1320
|
+
// so the registry entries of every instance of the adapter have to be freed here as well
|
|
1321
|
+
await this._freeUsedResources(adapter);
|
|
1299
1322
|
if (this.params.custom) {
|
|
1300
1323
|
// remove adapter from custom
|
|
1301
1324
|
await this._removeCustomFromObjects([...instances, adapter]);
|
|
1302
1325
|
}
|
|
1303
1326
|
await _uninstallNpm();
|
|
1327
|
+
await this._removePythonEnvironment(adapter);
|
|
1304
1328
|
}
|
|
1305
1329
|
}
|
|
1306
1330
|
catch (e) {
|
|
@@ -1308,6 +1332,32 @@ export class Install {
|
|
|
1308
1332
|
}
|
|
1309
1333
|
return resultCode;
|
|
1310
1334
|
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Remove the virtual environment a Python adapter leaves behind in the data directory
|
|
1337
|
+
*
|
|
1338
|
+
* Host-local state like `node_modules` - rebuildable, but easily a few hundred megabytes - so it goes when
|
|
1339
|
+
* the adapter goes. Deliberately not part of the npm uninstall: that one starts by resolving the adapter's
|
|
1340
|
+
* `io-package.json`, so for a half-removed installation, where the package directory is already gone, it
|
|
1341
|
+
* throws before ever getting here - and that is precisely the case which leaves the environment behind with
|
|
1342
|
+
* nothing pointing at it.
|
|
1343
|
+
*
|
|
1344
|
+
* Removed without looking at `common.platform` for the same reason: the directory only exists for Python
|
|
1345
|
+
* adapters, and the `io-package.json` that would say so may no longer be there.
|
|
1346
|
+
*
|
|
1347
|
+
* @param adapter adapter name, e.g. "pyexample"
|
|
1348
|
+
*/
|
|
1349
|
+
async _removePythonEnvironment(adapter) {
|
|
1350
|
+
try {
|
|
1351
|
+
const pythonEnvDir = tools.getPythonEnvDir(adapter);
|
|
1352
|
+
if (await fs.pathExists(pythonEnvDir)) {
|
|
1353
|
+
await fs.remove(pythonEnvDir);
|
|
1354
|
+
console.log(`host.${hostname} Python environment "${pythonEnvDir}" deleted`);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
catch (e) {
|
|
1358
|
+
console.error(`Cannot delete the Python environment of ${adapter}: ${e.message}`);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1311
1361
|
/**
|
|
1312
1362
|
* Deletes given instance of an adapter
|
|
1313
1363
|
*
|
|
@@ -1332,11 +1382,89 @@ export class Install {
|
|
|
1332
1382
|
await this._enumerateAdapterDocs(knownObjectIDs, adapter, instance);
|
|
1333
1383
|
await this._deleteAdapterObjects(knownObjectIDs);
|
|
1334
1384
|
await this._deleteAdapterStates(knownStateIDs);
|
|
1385
|
+
await this._freeUsedResources(adapter, instance);
|
|
1335
1386
|
if (this.params.custom) {
|
|
1336
1387
|
// delete instance from custom
|
|
1337
1388
|
await this._removeCustomFromObjects([`${adapter}.${instance}`]);
|
|
1338
1389
|
}
|
|
1339
1390
|
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Free all exclusive resources (serial ports, TCP/UDP ports, ...) the given instance(s) had registered.
|
|
1393
|
+
*
|
|
1394
|
+
* This is needed because an instance can be deleted via the CLI while a js-controller is not running: it
|
|
1395
|
+
* cannot notice that the instance object disappeared, so its `system.host.<host>.usedResources.<type>`
|
|
1396
|
+
* states would keep listing the resources of an instance that no longer exists.
|
|
1397
|
+
*
|
|
1398
|
+
* Hosts that are running are deliberately skipped. Such a host cleans its own registry up when it sees the
|
|
1399
|
+
* instance object being deleted, and it holds the registry in memory: it rewrites the state from that copy
|
|
1400
|
+
* on its next change, which would silently undo a write made here.
|
|
1401
|
+
*
|
|
1402
|
+
* @param adapter adapter name, e.g. "mqtt"
|
|
1403
|
+
* @param instance instance number; if undefined, all instances of the adapter are freed
|
|
1404
|
+
*/
|
|
1405
|
+
async _freeUsedResources(adapter, instance) {
|
|
1406
|
+
const matches = (namespace) => instance !== undefined ? namespace === `${adapter}.${instance}` : namespace.startsWith(`${adapter}.`);
|
|
1407
|
+
let keys;
|
|
1408
|
+
try {
|
|
1409
|
+
keys = await this.states.getKeys('system.host.*.usedResources.*');
|
|
1410
|
+
}
|
|
1411
|
+
catch (e) {
|
|
1412
|
+
console.warn(`Cannot read the used resources registry: ${e.message}`);
|
|
1413
|
+
return;
|
|
1414
|
+
}
|
|
1415
|
+
if (!keys?.length) {
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
const hostPrefix = 'system.host.';
|
|
1419
|
+
const registryMarker = '.usedResources.';
|
|
1420
|
+
/** whether a host is currently running, queried once per host */
|
|
1421
|
+
const hostIsRunning = new Map();
|
|
1422
|
+
for (const id of keys) {
|
|
1423
|
+
const markerIndex = id.lastIndexOf(registryMarker);
|
|
1424
|
+
if (!id.startsWith(hostPrefix) || markerIndex <= hostPrefix.length) {
|
|
1425
|
+
continue;
|
|
1426
|
+
}
|
|
1427
|
+
const host = id.substring(hostPrefix.length, markerIndex);
|
|
1428
|
+
let isRunning = hostIsRunning.get(host);
|
|
1429
|
+
if (isRunning === undefined) {
|
|
1430
|
+
try {
|
|
1431
|
+
const aliveState = await this.states.getState(`${hostPrefix}${host}.alive`);
|
|
1432
|
+
isRunning = aliveState?.val === true;
|
|
1433
|
+
}
|
|
1434
|
+
catch (e) {
|
|
1435
|
+
// if it cannot be determined, assume the host is running: leaving an entry behind is
|
|
1436
|
+
// harmless (its controller drops it on the next start) while fighting a live controller
|
|
1437
|
+
// over the same state is not
|
|
1438
|
+
console.warn(`Cannot check whether host "${host}" is running: ${e.message}`);
|
|
1439
|
+
isRunning = true;
|
|
1440
|
+
}
|
|
1441
|
+
hostIsRunning.set(host, isRunning);
|
|
1442
|
+
}
|
|
1443
|
+
if (isRunning) {
|
|
1444
|
+
continue;
|
|
1445
|
+
}
|
|
1446
|
+
try {
|
|
1447
|
+
const state = await this.states.getState(id);
|
|
1448
|
+
if (!state || typeof state.val !== 'string' || !state.val) {
|
|
1449
|
+
continue;
|
|
1450
|
+
}
|
|
1451
|
+
const parsed = JSON.parse(state.val);
|
|
1452
|
+
if (!Array.isArray(parsed)) {
|
|
1453
|
+
continue;
|
|
1454
|
+
}
|
|
1455
|
+
const original = parsed;
|
|
1456
|
+
// keep anything that is malformed: it cannot be attributed to the deleted instance, and one
|
|
1457
|
+
// broken entry must not stop the cleanup of the sound ones in the same state
|
|
1458
|
+
const filtered = original.filter(entry => typeof entry?.instance !== 'string' || !matches(entry.instance));
|
|
1459
|
+
if (filtered.length !== original.length) {
|
|
1460
|
+
await this.states.setStateAsync(id, { val: JSON.stringify(filtered), ack: true });
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
catch (e) {
|
|
1464
|
+
console.warn(`Cannot free the used resources in "${id}": ${e.message}`);
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1340
1468
|
/**
|
|
1341
1469
|
* Remove all node modules that has been installed by this instance
|
|
1342
1470
|
*
|
|
@@ -1625,4 +1753,189 @@ export class Install {
|
|
|
1625
1753
|
return instances;
|
|
1626
1754
|
}
|
|
1627
1755
|
}
|
|
1756
|
+
/**
|
|
1757
|
+
* @param options options provided by the processCommand dispatcher
|
|
1758
|
+
*/
|
|
1759
|
+
export function processCommandUrl(options) {
|
|
1760
|
+
const { args, params, callback } = options;
|
|
1761
|
+
let url = args[0];
|
|
1762
|
+
const name = args[1];
|
|
1763
|
+
if (!url) {
|
|
1764
|
+
console.log('Please provide a URL to install from and optionally a name of the adapter to install');
|
|
1765
|
+
return void callback(EXIT_CODES.INVALID_ARGUMENTS);
|
|
1766
|
+
}
|
|
1767
|
+
if (url[0] === '"' && url[url.length - 1] === '"') {
|
|
1768
|
+
url = url.substring(1, url.length - 1);
|
|
1769
|
+
}
|
|
1770
|
+
url = url.trim();
|
|
1771
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1772
|
+
const install = new Install({
|
|
1773
|
+
objects,
|
|
1774
|
+
states,
|
|
1775
|
+
processExit: callback,
|
|
1776
|
+
params,
|
|
1777
|
+
});
|
|
1778
|
+
try {
|
|
1779
|
+
await install.installAdapterFromUrl(url, name);
|
|
1780
|
+
return void callback(EXIT_CODES.NO_ERROR);
|
|
1781
|
+
}
|
|
1782
|
+
catch (e) {
|
|
1783
|
+
console.error(`Could not install adapter from url: ${e.message}`);
|
|
1784
|
+
return void callback(EXIT_CODES.CANNOT_INSTALL_NPM_PACKET);
|
|
1785
|
+
}
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* @param options options provided by the processCommand dispatcher
|
|
1790
|
+
*/
|
|
1791
|
+
export function processCommandInstall(options) {
|
|
1792
|
+
const { command, args, params, callback } = options;
|
|
1793
|
+
const { showHelp } = options.commandOptions;
|
|
1794
|
+
let name = args[0];
|
|
1795
|
+
let instance = args[1];
|
|
1796
|
+
let repoUrl = args[2];
|
|
1797
|
+
if (parseInt(instance, 10).toString() !== (instance || '').toString()) {
|
|
1798
|
+
repoUrl = instance;
|
|
1799
|
+
instance = undefined;
|
|
1800
|
+
}
|
|
1801
|
+
if (parseInt(repoUrl, 10).toString() === (repoUrl || '').toString()) {
|
|
1802
|
+
const temp = instance;
|
|
1803
|
+
instance = repoUrl;
|
|
1804
|
+
repoUrl = temp;
|
|
1805
|
+
}
|
|
1806
|
+
if (instance && parseInt(instance, 10).toString() === (instance || '').toString()) {
|
|
1807
|
+
params.instance = parseInt(instance, 10);
|
|
1808
|
+
}
|
|
1809
|
+
// If user accidentally wrote tools.appName.adapter => remove adapter
|
|
1810
|
+
name = CLITools.normalizeAdapterName(name);
|
|
1811
|
+
const parsedName = CLITools.splitAdapterOrInstanceIdentifierWithVersion(name);
|
|
1812
|
+
if (!parsedName) {
|
|
1813
|
+
console.log('Invalid adapter name for install');
|
|
1814
|
+
showHelp();
|
|
1815
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1816
|
+
}
|
|
1817
|
+
// split the adapter into its parts if necessary
|
|
1818
|
+
if (parsedName.instance !== null) {
|
|
1819
|
+
params.instance = parsedName.instance;
|
|
1820
|
+
}
|
|
1821
|
+
name = parsedName.name;
|
|
1822
|
+
const installName = parsedName.nameWithVersion;
|
|
1823
|
+
const adapterDir = tools.getAdapterDir(name);
|
|
1824
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1825
|
+
const install = new Install({
|
|
1826
|
+
objects,
|
|
1827
|
+
states,
|
|
1828
|
+
processExit: callback,
|
|
1829
|
+
params,
|
|
1830
|
+
});
|
|
1831
|
+
if (params.host && params.host !== tools.getHostName()) {
|
|
1832
|
+
// if host argument provided we should check, that host actually exists in mh environment
|
|
1833
|
+
let obj;
|
|
1834
|
+
try {
|
|
1835
|
+
obj = await objects.getObjectAsync(`system.host.${params.host}`);
|
|
1836
|
+
}
|
|
1837
|
+
catch (err) {
|
|
1838
|
+
console.warn(`Could not check existence of host "${params.host}": ${err.message}`);
|
|
1839
|
+
}
|
|
1840
|
+
if (!obj) {
|
|
1841
|
+
console.error(`Cannot add instance to non-existing host "${params.host}"`);
|
|
1842
|
+
return void callback(EXIT_CODES.NON_EXISTING_HOST);
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
if (!adapterDir || !fs.existsSync(adapterDir)) {
|
|
1846
|
+
try {
|
|
1847
|
+
const { stoppedList } = await install.downloadPacket(repoUrl, installName);
|
|
1848
|
+
await install.installAdapter(installName, repoUrl);
|
|
1849
|
+
await install.enableInstances(stoppedList, true); // even if unlikely make sure to re-enable disabled instances
|
|
1850
|
+
if (command !== 'install' && command !== 'i') {
|
|
1851
|
+
await install.createInstance(name, params);
|
|
1852
|
+
}
|
|
1853
|
+
return void callback();
|
|
1854
|
+
}
|
|
1855
|
+
catch (e) {
|
|
1856
|
+
console.error(`adapter "${name}" cannot be installed: ${e.message}`);
|
|
1857
|
+
return void callback(e instanceof IoBrokerError ? e.code : EXIT_CODES.UNKNOWN_ERROR);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
else if (command !== 'install' && command !== 'i') {
|
|
1861
|
+
try {
|
|
1862
|
+
await install.createInstance(name, params);
|
|
1863
|
+
return void callback();
|
|
1864
|
+
}
|
|
1865
|
+
catch (err) {
|
|
1866
|
+
console.error(`adapter "${name}" cannot be installed: ${err.message}`);
|
|
1867
|
+
return void callback(EXIT_CODES.UNKNOWN_ERROR);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
else {
|
|
1871
|
+
console.log(`adapter "${name}" already installed. Use "upgrade" to upgrade to a newer version.`);
|
|
1872
|
+
return void callback(EXIT_CODES.ADAPTER_ALREADY_INSTALLED);
|
|
1873
|
+
}
|
|
1874
|
+
});
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* @param options options provided by the processCommand dispatcher
|
|
1878
|
+
*/
|
|
1879
|
+
export function processCommandDelete(options) {
|
|
1880
|
+
const { args, params, callback } = options;
|
|
1881
|
+
const { showHelp } = options.commandOptions;
|
|
1882
|
+
let adapter = args[0];
|
|
1883
|
+
let instance = args[1];
|
|
1884
|
+
// The adapter argument is required
|
|
1885
|
+
if (!adapter) {
|
|
1886
|
+
showHelp();
|
|
1887
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1888
|
+
}
|
|
1889
|
+
// If the user accidentally wrote <tools.appName>.adapter,
|
|
1890
|
+
// remove <tools.appName> from the adapter name
|
|
1891
|
+
adapter = CLITools.normalizeAdapterName(adapter);
|
|
1892
|
+
// Avoid deleting stuff we don't want to delete
|
|
1893
|
+
// e.g. `system.adapter.*`
|
|
1894
|
+
if (!instance) {
|
|
1895
|
+
// Ensure that adapter contains a valid adapter (without instance nr)
|
|
1896
|
+
// or instance (with instance nr) identifier
|
|
1897
|
+
if (!CLITools.validateAdapterOrInstanceIdentifier(adapter)) {
|
|
1898
|
+
showHelp();
|
|
1899
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1900
|
+
}
|
|
1901
|
+
// split the adapter into adapter + instance if necessary
|
|
1902
|
+
if (adapter.indexOf('.') > -1) {
|
|
1903
|
+
[adapter, instance] = adapter.split('.', 2);
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
else {
|
|
1907
|
+
// ensure that adapter contains a valid adapter identifier
|
|
1908
|
+
// and the instance is a number
|
|
1909
|
+
if (!CLITools.validateAdapterIdentifier(adapter) || !/^\d+$/.test(instance)) {
|
|
1910
|
+
showHelp();
|
|
1911
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
if (instance) {
|
|
1915
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1916
|
+
const install = new Install({
|
|
1917
|
+
objects,
|
|
1918
|
+
states,
|
|
1919
|
+
processExit: callback,
|
|
1920
|
+
params,
|
|
1921
|
+
});
|
|
1922
|
+
console.log(`Delete instance "${adapter}.${instance}"`);
|
|
1923
|
+
await install.deleteInstance(adapter, parseInt(instance));
|
|
1924
|
+
callback();
|
|
1925
|
+
});
|
|
1926
|
+
}
|
|
1927
|
+
else {
|
|
1928
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1929
|
+
const install = new Install({
|
|
1930
|
+
objects,
|
|
1931
|
+
states,
|
|
1932
|
+
processExit: callback,
|
|
1933
|
+
params,
|
|
1934
|
+
});
|
|
1935
|
+
console.log(`Delete adapter "${adapter}"`);
|
|
1936
|
+
const resultCode = await install.deleteAdapter(adapter);
|
|
1937
|
+
callback(resultCode);
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1628
1941
|
//# sourceMappingURL=setupInstall.js.map
|