diff --git a/src/apps.js b/src/apps.js index 848a804f6..176fea9c4 100644 --- a/src/apps.js +++ b/src/apps.js @@ -153,6 +153,7 @@ const appstore = require('./appstore.js'), fs = require('fs'), mail = require('./mail.js'), manifestFormat = require('cloudron-manifestformat'), + mounts = require('./mounts.js'), once = require('once'), os = require('os'), path = require('path'), @@ -1903,6 +1904,20 @@ async function importApp(app, data, auditSource) { // TODO: make this smarter to do a read-only test and check if the file exists in the storage backend if (backupConfig) { + if (mounts.isMountProvider(backupConfig.provider)) { + backupConfig.mountPoint = `/mnt/appimport-${app.id}`; + error = mounts.validateMountOptions(backupConfig.provider, backupConfig.mountOptions); + if (error) throw error; + + const mountObject = { // keep this in sync with the import code in apptask + name: `appimport-${app.id}`, + hostPath: backupConfig.mountPoint, + mountType: backupConfig.provider, + mountOptions: backupConfig.mountOptions + }; + await mounts.tryAddMount(mountObject, { timeout: 10 }); + + } error = await backups.testProviderConfig(backupConfig); if (error) throw error; } diff --git a/src/apptask.js b/src/apptask.js index a367e9260..79bdeceb6 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -27,6 +27,7 @@ const apps = require('./apps.js'), fs = require('fs'), iputils = require('./iputils.js'), manifestFormat = require('cloudron-manifestformat'), + mounts = require('./mounts.js'), os = require('os'), path = require('path'), paths = require('./paths.js'), @@ -341,23 +342,41 @@ async function install(app, args, progressCallback) { await progressCallback({ percent: 50, message: 'Creating app data directory' }); await createAppDir(app); - // restore from backup - if (!restoreConfig) { + if (!restoreConfig) { // install await progressCallback({ percent: 60, message: 'Setting up addons' }); await services.setupAddons(app, app.manifest.addons); - } else if (!restoreConfig.backupId) { // in-place import + } else if (app.installationState === apps.ISTATE_PENDING_IMPORT && !restoreConfig.backupId) { // in-place import await progressCallback({ percent: 60, message: 'Importing addons in-place' }); await services.setupAddons(app, app.manifest.addons); await services.clearAddons(app, _.omit(app.manifest.addons, 'localstorage')); await apps.restoreConfig(app); await services.restoreAddons(app, app.manifest.addons); - } else { - await progressCallback({ percent: 65, message: 'Download backup and restoring addons' }); + } else if (app.installationState === apps.ISTATE_PENDING_IMPORT) { // import + await progressCallback({ percent: 65, message: 'Downloading backup and restoring addons' }); + await services.setupAddons(app, app.manifest.addons); + await services.clearAddons(app, app.manifest.addons); + const backupConfig = restoreConfig.backupConfig; // can be null + let mountObject = null; + if (backupConfig && mounts.isMountProvider(backupConfig.provider)) { + await progressCallback({ percent: 70, message: 'Setting up mount for importing' }); + mountObject = { // keep this in sync with importApp in apps.js + name: `appimport-${app.id}`, + hostPath: `/mnt/appimport-${app.id}`, + mountType: backupConfig.provider, + mountOptions: backupConfig.mountOptions + }; + await mounts.tryAddMount(mountObject, { timeout: 10 }); + } + await backuptask.downloadApp(app, restoreConfig, (progress) => { progressCallback({ percent: 75, message: progress.message }); }); + await apps.restoreConfig(app); + if (mountObject) await mounts.removeMount(mountObject); + await progressCallback({ percent: 75, message: 'Restoring addons' }); + await services.restoreAddons(app, app.manifest.addons); + } else { // clone and restore + await progressCallback({ percent: 65, message: 'Downloading backup and restoring addons' }); await services.setupAddons(app, app.manifest.addons); await services.clearAddons(app, app.manifest.addons); await backuptask.downloadApp(app, restoreConfig, (progress) => { progressCallback({ percent: 65, message: progress.message }); }); - - if (app.installationState === apps.ISTATE_PENDING_IMPORT) await apps.restoreConfig(app); await progressCallback({ percent: 70, message: 'Restoring addons' }); await services.restoreAddons(app, app.manifest.addons); }