Share backup provide form between app import and backup storage configuration
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { Button, InputGroup, SingleSelect, FormGroup, TextInput, Checkbox, PasswordInput, NumberInput } from 'pankow';
|
||||
import { BACKUP_FORMATS, STORAGE_PROVIDERS, REGIONS_CONTABO, REGIONS_VULTR, REGIONS_UPCLOUD, REGIONS_IONOS, REGIONS_OVH, REGIONS_LINODE, REGIONS_SCALEWAY, REGIONS_EXOSCALE, REGIONS_DIGITALOCEAN, REGIONS_HETZNER, REGIONS_WASABI, REGIONS_S3 } from '../constants.js';
|
||||
import { prettyBinarySize } from 'pankow/utils';
|
||||
import { BACKUP_FORMATS, STORAGE_PROVIDERS, REGIONS_CONTABO, REGIONS_VULTR, REGIONS_IONOS, REGIONS_OVH, REGIONS_LINODE, REGIONS_SCALEWAY, REGIONS_EXOSCALE, REGIONS_DIGITALOCEAN, REGIONS_HETZNER, REGIONS_WASABI, REGIONS_S3 } from '../constants.js';
|
||||
import SystemModel from '../models/SystemModel.js';
|
||||
import { mountlike, s3like } from '../utils.js';
|
||||
|
||||
@@ -28,6 +29,10 @@ const gcsKeyFileName = ref('');
|
||||
const gcsProjectId = ref('');
|
||||
const gcsKeyContentJson = ref(null);
|
||||
const gcsFileParseError = ref('');
|
||||
const advancedVisible = ref(false);
|
||||
|
||||
const minMemoryLimit = ref(1024 * 1024 * 1024); // 1 GB
|
||||
const maxMemoryLimit = ref(minMemoryLimit.value); // set later
|
||||
|
||||
function onGcsKeyChange(event) {
|
||||
gcsFileParseError.value = '';
|
||||
@@ -78,7 +83,26 @@ async function getBlockDevices() {
|
||||
.filter(d => { return d.type === 'xfs' || d.type === 'ext4'; });
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
watch(provider, (newProvider) => {
|
||||
if (newProvider === 'scaleway-objectstorage') {
|
||||
// scaleway only supports 1000 parts per object (https://www.scaleway.com/en/docs/s3-multipart-upload/)
|
||||
if (parseInt(providerConfig.value.uploadPartSize) < 100 * 1024 * 1024) providerConfig.value.uploadPartSize = 100 * 1024 * 1024;
|
||||
} else if (newProvider === 's3') {
|
||||
if (parseInt(providerConfig.value.downloadConcurrency) < 30) providerConfig.value.downloadConcurrency = 30;
|
||||
if (parseInt(providerConfig.value.syncConcurrency) < 20) providerConfig.value.syncConcurrency = 20;
|
||||
if (parseInt(providerConfig.value.copyConcurrency) < 500) providerConfig.value.downloadConcurrency = 500;
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await getMemory();
|
||||
await getBlockDevices();
|
||||
});
|
||||
|
||||
@@ -258,9 +282,51 @@ onMounted(async () => {
|
||||
<FormGroup v-if="provider !== 'noop'">
|
||||
<label for="encryptionPassswordInput">{{ $t('backups.configureBackupStorage.encryptionPassword') }} <sup><a href="https://docs.cloudron.io/backups/#encryption" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
||||
<TextInput id="encryptionPassswordInput" v-model="providerConfig.encryptionPassword" :placeholder="$t('backups.configureBackupStorage.encryptionPasswordPlaceholder')" />
|
||||
<div class="error-label" v-show="providerConfig.encryptionPassword">{{ $t('backups.configureBackupStorage.encryptionDescription') }}</div>
|
||||
</FormGroup>
|
||||
<Checkbox v-if="providerConfig.format === 'rsync' && providerConfig.encryptionPassword" v-model="providerConfig.encryptedFilenames" :label="$t(importOnly ? 'backups.configureBackupStorage.encryptedFilenames' : 'backups.configureBackupStorage.encryptFilenames')"/>
|
||||
<div class="warning-label" v-show="providerConfig.encryptionPassword && !importOnly">{{ $t('backups.configureBackupStorage.encryptionDescription') }}</div>
|
||||
|
||||
<Checkbox v-if="providerConfig.format === 'rsync' && providerConfig.encryptionPassword" v-model="providerConfig.encryptedFilenames" :label="$t('backups.configureBackupStorage.encryptFilenames')"/>
|
||||
<p class="actionable" @click="advancedVisible = true" v-if="!advancedVisible && !importOnly">{{ $t('backups.configureBackupStorage.advancedSettings') }}</p>
|
||||
<div v-if="advancedVisible && !importOnly">
|
||||
<FormGroup>
|
||||
<label for="memoryLimitInput">{{ $t('backups.configureBackupStorage.memoryLimit') }}: <b>{{ prettyBinarySize(memoryLimit, '1024 MB') }}</b></label>
|
||||
<p class="small">{{ $t('backups.configureBackupStorage.memoryLimitDescription') }}</p>
|
||||
<input type="range" id="memoryLimitInput" v-model="providerConfig.limits.memoryLimit" :step="256*1024*1024" :min="minMemoryLimit" :max="maxMemoryLimit" />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="s3like(provider)">
|
||||
<label for="uploadPartSizeInput">{{ $t('backups.configureBackupStorage.uploadPartSize') }}: <b>{{ prettyBinarySize(providerConfig.limits.uploadPartSize, 'Default (50 MiB)') }}</b></label>
|
||||
<p class="small">{{ $t('backups.configureBackupStorage.uploadPartSizeDescription') }}</p>
|
||||
<input type="range" id="uploadPartSizeInput" v-model="providerConfig.limits.uploadPartSize" list="uploadPartSizeTicks" :step="1024*1024" :min="10*1024*1024" :max="1024*1024*1024" />
|
||||
<datalist id="uploadPartSizeTicks">
|
||||
<option :value="1024*1024*10"></option>
|
||||
<option :value="1024*1024*64"></option>
|
||||
<option :value="1024*1024*128"></option>
|
||||
<option :value="1024*1024*256"></option>
|
||||
<option :value="1024*1024*512"></option>
|
||||
<option :value="1024*1024*1024"></option>
|
||||
</datalist>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="format === 'rsync' && provider !== 'noop'">
|
||||
<label for="syncConcurrencyInput">{{ $t('backups.configureBackupStorage.uploadConcurrency') }}: <b>{{ providerConfig.limits.syncConcurrency }}</b></label>
|
||||
<p class="small">{{ $t('backups.configureBackupStorage.uploadConcurrencyDescription') }}</p>
|
||||
<input type="range" id="syncConcurrencyInput" v-model="providerConfig.limits.syncConcurrency" step="10" min="10" max="200" />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="format === 'rsync' && (s3like(provider) || provider === 'gcs')">
|
||||
<label for="downloadConcurrencyInput">{{ $t('backups.configureBackupStorage.downloadConcurrency') }}: <b>{{ providerConfig.limits.downloadConcurrency }}</b></label>
|
||||
<p class="small">{{ $t('backups.configureBackupStorage.downloadConcurrencyDescription') }}</p>
|
||||
<input type="range" id="downloadConcurrencyInput" v-model="providerConfig.limits.downloadConcurrency" step="10" min="10" max="200" />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="format === 'rsync' && (s3like(provider) || provider === 'gcs')">
|
||||
<label for="copyConcurrencyInput">{{ $t('backups.configureBackupStorage.copyConcurrency') }}: <b>{{ providerConfig.limits.copyConcurrency }}</b></label>
|
||||
<p class="small">{{ $t('backups.configureBackupStorage.copyConcurrencyDescription') }}
|
||||
<span v-show="provider === 'digitalocean-spaces'">{{ $t('backups.configureBackupStorage.copyConcurrencyDigitalOceanNote') }}</span>
|
||||
</p>
|
||||
<input type="range" id="copyConcurrencyInput" v-model="providerConfig.limits.copyConcurrency" step="10" min="10" max="500" />
|
||||
</FormGroup>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user