-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
110 lines (99 loc) · 3.66 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env node
const { JsonlDB } = require('@alcalzone/jsonl-db');
const fs = require('fs');
const path = require('path');
function queryOwnIps() {
const ownIpArr = [];
try {
const ifaces = require('os').networkInterfaces();
Object.keys(ifaces).forEach(dev =>
ifaces[dev].forEach(
details =>
// noinspection JSUnresolvedVariable
!details.internal && ownIpArr.push(details.address)
)
);
} catch (e) {
console.error(`Can not query local IPs: ${e.message}`);
}
return ownIpArr;
}
function isLocalDbServer(host, ownIpArr) {
if (typeof host !== 'string') { // Host is invalid or a sentinel array with redis server list
return false;
}
return host === 'localhost' || host === '127.0.0.1' || // reachable locally only, seems single host system
host === '0.0.0.0' || // reachable by all others, seems a master host
!ownIpArr.length || // we were not able to find any IP, so we assume it is a single host system
ownIpArr.includes(host); // host is in the own IP list
}
async function compressDB(dbPath) {
let db = new JsonlDB(dbPath, { ignoreReadErrors: true });
try {
await db.open();
} catch (e) {
if (e.message.includes('Invalid data')) {
console.log(`The database file ${dbPath} have corrupt lines. Ignoring these lines. Please check data afterwards!`);
db = new JsonlDB(dbPath, { ignoreReadErrors: true });
await db.open();
} else {
throw e;
}
}
await db.compress();
await db.close();
}
async function main() {
let dbPath = process.argv[2];
if (!dbPath) {
dbPath = process.cwd();
console.log(`No path given, using ${dbPath}`);
}
const configFile = path.join(dbPath, 'iobroker.json');
let config;
try {
if (!fs.existsSync(configFile)) {
console.log(`${dbPath} is not a valid ioBroker directory, skip`);
return;
}
config = JSON.parse(fs.readFileSync(configFile, 'utf8'));
} catch (e) {
console.log(`Cannot check config file in ${dbPath}: ${e.stack}`);
}
const ownIps = queryOwnIps();
let compressCount = 0;
if (config && config.states && config.states.type === 'jsonl' && isLocalDbServer(config.states.host, ownIps)) {
const statesFile = path.join(dbPath, 'states.jsonl');
try {
if (fs.existsSync(statesFile)) {
console.log(`Compressing ${statesFile}`);
await compressDB(statesFile);
compressCount++;
} else {
console.log('states.jsonl not found to compress, skip');
}
} catch (e) {
console.log(`Cannot compress states.jsonl: ${e.stack}`);
}
}
if (config && config.objects && config.objects.type === 'jsonl' && isLocalDbServer(config.objects.host, ownIps)) {
const objectsFile = path.join(dbPath, 'objects.jsonl');
try {
if (fs.existsSync(objectsFile)) {
console.log(`Compressing ${objectsFile}`);
await compressDB(objectsFile);
compressCount++;
} else {
console.log('objects.jsonl not found to compress, skip');
}
} catch (e) {
console.log(`Cannot compress objects.jsonl: ${e.stack}`);
}
}
if (compressCount === 0) {
console.log('No relevant JSONL files found to compress, skip');
} else {
console.log(`Compressed ${compressCount} JSONL files. Done`);
}
}
main().then(() => process.exit(0)).catch(_e => {});