From ea86e8ac15d8cfcf1658ba1ee7b7862813a32225 Mon Sep 17 00:00:00 2001 From: Frederick Borges Date: Tue, 15 Nov 2022 10:59:12 +0100 Subject: [PATCH] F #5516: Expose backup functionality (#2346) --- .../etc/sunstone/admin/vm-template-tab.yaml | 2 + .../components/Forms/Vm/BackupForm/schema.js | 10 ++- .../Steps/ExtraConfiguration/backup/index.js | 60 ++++++++++++++ .../Steps/ExtraConfiguration/backup/schema.js | 80 ++++++++++++++++++ .../Steps/ExtraConfiguration/index.js | 2 + .../Steps/ExtraConfiguration/schema.js | 2 + .../src/client/constants/translates.js | 8 ++ .../src/client/constants/vmTemplate.js | 14 ++++ src/fireedge/src/client/features/OneApi/vm.js | 1 + .../src/server/utils/constants/commands/vm.js | 4 + .../etc/sunstone-views/kvm/admin.yaml | 1 + .../etc/sunstone-views/kvm/groupadmin.yaml | 1 + src/sunstone/etc/sunstone-views/kvm/user.yaml | 1 + .../etc/sunstone-views/mixed/admin.yaml | 1 + .../etc/sunstone-views/mixed/groupadmin.yaml | 1 + .../etc/sunstone-views/mixed/user.yaml | 1 + .../etc/sunstone-views/vcenter/admin.yaml | 1 + .../sunstone-views/vcenter/groupadmin.yaml | 1 + .../etc/sunstone-views/vcenter/user.yaml | 1 + .../OpenNebulaJSON/VirtualMachineJSON.rb | 2 +- src/sunstone/public/app/tabs/backups-tab.js | 1 + .../public/app/tabs/backups-tab/datatable.js | 1 - .../app/tabs/backups-tab/panels/increments.js | 81 +++++++++++++++++++ .../backups-tab/panels/increments/html.hbs | 32 ++++++++ .../backups-tab/panels/increments/panelId.js | 19 +++++ .../tabs/datastores-tab/form-panels/create.js | 10 ++- .../form-panels/create/wizard.hbs | 8 ++ .../app/tabs/images-tab/datatable-common.js | 8 ++ .../form-panels/create/wizard-tabs/backup.js | 11 ++- .../create/wizard-tabs/backup/html.hbs | 10 +++ .../public/app/tabs/vms-tab/dialogs/backup.js | 4 +- .../app/tabs/vms-tab/dialogs/backup/html.hbs | 15 ++-- src/sunstone/public/scss/_backups.scss | 23 ++++++ src/sunstone/public/scss/app.scss | 1 + 34 files changed, 405 insertions(+), 13 deletions(-) create mode 100644 src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js create mode 100644 src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js create mode 100644 src/sunstone/public/app/tabs/backups-tab/panels/increments.js create mode 100644 src/sunstone/public/app/tabs/backups-tab/panels/increments/html.hbs create mode 100644 src/sunstone/public/app/tabs/backups-tab/panels/increments/panelId.js create mode 100644 src/sunstone/public/scss/_backups.scss diff --git a/src/fireedge/etc/sunstone/admin/vm-template-tab.yaml b/src/fireedge/etc/sunstone/admin/vm-template-tab.yaml index 0abb4435f8..efffa57c0a 100644 --- a/src/fireedge/etc/sunstone/admin/vm-template-tab.yaml +++ b/src/fireedge/etc/sunstone/admin/vm-template-tab.yaml @@ -102,6 +102,7 @@ dialogs: placement: true sched_action: true booting: true + backup: true create_dialog: ownership: true capacity: true @@ -125,3 +126,4 @@ dialogs: not_on: - vcenter - kvm + backup: true diff --git a/src/fireedge/src/client/components/Forms/Vm/BackupForm/schema.js b/src/fireedge/src/client/components/Forms/Vm/BackupForm/schema.js index 05b6359465..2ae349dab0 100644 --- a/src/fireedge/src/client/components/Forms/Vm/BackupForm/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/BackupForm/schema.js @@ -40,6 +40,14 @@ const DS_ID = { .default(() => undefined), } -export const FIELDS = [DS_ID] +const RESET = { + name: 'reset', + label: T.Reset, + type: INPUT_TYPES.SWITCH, + validation: boolean(), + grid: { xs: 12, md: 6 }, +} + +export const FIELDS = [DS_ID, RESET] export const SCHEMA = object(getValidationFromFields(FIELDS)) diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js new file mode 100644 index 0000000000..2ebb5f599f --- /dev/null +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js @@ -0,0 +1,60 @@ +/* ------------------------------------------------------------------------- * + * Copyright 2002-2022, OpenNebula Project, OpenNebula Systems * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); you may * + * not use this file except in compliance with the License. You may obtain * + * a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + * ------------------------------------------------------------------------- */ +import PropTypes from 'prop-types' +import { RefreshDouble as BackupIcon } from 'iconoir-react' + +import FormWithSchema from 'client/components/Forms/FormWithSchema' + +import { + STEP_ID as EXTRA_ID, + TabType, +} from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration' +import { + SECTIONS, + FIELDS, +} from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema' +import { T } from 'client/constants' + +const Backup = () => ( + <> + {SECTIONS.map(({ id, ...section }) => ( + + ))} + +) + +Backup.propTypes = { + data: PropTypes.any, + setFormData: PropTypes.func, +} + +Backup.displayName = 'Backup' + +/** @type {TabType} */ +const TAB = { + id: 'backup', + name: T.Backup, + icon: BackupIcon, + Content: Backup, + getError: (error) => FIELDS.some(({ name }) => error?.[name]), +} + +export default TAB diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js new file mode 100644 index 0000000000..28b2000895 --- /dev/null +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js @@ -0,0 +1,80 @@ +/* ------------------------------------------------------------------------- * + * Copyright 2002-2022, OpenNebula Project, OpenNebula Systems * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); you may * + * not use this file except in compliance with the License. You may obtain * + * a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + * ------------------------------------------------------------------------- */ +import { string, boolean, number } from 'yup' + +import { Field, Section, arrayToOptions } from 'client/utils' +import { T, INPUT_TYPES, FS_FREEZE_OPTIONS } from 'client/constants' + +const BACKUP_VOLATILE_FIELD = { + name: 'BACKUP_CONFIG.BACKUP_VOLATILE', + label: T.BackupVolatileDisksQuestion, + type: INPUT_TYPES.SWITCH, + validation: boolean().yesOrNo().notRequired(), +} + +const FS_FREEZE_FIELD = { + name: 'BACKUP_CONFIG.FS_FREEZE', + label: T.FSFreeze, + tooltip: T.FSFreezeConcept, + type: INPUT_TYPES.SELECT, + values: arrayToOptions(Object.keys(FS_FREEZE_OPTIONS), { + getText: (type) => type, + getValue: (type) => FS_FREEZE_OPTIONS[type], + }), + validation: string() + .trim() + .default(() => undefined), +} + +const KEEP_LAST_FIELD = { + name: 'BACKUP_CONFIG.KEEP_LAST', + label: T.HowManyBackupsQuestion, + type: INPUT_TYPES.TEXT, + htmlType: 'number', + validation: number() + .notRequired() + .nullable(true) + .default(() => undefined) + .transform((_, val) => (val !== '' ? val : null)), +} + +const MODE_FIELD = { + name: 'BACKUP_CONFIG.MODE', + label: T.FSFreeze, + tooltip: T.FSFreezeConcept, + type: INPUT_TYPES.SELECT, + values: arrayToOptions(Object.keys(BACKUP_MODE_OPTIONS), { + addEmpty: true, + getText: (type) => type, + getValue: (type) => BACKUP_MODE_OPTIONS[type], + }), + validation: string() + .trim() + .default(() => undefined), +} + +/** @type {Section[]} Sections */ +const SECTIONS = [ + { + id: 'backup-configuration', + fields: [BACKUP_VOLATILE_FIELD, FS_FREEZE_FIELD, KEEP_LAST_FIELD, MODE_FIELD], + }, +] + +/** @type {Field[]} List of Placement fields */ +const FIELDS = [BACKUP_VOLATILE_FIELD, FS_FREEZE_FIELD, KEEP_LAST_FIELD, MODE_FIELD] + +export { SECTIONS, FIELDS } diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js index 35cdf8e045..df023d093e 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js @@ -31,6 +31,7 @@ import Booting from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraCo import Context from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/context' import InputOutput from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/inputOutput' import Numa from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/numa' +import Backup from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup' import { STEP_ID as GENERAL_ID } from 'client/components/Forms/VmTemplate/CreateForm/Steps/General' import { SCHEMA } from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/schema' @@ -58,6 +59,7 @@ export const TABS = [ ScheduleAction, Placement, Numa, + Backup, ] const Content = ({ data, setFormData }) => { diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/schema.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/schema.js index e98103754c..2917c5074c 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/schema.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/schema.js @@ -18,6 +18,7 @@ import { array, object, ObjectSchema } from 'yup' import { HYPERVISORS } from 'client/constants' import { getObjectSchemaFromFields } from 'client/utils' import { FIELDS as PLACEMENT_FIELDS } from './placement/schema' +import { FIELDS as BACKUP_FIELDS } from './backup/schema' import { FIELDS as OS_FIELDS, BOOT_ORDER_FIELD } from './booting/schema' import { SCHEMA as NUMA_SCHEMA, FIELDS as NUMA_FIELDS } from './numa/schema' import { SCHEMA as IO_SCHEMA } from './inputOutput/schema' @@ -59,6 +60,7 @@ export const SCHEMA = (hypervisor) => .concat( getObjectSchemaFromFields([...PLACEMENT_FIELDS, ...OS_FIELDS(hypervisor)]) ) + .concat(getObjectSchemaFromFields([...BACKUP_FIELDS])) .concat(NUMA_SCHEMA(hypervisor)) export { diff --git a/src/fireedge/src/client/constants/translates.js b/src/fireedge/src/client/constants/translates.js index 67a18a7a12..02190158b7 100644 --- a/src/fireedge/src/client/constants/translates.js +++ b/src/fireedge/src/client/constants/translates.js @@ -688,6 +688,14 @@ module.exports = { DatastorePolicyExpressionConcept: ` This field sets which attribute will be used to sort the suitable datastores for this VM`, + /* VM Template schema - Backup */ + BackupVolatileDisksQuestion: 'Backup volatile disks?', + FSFreeze: 'FS Freeze', + HowManyBackupsQuestion: 'How many backups do you want to keep?', + QEMUAgent: 'QEMU Agent', + FSFreezeConcept: ` + How the FS is freeze for running VMs. When + possible backups are crash consistent`, /* VM Template schema - OS & CPU */ /* VM Template schema - OS & CPU - boot */ Boot: 'Boot', diff --git a/src/fireedge/src/client/constants/vmTemplate.js b/src/fireedge/src/client/constants/vmTemplate.js index 9091102c4c..cb52b0bbaf 100644 --- a/src/fireedge/src/client/constants/vmTemplate.js +++ b/src/fireedge/src/client/constants/vmTemplate.js @@ -16,6 +16,7 @@ import * as ACTIONS from 'client/constants/actions' // eslint-disable-next-line no-unused-vars import { Permissions, LockInfo } from 'client/constants/common' +import { T } from 'client/constants' /** * @typedef VmTemplate @@ -105,3 +106,16 @@ export const TEMPLATE_LOGOS = { 'Windows xp': 'images/logos/windowsxp.png', 'Windows 10': 'images/logos/windows8.png', } + +/** @enum {string} FS freeze options type */ +export const FS_FREEZE_OPTIONS = { + [T.None]: 'NONE', + [T.QEMUAgent]: 'QEMU-AGENT', + [T.Suspend]: 'SUSPEND', +} + +/** @enum {string} Backup mode options type */ +export const BACKUP_MODE_OPTIONS = { + [T.Full]: 'FULL', + [T.Increment]: 'INCREMENT', +} diff --git a/src/fireedge/src/client/features/OneApi/vm.js b/src/fireedge/src/client/features/OneApi/vm.js index 2c9a094fe7..570a536b93 100644 --- a/src/fireedge/src/client/features/OneApi/vm.js +++ b/src/fireedge/src/client/features/OneApi/vm.js @@ -882,6 +882,7 @@ const vmApi = oneApi.injectEndpoints({ * @param {object} params - Request parameters * @param {string} params.id - Virtual machine id * @param {number} params.dsId - Backup Datastore id + * @param {boolean} params.reset - Backup reset * @returns {number} Virtual machine id * @throws Fails when response isn't code 200 */ diff --git a/src/fireedge/src/server/utils/constants/commands/vm.js b/src/fireedge/src/server/utils/constants/commands/vm.js index d841e552d3..5806a180be 100644 --- a/src/fireedge/src/server/utils/constants/commands/vm.js +++ b/src/fireedge/src/server/utils/constants/commands/vm.js @@ -688,6 +688,10 @@ module.exports = { from: postBody, default: 0, }, + reset: { + from: postBody, + default: 0, + }, }, }, [VM_POOL_INFO]: { diff --git a/src/sunstone/etc/sunstone-views/kvm/admin.yaml b/src/sunstone/etc/sunstone-views/kvm/admin.yaml index f01dc3a5f1..6faf353fac 100644 --- a/src/sunstone/etc/sunstone-views/kvm/admin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/admin.yaml @@ -726,6 +726,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml index 44d57e38ad..01c27cc145 100644 --- a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml @@ -723,6 +723,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/kvm/user.yaml b/src/sunstone/etc/sunstone-views/kvm/user.yaml index 45e95ebb55..7e22703746 100644 --- a/src/sunstone/etc/sunstone-views/kvm/user.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/user.yaml @@ -719,6 +719,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/mixed/admin.yaml b/src/sunstone/etc/sunstone-views/mixed/admin.yaml index 81e494bbe1..e3b5275639 100644 --- a/src/sunstone/etc/sunstone-views/mixed/admin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/admin.yaml @@ -728,6 +728,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml index f918e37721..428783b5b7 100644 --- a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml @@ -727,6 +727,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/mixed/user.yaml b/src/sunstone/etc/sunstone-views/mixed/user.yaml index ac2e0ff6ec..0db7410a44 100644 --- a/src/sunstone/etc/sunstone-views/mixed/user.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/user.yaml @@ -720,6 +720,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/vcenter/admin.yaml b/src/sunstone/etc/sunstone-views/vcenter/admin.yaml index 4537fe3e21..4790e18a01 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/admin.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/admin.yaml @@ -726,6 +726,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml b/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml index f77fa657e9..8edf8e1b5f 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml @@ -727,6 +727,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/vcenter/user.yaml b/src/sunstone/etc/sunstone-views/vcenter/user.yaml index 4a7a8d5d98..d627200d14 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/user.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/user.yaml @@ -720,6 +720,7 @@ tabs: panel_tabs: backup_info_tab: true backup_vms_tab: true + backup_increments_tab: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index e944a4ea34..738bb23ddb 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -135,7 +135,7 @@ module OpenNebulaJSON when 'sg_detach' sg_detach(action_hash['params']) when 'backup' - backup(action_hash['params']['dst_id'].to_i) + backup(action_hash['params']['dst_id'].to_i, action_hash['params']['reset']) else error_msg = "#{action_hash['perform']} action not " \ ' available for this resource' diff --git a/src/sunstone/public/app/tabs/backups-tab.js b/src/sunstone/public/app/tabs/backups-tab.js index 1379f3d0cf..6b45f87d06 100644 --- a/src/sunstone/public/app/tabs/backups-tab.js +++ b/src/sunstone/public/app/tabs/backups-tab.js @@ -30,6 +30,7 @@ define(function(require) { var _panels = [ require('./backups-tab/panels/info'), require('./backups-tab/panels/vms'), + require('./backups-tab/panels/increments'), ]; var _panelsHooks = [ diff --git a/src/sunstone/public/app/tabs/backups-tab/datatable.js b/src/sunstone/public/app/tabs/backups-tab/datatable.js index fe11629db2..e7edef7c89 100644 --- a/src/sunstone/public/app/tabs/backups-tab/datatable.js +++ b/src/sunstone/public/app/tabs/backups-tab/datatable.js @@ -20,7 +20,6 @@ define(function(require) { */ var ImageCommonDataTable = require("tabs/images-tab/datatable-common"); - var Locale = require("utils/locale"); var Humanize = require("utils/humanize"); var OpenNebulaImage = require("opennebula/image"); diff --git a/src/sunstone/public/app/tabs/backups-tab/panels/increments.js b/src/sunstone/public/app/tabs/backups-tab/panels/increments.js new file mode 100644 index 0000000000..b55bb9c1d0 --- /dev/null +++ b/src/sunstone/public/app/tabs/backups-tab/panels/increments.js @@ -0,0 +1,81 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2022, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +define(function(require){ + /* + DEPENDENCIES + */ + var Locale = require('utils/locale'); + var Humanize = require("utils/humanize"); + var TemplateHTML = require("hbs!./increments/html"); + + /* + CONSTANTS + */ + var PANEL_ID = require('./increments/panelId'); + var XML_ROOT = "IMAGE"; + + /* + CONSTRUCTOR + */ + function Panel(info) { + this.title = Locale.tr("Increments"); + this.icon = "fa-angle-double-up"; + + this.element = info[XML_ROOT]; + + return this; + } + + Panel.PANEL_ID = PANEL_ID; + Panel.prototype.html = _html; + Panel.prototype.setup = _setup; + + return Panel; + + /* + FUNCTION DEFINITIONS + */ + + function _html() { + if (!this.element.BACKUP_INCREMENTS.INCREMENT){ + return "" + } + + var increments = Array.isArray(this.element.BACKUP_INCREMENTS.INCREMENT) ? + this.element.BACKUP_INCREMENTS.INCREMENT : + [this.element.BACKUP_INCREMENTS.INCREMENT] + + var html = '
' + + increments.forEach(function(increment){ + html += TemplateHTML({ + id: increment.ID, + size: Humanize.sizeFromB(increment.SIZE), + date: Humanize.prettyTimeDatatable(increment.DATE), + type: increment.TYPE + }) + }); + + html += "
" + + return html + } + + function _setup(context) { + return false; + } +}) diff --git a/src/sunstone/public/app/tabs/backups-tab/panels/increments/html.hbs b/src/sunstone/public/app/tabs/backups-tab/panels/increments/html.hbs new file mode 100644 index 0000000000..cffb0c270b --- /dev/null +++ b/src/sunstone/public/app/tabs/backups-tab/panels/increments/html.hbs @@ -0,0 +1,32 @@ +{{! -------------------------------------------------------------------------- }} +{{! Copyright 2002-2022, OpenNebula Project, OpenNebula Systems }} +{{! }} +{{! Licensed under the Apache License, Version 2.0 (the "License"); you may }} +{{! not use this file except in compliance with the License. You may obtain }} +{{! a copy of the License at }} +{{! }} +{{! http://www.apache.org/licenses/LICENSE-2.0 }} +{{! }} +{{! Unless required by applicable law or agreed to in writing, software }} +{{! distributed under the License is distributed on an "AS IS" BASIS, }} +{{! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }} +{{! See the License for the specific language governing permissions and }} +{{! limitations under the License. }} +{{! -------------------------------------------------------------------------- }} + +
+
+ #{{id}} +
+
+
+ {{date}} +
+
+ {{tr "Size"}}: {{size}} +
+
+ {{tr "Type"}}: {{type}} +
+
+
diff --git a/src/sunstone/public/app/tabs/backups-tab/panels/increments/panelId.js b/src/sunstone/public/app/tabs/backups-tab/panels/increments/panelId.js new file mode 100644 index 0000000000..4702ec4456 --- /dev/null +++ b/src/sunstone/public/app/tabs/backups-tab/panels/increments/panelId.js @@ -0,0 +1,19 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2022, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +define(function(require){ + return 'backup_increments_tab'; +}) diff --git a/src/sunstone/public/app/tabs/datastores-tab/form-panels/create.js b/src/sunstone/public/app/tabs/datastores-tab/form-panels/create.js index 4905de7a9a..512a1899cc 100644 --- a/src/sunstone/public/app/tabs/datastores-tab/form-panels/create.js +++ b/src/sunstone/public/app/tabs/datastores-tab/form-panels/create.js @@ -285,6 +285,7 @@ define(function(require) { var compatible_sys_ds = $('#compatible_sys_ds', dialog).val(); var restic_password = $('#restic_password', dialog).val(); var restic_sftp_server = $('#restic_sftp_server', dialog).val(); + var restic_sftp_user = $('#restic_sftp_user', dialog).val(); var restic_ionice = $('#restic_ionice', dialog).val(); var restic_nice = $('#restic_nice', dialog).val(); var restic_bwlimit = $('#restic_bwlimit', dialog).val(); @@ -385,6 +386,9 @@ define(function(require) { if (restic_sftp_server) ds_obj.datastore.restic_sftp_server = restic_sftp_server; + + if (restic_sftp_user) + ds_obj.datastore.restic_sftp_user = restic_sftp_user; if (restic_ionice) ds_obj.datastore.restic_ionice = restic_ionice; @@ -457,12 +461,12 @@ define(function(require) { $('label[for="no_decompress"],input#no_decompress', dialog).parent().hide(); $('label[for="restic_password"]', dialog).parent().hide(); $('label[for="restic_sftp_server"]', dialog).parent().hide(); + $('label[for="restic_sftp_user"]', dialog).parent().hide(); $('label[for="restic_ionice"]', dialog).parent().hide(); $('label[for="restic_nice"]', dialog).parent().hide(); $('label[for="restic_bwlimit"]', dialog).parent().hide(); $('label[for="restic_compression"]', dialog).parent().hide(); $('label[for="restic_connections"]', dialog).parent().hide(); - $('label[for="restic_sftp_server"]', dialog).parent().hide(); $('label[for="rsync_host"]', dialog).parent().hide(); $('label[for="rsync_user"]', dialog).parent().hide(); @@ -496,12 +500,12 @@ define(function(require) { $('label[for="no_decompress"],input#no_decompress', dialog).parent().show(); $('label[for="restic_password"]', dialog).parent().show(); $('label[for="restic_sftp_server"]', dialog).parent().show(); + $('label[for="restic_sftp_user"]', dialog).parent().show(); $('label[for="restic_ionice"]', dialog).parent().show(); $('label[for="restic_nice"]', dialog).parent().show(); $('label[for="restic_bwlimit"]', dialog).parent().show(); $('label[for="restic_compression"]', dialog).parent().show(); $('label[for="restic_connections"]', dialog).parent().show(); - $('label[for="restic_sftp_server"]', dialog).parent().show(); $('label[for="rsync_host"]', dialog).parent().show(); $('label[for="rsync_user"]', dialog).parent().show(); @@ -614,12 +618,12 @@ define(function(require) { $('label[for="vcenter_cluster"],div#vcenter_cluster_wrapper', dialog).parent().hide(); $('label[for="restic_password"]', dialog).parent().fadeIn(); $('label[for="restic_sftp_server"]', dialog).parent().fadeIn(); + $('label[for="restic_sftp_user"]', dialog).parent().fadeIn(); $('label[for="restic_ionice"]', dialog).parent().fadeIn(); $('label[for="restic_nice"]', dialog).parent().fadeIn(); $('label[for="restic_bwlimit"]', dialog).parent().fadeIn(); $('label[for="restic_compression"]', dialog).parent().fadeIn(); $('label[for="restic_connections"]', dialog).parent().fadeIn(); - $('label[for="restic_sftp_server"]', dialog).parent().fadeIn(); } function _selectRsync(dialog) { diff --git a/src/sunstone/public/app/tabs/datastores-tab/form-panels/create/wizard.hbs b/src/sunstone/public/app/tabs/datastores-tab/form-panels/create/wizard.hbs index 7505946a1b..ae6d95f1d4 100644 --- a/src/sunstone/public/app/tabs/datastores-tab/form-panels/create/wizard.hbs +++ b/src/sunstone/public/app/tabs/datastores-tab/form-panels/create/wizard.hbs @@ -254,6 +254,7 @@ +
+
+ + +
+
+
+ + +
diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/backup.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/backup.js index 97326d7d39..9ca71a7533 100644 --- a/src/sunstone/public/app/tabs/vms-tab/dialogs/backup.js +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/backup.js @@ -78,7 +78,9 @@ define(function(require) { $("#" + DIALOG_ID + "Form", dialog).submit(function() { var sel_elems = Sunstone.getDataTable(VMS_TAB_ID).elements(); - var extra_info = {}; + var extra_info = { + "reset":$("#cb_backup_reset", dialog).prop("checked") + }; var targetDS = that.datastoreTable.retrieveResourceTableSelect(); extra_info["dst_id"] = targetDS; diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/backup/html.hbs b/src/sunstone/public/app/tabs/vms-tab/dialogs/backup/html.hbs index 26eab52add..17102b8bfd 100644 --- a/src/sunstone/public/app/tabs/vms-tab/dialogs/backup/html.hbs +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/backup/html.hbs @@ -22,13 +22,18 @@
+
+ +
{{tr "Datastore to restore"}} -
-
-
- {{{datastoreTableSelectHTML}}} +
+
-
+ {{{datastoreTableSelectHTML}}} +
+
diff --git a/src/sunstone/public/scss/_backups.scss b/src/sunstone/public/scss/_backups.scss new file mode 100644 index 0000000000..fd20708ef8 --- /dev/null +++ b/src/sunstone/public/scss/_backups.scss @@ -0,0 +1,23 @@ +.backup_increments_content { + display: flex; + flex-wrap: wrap; +} + +.backup-increment { + width: 30%; + margin: 1rem; + border: solid 1px #dfdfdf; + border-radius: 5px; + display: flex; +} + +.backup-increment-data > div { + margin: 0.2rem; +} + +.backup-increment-id { + font-size: xx-large; + font-weight: 400; + width: 30%; + text-align: center; +} \ No newline at end of file diff --git a/src/sunstone/public/scss/app.scss b/src/sunstone/public/scss/app.scss index ea36b980a2..a5c8b12c69 100644 --- a/src/sunstone/public/scss/app.scss +++ b/src/sunstone/public/scss/app.scss @@ -39,6 +39,7 @@ @import './visjs'; @import './flot'; @import './login'; +@import './backups';