* [pve-devel] [PATCH-SERIES v4 manager] split up content view/add prune window
@ 2020-11-18 10:04 Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 1/4] cluster resources: include content type for storages Fabian Ebner
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Fabian Ebner @ 2020-11-18 10:04 UTC (permalink / raw)
To: pve-devel
Follow-up to/finishing up the partially-applied series:
https://lists.proxmox.com/pipermail/pve-devel/2020-November/045929.html
The first two patches extend the cluster resources API call to include the
content types of a storage, and avoid dynamic loading of the content list in
the storage browser panel.
The third patch is a followup to one of Thomas's cleanups.
The fourth adds the prune window, based on the one from PBS.
Changes from v3:
* dropped already applied patches
* add new patches to avoid dynamic loading of content-dependend list in
storage browser panel
* don't use grouping headers for backups
Fabian Ebner (4):
cluster resources: include content type for storages
ui: storage: get content types from resources
ui: make remaining content views not stateful
ui: storage backup view: add prune window
PVE/API2/Cluster.pm | 6 +
PVE/API2Tools.pm | 4 +
www/manager6/Makefile | 1 +
www/manager6/storage/BackupView.js | 54 ++++-
www/manager6/storage/Browser.js | 144 ++++++-------
www/manager6/storage/TemplateView.js | 3 -
www/manager6/window/Prune.js | 300 +++++++++++++++++++++++++++
7 files changed, 430 insertions(+), 82 deletions(-)
create mode 100644 www/manager6/window/Prune.js
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH v4 manager 1/4] cluster resources: include content type for storages
2020-11-18 10:04 [pve-devel] [PATCH-SERIES v4 manager] split up content view/add prune window Fabian Ebner
@ 2020-11-18 10:04 ` Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 2/4] ui: storage: get content types from resources Fabian Ebner
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Fabian Ebner @ 2020-11-18 10:04 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
---
New in v4
PVE/API2/Cluster.pm | 6 ++++++
PVE/API2Tools.pm | 4 ++++
2 files changed, 10 insertions(+)
diff --git a/PVE/API2/Cluster.pm b/PVE/API2/Cluster.pm
index e768cbc6..8eb913b6 100644
--- a/PVE/API2/Cluster.pm
+++ b/PVE/API2/Cluster.pm
@@ -282,6 +282,12 @@ __PACKAGE__->register_method({
optional => 1,
renderer => 'bytes',
},
+ content => {
+ description => "Allowed storage content types (when type == storage).",
+ type => 'string',
+ format => 'pve-storage-content-list',
+ optional => 1,
+ },
},
},
},
diff --git a/PVE/API2Tools.pm b/PVE/API2Tools.pm
index b90c5488..3e2626ae 100644
--- a/PVE/API2Tools.pm
+++ b/PVE/API2Tools.pm
@@ -14,6 +14,7 @@ use Digest::MD5 qw(md5_hex);
use URI;
use URI::Escape;
use PVE::SafeSyslog;
+use PVE::Storage::Plugin;
my $hwaddress;
@@ -120,6 +121,8 @@ sub extract_vm_stats {
sub extract_storage_stats {
my ($storeid, $scfg, $node, $rrd) = @_;
+ my $content = PVE::Storage::Plugin::content_hash_to_string($scfg->{content});
+
my $entry = {
id => "storage/$node/$storeid",
storage => $storeid,
@@ -127,6 +130,7 @@ sub extract_storage_stats {
type => 'storage',
status => 'unknown',
shared => $scfg->{shared} || 0,
+ content => $content,
};
if (my $d = $rrd->{"pve2-storage/$node/$storeid"}) {
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH v4 manager 2/4] ui: storage: get content types from resources
2020-11-18 10:04 [pve-devel] [PATCH-SERIES v4 manager] split up content view/add prune window Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 1/4] cluster resources: include content type for storages Fabian Ebner
@ 2020-11-18 10:04 ` Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 3/4] ui: make remaining content views not stateful Fabian Ebner
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Fabian Ebner @ 2020-11-18 10:04 UTC (permalink / raw)
To: pve-devel
to avoid waiting for a status API call.
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
---
New in v4
Commit ed5d5403508a4713fd8a6c720ceaf11562352415 (introducing the insertNodes
function) could be reverted after this.
www/manager6/storage/Browser.js | 144 +++++++++++++++-----------------
1 file changed, 68 insertions(+), 76 deletions(-)
diff --git a/www/manager6/storage/Browser.js b/www/manager6/storage/Browser.js
index 81387111..64c492d8 100644
--- a/www/manager6/storage/Browser.js
+++ b/www/manager6/storage/Browser.js
@@ -38,89 +38,81 @@ Ext.define('PVE.storage.Browser', {
hstateid: 'storagetab'
});
- // call here, so there is a root for insertNodes()
- me.callParent();
-
if (caps.storage['Datastore.Allocate'] ||
caps.storage['Datastore.AllocateSpace'] ||
caps.storage['Datastore.Audit']) {
+ let storageInfo = PVE.data.ResourceStore.findRecord(
+ 'id',
+ `storage/${nodename}/${storeid}`,
+ );
+ let contents = storageInfo.data.content.split(',');
- Proxmox.Utils.API2Request({
- url: `/nodes/${nodename}/storage/${storeid}/status`,
- method: 'GET',
- success: function(response, opts) {
- var contents = response.result.data.content.split(',');
- var items = [];
-
- if (contents.includes('backup')) {
- items.push({
- xtype: 'pveStorageBackupView',
- title: gettext('Backups'),
- iconCls: 'fa fa-floppy-o',
- itemId: 'contentBackup',
- hasCommentColumn: true,
- });
- }
- if (contents.includes('images')) {
- items.push({
- xtype: 'pveStorageImageView',
- title: gettext('VM Disks'),
- iconCls: 'fa fa-hdd-o',
- itemId: 'contentImages',
- content: 'images',
- });
- }
- if (contents.includes('rootdir')) {
- items.push({
- xtype: 'pveStorageImageView',
- title: gettext('CT Volumes'),
- iconCls: 'fa fa-hdd-o lxc',
- itemId: 'contentRootdir',
- content: 'rootdir',
- });
- }
- if (contents.includes('iso')) {
- items.push({
- xtype: 'pveStorageContentView',
- title: gettext('ISO Images'),
- iconCls: 'pve-itype-treelist-item-icon-cdrom',
- itemId: 'contentIso',
- content: 'iso',
- useUploadButton: true,
- });
- }
- if (contents.includes('vztmpl')) {
- items.push({
- xtype: 'pveStorageTemplateView',
- title: gettext('CT Templates'),
- iconCls: 'fa fa-file-o lxc',
- itemId: 'contentVztmpl',
- });
- }
- if (contents.includes('snippets')) {
- items.push({
- xtype: 'pveStorageContentView',
- title: gettext('Snippets'),
- iconCls: 'fa fa-file-code-o',
- itemId: 'contentSnippets',
- content: 'snippets',
- });
- }
- me.insertNodes(items);
- },
- });
+ if (contents.includes('backup')) {
+ me.items.push({
+ xtype: 'pveStorageBackupView',
+ title: gettext('Backups'),
+ iconCls: 'fa fa-floppy-o',
+ itemId: 'contentBackup',
+ hasCommentColumn: true,
+ });
+ }
+ if (contents.includes('images')) {
+ me.items.push({
+ xtype: 'pveStorageImageView',
+ title: gettext('VM Disks'),
+ iconCls: 'fa fa-hdd-o',
+ itemId: 'contentImages',
+ content: 'images',
+ });
+ }
+ if (contents.includes('rootdir')) {
+ me.items.push({
+ xtype: 'pveStorageImageView',
+ title: gettext('CT Volumes'),
+ iconCls: 'fa fa-hdd-o lxc',
+ itemId: 'contentRootdir',
+ content: 'rootdir',
+ });
+ }
+ if (contents.includes('iso')) {
+ me.items.push({
+ xtype: 'pveStorageContentView',
+ title: gettext('ISO Images'),
+ iconCls: 'pve-itype-treelist-item-icon-cdrom',
+ itemId: 'contentIso',
+ content: 'iso',
+ useUploadButton: true,
+ });
+ }
+ if (contents.includes('vztmpl')) {
+ me.items.push({
+ xtype: 'pveStorageTemplateView',
+ title: gettext('CT Templates'),
+ iconCls: 'fa fa-file-o lxc',
+ itemId: 'contentVztmpl',
+ });
+ }
+ if (contents.includes('snippets')) {
+ me.items.push({
+ xtype: 'pveStorageContentView',
+ title: gettext('Snippets'),
+ iconCls: 'fa fa-file-code-o',
+ itemId: 'contentSnippets',
+ content: 'snippets',
+ });
+ }
}
if (caps.storage['Permissions.Modify']) {
- me.insertNodes([
- {
- xtype: 'pveACLView',
- title: gettext('Permissions'),
- iconCls: 'fa fa-unlock',
- itemId: 'permissions',
- path: '/storage/' + storeid
- },
- ]);
+ me.items.push({
+ xtype: 'pveACLView',
+ title: gettext('Permissions'),
+ iconCls: 'fa fa-unlock',
+ itemId: 'permissions',
+ path: '/storage/' + storeid
+ });
}
+
+ me.callParent();
}
});
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH v4 manager 3/4] ui: make remaining content views not stateful
2020-11-18 10:04 [pve-devel] [PATCH-SERIES v4 manager] split up content view/add prune window Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 1/4] cluster resources: include content type for storages Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 2/4] ui: storage: get content types from resources Fabian Ebner
@ 2020-11-18 10:04 ` Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 4/4] ui: storage backup view: add prune window Fabian Ebner
2020-11-23 6:09 ` [pve-devel] partially-applied: [PATCH-SERIES v4 manager] split up content view/add " Thomas Lamprecht
4 siblings, 0 replies; 7+ messages in thread
From: Fabian Ebner @ 2020-11-18 10:04 UTC (permalink / raw)
To: pve-devel
Commit c2b949f05bb8942b4827df4aeec91e10e09c1b2f removed the statefulness from
the other storage content views, so remove it from the remaining ones too.
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
---
New in v4
www/manager6/storage/BackupView.js | 3 ---
www/manager6/storage/TemplateView.js | 3 ---
2 files changed, 6 deletions(-)
diff --git a/www/manager6/storage/BackupView.js b/www/manager6/storage/BackupView.js
index 2669d2ca..8c1e2ed6 100644
--- a/www/manager6/storage/BackupView.js
+++ b/www/manager6/storage/BackupView.js
@@ -3,9 +3,6 @@ Ext.define('PVE.storage.BackupView', {
alias: 'widget.pveStorageBackupView',
- stateful: true,
- stateId: 'grid-storage-content-backup',
-
initComponent: function() {
var me = this;
diff --git a/www/manager6/storage/TemplateView.js b/www/manager6/storage/TemplateView.js
index 8500ca21..f7b5efe8 100644
--- a/www/manager6/storage/TemplateView.js
+++ b/www/manager6/storage/TemplateView.js
@@ -170,9 +170,6 @@ Ext.define('PVE.storage.TemplateView', {
alias: 'widget.pveStorageTemplateView',
- stateful: true,
- stateId: 'grid-storage-content-vztmpl',
-
initComponent: function() {
var me = this;
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH v4 manager 4/4] ui: storage backup view: add prune window
2020-11-18 10:04 [pve-devel] [PATCH-SERIES v4 manager] split up content view/add prune window Fabian Ebner
` (2 preceding siblings ...)
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 3/4] ui: make remaining content views not stateful Fabian Ebner
@ 2020-11-18 10:04 ` Fabian Ebner
2020-11-23 6:08 ` Thomas Lamprecht
2020-11-23 6:09 ` [pve-devel] partially-applied: [PATCH-SERIES v4 manager] split up content view/add " Thomas Lamprecht
4 siblings, 1 reply; 7+ messages in thread
From: Fabian Ebner @ 2020-11-18 10:04 UTC (permalink / raw)
To: pve-devel
adapted from PBS. Main differences are:
* loading of the prune-backups options from the storage configuration if
configured
* API has GET/DELETE distinction instead of 'dry-run'
* API expects a single property string for the prune options
Also, had to change the clear trigger, because now there can be original
values (from the storage config), but it doesn't really make sense to
reset to that value when clearing, so always set to 'null' when clearing
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
---
Changes from v3:
* don't use grouping headers with a prune button. Instead use a button in
the toolbar which displays the group to be pruned
* always use 'lxc' and 'qemu' as backup types (which the PVE API expects) instead
of 'VM' and 'CT' as types, to avoid some conversion
www/manager6/Makefile | 1 +
www/manager6/storage/BackupView.js | 51 +++++
www/manager6/window/Prune.js | 300 +++++++++++++++++++++++++++++
3 files changed, 352 insertions(+)
create mode 100644 www/manager6/window/Prune.js
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 4fa8e1a3..b95bd9a2 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -97,6 +97,7 @@ JSSRC= \
window/LoginWindow.js \
window/Migrate.js \
window/NotesEdit.js \
+ window/Prune.js \
window/Restore.js \
window/SafeDestroy.js \
window/Settings.js \
diff --git a/www/manager6/storage/BackupView.js b/www/manager6/storage/BackupView.js
index 8c1e2ed6..632a1d36 100644
--- a/www/manager6/storage/BackupView.js
+++ b/www/manager6/storage/BackupView.js
@@ -24,6 +24,56 @@ Ext.define('PVE.storage.BackupView', {
me.store.load();
};
+ let pruneButton = Ext.create('Proxmox.button.Button', {
+ text: gettext('Prune group'),
+ disabled: true,
+ selModel: sm,
+ setBackupGroup: function(backup) {
+ if (backup) {
+ let name = backup.text;
+ let vmid = backup.vmid;
+ let format = backup.format;
+
+ let vmtype;
+ if (name.startsWith('vzdump-lxc-') || format === "pbs-ct") {
+ vmtype = 'lxc';
+ } else if (name.startsWith('vzdump-qemu-') || format === "pbs-vm") {
+ vmtype = 'qemu';
+ }
+
+ if (vmid && vmtype) {
+ this.setText(gettext('Prune group') + ` ${vmtype}/${vmid}`);
+ this.vmid = vmid;
+ this.vmtype = vmtype;
+ this.setDisabled(false);
+ return;
+ }
+ }
+ this.setText(gettext('Prune group'));
+ this.vmid = null;
+ this.vmtype = null;
+ this.setDisabled(true);
+ },
+ handler: function(b, e, rec) {
+ let win = Ext.create('PVE.window.Prune', {
+ nodename: nodename,
+ storage: storage,
+ backup_id: this.vmid,
+ backup_type: this.vmtype,
+ });
+ win.show();
+ win.on('destroy', reload);
+ },
+ });
+
+ me.on('selectionchange', function(model, srecords, eOpts) {
+ if (srecords.length === 1) {
+ pruneButton.setBackupGroup(srecords[0].data);
+ } else {
+ pruneButton.setBackupGroup(null);
+ }
+ });
+
me.tbar = [
{
xtype: 'proxmoxButton',
@@ -64,6 +114,7 @@ Ext.define('PVE.storage.BackupView', {
win.show();
}
},
+ pruneButton,
];
me.callParent();
diff --git a/www/manager6/window/Prune.js b/www/manager6/window/Prune.js
new file mode 100644
index 00000000..6598d0f8
--- /dev/null
+++ b/www/manager6/window/Prune.js
@@ -0,0 +1,300 @@
+Ext.define('pve-prune-list', {
+ extend: 'Ext.data.Model',
+ fields: [
+ 'type',
+ 'vmid',
+ {
+ name: 'ctime',
+ type: 'date',
+ dateFormat: 'timestamp',
+ },
+ ],
+});
+
+Ext.define('PVE.PruneKeepInput', {
+ extend: 'Proxmox.form.field.Integer',
+ alias: 'widget.pvePruneKeepInput',
+
+ allowBlank: true,
+ minValue: 1,
+
+ listeners: {
+ change: function(field, newValue, oldValue) {
+ if (newValue === 0) { // might be configured in the storage options
+ this.setValue(null);
+ this.triggers.clear.setVisible(false);
+ } else {
+ this.triggers.clear.setVisible(newValue !== null);
+ }
+ },
+ },
+ triggers: {
+ clear: {
+ cls: 'pmx-clear-trigger',
+ weight: -1,
+ hidden: true,
+ handler: function() {
+ this.triggers.clear.setVisible(false);
+ this.setValue(null);
+ },
+ },
+ },
+});
+
+Ext.define('PVE.PruneInputPanel', {
+ extend: 'Proxmox.panel.InputPanel',
+ alias: 'widget.pvePruneInputPanel',
+ mixins: ['Proxmox.Mixin.CBind'],
+
+ onGetValues: function(values) {
+ let me = this;
+
+ // the API expects a single prune-backups property string
+ let pruneBackups = PVE.Parser.printPropertyString(values);
+ values = {
+ 'prune-backups': pruneBackups,
+ 'type': me.backup_type,
+ 'vmid': me.backup_id,
+ };
+
+ return values;
+ },
+
+ controller: {
+ xclass: 'Ext.app.ViewController',
+
+ init: function(view) {
+ if (!view.url) {
+ throw "no url specified";
+ }
+ if (!view.backup_type) {
+ throw "no backup_type specified";
+ }
+ if (!view.backup_id) {
+ throw "no backup_id specified";
+ }
+
+ this.reload(); // initial load
+ },
+
+ reload: function() {
+ let view = this.getView();
+
+ // helper to allow showing why a backup is kept
+ let addKeepReasons = function(backups, params) {
+ const rules = [
+ 'keep-last',
+ 'keep-hourly',
+ 'keep-daily',
+ 'keep-weekly',
+ 'keep-monthly',
+ 'keep-yearly',
+ 'keep-all', // when all keep options are not set
+ ];
+ let counter = {};
+
+ backups.sort(function(a, b) {
+ return a.ctime < b.ctime;
+ });
+
+ let ruleIndex = -1;
+ let nextRule = function() {
+ let rule;
+ do {
+ ruleIndex++;
+ rule = rules[ruleIndex];
+ } while (!params[rule] && rule !== 'keep-all');
+ counter[rule] = 0;
+ return rule;
+ };
+
+ let rule = nextRule();
+ for (let backup of backups) {
+ if (backup.mark === 'keep') {
+ counter[rule]++;
+ if (rule !== 'keep-all') {
+ backup.keepReason = rule + ': ' + counter[rule];
+ if (counter[rule] >= params[rule]) {
+ rule = nextRule();
+ }
+ } else {
+ backup.keepReason = rule;
+ }
+ }
+ }
+ };
+
+ let params = view.getValues();
+ let keepParams = PVE.Parser.parsePropertyString(params["prune-backups"]);
+
+ Proxmox.Utils.API2Request({
+ url: view.url,
+ method: "GET",
+ params: params,
+ callback: function() {
+ // for easy breakpoint setting
+ },
+ failure: function(response, opts) {
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+ },
+ success: function(response, options) {
+ var data = response.result.data;
+ addKeepReasons(data, keepParams);
+ view.pruneStore.setData(data);
+ },
+ });
+ },
+
+ control: {
+ field: { change: 'reload' },
+ },
+ },
+
+ column1: [
+ {
+ xtype: 'pvePruneKeepInput',
+ name: 'keep-last',
+ fieldLabel: gettext('keep-last'),
+ },
+ {
+ xtype: 'pvePruneKeepInput',
+ name: 'keep-hourly',
+ fieldLabel: gettext('keep-hourly'),
+ },
+ {
+ xtype: 'pvePruneKeepInput',
+ name: 'keep-daily',
+ fieldLabel: gettext('keep-daily'),
+ },
+ {
+ xtype: 'pvePruneKeepInput',
+ name: 'keep-weekly',
+ fieldLabel: gettext('keep-weekly'),
+ },
+ {
+ xtype: 'pvePruneKeepInput',
+ name: 'keep-monthly',
+ fieldLabel: gettext('keep-monthly'),
+ },
+ {
+ xtype: 'pvePruneKeepInput',
+ name: 'keep-yearly',
+ fieldLabel: gettext('keep-yearly'),
+ },
+ ],
+
+ initComponent: function() {
+ var me = this;
+
+ me.pruneStore = Ext.create('Ext.data.Store', {
+ model: 'pve-prune-list',
+ sorters: { property: 'ctime', direction: 'DESC' },
+ });
+
+ Proxmox.Utils.API2Request({
+ url: "/storage",
+ method: 'GET',
+ success: function(response, opts) {
+ let scfg = response.result.data.find(x => x.storage === me.storage);
+ if (!scfg || !scfg["prune-backups"]) {
+ return;
+ }
+ let prune_opts = PVE.Parser.parsePropertyString(scfg["prune-backups"]);
+ me.setValues(prune_opts);
+ },
+ });
+
+ me.column2 = [
+ {
+ xtype: 'grid',
+ height: 200,
+ store: me.pruneStore,
+ columns: [
+ {
+ header: gettext('Backup Time'),
+ sortable: true,
+ dataIndex: 'ctime',
+ renderer: function(value, metaData, record) {
+ let text = Ext.Date.format(value, 'Y-m-d H:i:s');
+ if (record.data.mark === 'remove') {
+ return '<div style="text-decoration: line-through;">'+ text +'</div>';
+ } else {
+ return text;
+ }
+ },
+ flex: 1,
+ },
+ {
+ text: 'Keep (reason)',
+ dataIndex: 'mark',
+ renderer: function(value, metaData, record) {
+ if (record.data.mark === 'keep') {
+ return 'true (' + record.data.keepReason + ')';
+ } else if (record.data.mark === 'protected') {
+ return 'true (strange name)';
+ } else {
+ return 'false';
+ }
+ },
+ flex: 1,
+ },
+ ],
+ },
+ ];
+
+ me.callParent();
+ },
+});
+
+Ext.define('PVE.window.Prune', {
+ extend: 'Proxmox.window.Edit',
+
+ method: 'DELETE',
+ submitText: gettext("Prune"),
+
+ fieldDefaults: { labelWidth: 130 },
+
+ isCreate: true,
+
+ initComponent: function() {
+ var me = this;
+
+ if (!me.nodename) {
+ throw "no nodename specified";
+ }
+ if (!me.storage) {
+ throw "no storage specified";
+ }
+ if (!me.backup_type) {
+ throw "no backup_type specified";
+ }
+ if (me.backup_type !== 'qemu' && me.backup_type !== 'lxc') {
+ throw "unknown backup type: " + me.backup_type;
+ }
+ if (!me.backup_id) {
+ throw "no backup_id specified";
+ }
+
+ let title = Ext.String.format(
+ gettext("Prune Backups for '{0}' on Storage '{1}'"),
+ me.backup_type + '/' + me.backup_id,
+ me.storage,
+ );
+
+ Ext.apply(me, {
+ url: '/api2/extjs/nodes/' + me.nodename + '/storage/' + me.storage + "/prunebackups",
+ title: title,
+ items: [
+ {
+ xtype: 'pvePruneInputPanel',
+ url: '/api2/extjs/nodes/' + me.nodename + '/storage/' + me.storage + "/prunebackups",
+ backup_type: me.backup_type,
+ backup_id: me.backup_id,
+ storage: me.storage,
+ },
+ ],
+ });
+
+ me.callParent();
+ },
+});
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pve-devel] [PATCH v4 manager 4/4] ui: storage backup view: add prune window
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 4/4] ui: storage backup view: add prune window Fabian Ebner
@ 2020-11-23 6:08 ` Thomas Lamprecht
0 siblings, 0 replies; 7+ messages in thread
From: Thomas Lamprecht @ 2020-11-23 6:08 UTC (permalink / raw)
To: Proxmox VE development discussion, Fabian Ebner
On 18.11.20 11:04, Fabian Ebner wrote:
> adapted from PBS. Main differences are:
> * loading of the prune-backups options from the storage configuration if
> configured
> * API has GET/DELETE distinction instead of 'dry-run'
> * API expects a single property string for the prune options
>
> Also, had to change the clear trigger, because now there can be original
> values (from the storage config), but it doesn't really make sense to
> reset to that value when clearing, so always set to 'null' when clearing
>
> Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
> ---
>
> Changes from v3:
> * don't use grouping headers with a prune button. Instead use a button in
> the toolbar which displays the group to be pruned
> * always use 'lxc' and 'qemu' as backup types (which the PVE API expects) instead
> of 'VM' and 'CT' as types, to avoid some conversion
>
I added the keep input field and a prune keep panel to proxmox-widget-toolkit,
so at least the input field should be reusable here.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] partially-applied: [PATCH-SERIES v4 manager] split up content view/add prune window
2020-11-18 10:04 [pve-devel] [PATCH-SERIES v4 manager] split up content view/add prune window Fabian Ebner
` (3 preceding siblings ...)
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 4/4] ui: storage backup view: add prune window Fabian Ebner
@ 2020-11-23 6:09 ` Thomas Lamprecht
4 siblings, 0 replies; 7+ messages in thread
From: Thomas Lamprecht @ 2020-11-23 6:09 UTC (permalink / raw)
To: Proxmox VE development discussion, Fabian Ebner
On 18.11.20 11:04, Fabian Ebner wrote:
> Follow-up to/finishing up the partially-applied series:
> https://lists.proxmox.com/pipermail/pve-devel/2020-November/045929.html
>
> The first two patches extend the cluster resources API call to include the
> content types of a storage, and avoid dynamic loading of the content list in
> the storage browser panel.
>
> The third patch is a followup to one of Thomas's cleanups.
>
> The fourth adds the prune window, based on the one from PBS.
>
> Changes from v3:
> * dropped already applied patches
> * add new patches to avoid dynamic loading of content-dependend list in
> storage browser panel
> * don't use grouping headers for backups
>
> Fabian Ebner (4):
> cluster resources: include content type for storages
> ui: storage: get content types from resources
> ui: make remaining content views not stateful
> ui: storage backup view: add prune window
>
> PVE/API2/Cluster.pm | 6 +
> PVE/API2Tools.pm | 4 +
> www/manager6/Makefile | 1 +
> www/manager6/storage/BackupView.js | 54 ++++-
> www/manager6/storage/Browser.js | 144 ++++++-------
> www/manager6/storage/TemplateView.js | 3 -
> www/manager6/window/Prune.js | 300 +++++++++++++++++++++++++++
> 7 files changed, 430 insertions(+), 82 deletions(-)
> create mode 100644 www/manager6/window/Prune.js
>
applied all but the fourth one for now, thanks!
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-11-23 6:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-18 10:04 [pve-devel] [PATCH-SERIES v4 manager] split up content view/add prune window Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 1/4] cluster resources: include content type for storages Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 2/4] ui: storage: get content types from resources Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 3/4] ui: make remaining content views not stateful Fabian Ebner
2020-11-18 10:04 ` [pve-devel] [PATCH v4 manager 4/4] ui: storage backup view: add prune window Fabian Ebner
2020-11-23 6:08 ` Thomas Lamprecht
2020-11-23 6:09 ` [pve-devel] partially-applied: [PATCH-SERIES v4 manager] split up content view/add " Thomas Lamprecht
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox