From: Lorenz Stechauner <l.stechauner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v5 manager 7/7] fix #1710: ui: storage: add download from url button
Date: Wed, 12 May 2021 10:22:40 +0200 [thread overview]
Message-ID: <20210512082240.36224-8-l.stechauner@proxmox.com> (raw)
In-Reply-To: <20210512082240.36224-1-l.stechauner@proxmox.com>
Signed-off-by: Lorenz Stechauner <l.stechauner@proxmox.com>
---
www/manager6/storage/Browser.js | 8 +
www/manager6/storage/ContentView.js | 282 +++++++++++++++++++++++++---
2 files changed, 265 insertions(+), 25 deletions(-)
diff --git a/www/manager6/storage/Browser.js b/www/manager6/storage/Browser.js
index 5fee94c7..c0d647d3 100644
--- a/www/manager6/storage/Browser.js
+++ b/www/manager6/storage/Browser.js
@@ -53,6 +53,9 @@ Ext.define('PVE.storage.Browser', {
let plugin = res.plugintype;
let contents = res.content.split(',');
+ let enableUpload = !!caps.storage['Datastore.AllocateTemplate'];
+ let enableDownloadUrl = !!(caps.nodes['Sys.Audit'] && caps.nodes['Sys.Modify']);
+
if (contents.includes('backup')) {
me.items.push({
xtype: 'pveStorageBackupView',
@@ -91,6 +94,8 @@ Ext.define('PVE.storage.Browser', {
itemId: 'contentIso',
content: 'iso',
pluginType: plugin,
+ enableUploadButton: enableUpload,
+ enableDownloadUrlButton: enableUpload && enableDownloadUrl,
useUploadButton: true,
});
}
@@ -101,6 +106,9 @@ Ext.define('PVE.storage.Browser', {
iconCls: 'fa fa-file-o lxc',
itemId: 'contentVztmpl',
pluginType: plugin,
+ enableUploadButton: enableUpload,
+ enableDownloadUrlButton: enableUpload && enableDownloadUrl,
+ useUploadButton: true,
});
}
if (contents.includes('snippets')) {
diff --git a/www/manager6/storage/ContentView.js b/www/manager6/storage/ContentView.js
index dd6df4b1..9125c0bb 100644
--- a/www/manager6/storage/ContentView.js
+++ b/www/manager6/storage/ContentView.js
@@ -191,6 +191,214 @@ Ext.define('PVE.storage.Upload', {
},
});
+Ext.define('PVE.storage.DownloadUrl', {
+ extend: 'Proxmox.window.Edit',
+ alias: 'widget.pveStorageDownloadUrl',
+
+ isCreate: true,
+
+ showTaskViewer: true,
+
+ title: gettext('Download from URL'),
+ submitText: gettext('Download'),
+
+ id: 'download-url',
+
+ controller: {
+ xclass: 'Ext.app.ViewController',
+
+ urlChange: function(field) {
+ let me = Ext.getCmp('download-url');
+ field = me.down('[name=url]');
+ field.setValidation("Waiting for response...");
+ field.validate();
+ me.setValues({size: ""});
+ Proxmox.Utils.API2Request({
+ url: `/nodes/${me.nodename}/query-url-metadata`,
+ method: 'GET',
+ params: {
+ url: field.getValue(),
+ 'verify-certificates': me.getValues()['verify-certificates'],
+ },
+ failure: function(res, opt) {
+ field.setValidation(res.result.message);
+ field.validate();
+ me.setValues({
+ size: "",
+ mimetype: "",
+ });
+ },
+ success: function(res, opt) {
+ field.setValidation();
+ field.validate();
+
+ let data = res.result.data;
+ me.setValues({
+ filename: data.filename || "",
+ size: data.size && Proxmox.Utils.format_size(data.size) || "",
+ mimetype: data.mimetype || "",
+ });
+ },
+ });
+ },
+
+ hashChange: function(field) {
+ let cecksum = Ext.getCmp('downloadUrlChecksum');
+ if (field.getValue() === '__default__') {
+ cecksum.setDisabled(true);
+ cecksum.setValue("");
+ cecksum.allowBlank = true;
+ } else {
+ cecksum.setDisabled(false);
+ cecksum.allowBlank = false;
+ }
+ },
+
+ typeChange: function(field) {
+ let me = Ext.getCmp('download-url');
+ let content = me.getValues()['content'];
+ let type = field.getValue();
+
+ const types = {
+ iso: [
+ 'application/octet-stream',
+ 'application/x-iso9660-image',
+ 'application/x-ima',
+ ],
+ vztmpl: [
+ 'application/octet-stream',
+ 'application/gzip',
+ 'application/tar',
+ 'application/tar+gzip',
+ 'application/x-gzip',
+ 'application/x-gtar',
+ 'application/x-tgz',
+ 'application/x-tar',
+ ],
+ };
+
+ if (type === "" || (types[content] && types[content].includes(type))) {
+ field.setValidation();
+ field.setDisabled(true);
+ } else {
+ field.setDisabled(false);
+ field.setValidation("Invalid type");
+ }
+ field.validate();
+ },
+ },
+
+ items: [
+ {
+ xtype: 'inputpanel',
+ waitMsgTarget: true,
+ border: false,
+ columnT: [
+ {
+ xtype: 'textfield',
+ name: 'url',
+ allowBlank: false,
+ fieldLabel: gettext('URL'),
+ listeners: {
+ change: {
+ buffer: 500,
+ fn: 'urlChange',
+ },
+ },
+ },
+ {
+ xtype: 'textfield',
+ name: 'filename',
+ allowBlank: false,
+ fieldLabel: gettext('File name'),
+ },
+ ],
+ column1: [
+ {
+ xtype: 'pveContentTypeSelector',
+ fieldLabel: gettext('Content'),
+ name: 'content',
+ allowBlank: false,
+ },
+ ],
+ column2: [
+ {
+ xtype: 'textfield',
+ name: 'size',
+ disabled: true,
+ fieldLabel: gettext('File size'),
+ emptyText: gettext('unknown'),
+ },
+ ],
+ advancedColumn1: [
+ {
+ xtype: 'textfield',
+ name: 'checksum',
+ fieldLabel: gettext('Checksum'),
+ allowBlank: true,
+ disabled: true,
+ emptyText: gettext('none'),
+ id: 'downloadUrlChecksum',
+ },
+ {
+ xtype: 'pveHashAlgorithmSelector',
+ name: 'checksum-algorithm',
+ fieldLabel: gettext('Hash algorithm'),
+ allowBlank: true,
+ hasNoneOption: true,
+ value: '__default__',
+ listeners: {
+ change: 'hashChange',
+ },
+ },
+ ],
+ advancedColumn2: [
+ {
+ xtype: 'textfield',
+ fieldLabel: gettext('MIME type'),
+ name: 'mimetype',
+ disabled: true,
+ editable: false,
+ emptyText: gettext('unknown'),
+ listeners: {
+ change: 'typeChange',
+ },
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ name: 'verify-certificates',
+ fieldLabel: gettext('Verify certificates'),
+ uncheckedValue: 0,
+ checked: true,
+ listeners: {
+ change: 'urlChange',
+ },
+ },
+ ],
+ },
+ ],
+
+ initComponent: function() {
+ var me = this;
+
+ if (!me.nodename) {
+ throw "no node name specified";
+ }
+ if (!me.storage) {
+ throw "no storage ID specified";
+ }
+
+ me.url = `/nodes/${me.nodename}/storage/${me.storage}/download-url`;
+ me.method = 'POST';
+
+ let contentTypeSel = me.items[0].column1[0];
+ contentTypeSel.cts = me.contents;
+ contentTypeSel.value = me.contents[0] || '';
+
+ me.callParent();
+ },
+});
+
Ext.define('PVE.storage.ContentView', {
extend: 'Ext.grid.GridPanel',
@@ -249,36 +457,60 @@ Ext.define('PVE.storage.ContentView', {
Proxmox.Utils.monStoreErrors(me, store);
- let uploadButton = Ext.create('Proxmox.button.Button', {
- text: gettext('Upload'),
- handler: function() {
- let win = Ext.create('PVE.storage.Upload', {
- nodename: nodename,
- storage: storage,
- contents: [content],
- });
- win.show();
- win.on('destroy', reload);
- },
- });
-
- let removeButton = Ext.create('Proxmox.button.StdRemoveButton', {
- selModel: sm,
- delay: 5,
- callback: function() {
- reload();
- },
- baseurl: baseurl + '/',
- });
-
if (!me.tbar) {
me.tbar = [];
}
if (me.useUploadButton) {
- me.tbar.push(uploadButton);
+ me.tbar.push(
+ {
+ xtype: 'button',
+ text: gettext('Upload'),
+ disabled: !me.enableUploadButton,
+ handler: function() {
+ Ext.create('PVE.storage.Upload', {
+ nodename: nodename,
+ storage: storage,
+ contents: [content],
+ autoShow: true,
+ listeners:{
+ destroy: () => reload(),
+ }
+ });
+ },
+ },
+ {
+ xtype: 'button',
+ text: gettext('Download from URL'),
+ disabled: !me.enableDownloadUrlButton,
+ handler: function() {
+ Ext.create('PVE.storage.DownloadUrl', {
+ nodename: nodename,
+ storage: storage,
+ contents: [content],
+ autoShow: true,
+ listeners: {
+ destroy: () => reload(),
+ },
+ });
+ },
+ },
+ '-',
+ );
}
- if (!me.useCustomRemoveButton) {
- me.tbar.push(removeButton);
+ if (me.useCustomRemoveButton) {
+ // custom remove button was inserted as first element
+ // -> place it at the end of tbar
+ me.tbar.push(me.tbar.shift());
+ } else {
+ me.tbar.push({
+ xtype: 'proxmoxStdRemoveButton',
+ selModel: sm,
+ delay: 5,
+ callback: function() {
+ reload();
+ },
+ baseurl: baseurl + '/',
+ });
}
me.tbar.push(
'->',
--
2.20.1
next prev parent reply other threads:[~2021-05-12 8:23 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-12 8:22 [pve-devel] [PATCH-SERIES v5 manager/common/storage] fix #1710: " Lorenz Stechauner
2021-05-12 8:22 ` [pve-devel] [PATCH v5 manager 1/7] api: nodes: add query_url_metadata method Lorenz Stechauner
2021-05-12 8:22 ` [pve-devel] [PATCH v5 common 2/7] tools: add download_file_from_url Lorenz Stechauner
2021-05-12 8:22 ` [pve-devel] [PATCH v5 manager 3/7] api: nodes: refactor aplinfo to use common download function Lorenz Stechauner
2021-05-12 8:22 ` [pve-devel] [PATCH v5 storage 4/7] status: add download_url method Lorenz Stechauner
2021-05-12 8:22 ` [pve-devel] [PATCH v5 manager 5/7] ui: add HashAlgorithmSelector Lorenz Stechauner
2021-05-12 8:22 ` [pve-devel] [PATCH v5 manager 6/7] ui: Utils: change download task format Lorenz Stechauner
2021-05-12 8:22 ` Lorenz Stechauner [this message]
2021-05-14 9:44 ` [pve-devel] [PATCH v5 manager 7/7] fix #1710: ui: storage: add download from url button Dominik Csapak
2021-05-14 9:23 ` [pve-devel] [PATCH-SERIES v5 manager/common/storage] fix #1710: " Dominik Csapak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210512082240.36224-8-l.stechauner@proxmox.com \
--to=l.stechauner@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox