[PATCH v4 0/5] [UI] CDROM Management in a VM

Allow user to manipulate CDROM(s) in a VM: 1) Attach one or more CDROM(s); 2) Replace a CDROM with another ISO file path; 3) Detach a CDROM from a VM. Tested on Chrome. Please apply the following patch first: * [UI] Window Widget Enhancement - Allow onClose Listener v3 -> v4: 4a) Re-organized UI layout based on Adam King's slides: * Promoted media management for VM as a separate action * Restricted to only CDROM replacement for a running VM 4b) Removed listeners to avoid duplicate functions v2 -> v3: 3a) Keep the edit window silver instead of white (Aline's comment) 3b) Added information after CDROM manipulations to avoid confusion (Aline & Adam King's comment) v1 -> v2: 2a) Separate one patch into 4 small ones to make it easier to review (Thanks to Ramon Medeiros's comment) 2b) Updated API calling to list CDROM (Thanks to Aline's comment) 2c) Separated VM updating window into 2 parts: general and storage (Thanks to Aline's comment) 2d) Enhanced UI to allow user trigger replace CDROM window by clicking ISO file path text box 2e) Changed uneditable fields from readonly to disabled 2f) Removed authors infomation (Thanks to Aline's comment) Hongliang Wang (5): [UI] kimchi.message - Enhancement [UI] Add CDROM-related APIs [UI] Add i18n Variables for CDROM-related Function [UI] Add/Edit CDROM Support [UI] Attach/Replace/Detach a CDROM to/in/from a VM ui/css/theme-default/guest-cdrom-edit.css | 62 +++++++++++ ui/css/theme-default/guest-edit.css | 144 ++++++++++++++++++++++--- ui/css/theme-default/guest-media.css | 42 ++++++++ ui/css/theme-default/guest-storage-add.css | 70 ++++++++++++ ui/images/theme-default/guest-icon-sprite.png | Bin 0 -> 6748 bytes ui/js/src/kimchi.api.js | 74 +++++++++++++ ui/js/src/kimchi.guest_cdrom_edit_main.js | 87 +++++++++++++++ ui/js/src/kimchi.guest_edit_main.js | 105 ++++++++++++++++-- ui/js/src/kimchi.guest_main.js | 20 +++- ui/js/src/kimchi.guest_media_main.js | 59 ++++++++++ ui/js/src/kimchi.guest_storage_add.main.js | 85 +++++++++++++++ ui/js/src/kimchi.message.js | 27 ++--- ui/pages/guest-cdrom-edit.html.tmpl | 73 +++++++++++++ ui/pages/guest-edit.html.tmpl | 150 ++++++++++++++++---------- ui/pages/guest-media.html.tmpl | 60 +++++++++++ ui/pages/guest-storage-add.html.tmpl | 80 ++++++++++++++ ui/pages/guest.html.tmpl | 1 + ui/pages/i18n.html.tmpl | 11 ++ 18 files changed, 1063 insertions(+), 87 deletions(-) create mode 100644 ui/css/theme-default/guest-cdrom-edit.css create mode 100644 ui/css/theme-default/guest-media.css create mode 100644 ui/css/theme-default/guest-storage-add.css create mode 100644 ui/images/theme-default/guest-icon-sprite.png create mode 100644 ui/js/src/kimchi.guest_cdrom_edit_main.js create mode 100644 ui/js/src/kimchi.guest_media_main.js create mode 100644 ui/js/src/kimchi.guest_storage_add.main.js create mode 100644 ui/pages/guest-cdrom-edit.html.tmpl create mode 100644 ui/pages/guest-media.html.tmpl create mode 100644 ui/pages/guest-storage-add.html.tmpl -- 1.8.1.4

Sometimes we want to show the message at a specific position, other than at the top of the browser. In this patch, we introduced a new parameter to the function with which we can place the message wherever we want. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.message.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ui/js/src/kimchi.message.js b/ui/js/src/kimchi.message.js index f997a73..35e3db9 100644 --- a/ui/js/src/kimchi.message.js +++ b/ui/js/src/kimchi.message.js @@ -15,16 +15,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -kimchi.message = function(msg, level) { - if ($('#messageField').size() < 1) { - $(document.body).append('<div id="messageField"></div>'); +kimchi.message = function(msg, level, node) { + var container = node || $('#messageField'); + if ($(container).size() < 1) { + container = $('<div id="messageField"/>').appendTo(document.body); } var message = '<div class="message ' + (level || '') + '" style="display: none;">'; - message += '<div class="close">X</div>'; + if(!node) { + message += '<div class="close">X</div>'; + } message += '<div class="content">' + msg + '</div>'; message += '</div>'; var $message = $(message); - $('#messageField').append($message); + $(container).append($message); $message.fadeIn(100); setTimeout(function() { @@ -33,7 +36,7 @@ kimchi.message = function(msg, level) { }); }, 4000); - $('#messageField').on("click", ".close", function(e) { + $(container).on("click", ".close", function(e) { $(this).parent().fadeOut(200, function() { $(this).remove(); }); @@ -98,16 +101,16 @@ kimchi.confirm = function(settings, confirmCallback, cancelCallback) { }); }; -kimchi.message.warn = function(msg) { - kimchi.message(msg, 'warn'); +kimchi.message.warn = function(msg, node) { + kimchi.message(msg, 'warn', node); }; -kimchi.message.error = function(msg) { - kimchi.message(msg, 'error'); +kimchi.message.error = function(msg, node) { + kimchi.message(msg, 'error', node); }; kimchi.message.error.code = function(code) { msg = code + ": " + i18n[code] kimchi.message(msg, 'error'); }; -kimchi.message.success = function(msg) { - kimchi.message(msg, 'success'); +kimchi.message.success = function(msg, node) { + kimchi.message(msg, 'success', node); }; -- 1.8.1.4

Reviewed-by: Aline Manera <alinefm@linux.vnet.ibm.com> On 03/10/2014 06:44 AM, Hongliang Wang wrote:
Sometimes we want to show the message at a specific position, other than at the top of the browser.
In this patch, we introduced a new parameter to the function with which we can place the message wherever we want.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.message.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/ui/js/src/kimchi.message.js b/ui/js/src/kimchi.message.js index f997a73..35e3db9 100644 --- a/ui/js/src/kimchi.message.js +++ b/ui/js/src/kimchi.message.js @@ -15,16 +15,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -kimchi.message = function(msg, level) { - if ($('#messageField').size() < 1) { - $(document.body).append('<div id="messageField"></div>'); +kimchi.message = function(msg, level, node) { + var container = node || $('#messageField'); + if ($(container).size() < 1) { + container = $('<div id="messageField"/>').appendTo(document.body); } var message = '<div class="message ' + (level || '') + '" style="display: none;">'; - message += '<div class="close">X</div>'; + if(!node) { + message += '<div class="close">X</div>'; + } message += '<div class="content">' + msg + '</div>'; message += '</div>'; var $message = $(message); - $('#messageField').append($message); + $(container).append($message); $message.fadeIn(100);
setTimeout(function() { @@ -33,7 +36,7 @@ kimchi.message = function(msg, level) { }); }, 4000);
- $('#messageField').on("click", ".close", function(e) { + $(container).on("click", ".close", function(e) { $(this).parent().fadeOut(200, function() { $(this).remove(); }); @@ -98,16 +101,16 @@ kimchi.confirm = function(settings, confirmCallback, cancelCallback) { }); };
-kimchi.message.warn = function(msg) { - kimchi.message(msg, 'warn'); +kimchi.message.warn = function(msg, node) { + kimchi.message(msg, 'warn', node); }; -kimchi.message.error = function(msg) { - kimchi.message(msg, 'error'); +kimchi.message.error = function(msg, node) { + kimchi.message(msg, 'error', node); }; kimchi.message.error.code = function(code) { msg = code + ": " + i18n[code] kimchi.message(msg, 'error'); }; -kimchi.message.success = function(msg) { - kimchi.message(msg, 'success'); +kimchi.message.success = function(msg, node) { + kimchi.message(msg, 'success', node); };

Add APIs for managing guest CDROM in kimchi.api.js. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index c93426f..3662a87 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -729,5 +729,79 @@ var kimchi = { success : suc, error : err }); + }, + + addVMStorage : function(settings, suc, err) { + var vm = encodeURIComponent(settings['vm']); + delete settings['vm']; + kimchi.requestJSON({ + url : kimchi.url + 'vms/' + vm + '/storages', + type : 'POST', + contentType : 'application/json', + data : JSON.stringify(settings), + dataType : 'json', + success : suc, + error : err + }); + }, + + retrieveVMStorage : function(settings, suc, err) { + var vm = encodeURIComponent(settings['vm']); + var dev = encodeURIComponent(settings['dev']); + kimchi.requestJSON({ + url : kimchi.url + "vms/" + vm + '/storages/' + dev, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + success: suc, + error: err + }); + }, + + replaceVMStorage : function(settings, suc, err) { + var vm = encodeURIComponent(settings['vm']); + var dev = encodeURIComponent(settings['dev']); + kimchi.requestJSON({ + url : kimchi.url + 'vms/' + vm + '/storages/' + dev, + type : 'PUT', + contentType : 'application/json', + data : JSON.stringify({ + path: settings['path'] + }), + dataType : 'json', + success : suc, + error : err + }); + }, + + deleteVMStorage : function(settings, suc, err) { + var vm = settings['vm']; + var dev = settings['dev']; + kimchi.requestJSON({ + url : kimchi.url + 'vms/' + encodeURIComponent(vm) + + '/storages/' + encodeURIComponent(dev), + type : 'DELETE', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + listVMStorages : function(params, suc, err) { + var vm = encodeURIComponent(params['vm']); + var type = params['storageType']; + var url = kimchi.url + 'vms/' + vm + '/storages'; + if(type) { + url += '?type=' + type; + } + kimchi.requestJSON({ + url : url, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); } }; -- 1.8.1.4

Reviewed-by: Aline Manera <alinefm@linux.vnet.ibm.com> On 03/10/2014 06:44 AM, Hongliang Wang wrote:
Add APIs for managing guest CDROM in kimchi.api.js.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index c93426f..3662a87 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -729,5 +729,79 @@ var kimchi = { success : suc, error : err }); + }, + + addVMStorage : function(settings, suc, err) { + var vm = encodeURIComponent(settings['vm']); + delete settings['vm']; + kimchi.requestJSON({ + url : kimchi.url + 'vms/' + vm + '/storages', + type : 'POST', + contentType : 'application/json', + data : JSON.stringify(settings), + dataType : 'json', + success : suc, + error : err + }); + }, + + retrieveVMStorage : function(settings, suc, err) { + var vm = encodeURIComponent(settings['vm']); + var dev = encodeURIComponent(settings['dev']); + kimchi.requestJSON({ + url : kimchi.url + "vms/" + vm + '/storages/' + dev, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + success: suc, + error: err + }); + }, + + replaceVMStorage : function(settings, suc, err) { + var vm = encodeURIComponent(settings['vm']); + var dev = encodeURIComponent(settings['dev']); + kimchi.requestJSON({ + url : kimchi.url + 'vms/' + vm + '/storages/' + dev, + type : 'PUT', + contentType : 'application/json', + data : JSON.stringify({ + path: settings['path'] + }), + dataType : 'json', + success : suc, + error : err + }); + }, + + deleteVMStorage : function(settings, suc, err) { + var vm = settings['vm']; + var dev = settings['dev']; + kimchi.requestJSON({ + url : kimchi.url + 'vms/' + encodeURIComponent(vm) + + '/storages/' + encodeURIComponent(dev), + type : 'DELETE', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + listVMStorages : function(params, suc, err) { + var vm = encodeURIComponent(params['vm']); + var type = params['storageType']; + var url = kimchi.url + 'vms/' + vm + '/storages'; + if(type) { + url += '?type=' + type; + } + kimchi.requestJSON({ + url : url, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); } };

Add i18n strings in i18n.html.tmpl. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/pages/i18n.html.tmpl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl index a7dddf4..b671af3 100644 --- a/ui/pages/i18n.html.tmpl +++ b/ui/pages/i18n.html.tmpl @@ -91,6 +91,17 @@ var i18n = { 'KCHVM6001M': "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")", + + 'KCHVMCD6001M': "$_("This CDROM will be detached permanently and you can re-attach it. Continue to detach it?")", + 'KCHVMCD6002M': "$_("Attach")", + 'KCHVMCD6003M': "$_("Attaching...")", + 'KCHVMCD6004M': "$_("Replace")", + 'KCHVMCD6005M': "$_("Replacing...")", + 'KCHVMCD6006M': "$_("Successfully attached!")", + 'KCHVMCD6007M': "$_("Successfully replaced!")", + 'KCHVMCD6008M': "$_("Successfully detached!")", + + 'KCHNET6001E': "$_("The VLAN id must be between 1 and 4094.")", 'KCHNET6001M': "$_("unavailable")", -- 1.8.1.4

Reviewed-by: Aline Manera <alinefm@linux.vnet.ibm.com> On 03/10/2014 06:44 AM, Hongliang Wang wrote:
Add i18n strings in i18n.html.tmpl.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/pages/i18n.html.tmpl | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl index a7dddf4..b671af3 100644 --- a/ui/pages/i18n.html.tmpl +++ b/ui/pages/i18n.html.tmpl @@ -91,6 +91,17 @@ var i18n = {
'KCHVM6001M': "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")",
+ + 'KCHVMCD6001M': "$_("This CDROM will be detached permanently and you can re-attach it. Continue to detach it?")", + 'KCHVMCD6002M': "$_("Attach")", + 'KCHVMCD6003M': "$_("Attaching...")", + 'KCHVMCD6004M': "$_("Replace")", + 'KCHVMCD6005M': "$_("Replacing...")", + 'KCHVMCD6006M': "$_("Successfully attached!")", + 'KCHVMCD6007M': "$_("Successfully replaced!")", + 'KCHVMCD6008M': "$_("Successfully detached!")", + + 'KCHNET6001E': "$_("The VLAN id must be between 1 and 4094.")",
'KCHNET6001M': "$_("unavailable")",

In this patch, we introduced 3 features: 1) Attach a CDROM to VM 2) Replace a CDROM in running VM 3) Replace a CDROM in stopped VM Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-cdrom-edit.css | 62 +++++++++++++++++++++ ui/css/theme-default/guest-media.css | 42 +++++++++++++++ ui/css/theme-default/guest-storage-add.css | 70 ++++++++++++++++++++++++ ui/js/src/kimchi.guest_cdrom_edit_main.js | 87 ++++++++++++++++++++++++++++++ ui/js/src/kimchi.guest_media_main.js | 59 ++++++++++++++++++++ ui/js/src/kimchi.guest_storage_add.main.js | 85 +++++++++++++++++++++++++++++ ui/pages/guest-cdrom-edit.html.tmpl | 73 +++++++++++++++++++++++++ ui/pages/guest-media.html.tmpl | 60 +++++++++++++++++++++ ui/pages/guest-storage-add.html.tmpl | 80 +++++++++++++++++++++++++++ 9 files changed, 618 insertions(+) create mode 100644 ui/css/theme-default/guest-cdrom-edit.css create mode 100644 ui/css/theme-default/guest-media.css create mode 100644 ui/css/theme-default/guest-storage-add.css create mode 100644 ui/js/src/kimchi.guest_cdrom_edit_main.js create mode 100644 ui/js/src/kimchi.guest_media_main.js create mode 100644 ui/js/src/kimchi.guest_storage_add.main.js create mode 100644 ui/pages/guest-cdrom-edit.html.tmpl create mode 100644 ui/pages/guest-media.html.tmpl create mode 100644 ui/pages/guest-storage-add.html.tmpl diff --git a/ui/css/theme-default/guest-cdrom-edit.css b/ui/css/theme-default/guest-cdrom-edit.css new file mode 100644 index 0000000..7008d73 --- /dev/null +++ b/ui/css/theme-default/guest-cdrom-edit.css @@ -0,0 +1,62 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#guest-cdrom-edit-window { + font-size: 13px; + height: 600px; + width: 700px; +} + +.guest-cdrom-edit-fieldset { + padding: 1em; +} + +#guest-cdrom-edit-window input[type="text"] { + font-size: 16px; + height: 38px; + background: #fff; + -webkit-border-radius: 5px; + border-radius: 5px; + box-shadow: 2px 2px 2px #eee inset; + border-top: 1px solid #bbb; + border-left: 1px solid #bbb; + padding-left: 10px; + width: 600px; +} + +#guest-cdrom-edit-window input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} + +#cdrom-error-message { + color: red; + padding: 5px; +} + +#vm-cdrom-button-edit[disabled] { + background: #c0c0c0; + color: #ddd; + padding-left: 26px; +} + +#vm-cdrom-button-edit.loading[disabled] { + background: url("../../images/theme-default/loading.gif") 7px center no-repeat #c0c0c0; + color: #ddd; + padding-left: 26px; +} diff --git a/ui/css/theme-default/guest-media.css b/ui/css/theme-default/guest-media.css new file mode 100644 index 0000000..3aee8ca --- /dev/null +++ b/ui/css/theme-default/guest-media.css @@ -0,0 +1,42 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#guest-media-window { + font-size: 14px; + height: 320px; + width: 570px; +} + +#form-guest-media { + padding: 1em; +} + +#guest-media-window .guest-media-fieldset { + padding-right: 0; +} + +#form-guest-media .guest-edit-wrapper-label { + width: 30px; +} + +#form-guest-media .guest-edit-wrapper-controls { + width: 480px; +} + +#form-guest-media .guest-edit-cdrom-row-container input[type="text"] { + width: 437px; +} diff --git a/ui/css/theme-default/guest-storage-add.css b/ui/css/theme-default/guest-storage-add.css new file mode 100644 index 0000000..c8c31a2 --- /dev/null +++ b/ui/css/theme-default/guest-storage-add.css @@ -0,0 +1,70 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#guest-storage-add-window { + font-size: 13px; + height: 600px; + width: 700px; +} + +.guest-storage-add-fieldset { + padding: 1em; +} + +#guest-storage-add-window .btn { + width: 587px; +} + +#form-guest-storage-add .form-section .field { + overflow: visible; +} + +#guest-storage-add-window input[type="text"] { + font-size: 16px; + height: 38px; + background: #fff; + -webkit-border-radius: 5px; + border-radius: 5px; + box-shadow: 2px 2px 2px #eee inset; + border-top: 1px solid #bbb; + border-left: 1px solid #bbb; + padding-left: 10px; + width: 600px; +} + +#guest-storage-add-window input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} + +#storage-error-message { + color: red; + padding: 5px; +} + +#vm-storage-button-add[disabled] { + background: #c0c0c0; + color: #ddd; + padding-left: 26px; +} + +#vm-storage-button-add.loading[disabled] { + background: url("../../images/theme-default/loading.gif") 7px center no-repeat #c0c0c0; + color: #ddd; + padding-left: 26px; +} diff --git a/ui/js/src/kimchi.guest_cdrom_edit_main.js b/ui/js/src/kimchi.guest_cdrom_edit_main.js new file mode 100644 index 0000000..45fc80c --- /dev/null +++ b/ui/js/src/kimchi.guest_cdrom_edit_main.js @@ -0,0 +1,87 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +kimchi.guest_cdrom_edit_main = function() { + var cdromEditForm = $('#form-vm-cdrom-edit'); + var submitButton = $('#vm-cdrom-button-edit'); + var nameTextbox = $('input[name="dev"]', cdromEditForm); + var typeTextbox = $('input[name="type"]', cdromEditForm); + var pathTextbox = $('input[name="path"]', cdromEditForm); + var errorMessage = $('#cdrom-error-message'); + var originalPath = null; + + kimchi.retrieveVMStorage({ + vm: kimchi.selectedGuest, + dev: kimchi.selectedGuestStorage + }, function(storage) { + for(var prop in storage) { + $('input[name="' + prop + '"]', cdromEditForm).val(storage[prop]); + } + + originalPath = storage['path']; + }); + + var submitForm = function(event) { + if(submitButton.prop('disabled')) { + return false; + } + + var path = pathTextbox.val(); + if(!path || path === '') { + return false; + } + + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', true); + }); + $(submitButton).addClass('loading').text(i18n['KCHVMCD6005M']); + $(errorMessage).text(''); + + var settings = { + vm: kimchi.selectedGuest, + dev: kimchi.selectedGuestStorage, + path: path + }; + + kimchi.replaceVMStorage(settings, function(result) { + kimchi.window.close(); + kimchi.topic('kimchi/vmCDROMReplaced').publish({ + result: result + }); + }, function(result) { + var errText = result['reason'] || + result['responseJSON']['reason']; + $(errorMessage).text(errText); + + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', false); + }); + $(submitButton).removeClass('loading').text(i18n['KCHVMCD6004M']); + }); + + event.preventDefault(); + }; + + cdromEditForm.on('submit', submitForm); + submitButton.on('click', submitForm); + pathTextbox.on('input propertychange', function(event) { + var invalid = + ($(this).val() === originalPath) || + ($(this).val() === ''); + $(submitButton).prop('disabled', invalid); + }); +}; diff --git a/ui/js/src/kimchi.guest_media_main.js b/ui/js/src/kimchi.guest_media_main.js new file mode 100644 index 0000000..1669646 --- /dev/null +++ b/ui/js/src/kimchi.guest_media_main.js @@ -0,0 +1,59 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +kimchi.guest_media_main = function() { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + }); + }; + + refreshCDROMs(); + + var messageNode = $('#message-container'); + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + + kimchi.clearGuestMedia = function() { + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + }; +}; diff --git a/ui/js/src/kimchi.guest_storage_add.main.js b/ui/js/src/kimchi.guest_storage_add.main.js new file mode 100644 index 0000000..7c96e3a --- /dev/null +++ b/ui/js/src/kimchi.guest_storage_add.main.js @@ -0,0 +1,85 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +kimchi.guest_storage_add_main = function() { + var types = [{ + label: 'cdrom', + value: 'cdrom' + }]; + kimchi.select('guest-storage-type-list', types); + + var storageAddForm = $('#form-guest-storage-add'); + var submitButton = $('#guest-storage-button-add'); + var nameTextbox = $('input[name="dev"]', storageAddForm); + var typeTextbox = $('input[name="type"]', storageAddForm); + var pathTextbox = $('input[name="path"]', storageAddForm); + var errorMessage = $('#storage-error-message'); + + var submitForm = function(event) { + if(submitButton.prop('disabled')) { + return false; + } + + var dev = nameTextbox.val(); + var type = typeTextbox.val(); + var path = pathTextbox.val(); + if(!path || path === '') { + return false; + } + + var formData = storageAddForm.serializeObject(); + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', true); + }); + $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']); + $(errorMessage).text(''); + + var settings = { + vm: kimchi.selectedGuest, + type: type, + path: path + }; + + if(dev && dev !== '') { + settings['dev'] = dev; + } + + kimchi.addVMStorage(settings, function(result) { + kimchi.window.close(); + kimchi.topic('kimchi/vmCDROMAttached').publish({ + result: result + }); + }, function(result) { + var errText = result['reason'] || + result['responseJSON']['reason']; + $(errorMessage).text(errText); + + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', false); + }); + $(submitButton).removeClass('loading').text(i18n['KCHVMCD6002M']); + }); + + event.preventDefault(); + }; + + storageAddForm.on('submit', submitForm); + submitButton.on('click', submitForm); + pathTextbox.on('input propertychange', function(event) { + $(submitButton).prop('disabled', $(this).val() === ''); + }); +}; diff --git a/ui/pages/guest-cdrom-edit.html.tmpl b/ui/pages/guest-cdrom-edit.html.tmpl new file mode 100644 index 0000000..9f07d9f --- /dev/null +++ b/ui/pages/guest-cdrom-edit.html.tmpl @@ -0,0 +1,73 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +<div id="guest-cdrom-edit-window" class="window"> + <header> + <h1 class="title">$_("Replace a CDROM of VM")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-vm-cdrom-edit"> + <section class="form-section"> + <h2>1. $_("Device Name")</h2> + <div class="field"> + <p class="text-help"> + $_("The name used to identify the CDROM. Read-only.") + </p> + <input type="text" class="text" name="dev" disabled="disabled" /> + </div> + </section> + <section class="form-section"> + <h2>2. $_("Device Type")</h2> + <div class="field"> + <p class="text-help"> + $_("The device type. Currently, only \"cdrom\" is supported.") + </p> + <input type="text" class="text" name="type" value="cdrom" disabled="disabled" /> + </div> + </section> + <section class="form-section"> + <h2>3. $_("ISO File Path")</h2> + <div class="field"> + <p class="text-help"> + $_("The ISO file path in the server.") + </p> + <input type="text" class="text" name="path" /> + </div> + </section> + <section class="form-section"> + <div id="cdrom-error-message"></div> + </section> + </form> + </div> + <footer> + <div class="btn-group"> + <button id="vm-cdrom-button-edit" class="btn-normal" disabled="disabled"> + <span class="text">$_("Replace")</span> + </button> + </div> + </footer> +</div> +<script type="text/javascript"> + kimchi.guest_cdrom_edit_main(); +</script> diff --git a/ui/pages/guest-media.html.tmpl b/ui/pages/guest-media.html.tmpl new file mode 100644 index 0000000..eb12d72 --- /dev/null +++ b/ui/pages/guest-media.html.tmpl @@ -0,0 +1,60 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext + +<div id="guest-media-window" class="window"> + <header> + <h1 class="title">$_("Manage Media")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-guest-media"> + <fieldset + id="guest-edit-cdrom-row-container" + class="guest-edit-fieldset guest-edit-cdrom-row-container"> + </fieldset> + </form> + </div> + <footer> + <div id="message-container"></div> + </footer> +</div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + </div> + </div> +</script> + +<script type="text/javascript"> + kimchi.guest_media_main(); +</script> diff --git a/ui/pages/guest-storage-add.html.tmpl b/ui/pages/guest-storage-add.html.tmpl new file mode 100644 index 0000000..c190d0e --- /dev/null +++ b/ui/pages/guest-storage-add.html.tmpl @@ -0,0 +1,80 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +<div id="guest-storage-add-window" class="window"> + <header> + <h1 class="title">$_("Add a Storage Device to VM")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-guest-storage-add"> + <section class="form-section"> + <h2>1. $_("Device Name")</h2> + <div class="field"> + <p class="text-help"> + $_("The name used to identify the device. If omitted, a name will be chosen automatically.") + </p> + <input type="text" class="text" name="dev" /> + </div> + </section> + <section class="form-section"> + <h2>2. $_("Device Type")</h2> + <div class="field"> + <p class="text-help"> + $_("The device type. Currently, only \"cdrom\" is supported.") + </p> + <div class="btn dropdown popable"> + <input id="guest-storage-type" name="type" value="cdrom" type="hidden" /> + <span class="text" id="guest-storage-type-label"></span> + <span class="arrow"></span> + <div class="popover"> + <ul class="select-list" id="guest-storage-type-list" data-target="guest-storage-type" data-label="guest-storage-type-label"></ul> + </div> + </div> + </div> + </section> + <section class="form-section"> + <h2>3. $_("File Path")</h2> + <div class="field"> + <p class="text-help"> + $_("The ISO file path in the server for CDROM.") + </p> + <input type="text" class="text" name="path" /> + </div> + </section> + <section class="form-section"> + <div id="storage-error-message"></div> + </section> + </form> + </div> + <footer> + <div class="btn-group"> + <button id="guest-storage-button-add" class="btn-normal" disabled="disabled"> + <span class="text">$_("Attach")</span> + </button> + </div> + </footer> +</div> +<script type="text/javascript"> + kimchi.guest_storage_add_main(); +</script> -- 1.8.1.4

Reviewed-by: Aline Manera <alinefm@linux.vnet.ibm.com> On 03/10/2014 06:44 AM, Hongliang Wang wrote:
In this patch, we introduced 3 features: 1) Attach a CDROM to VM 2) Replace a CDROM in running VM 3) Replace a CDROM in stopped VM
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-cdrom-edit.css | 62 +++++++++++++++++++++ ui/css/theme-default/guest-media.css | 42 +++++++++++++++ ui/css/theme-default/guest-storage-add.css | 70 ++++++++++++++++++++++++ ui/js/src/kimchi.guest_cdrom_edit_main.js | 87 ++++++++++++++++++++++++++++++ ui/js/src/kimchi.guest_media_main.js | 59 ++++++++++++++++++++ ui/js/src/kimchi.guest_storage_add.main.js | 85 +++++++++++++++++++++++++++++ ui/pages/guest-cdrom-edit.html.tmpl | 73 +++++++++++++++++++++++++ ui/pages/guest-media.html.tmpl | 60 +++++++++++++++++++++ ui/pages/guest-storage-add.html.tmpl | 80 +++++++++++++++++++++++++++ 9 files changed, 618 insertions(+) create mode 100644 ui/css/theme-default/guest-cdrom-edit.css create mode 100644 ui/css/theme-default/guest-media.css create mode 100644 ui/css/theme-default/guest-storage-add.css create mode 100644 ui/js/src/kimchi.guest_cdrom_edit_main.js create mode 100644 ui/js/src/kimchi.guest_media_main.js create mode 100644 ui/js/src/kimchi.guest_storage_add.main.js create mode 100644 ui/pages/guest-cdrom-edit.html.tmpl create mode 100644 ui/pages/guest-media.html.tmpl create mode 100644 ui/pages/guest-storage-add.html.tmpl
diff --git a/ui/css/theme-default/guest-cdrom-edit.css b/ui/css/theme-default/guest-cdrom-edit.css new file mode 100644 index 0000000..7008d73 --- /dev/null +++ b/ui/css/theme-default/guest-cdrom-edit.css @@ -0,0 +1,62 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#guest-cdrom-edit-window { + font-size: 13px; + height: 600px; + width: 700px; +} + +.guest-cdrom-edit-fieldset { + padding: 1em; +} + +#guest-cdrom-edit-window input[type="text"] { + font-size: 16px; + height: 38px; + background: #fff; + -webkit-border-radius: 5px; + border-radius: 5px; + box-shadow: 2px 2px 2px #eee inset; + border-top: 1px solid #bbb; + border-left: 1px solid #bbb; + padding-left: 10px; + width: 600px; +} + +#guest-cdrom-edit-window input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} + +#cdrom-error-message { + color: red; + padding: 5px; +} + +#vm-cdrom-button-edit[disabled] { + background: #c0c0c0; + color: #ddd; + padding-left: 26px; +} + +#vm-cdrom-button-edit.loading[disabled] { + background: url("../../images/theme-default/loading.gif") 7px center no-repeat #c0c0c0; + color: #ddd; + padding-left: 26px; +} diff --git a/ui/css/theme-default/guest-media.css b/ui/css/theme-default/guest-media.css new file mode 100644 index 0000000..3aee8ca --- /dev/null +++ b/ui/css/theme-default/guest-media.css @@ -0,0 +1,42 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#guest-media-window { + font-size: 14px; + height: 320px; + width: 570px; +} + +#form-guest-media { + padding: 1em; +} + +#guest-media-window .guest-media-fieldset { + padding-right: 0; +} + +#form-guest-media .guest-edit-wrapper-label { + width: 30px; +} + +#form-guest-media .guest-edit-wrapper-controls { + width: 480px; +} + +#form-guest-media .guest-edit-cdrom-row-container input[type="text"] { + width: 437px; +} diff --git a/ui/css/theme-default/guest-storage-add.css b/ui/css/theme-default/guest-storage-add.css new file mode 100644 index 0000000..c8c31a2 --- /dev/null +++ b/ui/css/theme-default/guest-storage-add.css @@ -0,0 +1,70 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#guest-storage-add-window { + font-size: 13px; + height: 600px; + width: 700px; +} + +.guest-storage-add-fieldset { + padding: 1em; +} + +#guest-storage-add-window .btn { + width: 587px; +} + +#form-guest-storage-add .form-section .field { + overflow: visible; +} + +#guest-storage-add-window input[type="text"] { + font-size: 16px; + height: 38px; + background: #fff; + -webkit-border-radius: 5px; + border-radius: 5px; + box-shadow: 2px 2px 2px #eee inset; + border-top: 1px solid #bbb; + border-left: 1px solid #bbb; + padding-left: 10px; + width: 600px; +} + +#guest-storage-add-window input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} + +#storage-error-message { + color: red; + padding: 5px; +} + +#vm-storage-button-add[disabled] { + background: #c0c0c0; + color: #ddd; + padding-left: 26px; +} + +#vm-storage-button-add.loading[disabled] { + background: url("../../images/theme-default/loading.gif") 7px center no-repeat #c0c0c0; + color: #ddd; + padding-left: 26px; +} diff --git a/ui/js/src/kimchi.guest_cdrom_edit_main.js b/ui/js/src/kimchi.guest_cdrom_edit_main.js new file mode 100644 index 0000000..45fc80c --- /dev/null +++ b/ui/js/src/kimchi.guest_cdrom_edit_main.js @@ -0,0 +1,87 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +kimchi.guest_cdrom_edit_main = function() { + var cdromEditForm = $('#form-vm-cdrom-edit'); + var submitButton = $('#vm-cdrom-button-edit'); + var nameTextbox = $('input[name="dev"]', cdromEditForm); + var typeTextbox = $('input[name="type"]', cdromEditForm); + var pathTextbox = $('input[name="path"]', cdromEditForm); + var errorMessage = $('#cdrom-error-message'); + var originalPath = null; + + kimchi.retrieveVMStorage({ + vm: kimchi.selectedGuest, + dev: kimchi.selectedGuestStorage + }, function(storage) { + for(var prop in storage) { + $('input[name="' + prop + '"]', cdromEditForm).val(storage[prop]); + } + + originalPath = storage['path']; + }); + + var submitForm = function(event) { + if(submitButton.prop('disabled')) { + return false; + } + + var path = pathTextbox.val(); + if(!path || path === '') { + return false; + } + + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', true); + }); + $(submitButton).addClass('loading').text(i18n['KCHVMCD6005M']); + $(errorMessage).text(''); + + var settings = { + vm: kimchi.selectedGuest, + dev: kimchi.selectedGuestStorage, + path: path + }; + + kimchi.replaceVMStorage(settings, function(result) { + kimchi.window.close(); + kimchi.topic('kimchi/vmCDROMReplaced').publish({ + result: result + }); + }, function(result) { + var errText = result['reason'] || + result['responseJSON']['reason']; + $(errorMessage).text(errText); + + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', false); + }); + $(submitButton).removeClass('loading').text(i18n['KCHVMCD6004M']); + }); + + event.preventDefault(); + }; + + cdromEditForm.on('submit', submitForm); + submitButton.on('click', submitForm); + pathTextbox.on('input propertychange', function(event) { + var invalid = + ($(this).val() === originalPath) || + ($(this).val() === ''); + $(submitButton).prop('disabled', invalid); + }); +}; diff --git a/ui/js/src/kimchi.guest_media_main.js b/ui/js/src/kimchi.guest_media_main.js new file mode 100644 index 0000000..1669646 --- /dev/null +++ b/ui/js/src/kimchi.guest_media_main.js @@ -0,0 +1,59 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +kimchi.guest_media_main = function() { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + }); + }; + + refreshCDROMs(); + + var messageNode = $('#message-container'); + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + + kimchi.clearGuestMedia = function() { + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + }; +}; diff --git a/ui/js/src/kimchi.guest_storage_add.main.js b/ui/js/src/kimchi.guest_storage_add.main.js new file mode 100644 index 0000000..7c96e3a --- /dev/null +++ b/ui/js/src/kimchi.guest_storage_add.main.js @@ -0,0 +1,85 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +kimchi.guest_storage_add_main = function() { + var types = [{ + label: 'cdrom', + value: 'cdrom' + }]; + kimchi.select('guest-storage-type-list', types); + + var storageAddForm = $('#form-guest-storage-add'); + var submitButton = $('#guest-storage-button-add'); + var nameTextbox = $('input[name="dev"]', storageAddForm); + var typeTextbox = $('input[name="type"]', storageAddForm); + var pathTextbox = $('input[name="path"]', storageAddForm); + var errorMessage = $('#storage-error-message'); + + var submitForm = function(event) { + if(submitButton.prop('disabled')) { + return false; + } + + var dev = nameTextbox.val(); + var type = typeTextbox.val(); + var path = pathTextbox.val(); + if(!path || path === '') { + return false; + } + + var formData = storageAddForm.serializeObject(); + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', true); + }); + $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']); + $(errorMessage).text(''); + + var settings = { + vm: kimchi.selectedGuest, + type: type, + path: path + }; + + if(dev && dev !== '') { + settings['dev'] = dev; + } + + kimchi.addVMStorage(settings, function(result) { + kimchi.window.close(); + kimchi.topic('kimchi/vmCDROMAttached').publish({ + result: result + }); + }, function(result) { + var errText = result['reason'] || + result['responseJSON']['reason']; + $(errorMessage).text(errText); + + $.each([submitButton, nameTextbox, pathTextbox], function(i, c) { + $(c).prop('disabled', false); + }); + $(submitButton).removeClass('loading').text(i18n['KCHVMCD6002M']); + }); + + event.preventDefault(); + }; + + storageAddForm.on('submit', submitForm); + submitButton.on('click', submitForm); + pathTextbox.on('input propertychange', function(event) { + $(submitButton).prop('disabled', $(this).val() === ''); + }); +}; diff --git a/ui/pages/guest-cdrom-edit.html.tmpl b/ui/pages/guest-cdrom-edit.html.tmpl new file mode 100644 index 0000000..9f07d9f --- /dev/null +++ b/ui/pages/guest-cdrom-edit.html.tmpl @@ -0,0 +1,73 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +<div id="guest-cdrom-edit-window" class="window"> + <header> + <h1 class="title">$_("Replace a CDROM of VM")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-vm-cdrom-edit"> + <section class="form-section"> + <h2>1. $_("Device Name")</h2> + <div class="field"> + <p class="text-help"> + $_("The name used to identify the CDROM. Read-only.") + </p> + <input type="text" class="text" name="dev" disabled="disabled" /> + </div> + </section> + <section class="form-section"> + <h2>2. $_("Device Type")</h2> + <div class="field"> + <p class="text-help"> + $_("The device type. Currently, only \"cdrom\" is supported.") + </p> + <input type="text" class="text" name="type" value="cdrom" disabled="disabled" /> + </div> + </section> + <section class="form-section"> + <h2>3. $_("ISO File Path")</h2> + <div class="field"> + <p class="text-help"> + $_("The ISO file path in the server.") + </p> + <input type="text" class="text" name="path" /> + </div> + </section> + <section class="form-section"> + <div id="cdrom-error-message"></div> + </section> + </form> + </div> + <footer> + <div class="btn-group"> + <button id="vm-cdrom-button-edit" class="btn-normal" disabled="disabled"> + <span class="text">$_("Replace")</span> + </button> + </div> + </footer> +</div> +<script type="text/javascript"> + kimchi.guest_cdrom_edit_main(); +</script> diff --git a/ui/pages/guest-media.html.tmpl b/ui/pages/guest-media.html.tmpl new file mode 100644 index 0000000..eb12d72 --- /dev/null +++ b/ui/pages/guest-media.html.tmpl @@ -0,0 +1,60 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext + +<div id="guest-media-window" class="window"> + <header> + <h1 class="title">$_("Manage Media")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-guest-media"> + <fieldset + id="guest-edit-cdrom-row-container" + class="guest-edit-fieldset guest-edit-cdrom-row-container"> + </fieldset> + </form> + </div> + <footer> + <div id="message-container"></div> + </footer> +</div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + </div> + </div> +</script> + +<script type="text/javascript"> + kimchi.guest_media_main(); +</script> diff --git a/ui/pages/guest-storage-add.html.tmpl b/ui/pages/guest-storage-add.html.tmpl new file mode 100644 index 0000000..c190d0e --- /dev/null +++ b/ui/pages/guest-storage-add.html.tmpl @@ -0,0 +1,80 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +<div id="guest-storage-add-window" class="window"> + <header> + <h1 class="title">$_("Add a Storage Device to VM")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-guest-storage-add"> + <section class="form-section"> + <h2>1. $_("Device Name")</h2> + <div class="field"> + <p class="text-help"> + $_("The name used to identify the device. If omitted, a name will be chosen automatically.") + </p> + <input type="text" class="text" name="dev" /> + </div> + </section> + <section class="form-section"> + <h2>2. $_("Device Type")</h2> + <div class="field"> + <p class="text-help"> + $_("The device type. Currently, only \"cdrom\" is supported.") + </p> + <div class="btn dropdown popable"> + <input id="guest-storage-type" name="type" value="cdrom" type="hidden" /> + <span class="text" id="guest-storage-type-label"></span> + <span class="arrow"></span> + <div class="popover"> + <ul class="select-list" id="guest-storage-type-list" data-target="guest-storage-type" data-label="guest-storage-type-label"></ul> + </div> + </div> + </div> + </section> + <section class="form-section"> + <h2>3. $_("File Path")</h2> + <div class="field"> + <p class="text-help"> + $_("The ISO file path in the server for CDROM.") + </p> + <input type="text" class="text" name="path" /> + </div> + </section> + <section class="form-section"> + <div id="storage-error-message"></div> + </section> + </form> + </div> + <footer> + <div class="btn-group"> + <button id="guest-storage-button-add" class="btn-normal" disabled="disabled"> + <span class="text">$_("Attach")</span> + </button> + </div> + </footer> +</div> +<script type="text/javascript"> + kimchi.guest_storage_add_main(); +</script>

Allow user to manipulate CDROM(s) in a VM: 1) Attach one or more CDROM(s) (only for stopped VM); 2) Replace a CDROM with another ISO file path; 3) Detach a CDROM from a VM (only for stopped VM). Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 144 ++++++++++++++++++++++--- ui/images/theme-default/guest-icon-sprite.png | Bin 0 -> 6748 bytes ui/js/src/kimchi.guest_edit_main.js | 105 ++++++++++++++++-- ui/js/src/kimchi.guest_main.js | 20 +++- ui/pages/guest-edit.html.tmpl | 150 ++++++++++++++++---------- ui/pages/guest.html.tmpl | 1 + 6 files changed, 345 insertions(+), 75 deletions(-) create mode 100644 ui/images/theme-default/guest-icon-sprite.png diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index f4ccdee..43f71c0 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -17,36 +17,53 @@ */ #guest-edit-window { font-size: 13px; - height: 380px; - width: 420px; + height: 400px; + width: 600px; } -.guest-edit-fieldset { - float: left; +#guest-edit-tabs { + background: transparent; + border: none; + height: 100%; + padding: 0; +} + +#form-guest-edit-general, +#form-guest-edit-storage { padding: 1em; } +.guest-edit-fieldset { + padding-right: 0; +} + .guest-edit-wrapper-label, .guest-edit-wrapper-controls { display: inline-block; } -.guest-edit-wrapper-controls input[type="text"][disabled] { - color: #bbb; - background-color: #fafafa; - cursor: not-allowed; +.guest-edit-wrapper-label { + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; + width: 80px; } -.guest-edit-wrapper-label { - width: 10em; +#form-guest-edit-storage .guest-edit-wrapper-label { + width: 60px; } .guest-edit-wrapper-controls { - width: 18em; + width: 470px; +} + +#form-guest-edit-storage .guest-edit-wrapper-controls { + width: 486px; } .guest-edit-wrapper-controls input[type="text"] { + font-size: 16px; height: 38px; - line-height: 38px; background: #fff; -webkit-border-radius: 5px; border-radius: 5px; @@ -54,7 +71,7 @@ border-top: 1px solid #bbb; border-left: 1px solid #bbb; padding-left: 10px; - width: 100%; + width: 450px; } .guest-edit-wrapper-controls input[type="text"][disabled] { @@ -62,3 +79,104 @@ background-color: #fafafa; cursor: not-allowed; } + +.guest-edit-cdrom-row-container { + max-height: 180px; + overflow: auto; +} + +.guest-edit-cdrom-row-container input[type="text"] { + width: 400px; +} + +.guest-edit-cdrom-button { + background: url("../images/theme-default/guest-icon-sprite.png") no-repeat left top transparent; + border: none; + height: 25px; + vertical-align: middle; + width: 25px; +} + +.guest-edit-cdrom-button.attach { + margin: 15px 0 0 521px; +} + +.guest-edit-cdrom-button.attach:hover { + background-position: 0 -27px; +} + +.guest-edit-cdrom-button.attach:focus { + background-position: 0 -54px; +} + +.guest-edit-cdrom-button.attach:active { + background-position: 0 -81px; +} + +.guest-edit-cdrom-button.attach[disabled] { + background-position: 0 -108px; +} + +.guest-edit-cdrom-button.replace { + background-position: -27px 0; +} + +.guest-edit-cdrom-button.replace:hover { + background-position: -27px -27px; +} + +.guest-edit-cdrom-button.replace:focus { + background-position: -27px -54px; +} + +.guest-edit-cdrom-button.replace:active { + background-position: -27px -81px; +} + +.guest-edit-cdrom-button.replace[disabled] { + background-position: -27px -108px; +} + +.guest-edit-cdrom-button.detach { + background-position: -54px 0; +} + +.guest-edit-cdrom-button.detach:hover { + background-position: -54px -27px; +} + +.guest-edit-cdrom-button.detach:focus { + background-position: -54px -54px; +} + +.guest-edit-cdrom-button.detach:active { + background-position: -54px -81px; +} + +.guest-edit-cdrom-button.detach[disabled] { + background-position: -54px -108px; +} + +#message-container { + color: #555; + font-size: 14px; + height: 100%; + line-height: 56px; +} + +#message-container .message { + background: transparent; +} + +#message-container .success { + color: green; +} + +#message-container .error { + color: red; +} + +#message-container .content { + margin: 0; + position: static; +} diff --git a/ui/images/theme-default/guest-icon-sprite.png b/ui/images/theme-default/guest-icon-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..81edb5945d3bd204313a6d53b55cecf17ee97679 GIT binary patch literal 6748 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 Bz#9Mn literal 0 HcmV?d00001 diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index f32fbb1..cdd6d49 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -16,18 +16,110 @@ * limitations under the License. */ kimchi.guest_edit_main = function() { - var guestEditForm = $('#form-guest-edit'); + var buttonContainer = $('#action-button-container'); + $('#guest-edit-tabs').tabs({ + beforeActivate: function(event, ui) { + var deactivated = ui['oldPanel']; + if($(deactivated).attr('id') === 'form-guest-edit-general') { + $(buttonContainer).addClass('hidden'); + } + else { + $(buttonContainer).removeClass('hidden'); + } + } + }); + + var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); - kimchi.retrieveVM(kimchi.selectedGuest, function(guest) { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + + $('.detach', container).on('click', function(e) { + event.preventDefault(); + var settings = { + title : i18n['KCHAPI6004M'], + content : i18n['KCHVMCD6001M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + + var dev = $(this).data('dev'); + kimchi.confirm(settings, function() { + kimchi.deleteVMStorage({ + vm: kimchi.selectedGuest, + dev: dev + }, function() { + kimchi.topic('kimchi/vmCDROMDetached').publish(); + }); + }); + }); + }); + }; + + var initContent = function(guest) { guest['icon'] = guest['icon'] || 'images/icon-vm.png'; for ( var prop in guest) { $('input[name="' + prop + '"]', guestEditForm).val(guest[prop]); } - }); - $('#guest-edit-button-cancel').on('click', function() { - kimchi.window.close(); - }); + refreshCDROMs(); + + $('#guest-edit-attach-cdrom-button').on('click', function(event) { + event.preventDefault(); + kimchi.window.open("guest-storage-add.html"); + }); + + var messageNode = $('#message-container'); + var onAttached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6006M'], messageNode); + refreshCDROMs(); + }; + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + var onDetached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6008M'], messageNode); + refreshCDROMs(); + }; + + kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached); + + kimchi.clearGuestEdit = function() { + kimchi.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached); + }; + }; + + kimchi.retrieveVM(kimchi.selectedGuest, initContent); var submitForm = function(event) { $(saveButton).prop('disabled', true); @@ -42,6 +134,7 @@ kimchi.guest_edit_main = function() { }, function(err) { kimchi.message.error(err.responseJSON.reason); }); + event.preventDefault(); }; diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js index 94fcf01..bbd8d3d 100644 --- a/ui/js/src/kimchi.guest_main.js +++ b/ui/js/src/kimchi.guest_main.js @@ -85,11 +85,28 @@ kimchi.vmdelete = function(event) { }); }; +kimchi.vmmedia = function(event) { + var vm = $(this).closest('li[name=guest]'); + var vm_id = vm.attr('id'); + kimchi.selectedGuest = vm_id; + kimchi.window.open({ + url: 'guest-media.html', + close: function() { + kimchi.clearGuestMedia(); + } + }); +}; + kimchi.vmedit = function(event) { var vm = $(this).closest('li[name=guest]'); var vm_id=vm.attr("id"); kimchi.selectedGuest = vm_id; - kimchi.window.open("guest-edit.html"); + kimchi.window.open({ + url: 'guest-edit.html', + close: function() { + kimchi.clearGuestEdit(); + } + }); }; kimchi.openVmConsole = function(event) { @@ -233,6 +250,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { if (vmRunningBool) { //If the guest is not running, do not enable reset guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset}); } + guestActions.find("[name=vm-media]").on({click : kimchi.vmmedia}); guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit}); guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete}); diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index a461031..ba6ba2b 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -27,74 +27,114 @@ <div class="close">X</div> </header> <div class="content"> - <form id="form-guest-edit"> - <fieldset class="guest-edit-fieldset"> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-id-textbox"> - $_("Name") - </label> + <div id="guest-edit-tabs"> + <ul> + <li> + <a href="#form-guest-edit-general">$_("General")</a> + </li> + <li> + <a href="#form-guest-edit-storage">$_("Storage")</a> + </li> + </ul> + <form id="form-guest-edit-general"> + <fieldset class="guest-edit-fieldset"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-id-textbox"> + $_("Name") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-id-textbox" + name="name" type="text" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-id-textbox" - name="name" type="text" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-cores-textbox"> + $_("CPUs") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-cores-textbox" + name="cpus" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-cores-textbox"> - $_("CPUs") - </label> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-memory-textbox"> + $_("Memory") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-memory-textbox" + name="memory" + type="text" + disabled="disabled" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-cores-textbox" - name="cpus" - type="text" - disabled="disabled" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-icon-textbox"> + $_("Icon") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-icon-textbox" + name="icon" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-memory-textbox"> - $_("Memory") - </label> + </fieldset> + </form> + <form id="form-guest-edit-storage"> + <fieldset class="guest-edit-fieldset"> + <div id="guest-edit-cdrom-row-container" class="guest-edit-cdrom-row-container"></div> + <div> + <button id="guest-edit-attach-cdrom-button" + class="guest-edit-cdrom-button attach" + title="$_("Attach")"> + </button> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-memory-textbox" - name="memory" - type="text" - disabled="disabled" /> - </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-icon-textbox"> - $_("Icon") - </label> - </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-icon-textbox" - name="icon" - type="text" - disabled="disabled" /> - </div> - </div> - </fieldset> - </form> + </fieldset> + </form> + </div> </div> <footer> - <div class="btn-group"> - <button id="guest-edit-button-cancel" class="btn-normal"> - <span class="text">$_("Cancel")</span> - </button> + <div id="action-button-container" class="btn-group"> <button id="guest-edit-button-save" class="btn-normal"> <span class="text">$_("Save")</span> </button> </div> + <div id="message-container"></div> </footer> </div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + <button class="guest-edit-cdrom-button detach" + data-vm="{vm}" data-dev="{dev}" + title="$_("Detach")"> + </button> + </div> + </div> +</script> + <script type="text/javascript"> kimchi.guest_edit_main(); </script> diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl index 0115837..a9737a5 100644 --- a/ui/pages/guest.html.tmpl +++ b/ui/pages/guest.html.tmpl @@ -56,6 +56,7 @@ <span class="text">$_("Actions")</span><span class="arrow"></span> <div class="popover actionsheet right-side" style="width: 250px"> <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Console")</span></button> + <button class="button-big shutoff-disabled" name="vm-media"><span class="text">$_("Manage Media")</span></button> <button class="button-big running-disabled" name="vm-edit"><span class="text">$_("Edit")</span></button> <a class="button-big red " name="vm-delete">$_("Delete")</a> </div> -- 1.8.1.4

I still can not detach a cdrom from a vm. Same error I commented before. After changing it: diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index cdd6d49..232ba08 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -57,7 +57,7 @@ kimchi.guest_edit_main = function() { $('.replace', container).on('click', replaceCDROM); $('.detach', container).on('click', function(e) { - event.preventDefault(); + //event.preventDefault(); var settings = { title : i18n['KCHAPI6004M'], content : i18n['KCHVMCD6001M'], I could see the confirmation dialog for 1 sec and then got the error ERROR CODE 404 Not Found REASON Unexpected query string parameters: cdrom STACK Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/cherrypy/_cprequest.py", line 656, in respond response.body = self.handler() File "/usr/lib/python2.7/dist-packages/cherrypy/lib/encoding.py", line 188, in __call__ self.body = self.oldhandler(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/cherrypy/_cpdispatch.py", line 40, in __call__ raise sys.exc_info()[1] HTTPError: (404, 'Unexpected query string parameters: cdrom') On 03/10/2014 06:44 AM, Hongliang Wang wrote:
Allow user to manipulate CDROM(s) in a VM: 1) Attach one or more CDROM(s) (only for stopped VM); 2) Replace a CDROM with another ISO file path; 3) Detach a CDROM from a VM (only for stopped VM).
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 144 ++++++++++++++++++++++--- ui/images/theme-default/guest-icon-sprite.png | Bin 0 -> 6748 bytes ui/js/src/kimchi.guest_edit_main.js | 105 ++++++++++++++++-- ui/js/src/kimchi.guest_main.js | 20 +++- ui/pages/guest-edit.html.tmpl | 150 ++++++++++++++++---------- ui/pages/guest.html.tmpl | 1 + 6 files changed, 345 insertions(+), 75 deletions(-) create mode 100644 ui/images/theme-default/guest-icon-sprite.png
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index f4ccdee..43f71c0 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -17,36 +17,53 @@ */ #guest-edit-window { font-size: 13px; - height: 380px; - width: 420px; + height: 400px; + width: 600px; }
-.guest-edit-fieldset { - float: left; +#guest-edit-tabs { + background: transparent; + border: none; + height: 100%; + padding: 0; +} + +#form-guest-edit-general, +#form-guest-edit-storage { padding: 1em; }
+.guest-edit-fieldset { + padding-right: 0; +} + .guest-edit-wrapper-label, .guest-edit-wrapper-controls { display: inline-block; }
-.guest-edit-wrapper-controls input[type="text"][disabled] { - color: #bbb; - background-color: #fafafa; - cursor: not-allowed; +.guest-edit-wrapper-label { + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; + width: 80px; }
-.guest-edit-wrapper-label { - width: 10em; +#form-guest-edit-storage .guest-edit-wrapper-label { + width: 60px; }
.guest-edit-wrapper-controls { - width: 18em; + width: 470px; +} + +#form-guest-edit-storage .guest-edit-wrapper-controls { + width: 486px; }
.guest-edit-wrapper-controls input[type="text"] { + font-size: 16px; height: 38px; - line-height: 38px; background: #fff; -webkit-border-radius: 5px; border-radius: 5px; @@ -54,7 +71,7 @@ border-top: 1px solid #bbb; border-left: 1px solid #bbb; padding-left: 10px; - width: 100%; + width: 450px; }
.guest-edit-wrapper-controls input[type="text"][disabled] { @@ -62,3 +79,104 @@ background-color: #fafafa; cursor: not-allowed; } + +.guest-edit-cdrom-row-container { + max-height: 180px; + overflow: auto; +} + +.guest-edit-cdrom-row-container input[type="text"] { + width: 400px; +} + +.guest-edit-cdrom-button { + background: url("../images/theme-default/guest-icon-sprite.png") no-repeat left top transparent; + border: none; + height: 25px; + vertical-align: middle; + width: 25px; +} + +.guest-edit-cdrom-button.attach { + margin: 15px 0 0 521px; +} + +.guest-edit-cdrom-button.attach:hover { + background-position: 0 -27px; +} + +.guest-edit-cdrom-button.attach:focus { + background-position: 0 -54px; +} + +.guest-edit-cdrom-button.attach:active { + background-position: 0 -81px; +} + +.guest-edit-cdrom-button.attach[disabled] { + background-position: 0 -108px; +} + +.guest-edit-cdrom-button.replace { + background-position: -27px 0; +} + +.guest-edit-cdrom-button.replace:hover { + background-position: -27px -27px; +} + +.guest-edit-cdrom-button.replace:focus { + background-position: -27px -54px; +} + +.guest-edit-cdrom-button.replace:active { + background-position: -27px -81px; +} + +.guest-edit-cdrom-button.replace[disabled] { + background-position: -27px -108px; +} + +.guest-edit-cdrom-button.detach { + background-position: -54px 0; +} + +.guest-edit-cdrom-button.detach:hover { + background-position: -54px -27px; +} + +.guest-edit-cdrom-button.detach:focus { + background-position: -54px -54px; +} + +.guest-edit-cdrom-button.detach:active { + background-position: -54px -81px; +} + +.guest-edit-cdrom-button.detach[disabled] { + background-position: -54px -108px; +} + +#message-container { + color: #555; + font-size: 14px; + height: 100%; + line-height: 56px; +} + +#message-container .message { + background: transparent; +} + +#message-container .success { + color: green; +} + +#message-container .error { + color: red; +} + +#message-container .content { + margin: 0; + position: static; +} diff --git a/ui/images/theme-default/guest-icon-sprite.png b/ui/images/theme-default/guest-icon-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..81edb5945d3bd204313a6d53b55cecf17ee97679 GIT binary patch literal 6748 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 Bz#9Mn
literal 0 HcmV?d00001
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index f32fbb1..cdd6d49 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -16,18 +16,110 @@ * limitations under the License. */ kimchi.guest_edit_main = function() { - var guestEditForm = $('#form-guest-edit'); + var buttonContainer = $('#action-button-container'); + $('#guest-edit-tabs').tabs({ + beforeActivate: function(event, ui) { + var deactivated = ui['oldPanel']; + if($(deactivated).attr('id') === 'form-guest-edit-general') { + $(buttonContainer).addClass('hidden'); + } + else { + $(buttonContainer).removeClass('hidden'); + } + } + }); + + var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); - kimchi.retrieveVM(kimchi.selectedGuest, function(guest) { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + + $('.detach', container).on('click', function(e) { + event.preventDefault(); + var settings = { + title : i18n['KCHAPI6004M'], + content : i18n['KCHVMCD6001M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + + var dev = $(this).data('dev'); + kimchi.confirm(settings, function() { + kimchi.deleteVMStorage({ + vm: kimchi.selectedGuest, + dev: dev + }, function() { + kimchi.topic('kimchi/vmCDROMDetached').publish(); + }); + }); + }); + }); + }; + + var initContent = function(guest) { guest['icon'] = guest['icon'] || 'images/icon-vm.png'; for ( var prop in guest) { $('input[name="' + prop + '"]', guestEditForm).val(guest[prop]); } - });
- $('#guest-edit-button-cancel').on('click', function() { - kimchi.window.close(); - }); + refreshCDROMs(); + + $('#guest-edit-attach-cdrom-button').on('click', function(event) { + event.preventDefault(); + kimchi.window.open("guest-storage-add.html"); + }); + + var messageNode = $('#message-container'); + var onAttached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6006M'], messageNode); + refreshCDROMs(); + }; + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + var onDetached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6008M'], messageNode); + refreshCDROMs(); + }; + + kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached); + + kimchi.clearGuestEdit = function() { + kimchi.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached); + }; + }; + + kimchi.retrieveVM(kimchi.selectedGuest, initContent);
var submitForm = function(event) { $(saveButton).prop('disabled', true); @@ -42,6 +134,7 @@ kimchi.guest_edit_main = function() { }, function(err) { kimchi.message.error(err.responseJSON.reason); }); + event.preventDefault(); };
diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js index 94fcf01..bbd8d3d 100644 --- a/ui/js/src/kimchi.guest_main.js +++ b/ui/js/src/kimchi.guest_main.js @@ -85,11 +85,28 @@ kimchi.vmdelete = function(event) { }); };
+kimchi.vmmedia = function(event) { + var vm = $(this).closest('li[name=guest]'); + var vm_id = vm.attr('id'); + kimchi.selectedGuest = vm_id; + kimchi.window.open({ + url: 'guest-media.html', + close: function() { + kimchi.clearGuestMedia(); + } + }); +}; + kimchi.vmedit = function(event) { var vm = $(this).closest('li[name=guest]'); var vm_id=vm.attr("id"); kimchi.selectedGuest = vm_id; - kimchi.window.open("guest-edit.html"); + kimchi.window.open({ + url: 'guest-edit.html', + close: function() { + kimchi.clearGuestEdit(); + } + }); };
kimchi.openVmConsole = function(event) { @@ -233,6 +250,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { if (vmRunningBool) { //If the guest is not running, do not enable reset guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset}); } + guestActions.find("[name=vm-media]").on({click : kimchi.vmmedia}); guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit}); guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index a461031..ba6ba2b 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -27,74 +27,114 @@ <div class="close">X</div> </header> <div class="content"> - <form id="form-guest-edit"> - <fieldset class="guest-edit-fieldset"> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-id-textbox"> - $_("Name") - </label> + <div id="guest-edit-tabs"> + <ul> + <li> + <a href="#form-guest-edit-general">$_("General")</a> + </li> + <li> + <a href="#form-guest-edit-storage">$_("Storage")</a> + </li> + </ul> + <form id="form-guest-edit-general"> + <fieldset class="guest-edit-fieldset"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-id-textbox"> + $_("Name") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-id-textbox" + name="name" type="text" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-id-textbox" - name="name" type="text" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-cores-textbox"> + $_("CPUs") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-cores-textbox" + name="cpus" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-cores-textbox"> - $_("CPUs") - </label> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-memory-textbox"> + $_("Memory") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-memory-textbox" + name="memory" + type="text" + disabled="disabled" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-cores-textbox" - name="cpus" - type="text" - disabled="disabled" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-icon-textbox"> + $_("Icon") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-icon-textbox" + name="icon" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-memory-textbox"> - $_("Memory") - </label> + </fieldset> + </form> + <form id="form-guest-edit-storage"> + <fieldset class="guest-edit-fieldset"> + <div id="guest-edit-cdrom-row-container" class="guest-edit-cdrom-row-container"></div> + <div> + <button id="guest-edit-attach-cdrom-button" + class="guest-edit-cdrom-button attach" + title="$_("Attach")"> + </button> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-memory-textbox" - name="memory" - type="text" - disabled="disabled" /> - </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-icon-textbox"> - $_("Icon") - </label> - </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-icon-textbox" - name="icon" - type="text" - disabled="disabled" /> - </div> - </div> - </fieldset> - </form> + </fieldset> + </form> + </div> </div> <footer> - <div class="btn-group"> - <button id="guest-edit-button-cancel" class="btn-normal"> - <span class="text">$_("Cancel")</span> - </button> + <div id="action-button-container" class="btn-group"> <button id="guest-edit-button-save" class="btn-normal"> <span class="text">$_("Save")</span> </button> </div> + <div id="message-container"></div> </footer> </div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + <button class="guest-edit-cdrom-button detach" + data-vm="{vm}" data-dev="{dev}" + title="$_("Detach")"> + </button> + </div> + </div> +</script> + <script type="text/javascript"> kimchi.guest_edit_main(); </script> diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl index 0115837..a9737a5 100644 --- a/ui/pages/guest.html.tmpl +++ b/ui/pages/guest.html.tmpl @@ -56,6 +56,7 @@ <span class="text">$_("Actions")</span><span class="arrow"></span> <div class="popover actionsheet right-side" style="width: 250px"> <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Console")</span></button>
+ <button class="button-big shutoff-disabled" name="vm-media"><span class="text">$_("Manage Media")</span></button>
Why this was added?
<button class="button-big running-disabled" name="vm-edit"><span class="text">$_("Edit")</span></button> <a class="button-big red " name="vm-delete">$_("Delete")</a> </div>

I am using Firefox 27.0.1 On 03/10/2014 02:27 PM, Aline Manera wrote:
I still can not detach a cdrom from a vm. Same error I commented before.
After changing it:
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index cdd6d49..232ba08 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -57,7 +57,7 @@ kimchi.guest_edit_main = function() { $('.replace', container).on('click', replaceCDROM);
$('.detach', container).on('click', function(e) { - event.preventDefault(); + //event.preventDefault(); var settings = { title : i18n['KCHAPI6004M'], content : i18n['KCHVMCD6001M'],
I could see the confirmation dialog for 1 sec and then got the error
ERROR CODE
404 Not Found
REASON
Unexpected query string parameters: cdrom
STACK
Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/cherrypy/_cprequest.py", line 656, in respond response.body = self.handler() File "/usr/lib/python2.7/dist-packages/cherrypy/lib/encoding.py", line 188, in __call__ self.body = self.oldhandler(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/cherrypy/_cpdispatch.py", line 40, in __call__ raise sys.exc_info()[1] HTTPError: (404, 'Unexpected query string parameters: cdrom')
On 03/10/2014 06:44 AM, Hongliang Wang wrote:
Allow user to manipulate CDROM(s) in a VM: 1) Attach one or more CDROM(s) (only for stopped VM); 2) Replace a CDROM with another ISO file path; 3) Detach a CDROM from a VM (only for stopped VM).
Signed-off-by: Hongliang Wang<hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 144 ++++++++++++++++++++++--- ui/images/theme-default/guest-icon-sprite.png | Bin 0 -> 6748 bytes ui/js/src/kimchi.guest_edit_main.js | 105 ++++++++++++++++-- ui/js/src/kimchi.guest_main.js | 20 +++- ui/pages/guest-edit.html.tmpl | 150 ++++++++++++++++---------- ui/pages/guest.html.tmpl | 1 + 6 files changed, 345 insertions(+), 75 deletions(-) create mode 100644 ui/images/theme-default/guest-icon-sprite.png
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index f4ccdee..43f71c0 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -17,36 +17,53 @@ */ #guest-edit-window { font-size: 13px; - height: 380px; - width: 420px; + height: 400px; + width: 600px; }
-.guest-edit-fieldset { - float: left; +#guest-edit-tabs { + background: transparent; + border: none; + height: 100%; + padding: 0; +} + +#form-guest-edit-general, +#form-guest-edit-storage { padding: 1em; }
+.guest-edit-fieldset { + padding-right: 0; +} + .guest-edit-wrapper-label, .guest-edit-wrapper-controls { display: inline-block; }
-.guest-edit-wrapper-controls input[type="text"][disabled] { - color: #bbb; - background-color: #fafafa; - cursor: not-allowed; +.guest-edit-wrapper-label { + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; + width: 80px; }
-.guest-edit-wrapper-label { - width: 10em; +#form-guest-edit-storage .guest-edit-wrapper-label { + width: 60px; }
.guest-edit-wrapper-controls { - width: 18em; + width: 470px; +} + +#form-guest-edit-storage .guest-edit-wrapper-controls { + width: 486px; }
.guest-edit-wrapper-controls input[type="text"] { + font-size: 16px; height: 38px; - line-height: 38px; background: #fff; -webkit-border-radius: 5px; border-radius: 5px; @@ -54,7 +71,7 @@ border-top: 1px solid #bbb; border-left: 1px solid #bbb; padding-left: 10px; - width: 100%; + width: 450px; }
.guest-edit-wrapper-controls input[type="text"][disabled] { @@ -62,3 +79,104 @@ background-color: #fafafa; cursor: not-allowed; } + +.guest-edit-cdrom-row-container { + max-height: 180px; + overflow: auto; +} + +.guest-edit-cdrom-row-container input[type="text"] { + width: 400px; +} + +.guest-edit-cdrom-button { + background: url("../images/theme-default/guest-icon-sprite.png") no-repeat left top transparent; + border: none; + height: 25px; + vertical-align: middle; + width: 25px; +} + +.guest-edit-cdrom-button.attach { + margin: 15px 0 0 521px; +} + +.guest-edit-cdrom-button.attach:hover { + background-position: 0 -27px; +} + +.guest-edit-cdrom-button.attach:focus { + background-position: 0 -54px; +} + +.guest-edit-cdrom-button.attach:active { + background-position: 0 -81px; +} + +.guest-edit-cdrom-button.attach[disabled] { + background-position: 0 -108px; +} + +.guest-edit-cdrom-button.replace { + background-position: -27px 0; +} + +.guest-edit-cdrom-button.replace:hover { + background-position: -27px -27px; +} + +.guest-edit-cdrom-button.replace:focus { + background-position: -27px -54px; +} + +.guest-edit-cdrom-button.replace:active { + background-position: -27px -81px; +} + +.guest-edit-cdrom-button.replace[disabled] { + background-position: -27px -108px; +} + +.guest-edit-cdrom-button.detach { + background-position: -54px 0; +} + +.guest-edit-cdrom-button.detach:hover { + background-position: -54px -27px; +} + +.guest-edit-cdrom-button.detach:focus { + background-position: -54px -54px; +} + +.guest-edit-cdrom-button.detach:active { + background-position: -54px -81px; +} + +.guest-edit-cdrom-button.detach[disabled] { + background-position: -54px -108px; +} + +#message-container { + color: #555; + font-size: 14px; + height: 100%; + line-height: 56px; +} + +#message-container .message { + background: transparent; +} + +#message-container .success { + color: green; +} + +#message-container .error { + color: red; +} + +#message-container .content { + margin: 0; + position: static; +} diff --git a/ui/images/theme-default/guest-icon-sprite.png b/ui/images/theme-default/guest-icon-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..81edb5945d3bd204313a6d53b55cecf17ee97679 GIT binary patch literal 6748 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 Bz#9Mn
literal 0 HcmV?d00001
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index f32fbb1..cdd6d49 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -16,18 +16,110 @@ * limitations under the License. */ kimchi.guest_edit_main = function() { - var guestEditForm = $('#form-guest-edit'); + var buttonContainer = $('#action-button-container'); + $('#guest-edit-tabs').tabs({ + beforeActivate: function(event, ui) { + var deactivated = ui['oldPanel']; + if($(deactivated).attr('id') === 'form-guest-edit-general') { + $(buttonContainer).addClass('hidden'); + } + else { + $(buttonContainer).removeClass('hidden'); + } + } + }); + + var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); - kimchi.retrieveVM(kimchi.selectedGuest, function(guest) { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + + $('.detach', container).on('click', function(e) { + event.preventDefault(); + var settings = { + title : i18n['KCHAPI6004M'], + content : i18n['KCHVMCD6001M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + + var dev = $(this).data('dev'); + kimchi.confirm(settings, function() { + kimchi.deleteVMStorage({ + vm: kimchi.selectedGuest, + dev: dev + }, function() { + kimchi.topic('kimchi/vmCDROMDetached').publish(); + }); + }); + }); + }); + }; + + var initContent = function(guest) { guest['icon'] = guest['icon'] || 'images/icon-vm.png'; for ( var prop in guest) { $('input[name="' + prop + '"]', guestEditForm).val(guest[prop]); } - });
- $('#guest-edit-button-cancel').on('click', function() { - kimchi.window.close(); - }); + refreshCDROMs(); + + $('#guest-edit-attach-cdrom-button').on('click', function(event) { + event.preventDefault(); + kimchi.window.open("guest-storage-add.html"); + }); + + var messageNode = $('#message-container'); + var onAttached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6006M'], messageNode); + refreshCDROMs(); + }; + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + var onDetached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6008M'], messageNode); + refreshCDROMs(); + }; + + kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached); + + kimchi.clearGuestEdit = function() { + kimchi.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached); + }; + }; + + kimchi.retrieveVM(kimchi.selectedGuest, initContent);
var submitForm = function(event) { $(saveButton).prop('disabled', true); @@ -42,6 +134,7 @@ kimchi.guest_edit_main = function() { }, function(err) { kimchi.message.error(err.responseJSON.reason); }); + event.preventDefault(); };
diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js index 94fcf01..bbd8d3d 100644 --- a/ui/js/src/kimchi.guest_main.js +++ b/ui/js/src/kimchi.guest_main.js @@ -85,11 +85,28 @@ kimchi.vmdelete = function(event) { }); };
+kimchi.vmmedia = function(event) { + var vm = $(this).closest('li[name=guest]'); + var vm_id = vm.attr('id'); + kimchi.selectedGuest = vm_id; + kimchi.window.open({ + url: 'guest-media.html', + close: function() { + kimchi.clearGuestMedia(); + } + }); +}; + kimchi.vmedit = function(event) { var vm = $(this).closest('li[name=guest]'); var vm_id=vm.attr("id"); kimchi.selectedGuest = vm_id; - kimchi.window.open("guest-edit.html"); + kimchi.window.open({ + url: 'guest-edit.html', + close: function() { + kimchi.clearGuestEdit(); + } + }); };
kimchi.openVmConsole = function(event) { @@ -233,6 +250,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { if (vmRunningBool) { //If the guest is not running, do not enable reset guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset}); } + guestActions.find("[name=vm-media]").on({click : kimchi.vmmedia}); guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit}); guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index a461031..ba6ba2b 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -27,74 +27,114 @@ <div class="close">X</div> </header> <div class="content"> - <form id="form-guest-edit"> - <fieldset class="guest-edit-fieldset"> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-id-textbox"> - $_("Name") - </label> + <div id="guest-edit-tabs"> + <ul> + <li> + <a href="#form-guest-edit-general">$_("General")</a> + </li> + <li> + <a href="#form-guest-edit-storage">$_("Storage")</a> + </li> + </ul> + <form id="form-guest-edit-general"> + <fieldset class="guest-edit-fieldset"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-id-textbox"> + $_("Name") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-id-textbox" + name="name" type="text" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-id-textbox" - name="name" type="text" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-cores-textbox"> + $_("CPUs") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-cores-textbox" + name="cpus" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-cores-textbox"> - $_("CPUs") - </label> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-memory-textbox"> + $_("Memory") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-memory-textbox" + name="memory" + type="text" + disabled="disabled" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-cores-textbox" - name="cpus" - type="text" - disabled="disabled" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-icon-textbox"> + $_("Icon") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-icon-textbox" + name="icon" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-memory-textbox"> - $_("Memory") - </label> + </fieldset> + </form> + <form id="form-guest-edit-storage"> + <fieldset class="guest-edit-fieldset"> + <div id="guest-edit-cdrom-row-container" class="guest-edit-cdrom-row-container"></div> + <div> + <button id="guest-edit-attach-cdrom-button" + class="guest-edit-cdrom-button attach" + title="$_("Attach")"> + </button> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-memory-textbox" - name="memory" - type="text" - disabled="disabled" /> - </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-icon-textbox"> - $_("Icon") - </label> - </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-icon-textbox" - name="icon" - type="text" - disabled="disabled" /> - </div> - </div> - </fieldset> - </form> + </fieldset> + </form> + </div> </div> <footer> - <div class="btn-group"> - <button id="guest-edit-button-cancel" class="btn-normal"> - <span class="text">$_("Cancel")</span> - </button> + <div id="action-button-container" class="btn-group"> <button id="guest-edit-button-save" class="btn-normal"> <span class="text">$_("Save")</span> </button> </div> + <div id="message-container"></div> </footer> </div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + <button class="guest-edit-cdrom-button detach" + data-vm="{vm}" data-dev="{dev}" + title="$_("Detach")"> + </button> + </div> + </div> +</script> + <script type="text/javascript"> kimchi.guest_edit_main(); </script> diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl index 0115837..a9737a5 100644 --- a/ui/pages/guest.html.tmpl +++ b/ui/pages/guest.html.tmpl @@ -56,6 +56,7 @@ <span class="text">$_("Actions")</span><span class="arrow"></span> <div class="popover actionsheet right-side" style="width: 250px"> <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Console")</span></button>
+ <button class="button-big shutoff-disabled" name="vm-media"><span class="text">$_("Manage Media")</span></button>
Why this was added?
<button class="button-big running-disabled" name="vm-edit"><span class="text">$_("Edit")</span></button> <a class="button-big red " name="vm-delete">$_("Delete")</a> </div>
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

On 03/10/2014 02:35 PM, Aline Manera wrote:
I am using Firefox 27.0.1
I tried on Chrome and it works. Seems the problem is only on Firefox
On 03/10/2014 02:27 PM, Aline Manera wrote:
I still can not detach a cdrom from a vm. Same error I commented before.
After changing it:
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index cdd6d49..232ba08 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -57,7 +57,7 @@ kimchi.guest_edit_main = function() { $('.replace', container).on('click', replaceCDROM);
$('.detach', container).on('click', function(e) { - event.preventDefault(); + //event.preventDefault(); var settings = { title : i18n['KCHAPI6004M'], content : i18n['KCHVMCD6001M'],
I could see the confirmation dialog for 1 sec and then got the error
ERROR CODE
404 Not Found
REASON
Unexpected query string parameters: cdrom
STACK
Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/cherrypy/_cprequest.py", line 656, in respond response.body = self.handler() File "/usr/lib/python2.7/dist-packages/cherrypy/lib/encoding.py", line 188, in __call__ self.body = self.oldhandler(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/cherrypy/_cpdispatch.py", line 40, in __call__ raise sys.exc_info()[1] HTTPError: (404, 'Unexpected query string parameters: cdrom')
On 03/10/2014 06:44 AM, Hongliang Wang wrote:
Allow user to manipulate CDROM(s) in a VM: 1) Attach one or more CDROM(s) (only for stopped VM); 2) Replace a CDROM with another ISO file path; 3) Detach a CDROM from a VM (only for stopped VM).
Signed-off-by: Hongliang Wang<hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 144 ++++++++++++++++++++++--- ui/images/theme-default/guest-icon-sprite.png | Bin 0 -> 6748 bytes ui/js/src/kimchi.guest_edit_main.js | 105 ++++++++++++++++-- ui/js/src/kimchi.guest_main.js | 20 +++- ui/pages/guest-edit.html.tmpl | 150 ++++++++++++++++---------- ui/pages/guest.html.tmpl | 1 + 6 files changed, 345 insertions(+), 75 deletions(-) create mode 100644 ui/images/theme-default/guest-icon-sprite.png
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index f4ccdee..43f71c0 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -17,36 +17,53 @@ */ #guest-edit-window { font-size: 13px; - height: 380px; - width: 420px; + height: 400px; + width: 600px; }
-.guest-edit-fieldset { - float: left; +#guest-edit-tabs { + background: transparent; + border: none; + height: 100%; + padding: 0; +} + +#form-guest-edit-general, +#form-guest-edit-storage { padding: 1em; }
+.guest-edit-fieldset { + padding-right: 0; +} + .guest-edit-wrapper-label, .guest-edit-wrapper-controls { display: inline-block; }
-.guest-edit-wrapper-controls input[type="text"][disabled] { - color: #bbb; - background-color: #fafafa; - cursor: not-allowed; +.guest-edit-wrapper-label { + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; + width: 80px; }
-.guest-edit-wrapper-label { - width: 10em; +#form-guest-edit-storage .guest-edit-wrapper-label { + width: 60px; }
.guest-edit-wrapper-controls { - width: 18em; + width: 470px; +} + +#form-guest-edit-storage .guest-edit-wrapper-controls { + width: 486px; }
.guest-edit-wrapper-controls input[type="text"] { + font-size: 16px; height: 38px; - line-height: 38px; background: #fff; -webkit-border-radius: 5px; border-radius: 5px; @@ -54,7 +71,7 @@ border-top: 1px solid #bbb; border-left: 1px solid #bbb; padding-left: 10px; - width: 100%; + width: 450px; }
.guest-edit-wrapper-controls input[type="text"][disabled] { @@ -62,3 +79,104 @@ background-color: #fafafa; cursor: not-allowed; } + +.guest-edit-cdrom-row-container { + max-height: 180px; + overflow: auto; +} + +.guest-edit-cdrom-row-container input[type="text"] { + width: 400px; +} + +.guest-edit-cdrom-button { + background: url("../images/theme-default/guest-icon-sprite.png") no-repeat left top transparent; + border: none; + height: 25px; + vertical-align: middle; + width: 25px; +} + +.guest-edit-cdrom-button.attach { + margin: 15px 0 0 521px; +} + +.guest-edit-cdrom-button.attach:hover { + background-position: 0 -27px; +} + +.guest-edit-cdrom-button.attach:focus { + background-position: 0 -54px; +} + +.guest-edit-cdrom-button.attach:active { + background-position: 0 -81px; +} + +.guest-edit-cdrom-button.attach[disabled] { + background-position: 0 -108px; +} + +.guest-edit-cdrom-button.replace { + background-position: -27px 0; +} + +.guest-edit-cdrom-button.replace:hover { + background-position: -27px -27px; +} + +.guest-edit-cdrom-button.replace:focus { + background-position: -27px -54px; +} + +.guest-edit-cdrom-button.replace:active { + background-position: -27px -81px; +} + +.guest-edit-cdrom-button.replace[disabled] { + background-position: -27px -108px; +} + +.guest-edit-cdrom-button.detach { + background-position: -54px 0; +} + +.guest-edit-cdrom-button.detach:hover { + background-position: -54px -27px; +} + +.guest-edit-cdrom-button.detach:focus { + background-position: -54px -54px; +} + +.guest-edit-cdrom-button.detach:active { + background-position: -54px -81px; +} + +.guest-edit-cdrom-button.detach[disabled] { + background-position: -54px -108px; +} + +#message-container { + color: #555; + font-size: 14px; + height: 100%; + line-height: 56px; +} + +#message-container .message { + background: transparent; +} + +#message-container .success { + color: green; +} + +#message-container .error { + color: red; +} + +#message-container .content { + margin: 0; + position: static; +} diff --git a/ui/images/theme-default/guest-icon-sprite.png b/ui/images/theme-default/guest-icon-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..81edb5945d3bd204313a6d53b55cecf17ee97679 GIT binary patch literal 6748 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 Bz#9Mn
literal 0 HcmV?d00001
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index f32fbb1..cdd6d49 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -16,18 +16,110 @@ * limitations under the License. */ kimchi.guest_edit_main = function() { - var guestEditForm = $('#form-guest-edit'); + var buttonContainer = $('#action-button-container'); + $('#guest-edit-tabs').tabs({ + beforeActivate: function(event, ui) { + var deactivated = ui['oldPanel']; + if($(deactivated).attr('id') === 'form-guest-edit-general') { + $(buttonContainer).addClass('hidden'); + } + else { + $(buttonContainer).removeClass('hidden'); + } + } + }); + + var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); - kimchi.retrieveVM(kimchi.selectedGuest, function(guest) { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + + $('.detach', container).on('click', function(e) { + event.preventDefault(); + var settings = { + title : i18n['KCHAPI6004M'], + content : i18n['KCHVMCD6001M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + + var dev = $(this).data('dev'); + kimchi.confirm(settings, function() { + kimchi.deleteVMStorage({ + vm: kimchi.selectedGuest, + dev: dev + }, function() { + kimchi.topic('kimchi/vmCDROMDetached').publish(); + }); + }); + }); + }); + }; + + var initContent = function(guest) { guest['icon'] = guest['icon'] || 'images/icon-vm.png'; for ( var prop in guest) { $('input[name="' + prop + '"]', guestEditForm).val(guest[prop]); } - });
- $('#guest-edit-button-cancel').on('click', function() { - kimchi.window.close(); - }); + refreshCDROMs(); + + $('#guest-edit-attach-cdrom-button').on('click', function(event) { + event.preventDefault(); + kimchi.window.open("guest-storage-add.html"); + }); + + var messageNode = $('#message-container'); + var onAttached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6006M'], messageNode); + refreshCDROMs(); + }; + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + var onDetached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6008M'], messageNode); + refreshCDROMs(); + }; + + kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached); + + kimchi.clearGuestEdit = function() { + kimchi.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached); + }; + }; + + kimchi.retrieveVM(kimchi.selectedGuest, initContent);
var submitForm = function(event) { $(saveButton).prop('disabled', true); @@ -42,6 +134,7 @@ kimchi.guest_edit_main = function() { }, function(err) { kimchi.message.error(err.responseJSON.reason); }); + event.preventDefault(); };
diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js index 94fcf01..bbd8d3d 100644 --- a/ui/js/src/kimchi.guest_main.js +++ b/ui/js/src/kimchi.guest_main.js @@ -85,11 +85,28 @@ kimchi.vmdelete = function(event) { }); };
+kimchi.vmmedia = function(event) { + var vm = $(this).closest('li[name=guest]'); + var vm_id = vm.attr('id'); + kimchi.selectedGuest = vm_id; + kimchi.window.open({ + url: 'guest-media.html', + close: function() { + kimchi.clearGuestMedia(); + } + }); +}; + kimchi.vmedit = function(event) { var vm = $(this).closest('li[name=guest]'); var vm_id=vm.attr("id"); kimchi.selectedGuest = vm_id; - kimchi.window.open("guest-edit.html"); + kimchi.window.open({ + url: 'guest-edit.html', + close: function() { + kimchi.clearGuestEdit(); + } + }); };
kimchi.openVmConsole = function(event) { @@ -233,6 +250,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { if (vmRunningBool) { //If the guest is not running, do not enable reset guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset}); } + guestActions.find("[name=vm-media]").on({click : kimchi.vmmedia}); guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit}); guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index a461031..ba6ba2b 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -27,74 +27,114 @@ <div class="close">X</div> </header> <div class="content"> - <form id="form-guest-edit"> - <fieldset class="guest-edit-fieldset"> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-id-textbox"> - $_("Name") - </label> + <div id="guest-edit-tabs"> + <ul> + <li> + <a href="#form-guest-edit-general">$_("General")</a> + </li> + <li> + <a href="#form-guest-edit-storage">$_("Storage")</a> + </li> + </ul> + <form id="form-guest-edit-general"> + <fieldset class="guest-edit-fieldset"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-id-textbox"> + $_("Name") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-id-textbox" + name="name" type="text" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-id-textbox" - name="name" type="text" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-cores-textbox"> + $_("CPUs") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-cores-textbox" + name="cpus" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-cores-textbox"> - $_("CPUs") - </label> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-memory-textbox"> + $_("Memory") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-memory-textbox" + name="memory" + type="text" + disabled="disabled" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-cores-textbox" - name="cpus" - type="text" - disabled="disabled" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-icon-textbox"> + $_("Icon") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-icon-textbox" + name="icon" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-memory-textbox"> - $_("Memory") - </label> + </fieldset> + </form> + <form id="form-guest-edit-storage"> + <fieldset class="guest-edit-fieldset"> + <div id="guest-edit-cdrom-row-container" class="guest-edit-cdrom-row-container"></div> + <div> + <button id="guest-edit-attach-cdrom-button" + class="guest-edit-cdrom-button attach" + title="$_("Attach")"> + </button> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-memory-textbox" - name="memory" - type="text" - disabled="disabled" /> - </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-icon-textbox"> - $_("Icon") - </label> - </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-icon-textbox" - name="icon" - type="text" - disabled="disabled" /> - </div> - </div> - </fieldset> - </form> + </fieldset> + </form> + </div> </div> <footer> - <div class="btn-group"> - <button id="guest-edit-button-cancel" class="btn-normal"> - <span class="text">$_("Cancel")</span> - </button> + <div id="action-button-container" class="btn-group"> <button id="guest-edit-button-save" class="btn-normal"> <span class="text">$_("Save")</span> </button> </div> + <div id="message-container"></div> </footer> </div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + <button class="guest-edit-cdrom-button detach" + data-vm="{vm}" data-dev="{dev}" + title="$_("Detach")"> + </button> + </div> + </div> +</script> + <script type="text/javascript"> kimchi.guest_edit_main(); </script> diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl index 0115837..a9737a5 100644 --- a/ui/pages/guest.html.tmpl +++ b/ui/pages/guest.html.tmpl @@ -56,6 +56,7 @@ <span class="text">$_("Actions")</span><span class="arrow"></span> <div class="popover actionsheet right-side" style="width: 250px"> <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Console")</span></button>
+ <button class="button-big shutoff-disabled" name="vm-media"><span class="text">$_("Manage Media")</span></button>
Why this was added?
<button class="button-big running-disabled" name="vm-edit"><span class="text">$_("Edit")</span></button> <a class="button-big red " name="vm-delete">$_("Delete")</a> </div>
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Allow user to manipulate CDROM(s) in a VM: 1) Attach one or more CDROM(s) (only for stopped VM); 2) Replace a CDROM with another ISO file path; 3) Detach a CDROM from a VM (only for stopped VM). Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 144 ++++++++++++++++++++++--- ui/images/theme-default/guest-icon-sprite.png | Bin 0 -> 6748 bytes ui/js/src/kimchi.guest_edit_main.js | 105 ++++++++++++++++-- ui/js/src/kimchi.guest_main.js | 20 +++- ui/pages/guest-edit.html.tmpl | 150 ++++++++++++++++---------- ui/pages/guest.html.tmpl | 1 + 6 files changed, 345 insertions(+), 75 deletions(-) create mode 100644 ui/images/theme-default/guest-icon-sprite.png diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index f4ccdee..43f71c0 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -17,36 +17,53 @@ */ #guest-edit-window { font-size: 13px; - height: 380px; - width: 420px; + height: 400px; + width: 600px; } -.guest-edit-fieldset { - float: left; +#guest-edit-tabs { + background: transparent; + border: none; + height: 100%; + padding: 0; +} + +#form-guest-edit-general, +#form-guest-edit-storage { padding: 1em; } +.guest-edit-fieldset { + padding-right: 0; +} + .guest-edit-wrapper-label, .guest-edit-wrapper-controls { display: inline-block; } -.guest-edit-wrapper-controls input[type="text"][disabled] { - color: #bbb; - background-color: #fafafa; - cursor: not-allowed; +.guest-edit-wrapper-label { + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; + width: 80px; } -.guest-edit-wrapper-label { - width: 10em; +#form-guest-edit-storage .guest-edit-wrapper-label { + width: 60px; } .guest-edit-wrapper-controls { - width: 18em; + width: 470px; +} + +#form-guest-edit-storage .guest-edit-wrapper-controls { + width: 486px; } .guest-edit-wrapper-controls input[type="text"] { + font-size: 16px; height: 38px; - line-height: 38px; background: #fff; -webkit-border-radius: 5px; border-radius: 5px; @@ -54,7 +71,7 @@ border-top: 1px solid #bbb; border-left: 1px solid #bbb; padding-left: 10px; - width: 100%; + width: 450px; } .guest-edit-wrapper-controls input[type="text"][disabled] { @@ -62,3 +79,104 @@ background-color: #fafafa; cursor: not-allowed; } + +.guest-edit-cdrom-row-container { + max-height: 180px; + overflow: auto; +} + +.guest-edit-cdrom-row-container input[type="text"] { + width: 400px; +} + +.guest-edit-cdrom-button { + background: url("../images/theme-default/guest-icon-sprite.png") no-repeat left top transparent; + border: none; + height: 25px; + vertical-align: middle; + width: 25px; +} + +.guest-edit-cdrom-button.attach { + margin: 15px 0 0 521px; +} + +.guest-edit-cdrom-button.attach:hover { + background-position: 0 -27px; +} + +.guest-edit-cdrom-button.attach:focus { + background-position: 0 -54px; +} + +.guest-edit-cdrom-button.attach:active { + background-position: 0 -81px; +} + +.guest-edit-cdrom-button.attach[disabled] { + background-position: 0 -108px; +} + +.guest-edit-cdrom-button.replace { + background-position: -27px 0; +} + +.guest-edit-cdrom-button.replace:hover { + background-position: -27px -27px; +} + +.guest-edit-cdrom-button.replace:focus { + background-position: -27px -54px; +} + +.guest-edit-cdrom-button.replace:active { + background-position: -27px -81px; +} + +.guest-edit-cdrom-button.replace[disabled] { + background-position: -27px -108px; +} + +.guest-edit-cdrom-button.detach { + background-position: -54px 0; +} + +.guest-edit-cdrom-button.detach:hover { + background-position: -54px -27px; +} + +.guest-edit-cdrom-button.detach:focus { + background-position: -54px -54px; +} + +.guest-edit-cdrom-button.detach:active { + background-position: -54px -81px; +} + +.guest-edit-cdrom-button.detach[disabled] { + background-position: -54px -108px; +} + +#message-container { + color: #555; + font-size: 14px; + height: 100%; + line-height: 56px; +} + +#message-container .message { + background: transparent; +} + +#message-container .success { + color: green; +} + +#message-container .error { + color: red; +} + +#message-container .content { + margin: 0; + position: static; +} diff --git a/ui/images/theme-default/guest-icon-sprite.png b/ui/images/theme-default/guest-icon-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..81edb5945d3bd204313a6d53b55cecf17ee97679 GIT binary patch literal 6748 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 Bz#9Mn literal 0 HcmV?d00001 diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index f32fbb1..5ec5459 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -16,18 +16,110 @@ * limitations under the License. */ kimchi.guest_edit_main = function() { - var guestEditForm = $('#form-guest-edit'); + var buttonContainer = $('#action-button-container'); + $('#guest-edit-tabs').tabs({ + beforeActivate: function(event, ui) { + var deactivated = ui['oldPanel']; + if($(deactivated).attr('id') === 'form-guest-edit-general') { + $(buttonContainer).addClass('hidden'); + } + else { + $(buttonContainer).removeClass('hidden'); + } + } + }); + + var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); - kimchi.retrieveVM(kimchi.selectedGuest, function(guest) { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + + $('.detach', container).on('click', function(e) { + e.preventDefault(); + var settings = { + title : i18n['KCHAPI6004M'], + content : i18n['KCHVMCD6001M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + + var dev = $(this).data('dev'); + kimchi.confirm(settings, function() { + kimchi.deleteVMStorage({ + vm: kimchi.selectedGuest, + dev: dev + }, function() { + kimchi.topic('kimchi/vmCDROMDetached').publish(); + }); + }); + }); + }); + }; + + var initContent = function(guest) { guest['icon'] = guest['icon'] || 'images/icon-vm.png'; for ( var prop in guest) { $('input[name="' + prop + '"]', guestEditForm).val(guest[prop]); } - }); - $('#guest-edit-button-cancel').on('click', function() { - kimchi.window.close(); - }); + refreshCDROMs(); + + $('#guest-edit-attach-cdrom-button').on('click', function(event) { + event.preventDefault(); + kimchi.window.open("guest-storage-add.html"); + }); + + var messageNode = $('#message-container'); + var onAttached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6006M'], messageNode); + refreshCDROMs(); + }; + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + var onDetached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6008M'], messageNode); + refreshCDROMs(); + }; + + kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached); + + kimchi.clearGuestEdit = function() { + kimchi.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached); + }; + }; + + kimchi.retrieveVM(kimchi.selectedGuest, initContent); var submitForm = function(event) { $(saveButton).prop('disabled', true); @@ -42,6 +134,7 @@ kimchi.guest_edit_main = function() { }, function(err) { kimchi.message.error(err.responseJSON.reason); }); + event.preventDefault(); }; diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js index 94fcf01..bbd8d3d 100644 --- a/ui/js/src/kimchi.guest_main.js +++ b/ui/js/src/kimchi.guest_main.js @@ -85,11 +85,28 @@ kimchi.vmdelete = function(event) { }); }; +kimchi.vmmedia = function(event) { + var vm = $(this).closest('li[name=guest]'); + var vm_id = vm.attr('id'); + kimchi.selectedGuest = vm_id; + kimchi.window.open({ + url: 'guest-media.html', + close: function() { + kimchi.clearGuestMedia(); + } + }); +}; + kimchi.vmedit = function(event) { var vm = $(this).closest('li[name=guest]'); var vm_id=vm.attr("id"); kimchi.selectedGuest = vm_id; - kimchi.window.open("guest-edit.html"); + kimchi.window.open({ + url: 'guest-edit.html', + close: function() { + kimchi.clearGuestEdit(); + } + }); }; kimchi.openVmConsole = function(event) { @@ -233,6 +250,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { if (vmRunningBool) { //If the guest is not running, do not enable reset guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset}); } + guestActions.find("[name=vm-media]").on({click : kimchi.vmmedia}); guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit}); guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete}); diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index a461031..ba6ba2b 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -27,74 +27,114 @@ <div class="close">X</div> </header> <div class="content"> - <form id="form-guest-edit"> - <fieldset class="guest-edit-fieldset"> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-id-textbox"> - $_("Name") - </label> + <div id="guest-edit-tabs"> + <ul> + <li> + <a href="#form-guest-edit-general">$_("General")</a> + </li> + <li> + <a href="#form-guest-edit-storage">$_("Storage")</a> + </li> + </ul> + <form id="form-guest-edit-general"> + <fieldset class="guest-edit-fieldset"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-id-textbox"> + $_("Name") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-id-textbox" + name="name" type="text" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-id-textbox" - name="name" type="text" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-cores-textbox"> + $_("CPUs") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-cores-textbox" + name="cpus" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-cores-textbox"> - $_("CPUs") - </label> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-memory-textbox"> + $_("Memory") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-memory-textbox" + name="memory" + type="text" + disabled="disabled" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-cores-textbox" - name="cpus" - type="text" - disabled="disabled" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-icon-textbox"> + $_("Icon") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-icon-textbox" + name="icon" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-memory-textbox"> - $_("Memory") - </label> + </fieldset> + </form> + <form id="form-guest-edit-storage"> + <fieldset class="guest-edit-fieldset"> + <div id="guest-edit-cdrom-row-container" class="guest-edit-cdrom-row-container"></div> + <div> + <button id="guest-edit-attach-cdrom-button" + class="guest-edit-cdrom-button attach" + title="$_("Attach")"> + </button> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-memory-textbox" - name="memory" - type="text" - disabled="disabled" /> - </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-icon-textbox"> - $_("Icon") - </label> - </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-icon-textbox" - name="icon" - type="text" - disabled="disabled" /> - </div> - </div> - </fieldset> - </form> + </fieldset> + </form> + </div> </div> <footer> - <div class="btn-group"> - <button id="guest-edit-button-cancel" class="btn-normal"> - <span class="text">$_("Cancel")</span> - </button> + <div id="action-button-container" class="btn-group"> <button id="guest-edit-button-save" class="btn-normal"> <span class="text">$_("Save")</span> </button> </div> + <div id="message-container"></div> </footer> </div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + <button class="guest-edit-cdrom-button detach" + data-vm="{vm}" data-dev="{dev}" + title="$_("Detach")"> + </button> + </div> + </div> +</script> + <script type="text/javascript"> kimchi.guest_edit_main(); </script> diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl index 0115837..a9737a5 100644 --- a/ui/pages/guest.html.tmpl +++ b/ui/pages/guest.html.tmpl @@ -56,6 +56,7 @@ <span class="text">$_("Actions")</span><span class="arrow"></span> <div class="popover actionsheet right-side" style="width: 250px"> <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Console")</span></button> + <button class="button-big shutoff-disabled" name="vm-media"><span class="text">$_("Manage Media")</span></button> <button class="button-big running-disabled" name="vm-edit"><span class="text">$_("Edit")</span></button> <a class="button-big red " name="vm-delete">$_("Delete")</a> </div> -- 1.8.1.4

Thanks, Adam! It fixed the problem on FF. On 03/10/2014 05:26 PM, Adam King wrote:
From: Hongliang Wang <hlwang@linux.vnet.ibm.com>
Allow user to manipulate CDROM(s) in a VM: 1) Attach one or more CDROM(s) (only for stopped VM); 2) Replace a CDROM with another ISO file path; 3) Detach a CDROM from a VM (only for stopped VM).
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 144 ++++++++++++++++++++++--- ui/images/theme-default/guest-icon-sprite.png | Bin 0 -> 6748 bytes ui/js/src/kimchi.guest_edit_main.js | 105 ++++++++++++++++-- ui/js/src/kimchi.guest_main.js | 20 +++- ui/pages/guest-edit.html.tmpl | 150 ++++++++++++++++---------- ui/pages/guest.html.tmpl | 1 + 6 files changed, 345 insertions(+), 75 deletions(-) create mode 100644 ui/images/theme-default/guest-icon-sprite.png
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index f4ccdee..43f71c0 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -17,36 +17,53 @@ */ #guest-edit-window { font-size: 13px; - height: 380px; - width: 420px; + height: 400px; + width: 600px; }
-.guest-edit-fieldset { - float: left; +#guest-edit-tabs { + background: transparent; + border: none; + height: 100%; + padding: 0; +} + +#form-guest-edit-general, +#form-guest-edit-storage { padding: 1em; }
+.guest-edit-fieldset { + padding-right: 0; +} + .guest-edit-wrapper-label, .guest-edit-wrapper-controls { display: inline-block; }
-.guest-edit-wrapper-controls input[type="text"][disabled] { - color: #bbb; - background-color: #fafafa; - cursor: not-allowed; +.guest-edit-wrapper-label { + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; + width: 80px; }
-.guest-edit-wrapper-label { - width: 10em; +#form-guest-edit-storage .guest-edit-wrapper-label { + width: 60px; }
.guest-edit-wrapper-controls { - width: 18em; + width: 470px; +} + +#form-guest-edit-storage .guest-edit-wrapper-controls { + width: 486px; }
.guest-edit-wrapper-controls input[type="text"] { + font-size: 16px; height: 38px; - line-height: 38px; background: #fff; -webkit-border-radius: 5px; border-radius: 5px; @@ -54,7 +71,7 @@ border-top: 1px solid #bbb; border-left: 1px solid #bbb; padding-left: 10px; - width: 100%; + width: 450px; }
.guest-edit-wrapper-controls input[type="text"][disabled] { @@ -62,3 +79,104 @@ background-color: #fafafa; cursor: not-allowed; } + +.guest-edit-cdrom-row-container { + max-height: 180px; + overflow: auto; +} + +.guest-edit-cdrom-row-container input[type="text"] { + width: 400px; +} + +.guest-edit-cdrom-button { + background: url("../images/theme-default/guest-icon-sprite.png") no-repeat left top transparent; + border: none; + height: 25px; + vertical-align: middle; + width: 25px; +} + +.guest-edit-cdrom-button.attach { + margin: 15px 0 0 521px; +} + +.guest-edit-cdrom-button.attach:hover { + background-position: 0 -27px; +} + +.guest-edit-cdrom-button.attach:focus { + background-position: 0 -54px; +} + +.guest-edit-cdrom-button.attach:active { + background-position: 0 -81px; +} + +.guest-edit-cdrom-button.attach[disabled] { + background-position: 0 -108px; +} + +.guest-edit-cdrom-button.replace { + background-position: -27px 0; +} + +.guest-edit-cdrom-button.replace:hover { + background-position: -27px -27px; +} + +.guest-edit-cdrom-button.replace:focus { + background-position: -27px -54px; +} + +.guest-edit-cdrom-button.replace:active { + background-position: -27px -81px; +} + +.guest-edit-cdrom-button.replace[disabled] { + background-position: -27px -108px; +} + +.guest-edit-cdrom-button.detach { + background-position: -54px 0; +} + +.guest-edit-cdrom-button.detach:hover { + background-position: -54px -27px; +} + +.guest-edit-cdrom-button.detach:focus { + background-position: -54px -54px; +} + +.guest-edit-cdrom-button.detach:active { + background-position: -54px -81px; +} + +.guest-edit-cdrom-button.detach[disabled] { + background-position: -54px -108px; +} + +#message-container { + color: #555; + font-size: 14px; + height: 100%; + line-height: 56px; +} + +#message-container .message { + background: transparent; +} + +#message-container .success { + color: green; +} + +#message-container .error { + color: red; +} + +#message-container .content { + margin: 0; + position: static; +} diff --git a/ui/images/theme-default/guest-icon-sprite.png b/ui/images/theme-default/guest-icon-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..81edb5945d3bd204313a6d53b55cecf17ee97679 GIT binary patch literal 6748 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 Bz#9Mn
literal 0 HcmV?d00001
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index f32fbb1..5ec5459 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -16,18 +16,110 @@ * limitations under the License. */ kimchi.guest_edit_main = function() { - var guestEditForm = $('#form-guest-edit'); + var buttonContainer = $('#action-button-container'); + $('#guest-edit-tabs').tabs({ + beforeActivate: function(event, ui) { + var deactivated = ui['oldPanel']; + if($(deactivated).attr('id') === 'form-guest-edit-general') { + $(buttonContainer).addClass('hidden'); + } + else { + $(buttonContainer).removeClass('hidden'); + } + } + }); + + var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); - kimchi.retrieveVM(kimchi.selectedGuest, function(guest) { + + var refreshCDROMs = function() { + kimchi.listVMStorages({ + vm: kimchi.selectedGuest, + storageType: 'cdrom' + }, function(storages) { + var rowHTML = $('#cdrom-row-tmpl').html(); + var container = $('#guest-edit-cdrom-row-container'); + $(container).empty(); + + $.each(storages, function(index, storage) { + storage['vm'] = kimchi.selectedGuest; + var templated = kimchi.template(rowHTML, storage); + container.append(templated); + }); + + var replaceCDROM = function(event) { + event.preventDefault(); + kimchi.selectedGuestStorage = $(this).data('dev'); + kimchi.window.open("guest-cdrom-edit.html"); + }; + + $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); + $('.replace', container).on('click', replaceCDROM); + + $('.detach', container).on('click', function(e) { + e.preventDefault(); + var settings = { + title : i18n['KCHAPI6004M'], + content : i18n['KCHVMCD6001M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + + var dev = $(this).data('dev'); + kimchi.confirm(settings, function() { + kimchi.deleteVMStorage({ + vm: kimchi.selectedGuest, + dev: dev + }, function() { + kimchi.topic('kimchi/vmCDROMDetached').publish(); + }); + }); + }); + }); + }; + + var initContent = function(guest) { guest['icon'] = guest['icon'] || 'images/icon-vm.png'; for ( var prop in guest) { $('input[name="' + prop + '"]', guestEditForm).val(guest[prop]); } - });
- $('#guest-edit-button-cancel').on('click', function() { - kimchi.window.close(); - }); + refreshCDROMs(); + + $('#guest-edit-attach-cdrom-button').on('click', function(event) { + event.preventDefault(); + kimchi.window.open("guest-storage-add.html"); + }); + + var messageNode = $('#message-container'); + var onAttached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6006M'], messageNode); + refreshCDROMs(); + }; + var onReplaced = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6007M'], messageNode); + refreshCDROMs(); + }; + var onDetached = function(params) { + $(messageNode).empty(); + kimchi.message.success(i18n['KCHVMCD6008M'], messageNode); + refreshCDROMs(); + }; + + kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached); + + kimchi.clearGuestEdit = function() { + kimchi.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached); + kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + kimchi.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached); + }; + }; + + kimchi.retrieveVM(kimchi.selectedGuest, initContent);
var submitForm = function(event) { $(saveButton).prop('disabled', true); @@ -42,6 +134,7 @@ kimchi.guest_edit_main = function() { }, function(err) { kimchi.message.error(err.responseJSON.reason); }); + event.preventDefault(); };
diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js index 94fcf01..bbd8d3d 100644 --- a/ui/js/src/kimchi.guest_main.js +++ b/ui/js/src/kimchi.guest_main.js @@ -85,11 +85,28 @@ kimchi.vmdelete = function(event) { }); };
+kimchi.vmmedia = function(event) { + var vm = $(this).closest('li[name=guest]'); + var vm_id = vm.attr('id'); + kimchi.selectedGuest = vm_id; + kimchi.window.open({ + url: 'guest-media.html', + close: function() { + kimchi.clearGuestMedia(); + } + }); +}; + kimchi.vmedit = function(event) { var vm = $(this).closest('li[name=guest]'); var vm_id=vm.attr("id"); kimchi.selectedGuest = vm_id; - kimchi.window.open("guest-edit.html"); + kimchi.window.open({ + url: 'guest-edit.html', + close: function() { + kimchi.clearGuestEdit(); + } + }); };
kimchi.openVmConsole = function(event) { @@ -233,6 +250,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { if (vmRunningBool) { //If the guest is not running, do not enable reset guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset}); } + guestActions.find("[name=vm-media]").on({click : kimchi.vmmedia}); guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit}); guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index a461031..ba6ba2b 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -27,74 +27,114 @@ <div class="close">X</div> </header> <div class="content"> - <form id="form-guest-edit"> - <fieldset class="guest-edit-fieldset"> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-id-textbox"> - $_("Name") - </label> + <div id="guest-edit-tabs"> + <ul> + <li> + <a href="#form-guest-edit-general">$_("General")</a> + </li> + <li> + <a href="#form-guest-edit-storage">$_("Storage")</a> + </li> + </ul> + <form id="form-guest-edit-general"> + <fieldset class="guest-edit-fieldset"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-id-textbox"> + $_("Name") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-id-textbox" + name="name" type="text" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-id-textbox" - name="name" type="text" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-cores-textbox"> + $_("CPUs") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-cores-textbox" + name="cpus" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-cores-textbox"> - $_("CPUs") - </label> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-memory-textbox"> + $_("Memory") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="guest-edit-memory-textbox" + name="memory" + type="text" + disabled="disabled" /> + </div> </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-cores-textbox" - name="cpus" - type="text" - disabled="disabled" /> + <div> + <div class="guest-edit-wrapper-label"> + <label for="guest-edit-icon-textbox"> + $_("Icon") + </label> + </div> + <div class="guest-edit-wrapper-controls"> + <input + id="guest-edit-icon-textbox" + name="icon" + type="text" + disabled="disabled" /> + </div> </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-memory-textbox"> - $_("Memory") - </label> + </fieldset> + </form> + <form id="form-guest-edit-storage"> + <fieldset class="guest-edit-fieldset"> + <div id="guest-edit-cdrom-row-container" class="guest-edit-cdrom-row-container"></div> + <div> + <button id="guest-edit-attach-cdrom-button" + class="guest-edit-cdrom-button attach" + title="$_("Attach")"> + </button> </div> - <div class="guest-edit-wrapper-controls"> - <input id="guest-edit-memory-textbox" - name="memory" - type="text" - disabled="disabled" /> - </div> - </div> - <div> - <div class="guest-edit-wrapper-label"> - <label for="guest-edit-icon-textbox"> - $_("Icon") - </label> - </div> - <div class="guest-edit-wrapper-controls"> - <input - id="guest-edit-icon-textbox" - name="icon" - type="text" - disabled="disabled" /> - </div> - </div> - </fieldset> - </form> + </fieldset> + </form> + </div> </div> <footer> - <div class="btn-group"> - <button id="guest-edit-button-cancel" class="btn-normal"> - <span class="text">$_("Cancel")</span> - </button> + <div id="action-button-container" class="btn-group"> <button id="guest-edit-button-save" class="btn-normal"> <span class="text">$_("Save")</span> </button> </div> + <div id="message-container"></div> </footer> </div> +<script id="cdrom-row-tmpl" type="text/html"> + <div> + <div class="guest-edit-wrapper-label"> + <label for="cdrom-{dev}">{dev}</label> + </div> + <div class="guest-edit-wrapper-controls"> + <input id="cdrom-{dev}" name="cdrom" type="text" + data-vm="{vm}" data-dev="{dev}" + value="{path}" readonly="readonly" /> + <button class="guest-edit-cdrom-button replace" + data-vm="{vm}" data-dev="{dev}" + title="$_("Replace")"> + </button> + <button class="guest-edit-cdrom-button detach" + data-vm="{vm}" data-dev="{dev}" + title="$_("Detach")"> + </button> + </div> + </div> +</script> + <script type="text/javascript"> kimchi.guest_edit_main(); </script> diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl index 0115837..a9737a5 100644 --- a/ui/pages/guest.html.tmpl +++ b/ui/pages/guest.html.tmpl @@ -56,6 +56,7 @@ <span class="text">$_("Actions")</span><span class="arrow"></span> <div class="popover actionsheet right-side" style="width: 250px"> <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Console")</span></button> + <button class="button-big shutoff-disabled" name="vm-media"><span class="text">$_("Manage Media")</span></button> <button class="button-big running-disabled" name="vm-edit"><span class="text">$_("Edit")</span></button> <a class="button-big red " name="vm-delete">$_("Delete")</a> </div>
participants (3)
-
Adam King
-
Aline Manera
-
Hongliang Wang