1 Ext
.define('PVE.window.Backup', {
2 extend
: 'Ext.window.Window',
6 initComponent: function() {
10 throw "no node name specified";
14 throw "no VM ID specified";
18 throw "no VM type specified";
21 let compressionSelector
= Ext
.create('PVE.form.CompressionSelector', {
24 fieldLabel
: gettext('Compression'),
27 let modeSelector
= Ext
.create('PVE.form.BackupModeSelector', {
28 fieldLabel
: gettext('Mode'),
33 let notificationTargetSelector
= Ext
.create('PVE.form.NotificationTargetSelector', {
34 fieldLabel
: gettext('Notification target'),
35 name
: 'notification-target',
36 emptyText
: Proxmox
.Utils
.noneText
,
40 let mailtoField
= Ext
.create('Ext.form.field.Text', {
41 fieldLabel
: gettext('Send email to'),
43 emptyText
: Proxmox
.Utils
.noneText
,
46 let notificationModeSelector
= Ext
.create('PVE.form.NotificationModeSelector', {
47 fieldLabel
: gettext('Notify via'),
49 name
: 'notification-mode',
51 change: function(f
, v
) {
52 let mailSelected
= v
=== 'mailto';
53 notificationTargetSelector
.setHidden(mailSelected
);
54 mailtoField
.setHidden(!mailSelected
);
60 ['keep-last', gettext('Keep Last')],
61 ['keep-hourly', gettext('Keep Hourly')],
62 ['keep-daily', gettext('Keep Daily')],
63 ['keep-weekly', gettext('Keep Weekly')],
64 ['keep-monthly', gettext('Keep Monthly')],
65 ['keep-yearly', gettext('Keep Yearly')],
68 let pruneSettings
= keepNames
.map(
69 name
=> Ext
.create('Ext.form.field.Display', {
76 let removeCheckbox
= Ext
.create('Proxmox.form.Checkbox', {
81 fieldLabel
: gettext('Prune'),
84 'data-qtip': gettext('Prune older backups afterwards'),
86 handler: function(checkbox
, value
) {
87 pruneSettings
.forEach(field
=> field
.setHidden(!value
));
88 me
.down('label[name="pruneLabel"]').setHidden(!value
);
92 let initialDefaults
= false;
94 var storagesel
= Ext
.create('PVE.form.StorageSelector', {
95 nodename
: me
.nodename
,
97 fieldLabel
: gettext('Storage'),
98 storageContent
: 'backup',
101 change: function(f
, v
) {
102 if (!initialDefaults
) {
103 me
.setLoading(false);
106 if (v
=== null || v
=== undefined || v
=== '') {
110 let store
= f
.getStore();
111 let rec
= store
.findRecord('storage', v
, 0, false, true, true);
113 if (rec
&& rec
.data
&& rec
.data
.type
=== 'pbs') {
114 compressionSelector
.setValue('zstd');
115 compressionSelector
.setDisabled(true);
116 } else if (!compressionSelector
.getEditable()) {
117 compressionSelector
.setDisabled(false);
120 Proxmox
.Utils
.API2Request({
121 url
: `/nodes/${me.nodename}/vzdump/defaults`,
127 success: function(response
, opts
) {
128 const data
= response
.result
.data
;
130 if (!initialDefaults
&& data
['notification-mode'] !== undefined) {
131 notificationModeSelector
.setValue(data
['notification-mode']);
133 if (!initialDefaults
&& data
['notification-channel'] !== undefined) {
134 notificationTargetSelector
.setValue(data
['notification-channel']);
136 if (!initialDefaults
&& data
.mailto
!== undefined) {
137 mailtoField
.setValue(data
.mailto
);
139 if (!initialDefaults
&& data
.mode
!== undefined) {
140 modeSelector
.setValue(data
.mode
);
142 if (!initialDefaults
&& (data
['notes-template'] ?? false)) {
143 me
.down('field[name=notes-template]').setValue(
144 PVE
.Utils
.unEscapeNotesTemplate(data
['notes-template']),
148 initialDefaults
= true;
150 // always update storage dependent properties
151 if (data
['prune-backups'] !== undefined) {
152 const keepParams
= PVE
.Parser
.parsePropertyString(
153 data
["prune-backups"],
155 if (!keepParams
['keep-all']) {
156 removeCheckbox
.setHidden(false);
157 pruneSettings
.forEach(function(field
) {
158 const keep
= keepParams
[field
.name
];
160 field
.setValue(keep
);
169 // no defaults or keep-all=1
170 removeCheckbox
.setHidden(true);
171 removeCheckbox
.setValue(false);
172 pruneSettings
.forEach(field
=> field
.reset());
174 failure: function(response
, opts
) {
175 initialDefaults
= true;
177 removeCheckbox
.setHidden(true);
178 removeCheckbox
.setValue(false);
179 pruneSettings
.forEach(field
=> field
.reset());
181 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
188 let protectedCheckbox
= Ext
.create('Proxmox.form.Checkbox', {
192 fieldLabel
: gettext('Protected'),
195 me
.formPanel
= Ext
.create('Proxmox.panel.InputPanel', {
205 notificationModeSelector
,
206 notificationTargetSelector
,
212 xtype
: 'textareafield',
213 name
: 'notes-template',
214 fieldLabel
: gettext('Notes'),
216 value
: '{{guestname}}',
222 'line-height': '1.5em',
224 html
: Ext
.String
.format(
225 gettext('Possible template variables are: {0}'),
226 PVE
.Utils
.notesTemplateVars
.map(v
=> `<code>{{${v}}}</code>`).join(', '),
232 text
: gettext('Storage Retention Configuration') + ':',
271 var submitBtn
= Ext
.create('Ext.Button', {
272 text
: gettext('Backup'),
273 handler: function() {
274 var storage
= storagesel
.getValue();
275 let values
= me
.formPanel
.getValues();
280 remove
: values
.remove
,
283 if (values
.mailto
&& values
['notification-mode'] === 'mailto') {
284 params
.mailto
= values
.mailto
;
287 if (values
['notification-target'] &&
288 values
['notification-mode'] === 'notification-target') {
289 params
['notification-target'] = values
['notification-target'];
292 if (values
.compress
) {
293 params
.compress
= values
.compress
;
296 if (values
.protected) {
297 params
.protected = values
.protected;
300 if (values
['notes-template']) {
301 params
['notes-template'] = PVE
.Utils
.escapeNotesTemplate(
302 values
['notes-template']);
305 Proxmox
.Utils
.API2Request({
306 url
: '/nodes/' + me
.nodename
+ '/vzdump',
309 failure: function(response
, opts
) {
310 Ext
.Msg
.alert('Error', response
.htmlStatus
);
312 success: function(response
, options
) {
313 // close later so we reload the grid
314 // after the task has completed
317 var upid
= response
.result
.data
;
319 var win
= Ext
.create('Proxmox.window.TaskViewer', {
333 var helpBtn
= Ext
.create('Proxmox.button.Help', {
334 onlineHelp
: 'chapter_vzdump',
335 listenToGlobalEvent
: false,
339 var title
= gettext('Backup') + " " +
340 (me
.vmtype
=== 'lxc' ? "CT" : "VM") +
349 items
: [me
.formPanel
],
350 buttons
: [helpBtn
, '->', submitBtn
],
352 afterrender: function() {
353 /// cleared within the storage selector's change listener
354 me
.setLoading(gettext('Please wait...'));
355 storagesel
.setValue(me
.storage
);