[pve-devel] [PATCH manager] WIP: upload disk image
Timo Grodzinski
t.grodzinski at profihost.ag
Fri Jan 29 18:38:15 CET 2016
Signed-off-by: Timo Grodzinski <t.grodzinski at 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
More information about the pve-devel
mailing list