@iobroker/js-controller-cli 7.2.3 → 8.0.0-alpha.2-20260923-99da17fcc
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 +66 -15
- package/build/cjs/lib/setup/setupInstall.js +282 -28
- 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 +66 -15
- package/build/esm/lib/setup/setupInstall.d.ts.map +1 -1
- package/build/esm/lib/setup/setupInstall.js +309 -23
- 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 });
|
|
@@ -250,7 +258,8 @@ export class Install {
|
|
|
250
258
|
unsafePerm: !!options.unsafePerm,
|
|
251
259
|
});
|
|
252
260
|
// code 1 is sometimes a real error and sometimes a strange error, where everything is installed but still the error
|
|
253
|
-
const isSuccess = result.success ||
|
|
261
|
+
const isSuccess = result.success ||
|
|
262
|
+
(result.exitCode === 1 && !result.stderr.startsWith('npm ERR!') && !result.stderr.startsWith('npm error '));
|
|
254
263
|
if (isSuccess) {
|
|
255
264
|
// Determine where the packet would be installed if npm succeeds
|
|
256
265
|
// TODO: There's probably a better way to figure this out
|
|
@@ -309,7 +318,7 @@ export class Install {
|
|
|
309
318
|
console.info('Try to solve ENOTEMPTY error automatically');
|
|
310
319
|
const errorFilePath = result.stderr
|
|
311
320
|
.split('\n')
|
|
312
|
-
?.find(line => line.startsWith('npm ERR! dest'))
|
|
321
|
+
?.find(line => line.startsWith('npm ERR! dest') || line.startsWith('npm error dest'))
|
|
313
322
|
?.split('dest')[1]
|
|
314
323
|
.trim();
|
|
315
324
|
const affectedNodeModulesPath = errorFilePath ? path.join(errorFilePath, '..') : undefined;
|
|
@@ -464,7 +473,7 @@ export class Install {
|
|
|
464
473
|
obj.from = `system.host.${hostname}.cli`;
|
|
465
474
|
obj.ts = Date.now();
|
|
466
475
|
try {
|
|
467
|
-
await this.objects.
|
|
476
|
+
await this.objects.extendObject(obj._id, obj);
|
|
468
477
|
}
|
|
469
478
|
catch (err) {
|
|
470
479
|
console.error(`host.${hostname} error setObject ${obj._id} ${err.message}`);
|
|
@@ -478,8 +487,8 @@ export class Install {
|
|
|
478
487
|
* Installs given adapter
|
|
479
488
|
*
|
|
480
489
|
* @param adapter The adapter name
|
|
481
|
-
* @param repoUrl
|
|
482
|
-
* @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
|
|
483
492
|
*/
|
|
484
493
|
async installAdapter(adapter, repoUrl, _installCount) {
|
|
485
494
|
_installCount = _installCount || 0;
|
|
@@ -546,6 +555,11 @@ export class Install {
|
|
|
546
555
|
await this.upload.upgradeAdapterObjects(adapter);
|
|
547
556
|
return adapter;
|
|
548
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
|
+
*/
|
|
549
563
|
async installOSPackages(osDependencies) {
|
|
550
564
|
if (osPlatform in osDependencies) {
|
|
551
565
|
try {
|
|
@@ -559,6 +573,12 @@ export class Install {
|
|
|
559
573
|
}
|
|
560
574
|
}
|
|
561
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
|
+
*/
|
|
562
582
|
async callInstallOfAdapter(adapter, config) {
|
|
563
583
|
if (config.common.install) {
|
|
564
584
|
// Install node modules
|
|
@@ -814,10 +834,10 @@ export class Install {
|
|
|
814
834
|
/**
|
|
815
835
|
* Enumerate all instances of an adapter
|
|
816
836
|
*
|
|
817
|
-
* @param knownObjIDs
|
|
818
|
-
* @param notDeleted
|
|
819
|
-
* @param adapter
|
|
820
|
-
* @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
|
|
821
841
|
*/
|
|
822
842
|
async _enumerateAdapterInstances(knownObjIDs, notDeleted, adapter, instance) {
|
|
823
843
|
if (!notDeleted) {
|
|
@@ -867,9 +887,9 @@ export class Install {
|
|
|
867
887
|
/**
|
|
868
888
|
* Enumerate all meta objects of an adapter
|
|
869
889
|
*
|
|
870
|
-
* @param knownObjIDs
|
|
871
|
-
* @param adapter
|
|
872
|
-
* @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
|
|
873
893
|
*/
|
|
874
894
|
async _enumerateAdapterMeta(knownObjIDs, adapter, metaFilesToDelete) {
|
|
875
895
|
try {
|
|
@@ -1076,9 +1096,9 @@ export class Install {
|
|
|
1076
1096
|
/**
|
|
1077
1097
|
* Enumerate all state IDs of an adapter (or instance)
|
|
1078
1098
|
*
|
|
1079
|
-
* @param knownStateIDs
|
|
1080
|
-
* @param adapter
|
|
1081
|
-
* @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
|
|
1082
1102
|
*/
|
|
1083
1103
|
async _enumerateAdapterStates(knownStateIDs, adapter, instance) {
|
|
1084
1104
|
for (const pattern of [
|
|
@@ -1107,8 +1127,8 @@ export class Install {
|
|
|
1107
1127
|
/**
|
|
1108
1128
|
* delete WWW pages, objects and meta files
|
|
1109
1129
|
*
|
|
1110
|
-
* @param adapter
|
|
1111
|
-
* @param metaFilesToDelete
|
|
1130
|
+
* @param adapter The adapter name
|
|
1131
|
+
* @param metaFilesToDelete The meta files that should be deleted
|
|
1112
1132
|
*/
|
|
1113
1133
|
async _deleteAdapterFiles(adapter, metaFilesToDelete) {
|
|
1114
1134
|
// special files, which are not meta (vis widgets), combined with meta object ids
|
|
@@ -1295,6 +1315,9 @@ export class Install {
|
|
|
1295
1315
|
await this._deleteAdapterFiles(adapter, metaFilesToDelete);
|
|
1296
1316
|
await this._deleteAdapterObjects(knownObjectIDs);
|
|
1297
1317
|
await this._deleteAdapterStates(knownStateIDs);
|
|
1318
|
+
// this path removes the instance objects itself instead of going through deleteInstance,
|
|
1319
|
+
// so the registry entries of every instance of the adapter have to be freed here as well
|
|
1320
|
+
await this._freeUsedResources(adapter);
|
|
1298
1321
|
if (this.params.custom) {
|
|
1299
1322
|
// remove adapter from custom
|
|
1300
1323
|
await this._removeCustomFromObjects([...instances, adapter]);
|
|
@@ -1331,11 +1354,89 @@ export class Install {
|
|
|
1331
1354
|
await this._enumerateAdapterDocs(knownObjectIDs, adapter, instance);
|
|
1332
1355
|
await this._deleteAdapterObjects(knownObjectIDs);
|
|
1333
1356
|
await this._deleteAdapterStates(knownStateIDs);
|
|
1357
|
+
await this._freeUsedResources(adapter, instance);
|
|
1334
1358
|
if (this.params.custom) {
|
|
1335
1359
|
// delete instance from custom
|
|
1336
1360
|
await this._removeCustomFromObjects([`${adapter}.${instance}`]);
|
|
1337
1361
|
}
|
|
1338
1362
|
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Free all exclusive resources (serial ports, TCP/UDP ports, ...) the given instance(s) had registered.
|
|
1365
|
+
*
|
|
1366
|
+
* This is needed because an instance can be deleted via the CLI while a js-controller is not running: it
|
|
1367
|
+
* cannot notice that the instance object disappeared, so its `system.host.<host>.usedResources.<type>`
|
|
1368
|
+
* states would keep listing the resources of an instance that no longer exists.
|
|
1369
|
+
*
|
|
1370
|
+
* Hosts that are running are deliberately skipped. Such a host cleans its own registry up when it sees the
|
|
1371
|
+
* instance object being deleted, and it holds the registry in memory: it rewrites the state from that copy
|
|
1372
|
+
* on its next change, which would silently undo a write made here.
|
|
1373
|
+
*
|
|
1374
|
+
* @param adapter adapter name, e.g. "mqtt"
|
|
1375
|
+
* @param instance instance number; if undefined, all instances of the adapter are freed
|
|
1376
|
+
*/
|
|
1377
|
+
async _freeUsedResources(adapter, instance) {
|
|
1378
|
+
const matches = (namespace) => instance !== undefined ? namespace === `${adapter}.${instance}` : namespace.startsWith(`${adapter}.`);
|
|
1379
|
+
let keys;
|
|
1380
|
+
try {
|
|
1381
|
+
keys = await this.states.getKeys('system.host.*.usedResources.*');
|
|
1382
|
+
}
|
|
1383
|
+
catch (e) {
|
|
1384
|
+
console.warn(`Cannot read the used resources registry: ${e.message}`);
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
if (!keys?.length) {
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
const hostPrefix = 'system.host.';
|
|
1391
|
+
const registryMarker = '.usedResources.';
|
|
1392
|
+
/** whether a host is currently running, queried once per host */
|
|
1393
|
+
const hostIsRunning = new Map();
|
|
1394
|
+
for (const id of keys) {
|
|
1395
|
+
const markerIndex = id.lastIndexOf(registryMarker);
|
|
1396
|
+
if (!id.startsWith(hostPrefix) || markerIndex <= hostPrefix.length) {
|
|
1397
|
+
continue;
|
|
1398
|
+
}
|
|
1399
|
+
const host = id.substring(hostPrefix.length, markerIndex);
|
|
1400
|
+
let isRunning = hostIsRunning.get(host);
|
|
1401
|
+
if (isRunning === undefined) {
|
|
1402
|
+
try {
|
|
1403
|
+
const aliveState = await this.states.getState(`${hostPrefix}${host}.alive`);
|
|
1404
|
+
isRunning = aliveState?.val === true;
|
|
1405
|
+
}
|
|
1406
|
+
catch (e) {
|
|
1407
|
+
// if it cannot be determined, assume the host is running: leaving an entry behind is
|
|
1408
|
+
// harmless (its controller drops it on the next start) while fighting a live controller
|
|
1409
|
+
// over the same state is not
|
|
1410
|
+
console.warn(`Cannot check whether host "${host}" is running: ${e.message}`);
|
|
1411
|
+
isRunning = true;
|
|
1412
|
+
}
|
|
1413
|
+
hostIsRunning.set(host, isRunning);
|
|
1414
|
+
}
|
|
1415
|
+
if (isRunning) {
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
try {
|
|
1419
|
+
const state = await this.states.getState(id);
|
|
1420
|
+
if (!state || typeof state.val !== 'string' || !state.val) {
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
const parsed = JSON.parse(state.val);
|
|
1424
|
+
if (!Array.isArray(parsed)) {
|
|
1425
|
+
continue;
|
|
1426
|
+
}
|
|
1427
|
+
const original = parsed;
|
|
1428
|
+
// keep anything that is malformed: it cannot be attributed to the deleted instance, and one
|
|
1429
|
+
// broken entry must not stop the cleanup of the sound ones in the same state
|
|
1430
|
+
const filtered = original.filter(entry => typeof entry?.instance !== 'string' || !matches(entry.instance));
|
|
1431
|
+
if (filtered.length !== original.length) {
|
|
1432
|
+
await this.states.setStateAsync(id, { val: JSON.stringify(filtered), ack: true });
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
catch (e) {
|
|
1436
|
+
console.warn(`Cannot free the used resources in "${id}": ${e.message}`);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1339
1440
|
/**
|
|
1340
1441
|
* Remove all node modules that has been installed by this instance
|
|
1341
1442
|
*
|
|
@@ -1624,4 +1725,189 @@ export class Install {
|
|
|
1624
1725
|
return instances;
|
|
1625
1726
|
}
|
|
1626
1727
|
}
|
|
1728
|
+
/**
|
|
1729
|
+
* @param options options provided by the processCommand dispatcher
|
|
1730
|
+
*/
|
|
1731
|
+
export function processCommandUrl(options) {
|
|
1732
|
+
const { args, params, callback } = options;
|
|
1733
|
+
let url = args[0];
|
|
1734
|
+
const name = args[1];
|
|
1735
|
+
if (!url) {
|
|
1736
|
+
console.log('Please provide a URL to install from and optionally a name of the adapter to install');
|
|
1737
|
+
return void callback(EXIT_CODES.INVALID_ARGUMENTS);
|
|
1738
|
+
}
|
|
1739
|
+
if (url[0] === '"' && url[url.length - 1] === '"') {
|
|
1740
|
+
url = url.substring(1, url.length - 1);
|
|
1741
|
+
}
|
|
1742
|
+
url = url.trim();
|
|
1743
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1744
|
+
const install = new Install({
|
|
1745
|
+
objects,
|
|
1746
|
+
states,
|
|
1747
|
+
processExit: callback,
|
|
1748
|
+
params,
|
|
1749
|
+
});
|
|
1750
|
+
try {
|
|
1751
|
+
await install.installAdapterFromUrl(url, name);
|
|
1752
|
+
return void callback(EXIT_CODES.NO_ERROR);
|
|
1753
|
+
}
|
|
1754
|
+
catch (e) {
|
|
1755
|
+
console.error(`Could not install adapter from url: ${e.message}`);
|
|
1756
|
+
return void callback(EXIT_CODES.CANNOT_INSTALL_NPM_PACKET);
|
|
1757
|
+
}
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
/**
|
|
1761
|
+
* @param options options provided by the processCommand dispatcher
|
|
1762
|
+
*/
|
|
1763
|
+
export function processCommandInstall(options) {
|
|
1764
|
+
const { command, args, params, callback } = options;
|
|
1765
|
+
const { showHelp } = options.commandOptions;
|
|
1766
|
+
let name = args[0];
|
|
1767
|
+
let instance = args[1];
|
|
1768
|
+
let repoUrl = args[2];
|
|
1769
|
+
if (parseInt(instance, 10).toString() !== (instance || '').toString()) {
|
|
1770
|
+
repoUrl = instance;
|
|
1771
|
+
instance = undefined;
|
|
1772
|
+
}
|
|
1773
|
+
if (parseInt(repoUrl, 10).toString() === (repoUrl || '').toString()) {
|
|
1774
|
+
const temp = instance;
|
|
1775
|
+
instance = repoUrl;
|
|
1776
|
+
repoUrl = temp;
|
|
1777
|
+
}
|
|
1778
|
+
if (instance && parseInt(instance, 10).toString() === (instance || '').toString()) {
|
|
1779
|
+
params.instance = parseInt(instance, 10);
|
|
1780
|
+
}
|
|
1781
|
+
// If user accidentally wrote tools.appName.adapter => remove adapter
|
|
1782
|
+
name = CLITools.normalizeAdapterName(name);
|
|
1783
|
+
const parsedName = CLITools.splitAdapterOrInstanceIdentifierWithVersion(name);
|
|
1784
|
+
if (!parsedName) {
|
|
1785
|
+
console.log('Invalid adapter name for install');
|
|
1786
|
+
showHelp();
|
|
1787
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1788
|
+
}
|
|
1789
|
+
// split the adapter into its parts if necessary
|
|
1790
|
+
if (parsedName.instance !== null) {
|
|
1791
|
+
params.instance = parsedName.instance;
|
|
1792
|
+
}
|
|
1793
|
+
name = parsedName.name;
|
|
1794
|
+
const installName = parsedName.nameWithVersion;
|
|
1795
|
+
const adapterDir = tools.getAdapterDir(name);
|
|
1796
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1797
|
+
const install = new Install({
|
|
1798
|
+
objects,
|
|
1799
|
+
states,
|
|
1800
|
+
processExit: callback,
|
|
1801
|
+
params,
|
|
1802
|
+
});
|
|
1803
|
+
if (params.host && params.host !== tools.getHostName()) {
|
|
1804
|
+
// if host argument provided we should check, that host actually exists in mh environment
|
|
1805
|
+
let obj;
|
|
1806
|
+
try {
|
|
1807
|
+
obj = await objects.getObjectAsync(`system.host.${params.host}`);
|
|
1808
|
+
}
|
|
1809
|
+
catch (err) {
|
|
1810
|
+
console.warn(`Could not check existence of host "${params.host}": ${err.message}`);
|
|
1811
|
+
}
|
|
1812
|
+
if (!obj) {
|
|
1813
|
+
console.error(`Cannot add instance to non-existing host "${params.host}"`);
|
|
1814
|
+
return void callback(EXIT_CODES.NON_EXISTING_HOST);
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
if (!adapterDir || !fs.existsSync(adapterDir)) {
|
|
1818
|
+
try {
|
|
1819
|
+
const { stoppedList } = await install.downloadPacket(repoUrl, installName);
|
|
1820
|
+
await install.installAdapter(installName, repoUrl);
|
|
1821
|
+
await install.enableInstances(stoppedList, true); // even if unlikely make sure to re-enable disabled instances
|
|
1822
|
+
if (command !== 'install' && command !== 'i') {
|
|
1823
|
+
await install.createInstance(name, params);
|
|
1824
|
+
}
|
|
1825
|
+
return void callback();
|
|
1826
|
+
}
|
|
1827
|
+
catch (e) {
|
|
1828
|
+
console.error(`adapter "${name}" cannot be installed: ${e.message}`);
|
|
1829
|
+
return void callback(e instanceof IoBrokerError ? e.code : EXIT_CODES.UNKNOWN_ERROR);
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
else if (command !== 'install' && command !== 'i') {
|
|
1833
|
+
try {
|
|
1834
|
+
await install.createInstance(name, params);
|
|
1835
|
+
return void callback();
|
|
1836
|
+
}
|
|
1837
|
+
catch (err) {
|
|
1838
|
+
console.error(`adapter "${name}" cannot be installed: ${err.message}`);
|
|
1839
|
+
return void callback(EXIT_CODES.UNKNOWN_ERROR);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
else {
|
|
1843
|
+
console.log(`adapter "${name}" already installed. Use "upgrade" to upgrade to a newer version.`);
|
|
1844
|
+
return void callback(EXIT_CODES.ADAPTER_ALREADY_INSTALLED);
|
|
1845
|
+
}
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* @param options options provided by the processCommand dispatcher
|
|
1850
|
+
*/
|
|
1851
|
+
export function processCommandDelete(options) {
|
|
1852
|
+
const { args, params, callback } = options;
|
|
1853
|
+
const { showHelp } = options.commandOptions;
|
|
1854
|
+
let adapter = args[0];
|
|
1855
|
+
let instance = args[1];
|
|
1856
|
+
// The adapter argument is required
|
|
1857
|
+
if (!adapter) {
|
|
1858
|
+
showHelp();
|
|
1859
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1860
|
+
}
|
|
1861
|
+
// If the user accidentally wrote <tools.appName>.adapter,
|
|
1862
|
+
// remove <tools.appName> from the adapter name
|
|
1863
|
+
adapter = CLITools.normalizeAdapterName(adapter);
|
|
1864
|
+
// Avoid deleting stuff we don't want to delete
|
|
1865
|
+
// e.g. `system.adapter.*`
|
|
1866
|
+
if (!instance) {
|
|
1867
|
+
// Ensure that adapter contains a valid adapter (without instance nr)
|
|
1868
|
+
// or instance (with instance nr) identifier
|
|
1869
|
+
if (!CLITools.validateAdapterOrInstanceIdentifier(adapter)) {
|
|
1870
|
+
showHelp();
|
|
1871
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1872
|
+
}
|
|
1873
|
+
// split the adapter into adapter + instance if necessary
|
|
1874
|
+
if (adapter.indexOf('.') > -1) {
|
|
1875
|
+
[adapter, instance] = adapter.split('.', 2);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
else {
|
|
1879
|
+
// ensure that adapter contains a valid adapter identifier
|
|
1880
|
+
// and the instance is a number
|
|
1881
|
+
if (!CLITools.validateAdapterIdentifier(adapter) || !/^\d+$/.test(instance)) {
|
|
1882
|
+
showHelp();
|
|
1883
|
+
return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
if (instance) {
|
|
1887
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1888
|
+
const install = new Install({
|
|
1889
|
+
objects,
|
|
1890
|
+
states,
|
|
1891
|
+
processExit: callback,
|
|
1892
|
+
params,
|
|
1893
|
+
});
|
|
1894
|
+
console.log(`Delete instance "${adapter}.${instance}"`);
|
|
1895
|
+
await install.deleteInstance(adapter, parseInt(instance));
|
|
1896
|
+
callback();
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
else {
|
|
1900
|
+
dbConnect(params, async ({ objects, states }) => {
|
|
1901
|
+
const install = new Install({
|
|
1902
|
+
objects,
|
|
1903
|
+
states,
|
|
1904
|
+
processExit: callback,
|
|
1905
|
+
params,
|
|
1906
|
+
});
|
|
1907
|
+
console.log(`Delete adapter "${adapter}"`);
|
|
1908
|
+
const resultCode = await install.deleteAdapter(adapter);
|
|
1909
|
+
callback(resultCode);
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1627
1913
|
//# sourceMappingURL=setupInstall.js.map
|