cloudron 5.14.9 → 5.15.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/bin/cloudron +5 -2
- package/package.json +3 -2
- package/src/actions.js +44 -3
- package/src/appstore-actions.js +2 -2
- package/src/backup-tools.js +22 -8
- package/src/build-actions.js +2 -2
package/bin/cloudron
CHANGED
|
@@ -10,7 +10,7 @@ const actions = require('../src/actions.js'),
|
|
|
10
10
|
Command = require('commander').Command,
|
|
11
11
|
safe = require('safetydance'),
|
|
12
12
|
semver = require('semver'),
|
|
13
|
-
superagent = require('
|
|
13
|
+
superagent = require('@cloudron/superagent'),
|
|
14
14
|
util = require('util');
|
|
15
15
|
|
|
16
16
|
const version = require('../package.json').version;
|
|
@@ -56,6 +56,7 @@ backupCommand.command('decrypt <infile> <outfile>')
|
|
|
56
56
|
backupCommand.command('decrypt-dir <indir> <outdir>')
|
|
57
57
|
.description('Decrypt an encrypted directory')
|
|
58
58
|
.option('--password <password>', 'password')
|
|
59
|
+
.option('--no-decrypt-filenames', 'Decrypt filenames [false]')
|
|
59
60
|
.action(backupTools.decryptDir);
|
|
60
61
|
|
|
61
62
|
backupCommand.command('decrypt-filename <path>')
|
|
@@ -111,7 +112,7 @@ envCommand.command('list')
|
|
|
111
112
|
.action(actions.envList);
|
|
112
113
|
|
|
113
114
|
envCommand.command('set <KEY=value...>')
|
|
114
|
-
.description('Set environment variables')
|
|
115
|
+
.description('Set environment variables. e.g X=1 Y=2')
|
|
115
116
|
.option('--app <id>', 'App id')
|
|
116
117
|
.action(actions.envSet);
|
|
117
118
|
|
|
@@ -168,10 +169,12 @@ program.command('install')
|
|
|
168
169
|
.option('-l, --location <domain>', 'Subdomain or full domain')
|
|
169
170
|
.option('-s, --secondary-domains [DOMAIN=domain,...]', 'Set secondary domains')
|
|
170
171
|
.option('-a, --alias-domains [domain,...]', 'Alias domains')
|
|
172
|
+
.option('-m, --memory-limit [domain,...]', 'Memory Limit (e.g 1.5G, 512M)')
|
|
171
173
|
.option('--appstore-id <appid[@version]>', 'Use app from the store')
|
|
172
174
|
.option('--no-sso', 'Disable Cloudron SSO [false]')
|
|
173
175
|
.option('--debug [cmd...]', 'Enable debug mode', false)
|
|
174
176
|
.option('--readonly', 'Mount filesystem readonly. Default is read/write in debug mode.')
|
|
177
|
+
.option('--env <KEY=value...>', 'Set environment variables. e.g X=1 Y=2')
|
|
175
178
|
.action(actions.install);
|
|
176
179
|
|
|
177
180
|
program.command('list')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudron",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.15.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Cloudron Commandline Tool",
|
|
6
6
|
"main": "main.js",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
},
|
|
18
18
|
"author": "Cloudron Developers <support@cloudron.io>",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"cloudron-
|
|
20
|
+
"@cloudron/manifest-format": "^5.27.0",
|
|
21
|
+
"@cloudron/superagent": "^1.0.0",
|
|
21
22
|
"commander": "^13.1.0",
|
|
22
23
|
"debug": "^4.4.0",
|
|
23
24
|
"easy-table": "^1.2.0",
|
package/src/actions.js
CHANGED
|
@@ -7,14 +7,14 @@ const assert = require('assert'),
|
|
|
7
7
|
{ EventSource } = require('eventsource'),
|
|
8
8
|
fs = require('fs'),
|
|
9
9
|
https = require('https'),
|
|
10
|
-
manifestFormat = require('cloudron-
|
|
10
|
+
manifestFormat = require('@cloudron/manifest-format'),
|
|
11
11
|
os = require('os'),
|
|
12
12
|
path = require('path'),
|
|
13
13
|
readline = require('./readline.js'),
|
|
14
14
|
safe = require('safetydance'),
|
|
15
15
|
spawn = require('child_process').spawn,
|
|
16
16
|
semver = require('semver'),
|
|
17
|
-
superagent = require('
|
|
17
|
+
superagent = require('@cloudron/superagent'),
|
|
18
18
|
Table = require('easy-table'),
|
|
19
19
|
tar = require('tar-fs'),
|
|
20
20
|
timers = require('timers/promises'),
|
|
@@ -544,6 +544,33 @@ async function getManifest(appstoreId) {
|
|
|
544
544
|
return { manifest: result.manifest, manifestFilePath };
|
|
545
545
|
}
|
|
546
546
|
|
|
547
|
+
function parseMemoryLimit(limit) {
|
|
548
|
+
assert.strictEqual(typeof limit, 'string');
|
|
549
|
+
|
|
550
|
+
const units = {
|
|
551
|
+
B: 1,
|
|
552
|
+
K: 1024,
|
|
553
|
+
KB: 1024,
|
|
554
|
+
M: 1024 ** 2,
|
|
555
|
+
MB: 1024 ** 2,
|
|
556
|
+
G: 1024 ** 3,
|
|
557
|
+
GB: 1024 ** 3,
|
|
558
|
+
T: 1024 ** 4,
|
|
559
|
+
TB: 1024 ** 4
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
const match = limit.trim().toUpperCase().match(/^([\d.]+)\s*([KMGT]?B?)$/);
|
|
563
|
+
if (!match) throw new Error(`Invalid size format: "${limit}"`);
|
|
564
|
+
|
|
565
|
+
const value = parseFloat(match[1]);
|
|
566
|
+
const unit = match[2] || 'B';
|
|
567
|
+
|
|
568
|
+
const multiplier = units[unit];
|
|
569
|
+
if (!multiplier) throw new Error(`Unknown unit: "${unit}"`);
|
|
570
|
+
|
|
571
|
+
return value * multiplier;
|
|
572
|
+
}
|
|
573
|
+
|
|
547
574
|
async function install(localOptions, cmd) {
|
|
548
575
|
const options = cmd.optsWithGlobals();
|
|
549
576
|
|
|
@@ -616,6 +643,18 @@ async function install(localOptions, cmd) {
|
|
|
616
643
|
|
|
617
644
|
for (const port in ports) console.log(`Port ${port}: ${ports[port]}`);
|
|
618
645
|
|
|
646
|
+
// environment variables
|
|
647
|
+
const env = {};
|
|
648
|
+
if (options.env) {
|
|
649
|
+
options.env.forEach(envVar => {
|
|
650
|
+
const m = envVar.match(/(.*?)=(.*)/);
|
|
651
|
+
if (!m) return exit(`Expecting KEY=VALUE pattern. Got ${envVar}`);
|
|
652
|
+
env[m[1]] = m[2];
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
const memoryLimit = options.memoryLimit ? parseMemoryLimit(options.memoryLimit) : 0;
|
|
657
|
+
|
|
619
658
|
const data = {
|
|
620
659
|
appStoreId: options.appstoreId || '', // note case change
|
|
621
660
|
manifest: options.appstoreId ? null : manifest, // cloudron ignores manifest anyway if appStoreId is set
|
|
@@ -625,7 +664,9 @@ async function install(localOptions, cmd) {
|
|
|
625
664
|
secondaryDomains,
|
|
626
665
|
aliasDomains,
|
|
627
666
|
ports,
|
|
628
|
-
accessRestriction: null
|
|
667
|
+
accessRestriction: null,
|
|
668
|
+
memoryLimit,
|
|
669
|
+
env
|
|
629
670
|
};
|
|
630
671
|
|
|
631
672
|
// the sso only applies for apps which allow optional sso
|
package/src/appstore-actions.js
CHANGED
|
@@ -7,11 +7,11 @@ const assert = require('assert'),
|
|
|
7
7
|
execSync = require('child_process').execSync,
|
|
8
8
|
fs = require('fs'),
|
|
9
9
|
{ exit, locateManifest } = require('./helper.js'),
|
|
10
|
-
manifestFormat = require('cloudron-
|
|
10
|
+
manifestFormat = require('@cloudron/manifest-format'),
|
|
11
11
|
path = require('path'),
|
|
12
12
|
readline = require('./readline.js'),
|
|
13
13
|
safe = require('safetydance'),
|
|
14
|
-
superagent = require('
|
|
14
|
+
superagent = require('@cloudron/superagent'),
|
|
15
15
|
Table = require('easy-table');
|
|
16
16
|
|
|
17
17
|
exports = module.exports = {
|
package/src/backup-tools.js
CHANGED
|
@@ -262,11 +262,13 @@ async function decryptDir(inDir, outDir, options) {
|
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
const encryption = aesKeysFromPassword(options.password);
|
|
265
|
+
const decryptFilenames = options.decryptFilenames;
|
|
265
266
|
|
|
266
267
|
const inDirAbs = path.resolve(process.cwd(), inDir);
|
|
267
268
|
const outDirAbs = path.resolve(process.cwd(), outDir);
|
|
268
269
|
|
|
269
270
|
const tbd = [ '' ]; // only has paths relative to inDirAbs
|
|
271
|
+
let errorCount = 0;
|
|
270
272
|
while (true) {
|
|
271
273
|
const cur = tbd.pop();
|
|
272
274
|
const entries = fs.readdirSync(path.join(inDirAbs, cur), { withFileTypes: true });
|
|
@@ -279,29 +281,41 @@ async function decryptDir(inDir, outDir, options) {
|
|
|
279
281
|
continue;
|
|
280
282
|
}
|
|
281
283
|
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (
|
|
284
|
+
const fullPath = path.join(cur, entry.name);
|
|
285
|
+
|
|
286
|
+
let destPath = fullPath;
|
|
287
|
+
if (decryptFilenames) {
|
|
288
|
+
const { error, decryptedFilePath } = decryptFilePath(fullPath, encryption);
|
|
289
|
+
if (error) {
|
|
290
|
+
console.warn(`Could not decrypt filename: ${error.message}`);
|
|
291
|
+
errorCount++;
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
destPath = decryptedFilePath;
|
|
295
|
+
}
|
|
286
296
|
|
|
287
|
-
console.log(`Decrypting ${
|
|
297
|
+
console.log(`Decrypting ${destPath}`);
|
|
288
298
|
|
|
289
299
|
const infile = path.join(inDirAbs, cur, entry.name);
|
|
290
300
|
const inStream = fs.createReadStream(infile);
|
|
291
|
-
fs.mkdirSync(path.dirname(path.join(outDirAbs,
|
|
292
|
-
const outfile = path.join(outDirAbs,
|
|
301
|
+
fs.mkdirSync(path.dirname(path.join(outDirAbs, destPath)), { recursive: true });
|
|
302
|
+
const outfile = path.join(outDirAbs, destPath);
|
|
293
303
|
const outStream = fs.createWriteStream(outfile);
|
|
294
304
|
const decryptStream = new DecryptStream(encryption);
|
|
295
305
|
|
|
296
306
|
const [decryptError] = await safe(stream.pipeline(inStream, decryptStream, outStream));
|
|
297
307
|
if (decryptError) {
|
|
298
308
|
safe.fs.rmSync(outfile);
|
|
299
|
-
|
|
309
|
+
console.warn(`Could not decrypt ${infile}: ${decryptError.message}`);
|
|
310
|
+
++errorCount;
|
|
300
311
|
}
|
|
301
312
|
}
|
|
302
313
|
|
|
303
314
|
if (tbd.length === 0) break;
|
|
304
315
|
}
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
if (errorCount) exit(`Failed to decrypt ${errorCount} files`);
|
|
305
319
|
}
|
|
306
320
|
|
|
307
321
|
async function decryptFilename(filePath, options) {
|
package/src/build-actions.js
CHANGED
|
@@ -16,14 +16,14 @@ const assert = require('assert'),
|
|
|
16
16
|
exit = require('./helper.js').exit,
|
|
17
17
|
fs = require('fs'),
|
|
18
18
|
helper = require('./helper.js'),
|
|
19
|
-
manifestFormat = require('cloudron-
|
|
19
|
+
manifestFormat = require('@cloudron/manifest-format'),
|
|
20
20
|
micromatch = require('micromatch'),
|
|
21
21
|
os = require('os'),
|
|
22
22
|
path = require('path'),
|
|
23
23
|
readline = require('./readline.js'),
|
|
24
24
|
safe = require('safetydance'),
|
|
25
25
|
stream = require('stream/promises'),
|
|
26
|
-
superagent = require('
|
|
26
|
+
superagent = require('@cloudron/superagent'),
|
|
27
27
|
tar = require('tar-fs'),
|
|
28
28
|
url = require('url');
|
|
29
29
|
|