cloudron 4.14.4 → 4.15.2

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/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # The Cloudron CLI tool
2
2
 
3
- The [Cloudron](https://cloudron.io) CLI tool allows you to install, configure and test apps on your Cloudron.
3
+ The [Cloudron](https://cloudron.io) [CLI tool](https://docs.cloudron.io/packaging/cli/) allows you to install, configure and test apps on your Cloudron.
4
4
  It is also used to submit your app to the Cloudron Store. The `machine` subcommand can be used for
5
5
  various maintenance tasks on a selfhosted Cloudron.
6
6
 
7
- Read the Cloudron.io [documentation](https://cloudron.io/documentation.html) for in-depth information.
7
+ Read the Cloudron.io [documentation](https://docs.cloudron.io/) for in-depth information.
8
8
 
9
9
  ## Installation
10
10
 
package/bin/cloudron CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- require('supererror');
6
-
7
5
  const actions = require('../src/actions.js'),
8
6
  buildActions = require('../src/build-actions.js'),
9
7
  completion = require('../src/completion.js'),
@@ -142,6 +140,7 @@ program.command('install')
142
140
  program.command('list')
143
141
  .description('List installed applications')
144
142
  .option('-q, --quiet', 'Only display app IDs')
143
+ .option('-t, --tag <tag>', 'Only display apps with this tag')
145
144
  .action(actions.list);
146
145
 
147
146
  program.command('login [cloudron]')
@@ -2,9 +2,7 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- require('supererror');
6
-
7
- var program = require('commander'),
5
+ const program = require('commander'),
8
6
  appstoreActions = require('../src/appstore-actions.js');
9
7
 
10
8
  program.version(require('../package.json').version);
@@ -2,9 +2,7 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- require('supererror');
6
-
7
- var program = require('commander'),
5
+ const program = require('commander'),
8
6
  actions = require('../src/actions.js'),
9
7
  backupTools = require('../src/backup-tools.js');
10
8
 
@@ -22,12 +20,12 @@ program.command('list')
22
20
  .action(actions.backupList);
23
21
 
24
22
  program.command('decrypt <file>')
25
- .description('Decrypt a directory')
23
+ .description('Decrypt an encrypted file')
26
24
  .option('--password <password>', 'password')
27
25
  .action(backupTools.decrypt);
28
26
 
29
27
  program.command('decrypt-dir <indir> <outdir>')
30
- .description('Decrypt a directory')
28
+ .description('Decrypt an encrypted directory')
31
29
  .option('--password <password>', 'password')
32
30
  .action(backupTools.decryptDir);
33
31
 
package/bin/cloudron-env CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- require('supererror');
6
-
7
- var program = require('commander'),
5
+ const program = require('commander'),
8
6
  actions = require('../src/actions.js');
9
7
 
10
8
  program.version(require('../package.json').version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudron",
3
- "version": "4.14.4",
3
+ "version": "4.15.2",
4
4
  "license": "MIT",
5
5
  "description": "Cloudron Commandline Tool",
6
6
  "main": "main.js",
@@ -34,7 +34,6 @@
34
34
  "safetydance": "^2.2.0",
35
35
  "split": "^1.0.1",
36
36
  "superagent": "^7.0.2",
37
- "supererror": "^0.7.2",
38
37
  "tar-fs": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.12.0.tgz",
39
38
  "underscore": "^1.13.2"
40
39
  },
package/src/actions.js CHANGED
@@ -325,6 +325,16 @@ async function startApp(app, options) {
325
325
  await waitForTask(response.body.taskId, options);
326
326
  }
327
327
 
328
+ async function restartApp(app, options) {
329
+ assert.strictEqual(typeof app, 'object');
330
+ assert.strictEqual(typeof options, 'object');
331
+
332
+ const response = await createRequest('POST', `/api/v1/apps/${app.id}/restart`, options);
333
+ if (response.statusCode !== 202) throw `Failed to restart app: ${requestError(response)}`;
334
+
335
+ await waitForTask(response.body.taskId, options);
336
+ }
337
+
328
338
  async function authenticate(adminFqdn, username, password, options) {
329
339
  assert.strictEqual(typeof adminFqdn, 'string');
330
340
  assert.strictEqual(typeof username, 'string');
@@ -427,30 +437,41 @@ async function list(options) {
427
437
  if (error) return exit(error);
428
438
  if (response.statusCode !== 200) return exit(`Failed to list apps: ${requestError(response)}`);
429
439
 
430
- if (response.body.apps.length === 0) return console.log('No apps installed.');
440
+ let apps = response.body.apps;
441
+
442
+ if (options.tag) apps = apps.filter(function (a) { return a.tags.indexOf(options.tag) !== -1; });
431
443
 
432
444
  if (options.quiet) {
433
- console.log(response.body.apps.map(a => a.id).join('\n'));
445
+ console.log(apps.map(a => a.id).join('\n'));
434
446
  return;
435
447
  }
436
448
 
437
- var t = new Table();
449
+ // after quiet
450
+ if (apps.length === 0) return console.log('No apps installed.');
438
451
 
439
- response.body.apps.forEach(function (app) {
440
- t.cell('Id', app.id);
441
- t.cell('Location', app.fqdn);
442
- t.cell('Manifest Id', (app.manifest.id || 'customapp') + '@' + app.manifest.version);
452
+ const t = new Table();
453
+
454
+ for (const app of apps) {
455
+ const response2 = await createRequest('GET', `/api/v1/apps/${app.id}`, options);
456
+ if (response2.statusCode !== 200) return exit(`Failed to list app: ${requestError(response2)}`);
457
+ response2.body.location = response2.body.location || response2.body.subdomain; // LEGACY support
458
+
459
+ const detailedApp = response2.body;
460
+
461
+ t.cell('Id', detailedApp.id);
462
+ t.cell('Location', detailedApp.fqdn);
463
+ t.cell('Manifest Id', (detailedApp.manifest.id || 'customapp') + '@' + detailedApp.manifest.version);
443
464
  var prettyState;
444
- if (app.installationState === 'installed') {
445
- prettyState = (app.debugMode ? 'debug' : app.runState);
446
- } else if (app.installationState === 'error') {
447
- prettyState = `error (${app.error.installationState})`;
465
+ if (detailedApp.installationState === 'installed') {
466
+ prettyState = (detailedApp.debugMode ? 'debug' : detailedApp.runState);
467
+ } else if (detailedApp.installationState === 'error') {
468
+ prettyState = `error (${detailedApp.error.installationState})`;
448
469
  } else {
449
- prettyState = app.installationState;
470
+ prettyState = detailedApp.installationState;
450
471
  }
451
472
  t.cell('State', prettyState);
452
473
  t.newRow();
453
- });
474
+ }
454
475
 
455
476
  console.log();
456
477
  console.log(t.toString());
@@ -999,8 +1020,7 @@ async function restart(options) {
999
1020
  try {
1000
1021
  const app = await getApp(options);
1001
1022
  if (!app) return exit(NO_APP_FOUND_ERROR_STRING);
1002
- await stopApp(app, options);
1003
- await startApp(app, options);
1023
+ await restartApp(app, options);
1004
1024
  await waitForHealthy(app.id, options);
1005
1025
  console.log('\n\nApp restarted');
1006
1026
  } catch (error) {
@@ -23,7 +23,7 @@ function encryptFilePath(filePath, encryption) {
23
23
  assert.strictEqual(typeof filePath, 'string');
24
24
  assert.strictEqual(typeof encryption, 'object');
25
25
 
26
- var encryptedParts = filePath.split('/').map(function (part) {
26
+ const encryptedParts = filePath.split('/').map(function (part) {
27
27
  let hmac = crypto.createHmac('sha256', Buffer.from(encryption.filenameHmacKey, 'hex'));
28
28
  const iv = hmac.update(part).digest().slice(0, 16); // iv has to be deterministic, for our sync (copy) logic to work
29
29
  const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(encryption.filenameKey, 'hex'), iv);
@@ -42,7 +42,7 @@ function decryptFilePath(filePath, encryption) {
42
42
  assert.strictEqual(typeof filePath, 'string');
43
43
  assert.strictEqual(typeof encryption, 'object');
44
44
 
45
- let decryptedParts = [];
45
+ const decryptedParts = [];
46
46
  for (let part of filePath.split('/')) {
47
47
  part = part + Array(part.length % 4).join('='); // add back = padding
48
48
  part = part.replace(/-/g, '/'); // replace with '/'
@@ -197,9 +197,9 @@ function encrypt(input, options) {
197
197
 
198
198
  const encryption = aesKeysFromPassword(options.password);
199
199
 
200
- let inStream = fs.createReadStream(input);
201
- let outStream = process.stdout;
202
- let encryptStream = new EncryptStream(encryption);
200
+ const inStream = fs.createReadStream(input);
201
+ const outStream = process.stdout;
202
+ const encryptStream = new EncryptStream(encryption);
203
203
 
204
204
  inStream.on('error', exit);
205
205
  encryptStream.on('error', exit);
@@ -227,9 +227,9 @@ function decrypt(input, options) {
227
227
 
228
228
  const encryption = aesKeysFromPassword(options.password);
229
229
 
230
- let inStream = fs.createReadStream(input);
231
- let outStream = process.stdout;
232
- let decryptStream = new DecryptStream(encryption);
230
+ const inStream = fs.createReadStream(input);
231
+ const outStream = process.stdout;
232
+ const decryptStream = new DecryptStream(encryption);
233
233
 
234
234
  inStream.on('error', exit);
235
235
  decryptStream.on('error', exit);
@@ -1,3 +1,3 @@
1
- FROM cloudron/base:3.1.0@sha256:eb2ab9c7d361acda2f3ef2d8388154bc48f1651b5013fe6de4beea003018e427
1
+ FROM cloudron/base:3.2.0@sha256:ba1d566164a67c266782545ea9809dc611c4152e27686fd14060332dd88263ea
2
2
 
3
3
  EXPOSE <%- httpPort %>