@iobroker/js-controller-cli 7.0.8-alpha.8-20251127-036be0224 → 7.1.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/build/cjs/lib/cli/cliLogs.js.map +1 -1
- package/build/cjs/lib/setup/dbConnection.js +4 -4
- package/build/cjs/lib/setup/dbConnection.js.map +2 -2
- package/build/cjs/lib/setup/multihostClient.d.ts +58 -22
- package/build/cjs/lib/setup/multihostClient.js +31 -24
- package/build/cjs/lib/setup/multihostClient.js.map +3 -3
- package/build/cjs/lib/setup/setupMultihost.d.ts +16 -4
- package/build/cjs/lib/setup/setupMultihost.js +32 -16
- package/build/cjs/lib/setup/setupMultihost.js.map +3 -3
- package/build/cjs/lib/setup/setupSetup.d.ts +3 -11
- package/build/cjs/lib/setup/setupSetup.js +65 -76
- package/build/cjs/lib/setup/setupSetup.js.map +2 -2
- package/build/cjs/lib/setup/setupVendor.d.ts +3 -1
- package/build/cjs/lib/setup/setupVendor.js +72 -35
- package/build/cjs/lib/setup/setupVendor.js.map +2 -2
- package/build/cjs/lib/setup.js +5 -2
- package/build/cjs/lib/setup.js.map +2 -2
- package/build/esm/lib/cli/cliLogs.js +1 -1
- package/build/esm/lib/cli/cliLogs.js.map +1 -1
- package/build/esm/lib/setup/dbConnection.d.ts.map +1 -1
- package/build/esm/lib/setup/dbConnection.js +14 -14
- package/build/esm/lib/setup/dbConnection.js.map +1 -1
- package/build/esm/lib/setup/multihostClient.d.ts +58 -22
- package/build/esm/lib/setup/multihostClient.d.ts.map +1 -1
- package/build/esm/lib/setup/multihostClient.js +47 -23
- package/build/esm/lib/setup/multihostClient.js.map +1 -1
- package/build/esm/lib/setup/setupMultihost.d.ts +16 -4
- package/build/esm/lib/setup/setupMultihost.d.ts.map +1 -1
- package/build/esm/lib/setup/setupMultihost.js +41 -18
- package/build/esm/lib/setup/setupMultihost.js.map +1 -1
- package/build/esm/lib/setup/setupSetup.d.ts +3 -11
- package/build/esm/lib/setup/setupSetup.d.ts.map +1 -1
- package/build/esm/lib/setup/setupSetup.js +66 -80
- package/build/esm/lib/setup/setupSetup.js.map +1 -1
- package/build/esm/lib/setup/setupVendor.d.ts +3 -1
- package/build/esm/lib/setup/setupVendor.d.ts.map +1 -1
- package/build/esm/lib/setup/setupVendor.js +72 -35
- package/build/esm/lib/setup/setupVendor.js.map +1 -1
- package/build/esm/lib/setup.d.ts.map +1 -1
- package/build/esm/lib/setup.js +6 -3
- package/build/esm/lib/setup.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +7 -7
|
@@ -34,15 +34,20 @@ module.exports = __toCommonJS(setupMultihost_exports);
|
|
|
34
34
|
var import_fs_extra = __toESM(require("fs-extra"), 1);
|
|
35
35
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
36
36
|
var import_node_readline = __toESM(require("node:readline"), 1);
|
|
37
|
+
var import_readline_sync = __toESM(require("readline-sync"), 1);
|
|
38
|
+
var import_prompt = __toESM(require("prompt"), 1);
|
|
37
39
|
var import_js_controller_common = require("@iobroker/js-controller-common");
|
|
38
40
|
var import_js_controller_common2 = require("@iobroker/js-controller-common");
|
|
39
41
|
var import_multihostClient = require("./multihostClient.js");
|
|
40
|
-
var import_readline_sync = __toESM(require("readline-sync"), 1);
|
|
41
|
-
var import_prompt = __toESM(require("prompt"), 1);
|
|
42
42
|
class Multihost {
|
|
43
43
|
configName;
|
|
44
44
|
params;
|
|
45
45
|
objects;
|
|
46
|
+
/**
|
|
47
|
+
* Constructor
|
|
48
|
+
*
|
|
49
|
+
* @param options options for the Multihost CLI
|
|
50
|
+
*/
|
|
46
51
|
constructor(options) {
|
|
47
52
|
this.configName = import_js_controller_common.tools.getConfigFileName();
|
|
48
53
|
this.params = options.params || {};
|
|
@@ -84,8 +89,7 @@ class Multihost {
|
|
|
84
89
|
async browse() {
|
|
85
90
|
const mhClient = new import_multihostClient.MHClient();
|
|
86
91
|
try {
|
|
87
|
-
|
|
88
|
-
return res;
|
|
92
|
+
return await mhClient.browse(2e3, !!this.params.debug);
|
|
89
93
|
} catch (e) {
|
|
90
94
|
throw new Error(`Multihost discovery client: Cannot browse: ${e.message}`);
|
|
91
95
|
}
|
|
@@ -134,8 +138,8 @@ Change "bind 127.0.0.1" to "bind ${import_js_controller_common.tools.getListenAl
|
|
|
134
138
|
console.log(`Multihost discovery server: ${config.multihostService.enabled ? "enabled" : "disabled"}`);
|
|
135
139
|
console.log(`Discovery authentication: ${config.multihostService.secure ? "enabled" : "disabled"}`);
|
|
136
140
|
console.log(`Persistent activation: ${config.multihostService.enabled && config.multihostService.persist ? "enabled" : "disabled"}`);
|
|
137
|
-
console.log(`Objects: ${config.objects.type} on ${config.objects.host}`);
|
|
138
|
-
console.log(`States: ${config.states.type} on ${config.states.host}`);
|
|
141
|
+
console.log(`Objects: ${config.objects.type} on ${Array.isArray(config.objects.host) ? config.objects.host.join(", ") : config.objects.host}`);
|
|
142
|
+
console.log(`States: ${config.states.type} on ${Array.isArray(config.states.host) ? config.states.host.join(", ") : config.states.host}`);
|
|
139
143
|
}
|
|
140
144
|
/**
|
|
141
145
|
* Enables or disables the multihost discovery server in the config json
|
|
@@ -151,7 +155,7 @@ Change "bind 127.0.0.1" to "bind ${import_js_controller_common.tools.getListenAl
|
|
|
151
155
|
changed = true;
|
|
152
156
|
config.multihostService.enabled = true;
|
|
153
157
|
config.multihostService.password = "";
|
|
154
|
-
console.log("Multihost discovery server activated on this host. If iobroker is currently not running please start
|
|
158
|
+
console.log("Multihost discovery server activated on this host. If iobroker is currently not running please start before trying to discover this host.");
|
|
155
159
|
console.log("Important: Multihost discovery works with UDP packets. Make sure they are routed correctly in your network. If you use Docker you also need to configure this correctly.");
|
|
156
160
|
if (!this.params.persist) {
|
|
157
161
|
console.log("Multihost discovery will be automatically deactivated after 15 minutes. If you want to activate it permanently use the --persist flag");
|
|
@@ -191,12 +195,12 @@ Change "bind 127.0.0.1" to "bind ${import_js_controller_common.tools.getListenAl
|
|
|
191
195
|
}
|
|
192
196
|
};
|
|
193
197
|
import_prompt.default.start();
|
|
194
|
-
import_prompt.default.get(schema, (
|
|
198
|
+
import_prompt.default.get(schema, (_err, password) => {
|
|
195
199
|
if (password?.password) {
|
|
196
200
|
if (password.password !== password.passwordRepeat) {
|
|
197
201
|
callback(new Error("Secret phrases are not equal!"));
|
|
198
202
|
} else {
|
|
199
|
-
this.objects.getObject("system.config", (
|
|
203
|
+
this.objects.getObject("system.config", (_err2, obj) => {
|
|
200
204
|
config.multihostService.password = import_js_controller_common.tools.encrypt(obj.native.secret, password.password);
|
|
201
205
|
this.showMHState(config, changed);
|
|
202
206
|
callback();
|
|
@@ -232,10 +236,10 @@ Change "bind 127.0.0.1" to "bind ${import_js_controller_common.tools.getListenAl
|
|
|
232
236
|
/**
|
|
233
237
|
* Connect to given MH server
|
|
234
238
|
*
|
|
235
|
-
* @param mhClient
|
|
236
|
-
* @param ip
|
|
239
|
+
* @param mhClient MultiHost Client used for connection
|
|
240
|
+
* @param ip IP address of server
|
|
237
241
|
* @param pass password
|
|
238
|
-
* @param callback
|
|
242
|
+
* @param callback callback
|
|
239
243
|
*/
|
|
240
244
|
connectHelper(mhClient, ip, pass, callback) {
|
|
241
245
|
mhClient.connect(ip, pass, async (err, oObjects, oStates, ipHost) => {
|
|
@@ -249,16 +253,28 @@ Change "bind 127.0.0.1" to "bind ${import_js_controller_common.tools.getListenAl
|
|
|
249
253
|
const hasLocalStatesServer = await (0, import_js_controller_common2.isLocalStatesDbServer)(config.states.type, config.states.host, true);
|
|
250
254
|
if (hasLocalObjectsServer || hasLocalStatesServer) {
|
|
251
255
|
callback(new Error(`IP Address of the remote host is ${import_js_controller_common.tools.getLocalAddress()}. Connections from this host will not be accepted. Please change the configuration of this host to accept remote connections.`));
|
|
252
|
-
} else {
|
|
253
|
-
|
|
256
|
+
} else if ((!Array.isArray(config.states.host) || config.states.host.length === 1) && (!Array.isArray(config.objects.host) || config.objects.host.length === 1)) {
|
|
257
|
+
const sHost = Array.isArray(config.states.host) ? config.states.host[0] : config.states.host;
|
|
258
|
+
if (import_js_controller_common.tools.isListenAllAddress(sHost)) {
|
|
254
259
|
config.states.host = ipHost ?? "";
|
|
255
260
|
}
|
|
256
|
-
|
|
261
|
+
const oHost = Array.isArray(config.objects.host) ? config.objects.host[0] : config.objects.host;
|
|
262
|
+
if (import_js_controller_common.tools.isListenAllAddress(oHost)) {
|
|
257
263
|
config.objects.host = ipHost ?? "";
|
|
258
264
|
}
|
|
259
265
|
import_fs_extra.default.writeFileSync(this.configName, JSON.stringify(config, null, 2));
|
|
260
266
|
console.log('Config ok. Please restart ioBroker: "iobroker restart"');
|
|
261
267
|
callback();
|
|
268
|
+
} else {
|
|
269
|
+
if (Array.isArray(config.states.host)) {
|
|
270
|
+
config.states.host = config.states.host.map((sHost) => import_js_controller_common.tools.isListenAllAddress(sHost) ? ipHost ?? "" : sHost);
|
|
271
|
+
}
|
|
272
|
+
if (Array.isArray(config.objects.host)) {
|
|
273
|
+
config.objects.host = config.objects.host.map((oHost) => import_js_controller_common.tools.isListenAllAddress(oHost) ? ipHost ?? "" : oHost);
|
|
274
|
+
}
|
|
275
|
+
import_fs_extra.default.writeFileSync(this.configName, JSON.stringify(config, null, 2));
|
|
276
|
+
console.log('Config ok. Please restart ioBroker: "iobroker restart"');
|
|
277
|
+
callback();
|
|
262
278
|
}
|
|
263
279
|
} else {
|
|
264
280
|
callback(new Error("No configuration received!"));
|
|
@@ -270,7 +286,7 @@ Change "bind 127.0.0.1" to "bind ${import_js_controller_common.tools.getListenAl
|
|
|
270
286
|
*
|
|
271
287
|
* @param index index of host to connect to
|
|
272
288
|
* @param pass password
|
|
273
|
-
* @param callback
|
|
289
|
+
* @param callback callback
|
|
274
290
|
*/
|
|
275
291
|
async connect(index, pass, callback) {
|
|
276
292
|
if (typeof pass === "function") {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/setup/setupMultihost.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport { tools } from '@iobroker/js-controller-common';\nimport { isLocalObjectsDbServer, isLocalStatesDbServer } from '@iobroker/js-controller-common';\nimport type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport { MHClient, type BrowseResultEntry } from './multihostClient.js';\nimport readlineSync from 'readline-sync';\nimport prompt from 'prompt';\n\ninterface MHParams {\n secure?: boolean;\n persist?: boolean;\n debug?: boolean;\n}\n\nexport interface CLIMultihostOptions {\n objects: ObjectsRedisClient;\n params?: MHParams;\n}\n\nexport class Multihost {\n private readonly configName: string;\n private params: MHParams;\n private objects: ObjectsRedisClient;\n\n constructor(options: CLIMultihostOptions) {\n this.configName = tools.getConfigFileName();\n this.params = options.params || {};\n this.objects = options.objects;\n }\n\n /**\n * Retrieve config (iobroker.json content)\n */\n getConfig(): ioBroker.IoBrokerJson {\n let config;\n // read actual configuration\n try {\n if (fs.existsSync(this.configName)) {\n config = fs.readJsonSync(this.configName);\n } else {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n } catch {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n return config;\n }\n\n /**\n * Show hosts on CLI\n *\n * @param list list of hosts\n */\n showHosts(list: BrowseResultEntry[]): void {\n if (!list || !list.length) {\n console.info(\n 'No Multihost server found. Make sure iobroker is running on the host where you enabled multihost discovery (and it is not this host)!',\n );\n } else {\n for (let i = 0; i < list.length; i++) {\n console.log(\n `${i + 1} | ${list[i].hostname!.padStart(20)} | ${list[i].slave ? 'slave' : ' host'} | ${list[\n i\n ].ip!.padStart(20)} | ${JSON.stringify(list[i].info)}`,\n );\n }\n }\n }\n\n /**\n * Start MH browsing\n */\n async browse(): Promise<BrowseResultEntry[]> {\n const mhClient = new MHClient();\n try {\n const res = await mhClient.browse(2_000, !!this.params.debug);\n return res;\n } catch (e) {\n throw new Error(`Multihost discovery client: Cannot browse: ${e.message}`);\n }\n }\n\n /**\n * Show MH state on CLI\n *\n * @param config iob config\n * @param changed if config has changed\n */\n private async showMHState(config: ioBroker.IoBrokerJson, changed: boolean): Promise<void> {\n if (config.multihostService.enabled) {\n let warningShown = false;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(config.objects.type, config.objects.host, true);\n\n if (hasLocalObjectsServer) {\n console.log('Changing objects server to accept connections on all IP addresses.');\n config.objects.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.objects.type === 'redis') {\n warningShown = true;\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n warningShown = true;\n console.log(\n `Please check the binding of the configured ${config.objects.type} server to allow remote connections.`,\n );\n }\n\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalStatesServer) {\n console.log('Changing states server to accept connections on all IP addresses.');\n config.states.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.states.type === 'redis') {\n !warningShown &&\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n !warningShown &&\n console.log(\n `Please check the binding of the configured ${config.states.type} server to allow remote connections.`,\n );\n }\n }\n if (!changed) {\n console.log('No configuration change needed.');\n } else {\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Please restart ioBroker for the changes to take effect: \"iobroker restart\"');\n }\n console.log('\\n');\n console.log(`Multihost discovery server: ${config.multihostService.enabled ? 'enabled' : 'disabled'}`);\n console.log(`Discovery authentication: ${config.multihostService.secure ? 'enabled' : 'disabled'}`);\n console.log(\n `Persistent activation: ${\n config.multihostService.enabled && config.multihostService.persist ? 'enabled' : 'disabled'\n }`,\n );\n console.log(`Objects: ${config.objects.type} on ${config.objects.host}`);\n console.log(`States: ${config.states.type} on ${config.states.host}`);\n }\n\n /**\n * Enables or disables the multihost discovery server in the config json\n *\n * @param isEnable - if the server should be activated or deactivated\n * @param callback - callback function to be executed\n */\n enable(isEnable: boolean, callback: (err?: Error) => void): void {\n let changed = false;\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n\n if (isEnable && !config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = true;\n config.multihostService.password = '';\n console.log(\n 'Multihost discovery server activated on this host. If iobroker is currently not running please start befeore trying to discover this host.',\n );\n console.log(\n 'Important: Multihost discovery works with UDP packets. Make sure they are routed correctly in your network. If you use Docker you also need to configure this correctly.',\n );\n if (!this.params.persist) {\n console.log(\n 'Multihost discovery will be automatically deactivated after 15 minutes. If you want to activate it permanently use the --persist flag',\n );\n }\n } else if (!isEnable && config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = false;\n config.multihostService.password = '';\n console.log('Multihost discovery server deactivated on this host.');\n }\n if (this.params.secure === undefined) {\n this.params.secure = true;\n }\n\n this.params.persist = !!this.params.persist;\n\n if (\n isEnable &&\n (config.multihostService.secure !== this.params.secure ||\n (config.multihostService.secure && !config.multihostService.password) ||\n config.multihostService.persist !== this.params.persist)\n ) {\n changed = true;\n config.multihostService.secure = this.params.secure;\n config.multihostService.persist = this.params.persist;\n console.log(`Discovery authentication ${this.params.secure ? 'activated' : 'deactivated'}.`);\n if (config.multihostService.secure) {\n prompt.message = '';\n prompt.delimiter = '';\n const schema = {\n properties: {\n password: {\n description: 'Enter secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n passwordRepeat: {\n description: 'Repeat secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n },\n };\n prompt.start();\n\n prompt.get(schema, (err, password) => {\n if (password?.password) {\n if (password.password !== password.passwordRepeat) {\n callback(new Error('Secret phrases are not equal!'));\n } else {\n this.objects.getObject('system.config', (err, obj) => {\n config.multihostService.password = tools.encrypt(\n obj!.native.secret,\n password.password as string,\n );\n this.showMHState(config, changed);\n callback();\n });\n }\n } else {\n callback(new Error('No secret phrase entered!'));\n }\n });\n } else {\n this.showMHState(config, changed);\n callback();\n }\n } else {\n this.showMHState(config, changed);\n callback();\n }\n }\n\n /**\n * Show the MH status\n */\n status(): void {\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n this.showMHState(config, false);\n }\n\n /**\n * Read password from cli\n */\n readPassword(): string {\n return readlineSync.question('Enter secret phrase for connection: ', { hideEchoBack: true });\n }\n\n /**\n * Connect to given MH server\n *\n * @param mhClient mhclient used for connection\n * @param ip ip address of server\n * @param pass password\n * @param callback\n */\n connectHelper(mhClient: MHClient, ip: string, pass: string, callback: (err?: Error) => void): void {\n mhClient.connect(ip, pass, async (err, oObjects, oStates, ipHost) => {\n if (err) {\n callback(new Error(`Cannot connect to \"${ip}\": ${err.message}`));\n } else if (oObjects && oStates) {\n const config = this.getConfig();\n config.objects = oObjects;\n config.states = oStates;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(\n config.objects.type,\n config.objects.host,\n true,\n );\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalObjectsServer || hasLocalStatesServer) {\n callback(\n new Error(\n `IP Address of the remote host is ${tools.getLocalAddress()}. Connections from this host will not be accepted. Please change the configuration of this host to accept remote connections.`,\n ),\n );\n } else {\n if (tools.isListenAllAddress(config.states.host)) {\n // TODO: why we set the remote IP only when the local config allows full connectivity?\n config.states.host = ipHost ?? '';\n }\n if (tools.isListenAllAddress(config.objects.host)) {\n // TODO: why we set the remote IP only when the local config allows full connectivity?\n config.objects.host = ipHost ?? '';\n }\n\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Config ok. Please restart ioBroker: \"iobroker restart\"');\n callback();\n }\n } else {\n callback(new Error('No configuration received!'));\n }\n });\n }\n\n /**\n * Connect to MH Server\n *\n * @param index index of host to connect to\n * @param pass password\n * @param callback\n */\n async connect(\n index: number | null,\n pass: string | null,\n callback: (err?: Error, list?: BrowseResultEntry[]) => void,\n ): Promise<void> {\n if (typeof pass === 'function') {\n callback = pass;\n pass = null;\n }\n if (typeof index === 'function') {\n callback = index;\n index = null;\n }\n\n const mhClient = new MHClient();\n let list: BrowseResultEntry[];\n\n try {\n list = await mhClient.browse(2_000, !!this.params.debug);\n } catch (e) {\n callback(new Error(`Cannot browse: ${e.message}`));\n return;\n }\n\n this.showHosts(list);\n\n if (index !== null && index !== undefined && index > 0) {\n if (list && index < list.length + 1) {\n if (!pass) {\n callback(new Error('No password defined: please use \"multihost connect <NUMBER> <PASSWORD>\"'));\n } else {\n this.connectHelper(mhClient, list[index - 1].ip!, pass, callback);\n }\n } else {\n callback(new Error(`Invalid index: ${index}`));\n }\n } else if (list && list.length) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question('Please select host [1]: ', answer => {\n if (answer === '' || answer === null || answer === undefined) {\n index = 1;\n }\n index = parseInt(answer, 10) - 1;\n const listEntry = list[index];\n if (!listEntry) {\n rl.close();\n callback(new Error(`Invalid index: ${answer}`));\n } else {\n if (listEntry.auth) {\n const password = this.readPassword();\n if (password) {\n this.connectHelper(mhClient, listEntry.ip!, password, callback);\n } else {\n callback(new Error('No password entered!'));\n }\n } else {\n this.connectHelper(mhClient, listEntry.ip!, '', callback);\n }\n }\n });\n } else {\n callback(undefined, list);\n }\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,sBAAe;AACf,uBAAiB;AACjB,2BAAqB;AACrB,kCAAsB;AACtB,IAAAA,+BAA8D;AAE9D,6BAAiD;
|
|
6
|
-
"names": ["import_js_controller_common", "fs", "path", "prompt", "
|
|
4
|
+
"sourcesContent": ["import fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport readlineSync from 'readline-sync';\nimport prompt from 'prompt';\n\nimport { tools } from '@iobroker/js-controller-common';\nimport { isLocalObjectsDbServer, isLocalStatesDbServer } from '@iobroker/js-controller-common';\nimport type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport { MHClient, type BrowseResultEntry } from './multihostClient.js';\n\ninterface MHParams {\n secure?: boolean;\n persist?: boolean;\n debug?: boolean;\n}\n\n/** Options for Multihost CLI */\nexport interface CLIMultihostOptions {\n /** Redis client for objects DB */\n objects: ObjectsRedisClient;\n /** Additional parameters */\n params?: MHParams;\n}\n\n/**\n * Multihost CLI class\n * Handles multihost related commands\n */\nexport class Multihost {\n private readonly configName: string;\n private params: MHParams;\n private objects: ObjectsRedisClient;\n\n /**\n * Constructor\n *\n * @param options options for the Multihost CLI\n */\n constructor(options: CLIMultihostOptions) {\n this.configName = tools.getConfigFileName();\n this.params = options.params || {};\n this.objects = options.objects;\n }\n\n /**\n * Retrieve config (iobroker.json content)\n */\n getConfig(): ioBroker.IoBrokerJson {\n let config;\n // read actual configuration\n try {\n if (fs.existsSync(this.configName)) {\n config = fs.readJsonSync(this.configName);\n } else {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n } catch {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n return config;\n }\n\n /**\n * Show hosts on CLI\n *\n * @param list list of hosts\n */\n showHosts(list: BrowseResultEntry[]): void {\n if (!list || !list.length) {\n console.info(\n 'No Multihost server found. Make sure iobroker is running on the host where you enabled multihost discovery (and it is not this host)!',\n );\n } else {\n for (let i = 0; i < list.length; i++) {\n console.log(\n `${i + 1} | ${list[i].hostname!.padStart(20)} | ${list[i].slave ? 'slave' : ' host'} | ${list[\n i\n ].ip!.padStart(20)} | ${JSON.stringify(list[i].info)}`,\n );\n }\n }\n }\n\n /**\n * Start MH browsing\n */\n async browse(): Promise<BrowseResultEntry[]> {\n const mhClient = new MHClient();\n try {\n return await mhClient.browse(2_000, !!this.params.debug);\n } catch (e) {\n throw new Error(`Multihost discovery client: Cannot browse: ${e.message}`);\n }\n }\n\n /**\n * Show MH state on CLI\n *\n * @param config iob config\n * @param changed if config has changed\n */\n private async showMHState(config: ioBroker.IoBrokerJson, changed: boolean): Promise<void> {\n if (config.multihostService.enabled) {\n let warningShown = false;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(config.objects.type, config.objects.host, true);\n\n if (hasLocalObjectsServer) {\n console.log('Changing objects server to accept connections on all IP addresses.');\n config.objects.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.objects.type === 'redis') {\n warningShown = true;\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n warningShown = true;\n console.log(\n `Please check the binding of the configured ${config.objects.type} server to allow remote connections.`,\n );\n }\n\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalStatesServer) {\n console.log('Changing states server to accept connections on all IP addresses.');\n config.states.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.states.type === 'redis') {\n !warningShown &&\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n !warningShown &&\n console.log(\n `Please check the binding of the configured ${config.states.type} server to allow remote connections.`,\n );\n }\n }\n if (!changed) {\n console.log('No configuration change needed.');\n } else {\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Please restart ioBroker for the changes to take effect: \"iobroker restart\"');\n }\n console.log('\\n');\n console.log(`Multihost discovery server: ${config.multihostService.enabled ? 'enabled' : 'disabled'}`);\n console.log(`Discovery authentication: ${config.multihostService.secure ? 'enabled' : 'disabled'}`);\n console.log(\n `Persistent activation: ${\n config.multihostService.enabled && config.multihostService.persist ? 'enabled' : 'disabled'\n }`,\n );\n console.log(\n `Objects: ${config.objects.type} on ${Array.isArray(config.objects.host) ? config.objects.host.join(', ') : config.objects.host}`,\n );\n console.log(\n `States: ${config.states.type} on ${Array.isArray(config.states.host) ? config.states.host.join(', ') : config.states.host}`,\n );\n }\n\n /**\n * Enables or disables the multihost discovery server in the config json\n *\n * @param isEnable - if the server should be activated or deactivated\n * @param callback - callback function to be executed\n */\n enable(isEnable: boolean, callback: (err?: Error) => void): void {\n let changed = false;\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n\n if (isEnable && !config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = true;\n config.multihostService.password = '';\n console.log(\n 'Multihost discovery server activated on this host. If iobroker is currently not running please start before trying to discover this host.',\n );\n console.log(\n 'Important: Multihost discovery works with UDP packets. Make sure they are routed correctly in your network. If you use Docker you also need to configure this correctly.',\n );\n if (!this.params.persist) {\n console.log(\n 'Multihost discovery will be automatically deactivated after 15 minutes. If you want to activate it permanently use the --persist flag',\n );\n }\n } else if (!isEnable && config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = false;\n config.multihostService.password = '';\n console.log('Multihost discovery server deactivated on this host.');\n }\n if (this.params.secure === undefined) {\n this.params.secure = true;\n }\n\n this.params.persist = !!this.params.persist;\n\n if (\n isEnable &&\n (config.multihostService.secure !== this.params.secure ||\n (config.multihostService.secure && !config.multihostService.password) ||\n config.multihostService.persist !== this.params.persist)\n ) {\n changed = true;\n config.multihostService.secure = this.params.secure;\n config.multihostService.persist = this.params.persist;\n console.log(`Discovery authentication ${this.params.secure ? 'activated' : 'deactivated'}.`);\n if (config.multihostService.secure) {\n prompt.message = '';\n prompt.delimiter = '';\n const schema = {\n properties: {\n password: {\n description: 'Enter secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n passwordRepeat: {\n description: 'Repeat secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n },\n };\n prompt.start();\n\n prompt.get(schema, (_err, password) => {\n if (password?.password) {\n if (password.password !== password.passwordRepeat) {\n callback(new Error('Secret phrases are not equal!'));\n } else {\n this.objects.getObject('system.config', (_err, obj) => {\n config.multihostService.password = tools.encrypt(\n obj!.native.secret,\n password.password as string,\n );\n this.showMHState(config, changed);\n callback();\n });\n }\n } else {\n callback(new Error('No secret phrase entered!'));\n }\n });\n } else {\n this.showMHState(config, changed);\n callback();\n }\n } else {\n this.showMHState(config, changed);\n callback();\n }\n }\n\n /**\n * Show the MH status\n */\n status(): void {\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n this.showMHState(config, false);\n }\n\n /**\n * Read password from cli\n */\n readPassword(): string {\n return readlineSync.question('Enter secret phrase for connection: ', { hideEchoBack: true });\n }\n\n /**\n * Connect to given MH server\n *\n * @param mhClient MultiHost Client used for connection\n * @param ip IP address of server\n * @param pass password\n * @param callback callback\n */\n connectHelper(mhClient: MHClient, ip: string, pass: string, callback: (err?: Error) => void): void {\n mhClient.connect(ip, pass, async (err, oObjects, oStates, ipHost) => {\n if (err) {\n callback(new Error(`Cannot connect to \"${ip}\": ${err.message}`));\n } else if (oObjects && oStates) {\n const config = this.getConfig();\n config.objects = oObjects;\n config.states = oStates;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(\n config.objects.type,\n config.objects.host,\n true,\n );\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalObjectsServer || hasLocalStatesServer) {\n callback(\n new Error(\n `IP Address of the remote host is ${tools.getLocalAddress()}. Connections from this host will not be accepted. Please change the configuration of this host to accept remote connections.`,\n ),\n );\n } else if (\n (!Array.isArray(config.states.host) || config.states.host.length === 1) &&\n (!Array.isArray(config.objects.host) || config.objects.host.length === 1)\n ) {\n const sHost = Array.isArray(config.states.host) ? config.states.host[0] : config.states.host;\n // If server delivers 0.0.0.0 or ::, set to actual IP of the host\n if (tools.isListenAllAddress(sHost)) {\n config.states.host = ipHost ?? '';\n }\n const oHost = Array.isArray(config.objects.host) ? config.objects.host[0] : config.objects.host;\n // If server delivers 0.0.0.0 or ::, set to actual IP of the host\n if (tools.isListenAllAddress(oHost)) {\n config.objects.host = ipHost ?? '';\n }\n\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Config ok. Please restart ioBroker: \"iobroker restart\"');\n callback();\n } else {\n // Find if any of the hosts is \"listen all\" or reachable\n if (Array.isArray(config.states.host)) {\n config.states.host = config.states.host.map((sHost: string) =>\n tools.isListenAllAddress(sHost) ? (ipHost ?? '') : sHost,\n );\n }\n if (Array.isArray(config.objects.host)) {\n config.objects.host = config.objects.host.map((oHost: string) =>\n tools.isListenAllAddress(oHost) ? (ipHost ?? '') : oHost,\n );\n }\n\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Config ok. Please restart ioBroker: \"iobroker restart\"');\n callback();\n }\n } else {\n callback(new Error('No configuration received!'));\n }\n });\n }\n\n /**\n * Connect to MH Server\n *\n * @param index index of host to connect to\n * @param pass password\n * @param callback callback\n */\n async connect(\n index: number | null,\n pass: string | null,\n callback: (err?: Error, list?: BrowseResultEntry[]) => void,\n ): Promise<void> {\n if (typeof pass === 'function') {\n callback = pass;\n pass = null;\n }\n if (typeof index === 'function') {\n callback = index;\n index = null;\n }\n\n const mhClient = new MHClient();\n let list: BrowseResultEntry[];\n\n try {\n list = await mhClient.browse(2_000, !!this.params.debug);\n } catch (e) {\n callback(new Error(`Cannot browse: ${e.message}`));\n return;\n }\n\n this.showHosts(list);\n\n if (index !== null && index !== undefined && index > 0) {\n if (list && index < list.length + 1) {\n if (!pass) {\n callback(new Error('No password defined: please use \"multihost connect <NUMBER> <PASSWORD>\"'));\n } else {\n this.connectHelper(mhClient, list[index - 1].ip!, pass, callback);\n }\n } else {\n callback(new Error(`Invalid index: ${index}`));\n }\n } else if (list && list.length) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question('Please select host [1]: ', answer => {\n if (answer === '' || answer === null || answer === undefined) {\n index = 1;\n }\n index = parseInt(answer, 10) - 1;\n const listEntry = list[index];\n if (!listEntry) {\n rl.close();\n callback(new Error(`Invalid index: ${answer}`));\n } else {\n if (listEntry.auth) {\n const password = this.readPassword();\n if (password) {\n this.connectHelper(mhClient, listEntry.ip!, password, callback);\n } else {\n callback(new Error('No password entered!'));\n }\n } else {\n this.connectHelper(mhClient, listEntry.ip!, '', callback);\n }\n }\n });\n } else {\n callback(undefined, list);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_js_controller_common", "fs", "path", "prompt", "_err", "readlineSync", "readline"]
|
|
7
7
|
}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Setup
|
|
3
|
-
*
|
|
4
|
-
* Copyright 2013-2024 bluefox <dogafox@gmail.com>
|
|
5
|
-
*
|
|
6
|
-
* MIT License
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
1
|
import type { CleanDatabaseHandler, IoPackage, ProcessExitCallback, RestartController } from '../../lib/_Types.js';
|
|
10
2
|
import { EXIT_CODES } from '@iobroker/js-controller-common';
|
|
11
3
|
export interface CLISetupOptions {
|
|
@@ -75,9 +67,9 @@ export declare class Setup {
|
|
|
75
67
|
*/
|
|
76
68
|
private _ensureHostObject;
|
|
77
69
|
/**
|
|
78
|
-
* Add adapter-core in supported version in the overrides field of the root package.json and call install there to apply it
|
|
70
|
+
* Add or update adapter-core in supported version in the overrides field of the root package.json and call install there to apply it
|
|
79
71
|
*/
|
|
80
|
-
private
|
|
72
|
+
private addOrUpdateAdapterCoreRequirement;
|
|
81
73
|
/**
|
|
82
74
|
* Create the adapters object per host if not yet existing
|
|
83
75
|
*/
|
|
@@ -111,7 +103,7 @@ export declare class Setup {
|
|
|
111
103
|
*/
|
|
112
104
|
private _cleanupInvalidGroupAssignments;
|
|
113
105
|
/**
|
|
114
|
-
*
|
|
106
|
+
* Set up the installation with config file, host object, scripts etc
|
|
115
107
|
*
|
|
116
108
|
* @param options setup options
|
|
117
109
|
*/
|
|
@@ -59,7 +59,7 @@ class Setup {
|
|
|
59
59
|
/** Object IDs which are not allowed to exist but could be generated due to errors in the past */
|
|
60
60
|
KNOWN_GARBAGE_OBJECT_IDS = ["null", "undefined"];
|
|
61
61
|
/** Adapter core version supported by this js-controller */
|
|
62
|
-
SUPPORTED_ADAPTER_CORE_VERSION = "^3.2
|
|
62
|
+
SUPPORTED_ADAPTER_CORE_VERSION = "^3.3.2";
|
|
63
63
|
/** Default name for redis sentinels */
|
|
64
64
|
DEFAULT_SENTINEL_NAME = "mymaster";
|
|
65
65
|
processExit;
|
|
@@ -167,7 +167,7 @@ class Setup {
|
|
|
167
167
|
await this._fixWindowsControllerJs();
|
|
168
168
|
}
|
|
169
169
|
try {
|
|
170
|
-
await this.
|
|
170
|
+
await this.addOrUpdateAdapterCoreRequirement();
|
|
171
171
|
} catch (e) {
|
|
172
172
|
console.error(`Could not add "@iobroker/adapter-core" requirement: ${e.message}`);
|
|
173
173
|
}
|
|
@@ -262,7 +262,7 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
262
262
|
}
|
|
263
263
|
if (!configObj.native?.secret) {
|
|
264
264
|
const buf = import_node_crypto.default.randomBytes(24);
|
|
265
|
-
configObj.native
|
|
265
|
+
configObj.native ||= {};
|
|
266
266
|
configObj.native.secret = buf.toString("hex");
|
|
267
267
|
configObj.from = `system.host.${import_js_controller_common.tools.getHostName()}.cli`;
|
|
268
268
|
configObj.ts = Date.now();
|
|
@@ -295,14 +295,14 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
295
295
|
let certObj;
|
|
296
296
|
if (iopkg?.objects) {
|
|
297
297
|
for (const obj of iopkg.objects) {
|
|
298
|
-
if (obj
|
|
298
|
+
if (obj?._id === "system.certificates") {
|
|
299
299
|
certObj = obj;
|
|
300
300
|
break;
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
if (certObj) {
|
|
305
|
-
let obj;
|
|
305
|
+
let obj = null;
|
|
306
306
|
try {
|
|
307
307
|
obj = await this.objects.getObjectAsync("system.certificates");
|
|
308
308
|
} catch {
|
|
@@ -529,31 +529,30 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
529
529
|
}
|
|
530
530
|
async setupCustom() {
|
|
531
531
|
let config;
|
|
532
|
-
let originalConfig;
|
|
533
532
|
try {
|
|
534
533
|
if (import_fs_extra.default.existsSync(import_js_controller_common.tools.getConfigFileName())) {
|
|
535
534
|
config = import_fs_extra.default.readJsonSync(import_js_controller_common.tools.getConfigFileName());
|
|
536
|
-
originalConfig = (0, import_deep_clone.default)(config);
|
|
537
535
|
} else {
|
|
538
536
|
config = import_fs_extra.default.readJsonSync(import_node_path.default.join(CONTROLLER_DIR, "conf", `${import_js_controller_common.tools.appName.toLowerCase()}-dist.json`));
|
|
539
537
|
}
|
|
540
538
|
} catch {
|
|
541
539
|
config = import_fs_extra.default.readJsonSync(import_node_path.default.join(CONTROLLER_DIR, "conf", `${import_js_controller_common.tools.appName.toLowerCase()}-dist.json`));
|
|
542
540
|
}
|
|
541
|
+
const originalConfig = (0, import_deep_clone.default)(config);
|
|
543
542
|
const currentObjectsType = originalConfig.objects.type || "jsonl";
|
|
544
543
|
const currentStatesType = originalConfig.states.type || "jsonl";
|
|
545
544
|
console.log("Current configuration:");
|
|
546
545
|
console.log("- Objects database:");
|
|
547
546
|
console.log(` - Type: ${originalConfig.objects.type}`);
|
|
548
|
-
console.log(` - Host/Unix Socket: ${originalConfig.objects.host}`);
|
|
549
|
-
console.log(` - Port: ${originalConfig.objects.port}`);
|
|
547
|
+
console.log(` - Host/Unix Socket: ${Array.isArray(originalConfig.objects.host) ? originalConfig.objects.host.join(",") : originalConfig.objects.host}`);
|
|
548
|
+
console.log(` - Port: ${Array.isArray(originalConfig.objects.port) ? originalConfig.objects.port.join(",") : originalConfig.objects.port}`);
|
|
550
549
|
if (Array.isArray(originalConfig.objects.host)) {
|
|
551
550
|
console.log(` - Sentinel-Master-Name: ${originalConfig.objects.sentinelName ? originalConfig.objects.sentinelName : this.DEFAULT_SENTINEL_NAME}`);
|
|
552
551
|
}
|
|
553
552
|
console.log("- States database:");
|
|
554
553
|
console.log(` - Type: ${originalConfig.states.type}`);
|
|
555
|
-
console.log(` - Host/Unix Socket: ${originalConfig.states.host}`);
|
|
556
|
-
console.log(` - Port: ${originalConfig.states.port}`);
|
|
554
|
+
console.log(` - Host/Unix Socket: ${Array.isArray(originalConfig.states.host) ? originalConfig.states.host.join(",") : originalConfig.states.host}`);
|
|
555
|
+
console.log(` - Port: ${Array.isArray(originalConfig.states.port) ? originalConfig.states.port.join(",") : originalConfig.states.port}`);
|
|
557
556
|
if (Array.isArray(originalConfig.states.host)) {
|
|
558
557
|
console.log(` - Sentinel-Master-Name: ${originalConfig.states.sentinelName ? originalConfig.states.sentinelName : this.DEFAULT_SENTINEL_NAME}`);
|
|
559
558
|
}
|
|
@@ -562,37 +561,37 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
562
561
|
if (hasObjectsServer || hasStatesServer) {
|
|
563
562
|
console.log(`- Data Directory: ${import_js_controller_common.tools.getDefaultDataDir()}`);
|
|
564
563
|
}
|
|
565
|
-
if (originalConfig
|
|
564
|
+
if (originalConfig?.system?.hostname) {
|
|
566
565
|
console.log(`- Host name: ${originalConfig.system.hostname}`);
|
|
567
566
|
}
|
|
568
567
|
console.log("");
|
|
569
|
-
let
|
|
568
|
+
let oType = import_readline_sync.default.question(`Type of objects DB [(j)sonl, (f)ile, (r)edis, ...], default [${currentObjectsType}]: `, {
|
|
570
569
|
defaultInput: currentObjectsType
|
|
571
570
|
});
|
|
572
|
-
|
|
573
|
-
if (
|
|
574
|
-
|
|
575
|
-
} else if (
|
|
576
|
-
|
|
577
|
-
} else if (
|
|
578
|
-
|
|
571
|
+
oType = oType.toLowerCase();
|
|
572
|
+
if (oType === "r") {
|
|
573
|
+
oType = "redis";
|
|
574
|
+
} else if (oType === "f") {
|
|
575
|
+
oType = "file";
|
|
576
|
+
} else if (oType === "j") {
|
|
577
|
+
oType = "jsonl";
|
|
579
578
|
}
|
|
580
579
|
let getDefaultObjectsPort;
|
|
581
580
|
try {
|
|
582
|
-
const path2 = require2.resolve(`@iobroker/db-objects-${
|
|
581
|
+
const path2 = require2.resolve(`@iobroker/db-objects-${oType}`);
|
|
583
582
|
getDefaultObjectsPort = require2(path2).getDefaultPort;
|
|
584
583
|
} catch {
|
|
585
|
-
console.log(`${COLOR_RED}Unknown objects type: ${
|
|
586
|
-
if (
|
|
584
|
+
console.log(`${COLOR_RED}Unknown objects type: ${oType}${COLOR_RESET}`);
|
|
585
|
+
if (oType !== "file" && oType !== "redis") {
|
|
587
586
|
console.log(COLOR_YELLOW);
|
|
588
587
|
console.log(`Please check that the objects db type you entered is really correct!`);
|
|
589
|
-
console.log(`If yes please use "npm i @iobroker/db-objects-${
|
|
588
|
+
console.log(`If yes please use "npm i @iobroker/db-objects-${oType}" to install it manually.`);
|
|
590
589
|
console.log(`You also need to make sure you stay up to date with this package in the future!`);
|
|
591
590
|
console.log(COLOR_RESET);
|
|
592
591
|
}
|
|
593
592
|
return import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS;
|
|
594
593
|
}
|
|
595
|
-
if (
|
|
594
|
+
if (oType === "redis" && originalConfig.objects.type !== "redis") {
|
|
596
595
|
console.log(COLOR_YELLOW);
|
|
597
596
|
console.log("When Objects and Files are stored in a Redis database please consider the following:");
|
|
598
597
|
console.log("1. All data will be stored in RAM, make sure to have enough free RAM available!");
|
|
@@ -600,18 +599,18 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
600
599
|
console.log("3. The Redis persistence files can get big, make sure not to use an SD card to store them.");
|
|
601
600
|
console.log(COLOR_RESET);
|
|
602
601
|
}
|
|
603
|
-
const defaultObjectsHost =
|
|
604
|
-
let oHost = import_readline_sync.default.question(`Host / Unix Socket of objects DB(${
|
|
602
|
+
const defaultObjectsHost = oType === originalConfig.objects.type ? originalConfig.objects.host : import_js_controller_common.tools.getLocalAddress();
|
|
603
|
+
let oHost = import_readline_sync.default.question(`Host / Unix Socket of objects DB(${oType}), default[${Array.isArray(defaultObjectsHost) ? defaultObjectsHost.join(",") : defaultObjectsHost}]: `, {
|
|
605
604
|
defaultInput: Array.isArray(defaultObjectsHost) ? defaultObjectsHost.join(",") : defaultObjectsHost
|
|
606
605
|
});
|
|
607
606
|
oHost = oHost.toLowerCase();
|
|
608
607
|
const op = getDefaultObjectsPort(oHost);
|
|
609
|
-
const oSentinel =
|
|
608
|
+
const oSentinel = oType === "redis" && oHost.includes(",");
|
|
610
609
|
if (oSentinel) {
|
|
611
610
|
oHost = oHost.split(",").map((host) => host.trim());
|
|
612
611
|
}
|
|
613
|
-
const defaultObjectsPort =
|
|
614
|
-
const userObjPort = import_readline_sync.default.question(`Port of objects DB(${
|
|
612
|
+
const defaultObjectsPort = oType === originalConfig.objects.type && oHost === originalConfig.objects.host ? originalConfig.objects.port : op;
|
|
613
|
+
const userObjPort = import_readline_sync.default.question(`Port of objects DB(${oType}), default[${Array.isArray(defaultObjectsPort) ? defaultObjectsPort.join(",") : defaultObjectsPort}]: `, {
|
|
615
614
|
defaultInput: Array.isArray(defaultObjectsPort) ? defaultObjectsPort.join(",") : defaultObjectsPort,
|
|
616
615
|
limit: /^[0-9, ]+$/
|
|
617
616
|
});
|
|
@@ -637,7 +636,7 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
637
636
|
return import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS;
|
|
638
637
|
}
|
|
639
638
|
}
|
|
640
|
-
config.objects = await (0, import_js_controller_common2.performObjectsInterview)({ dbType:
|
|
639
|
+
config.objects = await (0, import_js_controller_common2.performObjectsInterview)({ dbType: oType, config: config.objects });
|
|
641
640
|
let oSentinelName = null;
|
|
642
641
|
if (oSentinel) {
|
|
643
642
|
const defaultSentinelName = originalConfig.objects.sentinelName ? originalConfig.objects.sentinelName : this.DEFAULT_SENTINEL_NAME;
|
|
@@ -647,61 +646,61 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
647
646
|
}
|
|
648
647
|
let defaultStatesType = currentStatesType;
|
|
649
648
|
try {
|
|
650
|
-
require2.resolve(`@iobroker/db-states-${
|
|
651
|
-
defaultStatesType =
|
|
649
|
+
require2.resolve(`@iobroker/db-states-${oType}`);
|
|
650
|
+
defaultStatesType = oType;
|
|
652
651
|
} catch {
|
|
653
652
|
}
|
|
654
|
-
let
|
|
653
|
+
let sType = import_readline_sync.default.question(`Type of states DB [(j)sonl, (f)file, (r)edis, ...], default [${defaultStatesType}]: `, {
|
|
655
654
|
defaultInput: defaultStatesType
|
|
656
655
|
});
|
|
657
|
-
|
|
658
|
-
if (
|
|
659
|
-
|
|
660
|
-
} else if (
|
|
661
|
-
|
|
662
|
-
} else if (
|
|
663
|
-
|
|
656
|
+
sType = sType.toLowerCase();
|
|
657
|
+
if (sType === "r") {
|
|
658
|
+
sType = "redis";
|
|
659
|
+
} else if (sType === "f") {
|
|
660
|
+
sType = "file";
|
|
661
|
+
} else if (sType === "j") {
|
|
662
|
+
sType = "jsonl";
|
|
664
663
|
}
|
|
665
664
|
let getDefaultStatesPort;
|
|
666
665
|
try {
|
|
667
|
-
const path2 = require2.resolve(`@iobroker/db-states-${
|
|
666
|
+
const path2 = require2.resolve(`@iobroker/db-states-${sType}`);
|
|
668
667
|
getDefaultStatesPort = require2(path2).getDefaultPort;
|
|
669
668
|
} catch {
|
|
670
|
-
console.log(`${COLOR_RED}Unknown states type: ${
|
|
671
|
-
if (
|
|
669
|
+
console.log(`${COLOR_RED}Unknown states type: ${sType}${COLOR_RESET}`);
|
|
670
|
+
if (sType !== "file" && sType !== "redis") {
|
|
672
671
|
console.log(COLOR_YELLOW);
|
|
673
672
|
console.log(`Please check that the states db type you entered is really correct!`);
|
|
674
|
-
console.log(`If yes please use "npm i @iobroker/db-states-${
|
|
673
|
+
console.log(`If yes please use "npm i @iobroker/db-states-${sType}" to install it manually.`);
|
|
675
674
|
console.log(`You also need to make sure you stay up to date with this package in the future!`);
|
|
676
675
|
console.log(COLOR_RESET);
|
|
677
676
|
}
|
|
678
677
|
return import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS;
|
|
679
678
|
}
|
|
680
|
-
if (
|
|
679
|
+
if (sType === "redis" && originalConfig.states.type !== "redis" && oType !== "redis") {
|
|
681
680
|
console.log(COLOR_YELLOW);
|
|
682
681
|
console.log("When States are stored in a Redis database please make sure to configure Redis");
|
|
683
682
|
console.log("persistence to make sure a Redis problem will not cause data loss!");
|
|
684
683
|
console.log(COLOR_RESET);
|
|
685
684
|
}
|
|
686
|
-
let defaultStatesHost =
|
|
687
|
-
if (
|
|
685
|
+
let defaultStatesHost = sType === originalConfig.states.type ? originalConfig.states.host : oHost || import_js_controller_common.tools.getLocalAddress();
|
|
686
|
+
if (sType === oType) {
|
|
688
687
|
defaultStatesHost = oHost;
|
|
689
688
|
}
|
|
690
|
-
let sHost = import_readline_sync.default.question(`Host / Unix Socket of states DB (${
|
|
689
|
+
let sHost = import_readline_sync.default.question(`Host / Unix Socket of states DB (${sType}), default[${Array.isArray(defaultStatesHost) ? defaultStatesHost.join(",") : defaultStatesHost}]: `, {
|
|
691
690
|
defaultInput: Array.isArray(defaultStatesHost) ? defaultStatesHost.join(",") : defaultStatesHost
|
|
692
691
|
});
|
|
693
692
|
sHost = sHost.toLowerCase();
|
|
694
693
|
const sp = getDefaultStatesPort(sHost);
|
|
695
|
-
const sSentinel =
|
|
694
|
+
const sSentinel = sType === "redis" && sHost.includes(",");
|
|
696
695
|
if (sSentinel) {
|
|
697
696
|
sHost = sHost.split(",").map((host) => host.trim());
|
|
698
697
|
}
|
|
699
|
-
let defaultStatesPort =
|
|
700
|
-
const statesHasServer = await (0, import_js_controller_common2.statesDbHasServer)(
|
|
701
|
-
if (
|
|
698
|
+
let defaultStatesPort = sType === originalConfig.states.type && sHost === originalConfig.states.host ? originalConfig.states.port : sp;
|
|
699
|
+
const statesHasServer = await (0, import_js_controller_common2.statesDbHasServer)(sType);
|
|
700
|
+
if (sType === oType && !statesHasServer && sHost === oHost) {
|
|
702
701
|
defaultStatesPort = oPort;
|
|
703
702
|
}
|
|
704
|
-
const userStatePort = import_readline_sync.default.question(`Port of states DB (${
|
|
703
|
+
const userStatePort = import_readline_sync.default.question(`Port of states DB (${sType}), default[${Array.isArray(defaultStatesPort) ? defaultStatesPort.join(",") : defaultStatesPort}]: `, {
|
|
705
704
|
defaultInput: Array.isArray(defaultStatesPort) ? defaultStatesPort.join(",") : defaultStatesPort,
|
|
706
705
|
limit: /^[0-9, ]+$/
|
|
707
706
|
});
|
|
@@ -728,7 +727,7 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
728
727
|
return import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS;
|
|
729
728
|
}
|
|
730
729
|
}
|
|
731
|
-
config.states = await (0, import_js_controller_common2.performStatesInterview)({ dbType:
|
|
730
|
+
config.states = await (0, import_js_controller_common2.performStatesInterview)({ dbType: sType, config: config.states });
|
|
732
731
|
let sSentinelName = null;
|
|
733
732
|
if (sSentinel) {
|
|
734
733
|
const defaultSentinelName = originalConfig.states.sentinelName ? originalConfig.states.sentinelName : oSentinelName && oPort === sPort ? oSentinelName : this.DEFAULT_SENTINEL_NAME;
|
|
@@ -738,8 +737,8 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
738
737
|
}
|
|
739
738
|
let dir;
|
|
740
739
|
let hname;
|
|
741
|
-
const hasLocalObjectsServer = await (0, import_js_controller_common2.isLocalObjectsDbServer)(
|
|
742
|
-
const hasLocalStatesServer = await (0, import_js_controller_common2.isLocalStatesDbServer)(
|
|
740
|
+
const hasLocalObjectsServer = await (0, import_js_controller_common2.isLocalObjectsDbServer)(oType, oHost);
|
|
741
|
+
const hasLocalStatesServer = await (0, import_js_controller_common2.isLocalStatesDbServer)(sType, sHost);
|
|
743
742
|
if (hasLocalStatesServer || hasLocalObjectsServer) {
|
|
744
743
|
let validDataDir = false;
|
|
745
744
|
while (!validDataDir) {
|
|
@@ -765,13 +764,13 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
765
764
|
console.log(`${COLOR_RED}Invalid host name: ${hname}${COLOR_RESET}`);
|
|
766
765
|
return import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS;
|
|
767
766
|
}
|
|
768
|
-
config.system
|
|
767
|
+
config.system ||= {};
|
|
769
768
|
config.system.hostname = hname;
|
|
770
769
|
config.objects.host = oHost;
|
|
771
|
-
config.objects.type =
|
|
770
|
+
config.objects.type = oType;
|
|
772
771
|
config.objects.port = oPort;
|
|
773
772
|
config.states.host = sHost;
|
|
774
|
-
config.states.type =
|
|
773
|
+
config.states.type = sType;
|
|
775
774
|
config.states.port = sPort;
|
|
776
775
|
config.states.dataDir = void 0;
|
|
777
776
|
config.objects.dataDir = void 0;
|
|
@@ -787,8 +786,7 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
787
786
|
if (config.states.type === "redis" && sSentinel && sSentinelName && sSentinelName !== this.DEFAULT_SENTINEL_NAME) {
|
|
788
787
|
config.states.sentinelName = sSentinelName;
|
|
789
788
|
}
|
|
790
|
-
|
|
791
|
-
return exitCode;
|
|
789
|
+
return await this.migrateObjects(config, originalConfig);
|
|
792
790
|
}
|
|
793
791
|
/**
|
|
794
792
|
* Checks if single host setup and if so migrates and activates Redis Sets Usage
|
|
@@ -825,9 +823,9 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
825
823
|
}
|
|
826
824
|
}
|
|
827
825
|
/**
|
|
828
|
-
* Add adapter-core in supported version in the overrides field of the root package.json and call install there to apply it
|
|
826
|
+
* Add or update adapter-core in supported version in the overrides field of the root package.json and call install there to apply it
|
|
829
827
|
*/
|
|
830
|
-
async
|
|
828
|
+
async addOrUpdateAdapterCoreRequirement() {
|
|
831
829
|
if (import_js_controller_common.tools.isDevInstallation()) {
|
|
832
830
|
return;
|
|
833
831
|
}
|
|
@@ -1099,7 +1097,7 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
1099
1097
|
}
|
|
1100
1098
|
}
|
|
1101
1099
|
/**
|
|
1102
|
-
*
|
|
1100
|
+
* Set up the installation with config file, host object, scripts etc
|
|
1103
1101
|
*
|
|
1104
1102
|
* @param options setup options
|
|
1105
1103
|
*/
|
|
@@ -1214,19 +1212,10 @@ require('${import_node_path.default.normalize(`${thisDir}/..`)}/setup').execute(
|
|
|
1214
1212
|
console.log(`Non-critical error: ${e.message}`);
|
|
1215
1213
|
}
|
|
1216
1214
|
} else if (ignoreIfExist) {
|
|
1217
|
-
|
|
1218
|
-
config = import_fs_extra.default.readJSONSync(configFileName);
|
|
1219
|
-
if (!Object.prototype.hasOwnProperty.call(config, "dataDir")) {
|
|
1220
|
-
config.dataDir = import_js_controller_common.tools.getDefaultDataDir();
|
|
1221
|
-
import_fs_extra.default.writeJSONSync(configFileName, config, { spaces: 2 });
|
|
1222
|
-
}
|
|
1223
|
-
} catch (e) {
|
|
1224
|
-
console.warn(`Cannot check config file: ${e.message}`);
|
|
1225
|
-
}
|
|
1226
|
-
this.setupObjects(() => callback && callback(), true);
|
|
1215
|
+
this.setupObjects(() => callback?.(), true);
|
|
1227
1216
|
return;
|
|
1228
1217
|
}
|
|
1229
|
-
this.setupObjects(() => callback
|
|
1218
|
+
this.setupObjects(() => callback?.(isCreated));
|
|
1230
1219
|
}
|
|
1231
1220
|
}
|
|
1232
1221
|
// Annotate the CommonJS export names for ESM import in node:
|