diff --git a/dashboard/src/Index.vue b/dashboard/src/Index.vue index cc94ea05f..d37e139a0 100644 --- a/dashboard/src/Index.vue +++ b/dashboard/src/Index.vue @@ -16,7 +16,7 @@ import AppsView from './views/AppsView.vue'; import AppConfigureView from './views/AppConfigureView.vue'; import AppearanceView from './views/AppearanceView.vue'; import AppstoreView from './views/AppstoreView.vue'; -import BackupTargetsView from './views/BackupTargetsView.vue'; +import BackupSitesView from './views/BackupSitesView.vue'; import BackupAppArchivesView from './views/BackupAppArchivesView.vue'; import BackupListView from './views/BackupListView.vue'; import CloudronAccountView from './views/CloudronAccountView.vue'; @@ -46,7 +46,7 @@ const VIEWS = { APPEARANCE: 'appearance', APPS: 'apps', APPSTORE: 'appstore', - BACKUP_TARGETS: 'backup-targets', + BACKUP_SITES: 'backup-sites', BACKUP_LIST: 'backup-list', BACKUP_APP_ARCHIVES: 'backup-app-archives', CLOUDRON_ACCOUNT: 'cloudron-account', @@ -145,8 +145,8 @@ function onHashChange() { view.value = VIEWS.APP; } else if (v === VIEWS.APPEARANCE && profile.value.isAtLeastAdmin) { view.value = VIEWS.APPEARANCE; - } else if (v === VIEWS.BACKUP_TARGETS && profile.value.isAtLeastAdmin) { - view.value = VIEWS.BACKUP_TARGETS; + } else if (v === VIEWS.BACKUP_SITES && profile.value.isAtLeastAdmin) { + view.value = VIEWS.BACKUP_SITES; } else if (v === VIEWS.BACKUP_LIST && profile.value.isAtLeastAdmin) { view.value = VIEWS.BACKUP_LIST; } else if (v === VIEWS.BACKUP_APP_ARCHIVES && profile.value.isAtLeastAdmin) { @@ -282,7 +282,7 @@ onMounted(async () => { @@ -335,7 +335,7 @@ onMounted(async () => { - + diff --git a/dashboard/src/components/BackupScheduleDialog.vue b/dashboard/src/components/BackupScheduleDialog.vue index 7b42cb299..24ca9e279 100644 --- a/dashboard/src/components/BackupScheduleDialog.vue +++ b/dashboard/src/components/BackupScheduleDialog.vue @@ -2,11 +2,11 @@ import { ref, useTemplateRef, computed } from 'vue'; import { Dialog, FormGroup, MultiSelect } from '@cloudron/pankow'; -import BackupTargetsModel from '../models/BackupTargetsModel.js'; +import BackupSitesModel from '../models/BackupSitesModel.js'; const emit = defineEmits([ 'success' ]); -const backupTargetsModel = BackupTargetsModel.create(); +const backupSitesModel = BackupSitesModel.create(); const backupRetentions = [ { name: '2 days', id: { keepWithinSecs: 2 * 24 * 60 * 60 }}, @@ -57,14 +57,14 @@ async function onSubmit() { if (hours.value.length === 24) hoursPattern = '*'; else hoursPattern = hours.value; - let [error] = await backupTargetsModel.setSchedule(id.value, `00 00 ${hoursPattern} * * ${daysPattern}`); + let [error] = await backupSitesModel.setSchedule(id.value, `00 00 ${hoursPattern} * * ${daysPattern}`); if (error) { busy.value = false; formError.value = error.body ? error.body.message : 'Internal error'; return console.error(error); } - [error] = await backupTargetsModel.setRetention(id.value, configureRetention.value); + [error] = await backupSitesModel.setRetention(id.value, configureRetention.value); if (error) { busy.value = false; formError.value = error.body ? error.body.message : 'Internal error'; @@ -78,17 +78,17 @@ async function onSubmit() { } defineExpose({ - async open(target) { - id.value = target.id; + async open(site) { + id.value = site.id; busy.value = false; formError.value = false; - const currentRetentionString = JSON.stringify(target.retention); + const currentRetentionString = JSON.stringify(site.retention); let selectedRetention = backupRetentions.find(function (x) { return JSON.stringify(x.id) === currentRetentionString; }); if (!selectedRetention) selectedRetention = backupRetentions[0]; configureRetention.value = selectedRetention.id; - const tmp = target.schedule.split(' '); + const tmp = site.schedule.split(' '); const tmpHours = tmp[2].split(','); const tmpDays = tmp[5].split(','); diff --git a/dashboard/src/components/BackupTargetAddDialog.vue b/dashboard/src/components/BackupSiteAddDialog.vue similarity index 97% rename from dashboard/src/components/BackupTargetAddDialog.vue rename to dashboard/src/components/BackupSiteAddDialog.vue index 152ff20f4..e154115b2 100644 --- a/dashboard/src/components/BackupTargetAddDialog.vue +++ b/dashboard/src/components/BackupSiteAddDialog.vue @@ -6,18 +6,18 @@ import { prettyBinarySize } from '@cloudron/pankow/utils'; import { REGIONS_CONTABO, REGIONS_VULTR, REGIONS_IONOS, REGIONS_OVH, REGIONS_LINODE, REGIONS_SCALEWAY, REGIONS_WASABI } from '../constants.js'; import { mountlike, s3like } from '../utils.js'; import BackupProviderForm from './BackupProviderForm.vue'; -import BackupTargetsModel from '../models/BackupTargetsModel.js'; +import BackupSitesModel from '../models/BackupSitesModel.js'; import SystemModel from '../models/SystemModel.js'; const emit = defineEmits([ 'success' ]); -const backupTargetsModel = BackupTargetsModel.create(); +const backupSitesModel = BackupSitesModel.create(); const systemModel = SystemModel.create(); const dialog = useTemplateRef('dialog'); const form = useTemplateRef('form'); const step = ref('storage'); -const newTargetId = ref(''); +const newSiteId = ref(''); const name = ref(''); const useEncryption = ref(false); const encryptionPassword = ref(''); @@ -146,7 +146,7 @@ async function onSubmit() { formError.value = {}; busy.value = true; - const [error, result] = await backupTargetsModel.add(name.value, format.value, provider.value, data, schedulePattern, retention, limitsConfig); + const [error, result] = await backupSitesModel.add(name.value, format.value, provider.value, data, schedulePattern, retention, limitsConfig); if (error) { formError.value.generic = error.body ? error.body.message : 'Internal error'; busy.value = false; @@ -154,7 +154,7 @@ async function onSubmit() { } // stash for encryption password step - newTargetId.value = result; + newSiteId.value = result; busy.value = false; formError.value = {}; @@ -178,7 +178,7 @@ async function onSetupEncryption() { busy.value = true; - const [error] = await backupTargetsModel.setEncryption(newTargetId.value, encryptionPassword.value, encryptedFilenames.value, encryptionPasswordHint.value); + const [error] = await backupSitesModel.setEncryption(newSiteId.value, encryptionPassword.value, encryptedFilenames.value, encryptionPasswordHint.value); if (error) { if (error.body && error.body.message.indexOf('password') === 0) { formError.value.password = error.body.message; diff --git a/dashboard/src/components/BackupTargetEditDialog.vue b/dashboard/src/components/BackupSiteEditDialog.vue similarity index 70% rename from dashboard/src/components/BackupTargetEditDialog.vue rename to dashboard/src/components/BackupSiteEditDialog.vue index a63ce5621..3f9b64e6a 100644 --- a/dashboard/src/components/BackupTargetEditDialog.vue +++ b/dashboard/src/components/BackupSiteEditDialog.vue @@ -4,19 +4,19 @@ import { ref, useTemplateRef } from 'vue'; import { Dialog, FormGroup, TextInput } from '@cloudron/pankow'; import { prettyBinarySize } from '@cloudron/pankow/utils'; import { mountlike, s3like } from '../utils.js'; -import BackupTargetsModel from '../models/BackupTargetsModel.js'; +import BackupSitesModel from '../models/BackupSitesModel.js'; import SystemModel from '../models/SystemModel.js'; const emit = defineEmits([ 'success' ]); -const backupTargetsModel = BackupTargetsModel.create(); +const backupSitesModel = BackupSitesModel.create(); const systemModel = SystemModel.create(); const minMemoryLimit = ref(1024 * 1024 * 1024); // 1 GB const maxMemoryLimit = ref(minMemoryLimit.value); // set later const dialog = useTemplateRef('dialog'); -const target = ref({}); +const site = ref({}); const formError = ref({}); const busy = ref(false); const name = ref(''); @@ -29,7 +29,7 @@ const copyConcurrency = ref(0); async function onSubmit() { busy.value = true; - let [error] = await backupTargetsModel.setName(target.value.id, name.value); + let [error] = await backupSitesModel.setName(site.value.id, name.value); if (error) { formError.value.generic = error.body ? error.body.message : 'Internal error'; busy.value = false; @@ -44,7 +44,7 @@ async function onSubmit() { copyConcurrency: parseInt(copyConcurrency.value), }; - [error] = await backupTargetsModel.setLimits(target.value.id, limits); + [error] = await backupSitesModel.setLimits(site.value.id, limits); if (error) { formError.value.generic = error.body ? error.body.message : 'Internal error'; busy.value = false; @@ -67,7 +67,7 @@ defineExpose({ async open(t) { formError.value = {}; busy.value = false; - target.value = t; + site.value = t; name.value = t.name || ''; memoryLimit.value = t.limits.memoryLimit || 1024 * 1024 * 1024; // 1 GB @@ -97,33 +97,33 @@ defineExpose({
{{ $t('backups.configureBackupStorage.provider') }}
-
{{ target.provider }}
+
{{ site.provider }}
-
+
{{ $t('backups.configureBackupStorage.format') }}
-
{{ target.format }}
+
{{ site.format }}
-
+
{{ $t('backups.location.location') }}
- - {{ target.config.backupDir }}{{ (target.config.prefix ? `/${target.config.prefix}` : '') }} - {{ target.config.mountOptions.diskPath || target.config.mountPoint }}{{ (target.config.prefix ? '/' : '') + target.config.prefix }} - {{ target.config.mountOptions.host }}:{{ target.config.mountOptions.remoteDir }}{{ (target.config.prefix ? '/' : '') + target.config.prefix }} + + {{ site.config.backupDir }}{{ (site.config.prefix ? `/${site.config.prefix}` : '') }} + {{ site.config.mountOptions.diskPath || site.config.mountPoint }}{{ (site.config.prefix ? '/' : '') + site.config.prefix }} + {{ site.config.mountOptions.host }}:{{ site.config.mountOptions.remoteDir }}{{ (site.config.prefix ? '/' : '') + site.config.prefix }} - {{ target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }} - {{ target.config.region + ' ' + target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }} - {{ target.config.endpoint + ' ' + target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }} + {{ site.config.bucket + (site.config.prefix ? '/' : '') + site.config.prefix }} + {{ site.config.region + ' ' + site.config.bucket + (site.config.prefix ? '/' : '') + site.config.prefix }} + {{ site.config.endpoint + ' ' + site.config.bucket + (site.config.prefix ? '/' : '') + site.config.prefix }}
-
+
{{ $t('backups.location.endpoint') }}
-
{{ target.config.endpoint || target.config.region }}
+
{{ site.config.endpoint || site.config.region }}
-
+
{{ $t('backups.configureBackupStorage.encryptionHint') }}
-
{{ target.encryptionPasswordHint }}
+
{{ site.encryptionPasswordHint }}
@@ -147,7 +147,7 @@ defineExpose({ - +

{{ $t('backups.configureBackupStorage.uploadPartSizeDescription') }}

@@ -161,22 +161,22 @@ defineExpose({
- +
{{ $t('backups.configureBackupStorage.uploadConcurrencyDescription') }}
- +
{{ $t('backups.configureBackupStorage.downloadConcurrencyDescription') }}
- +
{{ $t('backups.configureBackupStorage.copyConcurrencyDescription') }} - {{ $t('backups.configureBackupStorage.copyConcurrencyDigitalOceanNote') }} + {{ $t('backups.configureBackupStorage.copyConcurrencyDigitalOceanNote') }}
diff --git a/dashboard/src/components/app/Backups.vue b/dashboard/src/components/app/Backups.vue index 0ac2e011b..1880f63ca 100644 --- a/dashboard/src/components/app/Backups.vue +++ b/dashboard/src/components/app/Backups.vue @@ -7,18 +7,18 @@ const t = i18n.t; import { ref, onMounted, useTemplateRef } from 'vue'; import { Icon, Button, Switch, Checkbox, FormGroup, TextInput, TableView, Menu, Dialog, ProgressBar } from '@cloudron/pankow'; import { prettyLongDate } from '@cloudron/pankow/utils'; -import { API_ORIGIN, RSTATES, TASK_TYPES } from '../../constants.js'; +import { API_ORIGIN, RSTATES } from '../../constants.js'; import { download } from '../../utils.js'; import AppImportDialog from '../AppImportDialog.vue'; import AppRestoreDialog from '../AppRestoreDialog.vue'; import SettingsItem from '../SettingsItem.vue'; import AppsModel from '../../models/AppsModel.js'; -import BackupTargetsModel from '../../models/BackupTargetsModel.js'; +import BackupSitesModel from '../../models/BackupSitesModel.js'; import TasksModel from '../../models/TasksModel.js'; import BackupsModel from '../../models/BackupsModel.js'; const appsModel = AppsModel.create(); -const backupTargetsModel = BackupTargetsModel.create(); +const backupSitesModel = BackupSitesModel.create(); const tasksModel = TasksModel.create(); const props = defineProps([ 'app' ]); @@ -38,7 +38,7 @@ const columns = ref({ label: t('app.backups.backups.time'), sort: true, }, - target: { + site: { label: t('backup.target.label'), sort: true, }, @@ -59,7 +59,7 @@ function onActionMenu(backup, event) { }, { icon: 'fa-solid fa-download', label: t('app.backups.backups.downloadBackupTooltip'), - visible: backup.target.format === 'tgz' && props.app.accessLevel === 'admin', + visible: backup.site.format === 'tgz' && props.app.accessLevel === 'admin', action: getDownloadLink.bind(null, backup), }, { icon: 'fa-solid fa-file-alt', @@ -102,7 +102,7 @@ const taskLogsMenu = ref([]); const lastTask = ref({}); const startBackupBusy = ref(false); const stopBackupBusy = ref(false); -let backupTargets = []; +let backupSites = []; async function onChangeAutoBackups(value) { const [error] = await appsModel.configure(props.app.id, 'automatic_backup', { enable: value }); @@ -197,14 +197,14 @@ function getDownloadLink(backup) { } async function onDownloadConfig(backup) { - const [error, backupTarget] = await backupTargetsModel.get(backup.targetId); + const [error, backupSite] = await backupSitesModel.get(backup.siteId); if (error) return console.error(error); const tmp = { remotePath: backup.remotePath }; for (const k of ['provider', 'config', 'limits', 'format', 'encrypted', 'encryptedFilenames', 'encryptionPasswordHint']) { - tmp[k] = backupTarget[k]; + tmp[k] = backupSite[k]; } const filename = `${props.app.fqdn}-backup-config-${(new Date(backup.creationTime)).toISOString().split('T')[0]}.json`; @@ -253,7 +253,7 @@ async function refreshBackupList() { if (error) return console.error(error); result.forEach(backup => { - backup.target = backupTargets.find(t => t.id === backup.targetId); + backup.site = backupSites.find(t => t.id === backup.siteId); }); backups.value = result; } @@ -261,10 +261,10 @@ async function refreshBackupList() { onMounted(async () => { autoBackupsEnabled.value = props.app.enableBackup; - const [error, result] = await backupTargetsModel.list(); + const [error, result] = await backupSitesModel.list(); if (error) return console.error(error); - backupTargets = result; + backupSites = result; await refreshBackupList(); await refreshTasks(); @@ -378,8 +378,8 @@ onMounted(async () => { -