dashboard: rename backupTargets to backupSites
This commit is contained in:
@@ -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(',');
|
||||
|
||||
|
||||
+6
-6
@@ -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;
|
||||
+26
-26
@@ -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({
|
||||
<div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">{{ $t('backups.configureBackupStorage.provider') }}</div>
|
||||
<div class="info-value">{{ target.provider }}</div>
|
||||
<div class="info-value">{{ site.provider }}</div>
|
||||
</div>
|
||||
<div class="info-row" v-if="target.provider !== 'noop'">
|
||||
<div class="info-row" v-if="site.provider !== 'noop'">
|
||||
<div class="info-label">{{ $t('backups.configureBackupStorage.format') }}</div>
|
||||
<div class="info-value">{{ target.format }} <i v-if="target.encrypted" class="fa-solid fa-lock"></i></div>
|
||||
<div class="info-value">{{ site.format }} <i v-if="site.encrypted" class="fa-solid fa-lock"></i></div>
|
||||
</div>
|
||||
<div class="info-row" v-if="target.provider !== 'noop'">
|
||||
<div class="info-row" v-if="site.provider !== 'noop'">
|
||||
<div class="info-label">{{ $t('backups.location.location') }}</div>
|
||||
<div class="info-value" style="overflow: auto;">
|
||||
<span v-if="mountlike(target.provider) || target.provider === 'filesystem'">
|
||||
<span v-if="target.provider === 'filesystem'">{{ target.config.backupDir }}{{ (target.config.prefix ? `/${target.config.prefix}` : '') }}</span>
|
||||
<span v-if="target.provider === 'disk' || target.provider === 'ext4' || target.provider === 'xfs' || target.provider === 'mountpoint'">{{ target.config.mountOptions.diskPath || target.config.mountPoint }}{{ (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
|
||||
<span v-if="target.provider === 'cifs' || target.provider === 'nfs' || target.provider === 'sshfs'">{{ target.config.mountOptions.host }}:{{ target.config.mountOptions.remoteDir }}{{ (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
|
||||
<span v-if="mountlike(site.provider) || site.provider === 'filesystem'">
|
||||
<span v-if="site.provider === 'filesystem'">{{ site.config.backupDir }}{{ (site.config.prefix ? `/${site.config.prefix}` : '') }}</span>
|
||||
<span v-if="site.provider === 'disk' || site.provider === 'ext4' || site.provider === 'xfs' || site.provider === 'mountpoint'">{{ site.config.mountOptions.diskPath || site.config.mountPoint }}{{ (site.config.prefix ? '/' : '') + site.config.prefix }}</span>
|
||||
<span v-if="site.provider === 'cifs' || site.provider === 'nfs' || site.provider === 'sshfs'">{{ site.config.mountOptions.host }}:{{ site.config.mountOptions.remoteDir }}{{ (site.config.prefix ? '/' : '') + site.config.prefix }}</span>
|
||||
</span>
|
||||
|
||||
<span v-if="target.provider !== 's3' && target.provider !== 'minio' && (s3like(target.provider) || target.provider === 'gcs')">{{ target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
|
||||
<span v-if="target.provider === 's3'">{{ target.config.region + ' ' + target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
|
||||
<span v-if="target.provider === 'minio'">{{ target.config.endpoint + ' ' + target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
|
||||
<span v-if="site.provider !== 's3' && site.provider !== 'minio' && (s3like(site.provider) || site.provider === 'gcs')">{{ site.config.bucket + (site.config.prefix ? '/' : '') + site.config.prefix }}</span>
|
||||
<span v-if="site.provider === 's3'">{{ site.config.region + ' ' + site.config.bucket + (site.config.prefix ? '/' : '') + site.config.prefix }}</span>
|
||||
<span v-if="site.provider === 'minio'">{{ site.config.endpoint + ' ' + site.config.bucket + (site.config.prefix ? '/' : '') + site.config.prefix }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row" v-if="target.provider !== 'minio' && target.config?.endpoint">
|
||||
<div class="info-row" v-if="site.provider !== 'minio' && site.config?.endpoint">
|
||||
<div class="info-label">{{ $t('backups.location.endpoint') }}</div>
|
||||
<div class="info-value">{{ target.config.endpoint || target.config.region }}</div>
|
||||
<div class="info-value">{{ site.config.endpoint || site.config.region }}</div>
|
||||
</div>
|
||||
<div class="info-row" v-if="target.encrypted">
|
||||
<div class="info-row" v-if="site.encrypted">
|
||||
<div class="info-label">{{ $t('backups.configureBackupStorage.encryptionHint') }}</div>
|
||||
<div class="info-value">{{ target.encryptionPasswordHint }}</div>
|
||||
<div class="info-value">{{ site.encryptionPasswordHint }}</div>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="onSubmit()" autocomplete="off" ref="form">
|
||||
@@ -147,7 +147,7 @@ defineExpose({
|
||||
<input type="range" id="memoryLimitInput" v-model="memoryLimit" :step="256*1024*1024" :min="minMemoryLimit" :max="maxMemoryLimit" />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="s3like(target.provider)">
|
||||
<FormGroup v-if="s3like(site.provider)">
|
||||
<label for="uploadPartSizeInput">{{ $t('backups.configureBackupStorage.uploadPartSize') }}: <b>{{ prettyBinarySize(uploadPartSize, 'Default (50 MiB)') }}</b></label>
|
||||
<p class="small">{{ $t('backups.configureBackupStorage.uploadPartSizeDescription') }}</p>
|
||||
<input type="range" id="uploadPartSizeInput" v-model="uploadPartSize" list="uploadPartSizeTicks" :step="1024*1024" :min="10*1024*1024" :max="1024*1024*1024" />
|
||||
@@ -161,22 +161,22 @@ defineExpose({
|
||||
</datalist>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="target.format === 'rsync' && target.provider !== 'noop'">
|
||||
<FormGroup v-if="site.format === 'rsync' && site.provider !== 'noop'">
|
||||
<label for="syncConcurrencyInput">{{ $t('backups.configureBackupStorage.uploadConcurrency') }}: <b>{{ syncConcurrency }}</b></label>
|
||||
<div class="small">{{ $t('backups.configureBackupStorage.uploadConcurrencyDescription') }}</div>
|
||||
<input type="range" id="syncConcurrencyInput" v-model="syncConcurrency" step="10" min="10" max="200" />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="target.format === 'rsync' && (s3like(target.provider) || target.provider === 'gcs')">
|
||||
<FormGroup v-if="site.format === 'rsync' && (s3like(site.provider) || site.provider === 'gcs')">
|
||||
<label for="downloadConcurrencyInput">{{ $t('backups.configureBackupStorage.downloadConcurrency') }}: <b>{{ downloadConcurrency }}</b></label>
|
||||
<div class="small">{{ $t('backups.configureBackupStorage.downloadConcurrencyDescription') }}</div>
|
||||
<input type="range" id="downloadConcurrencyInput" v-model="downloadConcurrency" step="10" min="10" max="200" />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="target.format === 'rsync' && (s3like(target.provider) || target.provider === 'gcs')">
|
||||
<FormGroup v-if="site.format === 'rsync' && (s3like(site.provider) || site.provider === 'gcs')">
|
||||
<label for="copyConcurrencyInput">{{ $t('backups.configureBackupStorage.copyConcurrency') }}: <b>{{ copyConcurrency }}</b></label>
|
||||
<div class="small">{{ $t('backups.configureBackupStorage.copyConcurrencyDescription') }}
|
||||
<span v-show="target.provider === 'digitalocean-spaces'">{{ $t('backups.configureBackupStorage.copyConcurrencyDigitalOceanNote') }}</span>
|
||||
<span v-show="site.provider === 'digitalocean-spaces'">{{ $t('backups.configureBackupStorage.copyConcurrencyDigitalOceanNote') }}</span>
|
||||
</div>
|
||||
<input type="range" id="copyConcurrencyInput" v-model="copyConcurrency" step="10" min="10" max="500" />
|
||||
</FormGroup>
|
||||
@@ -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 () => {
|
||||
<template #creationTime="backup">
|
||||
{{ prettyLongDate(backup.creationTime) }} <b v-show="backup.label">({{ backup.label }})</b>
|
||||
</template>
|
||||
<template #target="backup">
|
||||
{{ backup.target ? backup.target.name : 'unknown' }}
|
||||
<template #site="backup">
|
||||
{{ backup.site ? backup.site.name : 'unknown' }}
|
||||
</template>
|
||||
<template #actions="backup">
|
||||
<div style="text-align: right;">
|
||||
|
||||
Reference in New Issue
Block a user