Signed-off-by: Timo Grodzinski <t.grodzin...@profihost.ag> --- PVE/REST.pm | 2 +- www/manager/qemu/HardwareView.js | 189 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-)
diff --git a/PVE/REST.pm b/PVE/REST.pm index bf7ce15..f66d28e 100644 --- a/PVE/REST.pm +++ b/PVE/REST.pm @@ -98,7 +98,7 @@ sub auth_handler { $rpcenv->set_user($username); - if ($method eq 'POST' && $rel_uri =~ m|^/nodes/([^/]+)/storage/([^/]+)/upload$|) { + if ($method eq 'POST' && $rel_uri =~ m|^/nodes/([^/]+)/storage/([^/]+)/upload(?:_image)?$|) { my ($node, $storeid) = ($1, $2); # we disable CSRF checks if $isUpload is set, # to improve security we check user upload permission here diff --git a/www/manager/qemu/HardwareView.js b/www/manager/qemu/HardwareView.js index 89f2f4e..34a5dcc 100644 --- a/www/manager/qemu/HardwareView.js +++ b/www/manager/qemu/HardwareView.js @@ -298,6 +298,16 @@ Ext.define('PVE.qemu.HardwareView', { win.on('destroy', reload); }; + var run_upload = function() { + var win = Ext.create('PVE.storage.UploadImage', { + nodename: nodename, + vmid: vmid, + storage: "local" // XXX + }); + win.show(); + win.on('destroy', reload); + }; + var run_cpuoptions = function() { var sockets = me.getObjectValue('sockets', 1); var cores = me.getObjectValue('cores', 1); @@ -344,6 +354,10 @@ Ext.define('PVE.qemu.HardwareView', { disabled: true, handler: run_resize }); + var upload_btn = new PVE.button.Button({ + text: gettext('Upload disk'), + handler: run_upload + }); var move_btn = new PVE.button.Button({ text: gettext('Move disk'), @@ -510,6 +524,7 @@ Ext.define('PVE.qemu.HardwareView', { }, remove_btn, edit_btn, + upload_btn, resize_btn, move_btn, diskthrottle_btn, @@ -535,3 +550,177 @@ Ext.define('PVE.qemu.HardwareView', { }); } }); + +// XXX move to pve-manager/www/manager/qemu/HardwareView.js +// XXX borrowed from /home/tgrodzinski/devel/proxmox2/pve-manager/www/manager/storage/ContentView.js +// XXX 'PVE.storage.Upload' +Ext.define('PVE.storage.UploadImage', { + extend: 'Ext.window.Window', + alias: ['widget.pveStorageUploadImage'], + + resizable: false, + + modal: true, + + initComponent : function() { + /*jslint confusion: true */ + var me = this; + + var xhr; + + if (!me.nodename) { + throw "no node name specified"; + } + + if (!me.vmid) { + throw "no vm ID specified"; + } + + + if (!me.storage) { + throw "no storage ID specified"; + } + + var baseurl = "/nodes/" + me.nodename + "/storage/" + me.storage + "/upload_image"; + + var pbar = Ext.create('Ext.ProgressBar', { + text: 'Ready', + hidden: true + }); + + me.formPanel = Ext.create('Ext.form.Panel', { + method: 'POST', + waitMsgTarget: true, + bodyPadding: 10, + border: false, + width: 300, + fieldDefaults: { + labelWidth: 100, + anchor: '100%' + }, + items: [ + { // XXX erlaubte dateiendungen angeben + xtype: 'filefield', + name: 'filename', + buttonText: gettext('Select File...'), + allowBlank: false + }, + pbar + ] + }); + + var form = me.formPanel.getForm(); + + var doStandardSubmit = function() { + form.submit({ + url: "/api2/htmljs" + baseurl, + waitMsg: gettext('Uploading file...'), + success: function(f, action) { + me.close(); + }, + failure: function(f, action) { + var msg = PVE.Utils.extractFormActionError(action); + Ext.Msg.alert(gettext('Error'), msg); + } + }); + }; + + var updateProgress = function(per, bytes) { + var text = (per * 100).toFixed(2) + '%'; + if (bytes) { + text += " (" + PVE.Utils.format_size(bytes) + ')'; + } + pbar.updateProgress(per, text); + }; + + var abortBtn = Ext.create('Ext.Button', { + text: gettext('Abort'), + disabled: true, + handler: function() { + me.close(); + } + }); + + var submitBtn = Ext.create('Ext.Button', { + text: gettext('Upload'), + disabled: true, + handler: function(button) { + var fd; + try { + fd = new FormData(); + } catch (err) { + doStandardSubmit(); + return; + } + + button.setDisabled(true); + abortBtn.setDisabled(false); + + fd.append('content', 'images'); // XXX hard coded, see /PVE/API2/Storage/Status.pm + fd.append('vmid', me.vmid); + fd.append('format', 'qcow2'); // XXX hard coded + + field = form.findField('filename'); + var file = field.fileInputEl.dom; + fd.append("filename", file.files[0]); + field.setDisabled(true); + + pbar.setVisible(true); + updateProgress(0); + + xhr = new XMLHttpRequest(); + + xhr.addEventListener("load", function(e) { + if (xhr.status == 200) { + me.close(); + } else { + var msg = gettext('Error') + " " + xhr.status.toString() + ": " + Ext.htmlEncode(xhr.statusText); + var result = Ext.decode(xhr.responseText); + result.message = msg; + var htmlStatus = PVE.Utils.extractRequestError(result, true); + Ext.Msg.alert(gettext('Error'), htmlStatus, function(btn) { + me.close(); + }); + + } + }, false); + + xhr.addEventListener("error", function(e) { + var msg = "Error " + e.target.status.toString() + " occurred while receiving the document."; + Ext.Msg.alert(gettext('Error'), msg, function(btn) { + me.close(); + }); + }); + + xhr.upload.addEventListener("progress", function(evt) { + if (evt.lengthComputable) { + var percentComplete = evt.loaded / evt.total; + updateProgress(percentComplete, evt.loaded); + } + }, false); + + xhr.open("POST", "/api2/json" + baseurl, true); + xhr.send(fd); + } + }); + + form.on('validitychange', function(f, valid) { + submitBtn.setDisabled(!valid); + }); + + Ext.applyIf(me, { + title: gettext('Upload'), + items: me.formPanel, + buttons: [ abortBtn, submitBtn ], + listeners: { + close: function() { + if (xhr) { + xhr.abort(); + } + } + } + }); + + me.callParent(); + } +}); -- 2.1.4 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel