cloudron 5.1.2 → 5.2.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 +2 -2
- package/package.json +2 -2
- package/src/actions.js +22 -16
package/bin/cloudron
CHANGED
|
@@ -64,7 +64,7 @@ backupCommand.command('decrypt-dir <indir> <outdir>')
|
|
|
64
64
|
.action(backupTools.decryptDir);
|
|
65
65
|
|
|
66
66
|
backupCommand.command('decrypt-filename <path>')
|
|
67
|
-
.description('
|
|
67
|
+
.description('Decrypt a file name')
|
|
68
68
|
.option('--password <password>', 'password')
|
|
69
69
|
.action(backupTools.decryptFilename);
|
|
70
70
|
|
|
@@ -172,12 +172,12 @@ program.command('export')
|
|
|
172
172
|
program.command('import')
|
|
173
173
|
.description('Import app from an external backup')
|
|
174
174
|
.option('--app <id/location>', 'App id or location')
|
|
175
|
-
.option('--backup-id <backup>', 'Backup id')
|
|
176
175
|
.option('--backup-format <tgz|rsync>', 'Backup format (default: tgz)')
|
|
177
176
|
.option('--backup-config <json>', 'Backup config in JSON format')
|
|
178
177
|
.option('--backup-path <file|dir>', 'Absolute path to a backup on the filesystem')
|
|
179
178
|
.option('--backup-key <key>', 'Encryption key')
|
|
180
179
|
.option('--in-place', 'Re-import from current app directory without downloading any backup', false)
|
|
180
|
+
.option('--remote-path <remote-path>', 'Remote Path')
|
|
181
181
|
.action(actions.importApp);
|
|
182
182
|
|
|
183
183
|
program.command('inspect')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudron",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Cloudron Commandline Tool",
|
|
6
6
|
"main": "main.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"author": "Cloudron Developers <support@cloudron.io>",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"async": "^3.2.4",
|
|
21
|
-
"cloudron-manifestformat": "^5.
|
|
21
|
+
"cloudron-manifestformat": "^5.19.0",
|
|
22
22
|
"commander": "^9.4.0",
|
|
23
23
|
"debug": "^4.3.4",
|
|
24
24
|
"delay": "^5.0.0",
|
package/src/actions.js
CHANGED
|
@@ -450,12 +450,16 @@ async function list(localOptions, cmd) {
|
|
|
450
450
|
|
|
451
451
|
const t = new Table();
|
|
452
452
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
if (
|
|
456
|
-
|
|
453
|
+
const responses = await Promise.allSettled(apps.map(function (app) { return createRequest('GET', `/api/v1/apps/${app.id}`, options); }));
|
|
454
|
+
responses.forEach(function (result) {
|
|
455
|
+
if (result.status !== 'fulfilled') return exit(`Failed to list app: ${requestError(result.value)}`);
|
|
456
|
+
|
|
457
|
+
const response = result.value;
|
|
458
|
+
|
|
459
|
+
if (response.statusCode !== 200) return exit(`Failed to list app: ${requestError(response)}`);
|
|
460
|
+
response.body.location = response.body.location || response.body.subdomain; // LEGACY support
|
|
457
461
|
|
|
458
|
-
const detailedApp =
|
|
462
|
+
const detailedApp = response.body;
|
|
459
463
|
|
|
460
464
|
t.cell('Id', detailedApp.id);
|
|
461
465
|
t.cell('Location', detailedApp.fqdn);
|
|
@@ -470,7 +474,7 @@ async function list(localOptions, cmd) {
|
|
|
470
474
|
}
|
|
471
475
|
t.cell('State', prettyState);
|
|
472
476
|
t.newRow();
|
|
473
|
-
}
|
|
477
|
+
});
|
|
474
478
|
|
|
475
479
|
console.log();
|
|
476
480
|
console.log(t.toString());
|
|
@@ -822,7 +826,7 @@ async function debug(args, localOptions, cmd) {
|
|
|
822
826
|
if (app.memoryLimit === memoryLimit) return console.log('\n\nDone');
|
|
823
827
|
|
|
824
828
|
console.log('\n');
|
|
825
|
-
console.log(options.limitMemory ? 'Limiting memory' : 'Setting unlimited memory');
|
|
829
|
+
console.log(options.limitMemory || options.disable ? 'Limiting memory' : 'Setting unlimited memory');
|
|
826
830
|
|
|
827
831
|
const request2 = createRequest('POST', `/api/v1/apps/${app.id}/configure/memory_limit`, options);
|
|
828
832
|
const response2 = await request2.send({ memoryLimit });
|
|
@@ -1149,27 +1153,27 @@ async function importApp(localOptions, cmd) {
|
|
|
1149
1153
|
let data = {};
|
|
1150
1154
|
|
|
1151
1155
|
if (!options.inPlace) {
|
|
1152
|
-
let {
|
|
1156
|
+
let { remotePath, backupFormat, backupConfig, backupPath, backupKey } = options;
|
|
1153
1157
|
let backupFolder;
|
|
1154
1158
|
|
|
1155
1159
|
if (backupPath) {
|
|
1156
1160
|
if (backupPath.endsWith('.tar.gz')) {
|
|
1157
1161
|
backupFolder = path.dirname(backupPath);
|
|
1158
|
-
|
|
1162
|
+
remotePath = path.basename(backupPath).replace(/.tar.gz$/, '');
|
|
1159
1163
|
backupFormat = 'tgz';
|
|
1160
1164
|
} else {
|
|
1161
1165
|
backupFolder = path.dirname(backupPath);
|
|
1162
|
-
|
|
1166
|
+
remotePath = path.basename(backupPath);
|
|
1163
1167
|
backupFormat = 'rsync';
|
|
1164
1168
|
}
|
|
1165
1169
|
backupConfig = { provider: 'filesystem', backupFolder };
|
|
1166
|
-
data = {
|
|
1170
|
+
data = { remotePath, backupFormat, backupConfig };
|
|
1167
1171
|
} else {
|
|
1168
|
-
if (!
|
|
1172
|
+
if (!remotePath) return exit('--remote-path, --backup-file or --in-place is required');
|
|
1169
1173
|
if (!backupFormat) return exit('--backup-format is required');
|
|
1170
1174
|
|
|
1171
|
-
if (
|
|
1172
|
-
return exit('
|
|
1175
|
+
if (remotePath.endsWith('.tar.gz')) { // common mistake...
|
|
1176
|
+
return exit('remotePath should not end with .tar.gz. Try again removing the extension from remote path');
|
|
1173
1177
|
}
|
|
1174
1178
|
|
|
1175
1179
|
if (backupConfig) {
|
|
@@ -1179,7 +1183,7 @@ async function importApp(localOptions, cmd) {
|
|
|
1179
1183
|
backupConfig = null; // ensure null-ness
|
|
1180
1184
|
}
|
|
1181
1185
|
|
|
1182
|
-
data = {
|
|
1186
|
+
data = { remotePath, backupFormat, backupConfig };
|
|
1183
1187
|
}
|
|
1184
1188
|
|
|
1185
1189
|
if (backupKey) data.backupConfig.key = backupKey;
|
|
@@ -1283,6 +1287,7 @@ async function exec(args, localOptions, cmd) {
|
|
|
1283
1287
|
|
|
1284
1288
|
const options = cmd.optsWithGlobals();
|
|
1285
1289
|
let tty = !!options.tty;
|
|
1290
|
+
let lang; // used as body param later
|
|
1286
1291
|
|
|
1287
1292
|
const [error, app] = await safe(getApp(options));
|
|
1288
1293
|
if (error) return exit(error);
|
|
@@ -1293,12 +1298,13 @@ async function exec(args, localOptions, cmd) {
|
|
|
1293
1298
|
if (args.length === 0) {
|
|
1294
1299
|
args = [ '/bin/bash' ];
|
|
1295
1300
|
tty = true; // override
|
|
1301
|
+
lang = 'C.UTF-8';
|
|
1296
1302
|
}
|
|
1297
1303
|
|
|
1298
1304
|
if (tty && !stdin.isTTY) exit('stdin is not tty');
|
|
1299
1305
|
|
|
1300
1306
|
const request = createRequest('POST', `/api/v1/apps/${app.id}/exec`, options);
|
|
1301
|
-
const response = await request.send({ cmd: args, tty });
|
|
1307
|
+
const response = await request.send({ cmd: args, tty, lang });
|
|
1302
1308
|
if (response.statusCode !== 200) return exit(`Failed to create exec: ${requestError(response)}`);
|
|
1303
1309
|
const execId = response.body.id;
|
|
1304
1310
|
|