diff --git a/dashboard/src/components/BackupTargetEditDialog.vue b/dashboard/src/components/BackupTargetEditDialog.vue index 6250314c2..265ef2001 100644 --- a/dashboard/src/components/BackupTargetEditDialog.vue +++ b/dashboard/src/components/BackupTargetEditDialog.vue @@ -5,7 +5,6 @@ import { Dialog, FormGroup, TextInput, PasswordInput, Button, Checkbox } from '@ 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 SystemModel from '../models/SystemModel.js'; @@ -14,14 +13,47 @@ const emit = defineEmits([ 'success' ]); const backupTargetsModel = BackupTargetsModel.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 formError = ref({}); const busy = ref(false); +const memoryLimit = ref(0); +const uploadPartSize = ref(0); +const syncConcurrency = ref(0); +const downloadConcurrency = ref(0); +const copyConcurrency = ref(0); async function onSubmit() { + busy.value = true; + + const limits = { + memoryLimit: parseInt(memoryLimit.value), + uploadPartSize: parseInt(uploadPartSize.value), + syncConcurrency: parseInt(syncConcurrency.value), + downloadConcurrency: parseInt(downloadConcurrency.value), + copyConcurrency: parseInt(copyConcurrency.value), + }; + + const [error] = await backupTargetsModel.setLimits(target.value.id, limits); + if (error) { + formError.value.generic = error.body ? error.body.message : 'Internal error'; + busy.value = false; + return console.error(error); + } + emit('success'); dialog.value.close(); + busy.value = false; +} + +async function getMemory() { + const [error, result] = await systemModel.memory(); + if (error) return console.error(error); + + maxMemoryLimit.value = Math.ceil(result.memory / (1024*1024*1024)) * 1024 * 1024 * 1024; } defineExpose({ @@ -30,7 +62,13 @@ defineExpose({ busy.value = false; target.value = t; - console.log(t) + memoryLimit.value = t.limits.memoryLimit || 1024 * 1024 * 1024; // 1 GB + uploadPartSize.value = t.limits.uploadPartSize || 10 * 1024 * 1024; + syncConcurrency.value = t.limits.syncConcurrency || 10; + downloadConcurrency.value = t.limits.downloadConcurrency || 10; + copyConcurrency.value = t.limits.copyConcurrency || 10; + + await getMemory(); dialog.value.open(); } @@ -80,6 +118,46 @@ defineExpose({
Encryption Password Hint
{{ target.encryptionPasswordHint }}
+ + + +
{{ $t('backups.configureBackupStorage.memoryLimitDescription') }}
+ +
+ + + +

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

+ + + + + + + + + +
+ + + +
{{ $t('backups.configureBackupStorage.uploadConcurrencyDescription') }}
+ +
+ + + +
{{ $t('backups.configureBackupStorage.downloadConcurrencyDescription') }}
+ +
+ + + +
{{ $t('backups.configureBackupStorage.copyConcurrencyDescription') }} + {{ $t('backups.configureBackupStorage.copyConcurrencyDigitalOceanNote') }} +
+ +