[Kimchi-devel] [PATCH] [Kimchi] [RFC] Create new volume and attach to VM
Paulo Ricardo Paz Vital
pvital at linux.vnet.ibm.com
Fri Feb 5 12:40:53 UTC 2016
On 02/05/2016 10:35 AM, Aline Manera wrote:
>
>
> On 02/05/2016 10:27 AM, Paulo Ricardo Paz Vital wrote:
>> On 02/05/2016 10:03 AM, Aline Manera wrote:
>>>
>>> On 02/05/2016 09:03 AM, Paulo Ricardo Paz Vital wrote:
>>>> Looks good! I tested the patch and could create a new volume and attach
>>>> it to the VM I was editing.
>>>>
>>>> Just only one suggestion. Add the extension iso in the end of the
>>>> filename of the volume when creating. The volume I added to my VM
>>>> 'ubuntu15.10-vm-1' was created with this info:
>>>>
>>>> $ sudo qemu-img info
>>>> /var/lib/libvirt/images/ubuntu15.10-vm-11454669512074
>>>> image: /var/lib/libvirt/images/ubuntu15.10-vm-11454669512074
>>>> file format: qcow2
>>>> virtual size: 10K (10240 bytes)
>>>> disk size: 196K
>>>> cluster_size: 65536
>>>> Format specific information:
>>>> compat: 0.10
>>>> refcount bits: 16
>>>>
>>>> Would be nice, that the file has the name
>>>> ubuntu15.10-vm-11454669512074.iso
>>> The extension '.iso' is for ISO files. In this case, we should use the
>>> extension given by the selected format, ie, in your case
>>> ubuntu15.10-vm-11454669512074*.qcow2
>>>
>>> *Socorro, following Paulo's suggestion, please, append the ".<format>"
>>> to the end of the file name.
>>
>> Ooops, I mean '.img' instead of '.iso', but if add the '.<format>' is
>> not a big issue, would be better than.
>
> Yeap! So I'd suggest to use .img (instead the format) as Template is
> using that way and we keep consistence.
>
+1 for .img
>>> *
>>> *
>>>> On 02/05/2016 12:41 AM, Socorro Stoppler wrote:
>>>>> This is the initial checkin for creating a new volume and attaching
>>>>> to VM when editing a guest.
>>>>> Not sure of all the supported cases, but certainly tried default
>>>>> pool and qcow2 format per the
>>>>> example provided and it was successful.
>>>>>
>>>>> Known issue - which currently exists in the code already in master
>>>>> - code is broken when VM
>>>>> is running. This patch does not address that. It will get
>>>>> addressed separately.
>>>>>
>>>>>
>>>>> Signed-off-by: Socorro Stoppler <socorro at linux.vnet.ibm.com>
>>>>> ---
>>>>> ui/js/src/kimchi.guest_storage_add.main.js | 320
>>>>> ++++++++++++++++++++++++-----
>>>>> ui/pages/guest-storage-add.html.tmpl | 58 ++++--
>>>>> 2 files changed, 315 insertions(+), 63 deletions(-)
>>>>>
>>>>> diff --git a/ui/js/src/kimchi.guest_storage_add.main.js
>>>>> b/ui/js/src/kimchi.guest_storage_add.main.js
>>>>> index 6e1926b..9c3f6e4 100644
>>>>> --- a/ui/js/src/kimchi.guest_storage_add.main.js
>>>>> +++ b/ui/js/src/kimchi.guest_storage_add.main.js
>>>>> @@ -15,6 +15,37 @@
>>>>> * See the License for the specific language governing
>>>>> permissions and
>>>>> * limitations under the License.
>>>>> */
>>>>> +kimchi.switchPage = function(fromPageId, toPageId, direction) {
>>>>> + $('.tab-content').css('overflow', 'hidden');
>>>>> + direction = direction || 'left';
>>>>> + var toLeftBegin;
>>>>> + var fromLeftEnd;
>>>>> + if ('left' === direction) {
>>>>> + toLeftBegin = '100%';
>>>>> + fromLeftEnd = '-100%';
>>>>> + } else if ('right' === direction) {
>>>>> + toLeftBegin = '-100%';
>>>>> + fromLeftEnd = '100%';
>>>>> + }
>>>>> + var formPage = $('#' + fromPageId);
>>>>> + var toPage = $('#' + toPageId);
>>>>> + toPage.css({
>>>>> + left: toLeftBegin
>>>>> + });
>>>>> + formPage.animate({
>>>>> + left: fromLeftEnd,
>>>>> + opacity: 0.1
>>>>> + }, 400, function() {
>>>>> + $('.tab-content').css('overflow', 'visible');
>>>>> + });
>>>>> + toPage.animate({
>>>>> + left: '0',
>>>>> + opacity: 1
>>>>> + }, 400, function() {
>>>>> + $('.tab-content').css('overflow', 'visible');
>>>>> + });
>>>>> +};
>>>>> +
>>>>> kimchi.guest_storage_add_main = function() {
>>>>> var types = [{
>>>>> label: 'cdrom',
>>>>> @@ -35,9 +66,27 @@ kimchi.guest_storage_add_main = function() {
>>>>> var pathTextbox = $('input[name="path"]', storageAddForm);
>>>>> var poolTextbox = $('select#guest-disk-pool', storageAddForm);
>>>>> var volTextbox = $('select#guest-disk-vol', storageAddForm);
>>>>> + var newPoolTextbox = $('select#guest-disk-pool-new',
>>>>> storageAddForm);
>>>>> + var capacityTextbox = $('input[name="capacity"]',
>>>>> storageAddForm);
>>>>> + var formatTextbox = $('select#guest-disk-format-new',
>>>>> storageAddForm);
>>>>> var selectStorageTypeHTML = '';
>>>>> var selectStoragePoolHTML = '';
>>>>> var selectStorageVolHTML = '';
>>>>> + var rbExisting = 'false';
>>>>> +
>>>>> + var getFormatList = function() {
>>>>> + var format = ["bochs", "cloop", "cow", "dmg", "qcow",
>>>>> "qcow2", "qed", "raw", "vmdk", "vpc"];
>>>>> + var selectFormatHTML = '';
>>>>> + var i;
>>>>> + for (i = 0; i < format.length; i++) {
>>>>> + selectFormatHTML += '<option value="'+ format[i] +
>>>>> '">' + format[i] + '</option>';
>>>>> + }
>>>>> + formatTextbox.empty();
>>>>> + formatTextbox.append(selectFormatHTML);
>>>>> + $(formatTextbox).change();
>>>>> + formatTextbox.selectpicker();
>>>>> + $('.selectpicker').selectpicker('refresh');
>>>>> + };
>>>>>
>>>>> typeTextbox.change(function() {
>>>>> var pathObject = {'cdrom': ".path-section", 'disk':
>>>>> '.volume-section'};
>>>>> @@ -45,41 +94,82 @@ kimchi.guest_storage_add_main = function() {
>>>>> $.each(pathObject, function(type, value) {
>>>>> if(selectType === type){
>>>>> $(value).removeClass('hidden');
>>>>> + } else if ((selectType === null) && (type === 'disk')) {
>>>>> + $(value).removeClass('hidden');
>>>>> } else {
>>>>> $(value).addClass('hidden');
>>>>> }
>>>>> });
>>>>> -
>>>>> if ($(".path-section").hasClass('hidden')) {
>>>>> - $(poolTextbox).val('default');
>>>>> - $(poolTextbox).change();
>>>>> $(pathTextbox).val("");
>>>>> - }
>>>>> - else {
>>>>> + if ($('#new-disk').checked) {
>>>>> + $('#existing-disk-box').addClass('hidden');
>>>>> + $(newPoolTextbox).val('default');
>>>>> + $(newPoolTextbox).change();
>>>>> + } else if ($('#existing-disk').checked) {
>>>>> + $('#new-disk-box').addClass('hidden');
>>>>> + $(poolTextbox).val('default');
>>>>> + $(poolTextbox).change();
>>>>> + } else {
>>>>> + if (rbExisting === 'true') {
>>>>> + $('#new-disk-box').addClass('hidden');
>>>>> + } else {
>>>>> + $('#existing-disk-box').addClass('hidden');
>>>>> + }
>>>>> + }
>>>>> + } else {
>>>>> $(poolTextbox).val("");
>>>>> $(volTextbox).val("");
>>>>> + $(newPoolTextbox).val("");
>>>>> + $(capacityTextbox).val("");
>>>>> + $(formatTextbox).val("");
>>>>> }
>>>>> $('.selectpicker').selectpicker('refresh');
>>>>> });
>>>>>
>>>>> - kimchi.listStoragePools(function(result) {
>>>>> - var options = [];
>>>>> - if (result && result.length) {
>>>>> - $.each(result, function(index, storagePool) {
>>>>> - if ((storagePool.state==="active") &&
>>>>> (storagePool.type !== 'kimchi-iso')) {
>>>>> - options.push({
>>>>> - label: storagePool.name,
>>>>> - value: storagePool.name
>>>>> - });
>>>>> - selectStoragePoolHTML += '<option value="'+
>>>>> storagePool.name + '">' + storagePool.name + '</option>';
>>>>> + var getStoragePools = function(radioButton) {
>>>>> + kimchi.listStoragePools(function(result) {
>>>>> + var options = [];
>>>>> + selectStoragePoolHTML = ''; //reset string
>>>>> + if (result && result.length) {
>>>>> + $.each(result, function(index, storagePool) {
>>>>> + if (radioButton === 'existing') {
>>>>> + if ((storagePool.state==="active") &&
>>>>> (storagePool.type !== 'kimchi-iso')) {
>>>>> + options.push({
>>>>> + label: storagePool.name,
>>>>> + value: storagePool.name
>>>>> + });
>>>>> + selectStoragePoolHTML += '<option
>>>>> value="'+ storagePool.name + '">' + storagePool.name + '</option>';
>>>>> + }
>>>>> + } else { //new disk
>>>>> + if ((storagePool.type != 'iscsi') &&
>>>>> (storagePool.type != 'scsi')) {
>>>>> + options.push({
>>>>> + label: storagePool.name,
>>>>> + value: storagePool.name
>>>>> + });
>>>>> + selectStoragePoolHTML += '<option
>>>>> value="'+ storagePool.name + '">' + storagePool.name + '</option>';
>>>>> + }
>>>>> }
>>>>> -
>>>>> });
>>>>> - poolTextbox.append(selectStoragePoolHTML);
>>>>> - poolTextbox.val(options[0].value);
>>>>> - poolTextbox.selectpicker();
>>>>> - }
>>>>> - });
>>>>> + if (radioButton === 'existing') {
>>>>> + poolTextbox.empty();
>>>>> + poolTextbox.append(selectStoragePoolHTML);
>>>>> + $(poolTextbox).change();
>>>>> + poolTextbox.selectpicker();
>>>>> + $('.selectpicker').selectpicker('refresh');
>>>>> + } else if (radioButton === 'new') { //new disk
>>>>> + newPoolTextbox.empty();
>>>>> + newPoolTextbox.append(selectStoragePoolHTML);
>>>>> + $(newPoolTextbox).val(options[0].value);
>>>>> + newPoolTextbox.selectpicker();
>>>>> + getFormatList();
>>>>> + }
>>>>> + }
>>>>> + });
>>>>> + };
>>>>> +
>>>>> + //First time retrieving list of Storage Pools - defaulting to
>>>>> new disk
>>>>> + getStoragePools('new');
>>>>>
>>>>> poolTextbox.change(function() {
>>>>> var options = [];
>>>>> @@ -109,13 +199,15 @@ kimchi.guest_storage_add_main = function() {
>>>>> $(volTextbox).prop('disabled',true);
>>>>> $(submitButton).prop('disabled', true);
>>>>> }
>>>>> - volTextbox.selectpicker();
>>>>> - $('.selectpicker').selectpicker('refresh');
>>>>> + } else {
>>>>> + $(volTextbox).prop('disabled',true);
>>>>> + $(submitButton).prop('disabled', true);
>>>>> }
>>>>> + volTextbox.selectpicker();
>>>>> + $('.selectpicker').selectpicker('refresh');
>>>>> }, null, false);
>>>>> });
>>>>>
>>>>> -
>>>>> typeTextbox.change(function() {
>>>>> var pathObject = {'cdrom': ".path-section", 'disk':
>>>>> '.volume-section'}; var selectType = $(this).val(); @@
>>>>> -128,6 +220,47 @@ kimchi.guest_storage_add_main = function() { });
>>>>> }); + var currentPage = 'new-disk-box'; +
>>>>> $('#existing-disk').change(function() { + if (this.checked) { +
>>>>> rbExisting = 'true'; + if (currentPage === 'new-disk-box') { +
>>>>> kimchi.switchPage(currentPage, 'existing-disk-box', 'right'); + } +
>>>>> currentPage = 'existing-disk-box'; +
>>>>> $('#existing-disk-box').removeClass('hidden'); +
>>>>> $('#new-disk-box').addClass('hidden'); + $('#guest-storage-add-window
>>>>> .modal-body .template-pager').animate({ + height: "200px"
>>>>> + }, 300);
>>>>> + getStoragePools('existing');
>>>>> + $(pathTextbox).val("");
>>>>> + $(newPoolTextbox).val("");
>>>>> + $(capacityTextbox).val("");
>>>>> + $(formatTextbox).val("");
>>>>> + }
>>>>> + });
>>>>> +
>>>>> + $('#new-disk').change(function() {
>>>>> + if (this.checked) {
>>>>> + rbExisting = 'false';
>>>>> + if (currentPage === 'existing-disk-box') {
>>>>> + kimchi.switchPage(currentPage, 'new-disk-box',
>>>>> 'right');
>>>>> + } else if($(capacityTextbox).is(":visible") === false ) {
>>>>> + kimchi.switchPage(currentPage, 'new-disk-box',
>>>>> 'right');
>>>>> + }
>>>>> + currentPage = 'new-disk-box';
>>>>> + $('#existing-disk-box').addClass('hidden');
>>>>> + $('#new-disk-box').removeClass('hidden');
>>>>> + $('#guest-storage-add-window .modal-body
>>>>> .template-pager').animate({
>>>>> + height: "300px"
>>>>> + }, 400);
>>>>> + $(pathTextbox).val("");
>>>>> + $(poolTextbox).val("");
>>>>> + $(volTextbox).val("");
>>>>> + }
>>>>> + });
>>>>> +
>>>>> if (kimchi.thisVMState === 'running') {
>>>>> types =typesRunning;
>>>>> $(typeTextbox).val('disk');
>>>>> @@ -155,15 +288,104 @@ kimchi.guest_storage_add_main = function() {
>>>>> }
>>>>> };
>>>>>
>>>>> + var onError = function(result) {
>>>>> + if(!result) {
>>>>> + return;
>>>>> + }
>>>>> + var msg = result['message'] || (
>>>>> + result['responseJSON'] &&
>>>>> result['responseJSON']['reason']
>>>>> + );
>>>>> + wok.message.error(msg);
>>>>> + };
>>>>> +
>>>>> + var addStorage = function(settings) {
>>>>> + kimchi.addVMStorage(settings, function(result) {
>>>>> + wok.window.close();
>>>>> + wok.topic('kimchi/vmCDROMAttached').publish({
>>>>> + result: result
>>>>> + });
>>>>> + }, function(result) {
>>>>> + var errText = result['reason'] ||
>>>>> + result['responseJSON']['reason'];
>>>>> + wok.message.error(errText, '#alert-modal-container2');
>>>>> + $.each([submitButton, pathTextbox, poolTextbox,
>>>>> volTextbox, newPoolTextbox, capacityTextbox, formatTextbox],
>>>>> function(i, c) {
>>>>> + $(c).prop('disabled', false);
>>>>> + });
>>>>> + });
>>>>> + }
>>>>> +
>>>>> + var createVol = function(settings, addVolSettings) {
>>>>> + kimchi.createVolumeWithCapacity('default', {
>>>>> + name: settings['vol'],
>>>>> + format: settings['format'],
>>>>> + capacity: settings['capacity']
>>>>> + }, function(result) {
>>>>> + var taskId = result.id;
>>>>> + function monitorTask() {
>>>>> + kimchi.getTask(taskId, function(result) {
>>>>> + var status = result.status;
>>>>> + if (status === "finished") {
>>>>> + //Now add newly created volume to VM
>>>>> + addStorage(addVolSettings);
>>>>> + } else if (status === "running") {
>>>>> + setTimeout(monitorTask, 2000);
>>>>> + $(submitButton).prop('disabled', true);
>>>>> + } else if (status === "failed") {
>>>>> + var errText = result['reason'] ||
>>>>> + result['responseJSON']['reason'];
>>>>> + $(submitButton).prop('disabled', true);
>>>>> + wok.message.error(errText,
>>>>> '#alert-modal-container2');
>>>>> + }
>>>>> + });
>>>>> + }
>>>>> + setTimeout(monitorTask, 2000);
>>>>> + }, onError);
>>>>> + };
>>>>> +
>>>>> + var bNewDisk = 'false';
>>>>> +
>>>>> var validateDisk = function(settings) {
>>>>> - if (settings['pool'] && settings['vol']){
>>>>> - // Delete path property since it's not needed for disk
>>>>> - delete settings['path'];
>>>>> - return true;
>>>>> + // Determine whether it's existing disk or new disk
>>>>> + if($(capacityTextbox).is(":visible") === true ) {
>>>>> + bNewDisk = 'true';
>>>>> }
>>>>> - else {
>>>>> -
>>>>> wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2');
>>>>> - return false;
>>>>> + if (bNewDisk === 'true') {
>>>>> + if (settings['newpool'] && settings['capacity'] &&
>>>>> settings['format']){
>>>>> + //Change settings['newpool'] to settings['pool']
>>>>> + settings['pool']=settings['newpool'];
>>>>> + var vmname = settings['vm'];
>>>>> + vmname = vmname + new Date().getTime();
>>>>> + //Unique vol name to be created
>>>>> + settings['vol']=vmname;
>>>>> + //This is all that is needed for attaching newly
>>>>> created volume to VM
>>>>> + var addVolSettings = {
>>>>> + vm: settings['vm'],
>>>>> + type: settings['type'],
>>>>> + vol: settings['vol'],
>>>>> + pool: settings['pool']
>>>>> + };
>>>>> + var sizeInMB = parseInt(settings['capacity']) * 1024;
>>>>> + settings['capacity'] = sizeInMB;
>>>>> + //These need to be deleted so they don't get
>>>>> passed to backend
>>>>> + delete settings['path'];
>>>>> + delete settings['newpool'];
>>>>> + //Create an empty storage volume and attach to VM
>>>>> if successful
>>>>> + createVol(settings, addVolSettings);
>>>>> + return true;
>>>>> + } else {
>>>>> +
>>>>> wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2');
>>>>> + return false;
>>>>> + }
>>>>> + } else {
>>>>> + if (settings['pool'] && settings['vol']){
>>>>> + // Delete path property since it's not needed for
>>>>> disk
>>>>> + delete settings['path'];
>>>>> + return true;
>>>>> + }
>>>>> + else {
>>>>> +
>>>>> wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2');
>>>>> + return false;
>>>>> + }
>>>>> }
>>>>> };
>>>>>
>>>>> @@ -172,6 +394,11 @@ kimchi.guest_storage_add_main = function() {
>>>>> if (submitButton.prop('disabled')) {
>>>>> return false;
>>>>> }
>>>>> + var bNewDisk = 'false';
>>>>> + // Determine whether it's existing disk or new disk
>>>>> + if($(capacityTextbox).is(":visible") === true ) {
>>>>> + bNewDisk = 'true';
>>>>> + }
>>>>>
>>>>> var formData = storageAddForm.serializeObject();
>>>>> var settings = {
>>>>> @@ -179,40 +406,30 @@ kimchi.guest_storage_add_main = function() {
>>>>> type: typeTextbox.val(),
>>>>> path: pathTextbox.val(),
>>>>> pool: poolTextbox.val(),
>>>>> - vol: volTextbox.val()
>>>>> + vol: volTextbox.val(),
>>>>> + newpool: newPoolTextbox.val(),
>>>>> + format: formatTextbox.val(),
>>>>> + capacity: capacityTextbox.val()
>>>>> };
>>>>>
>>>>> $(submitButton).prop('disabled', true);
>>>>> - $.each([pathTextbox, poolTextbox, volTextbox], function(i,
>>>>> c) {
>>>>> + $.each([pathTextbox, poolTextbox, volTextbox,
>>>>> newPoolTextbox, capacityTextbox, formatTextbox], function(i, c) {
>>>>> $(c).prop('disabled', true);
>>>>> });
>>>>> // Validate form for cdrom and disk
>>>>> validateSpecifiedForm = validator[settings['type']];
>>>>> if (!validateSpecifiedForm(settings)) {
>>>>> $(submitButton).prop('disabled', false);
>>>>> - $.each([submitButton, pathTextbox, poolTextbox,
>>>>> volTextbox], function(i, c) {
>>>>> + $.each([submitButton, pathTextbox, poolTextbox,
>>>>> volTextbox, newPoolTextbox, capacityTextbox, formatTextbox],
>>>>> function(i, c) {
>>>>> $(c).prop('disabled', false);
>>>>> });
>>>>> return false;
>>>>> }
>>>>>
>>>>> $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']);
>>>>>
>>>>> - kimchi.addVMStorage(settings, function(result) {
>>>>> - wok.window.close();
>>>>> - wok.topic('kimchi/vmCDROMAttached').publish({
>>>>> - result: result
>>>>> - });
>>>>> - }, function(result) {
>>>>> - var errText = result['reason'] ||
>>>>> - result['responseJSON']['reason'];
>>>>> - wok.message.error(errText, '#alert-modal-container2');
>>>>> -
>>>>> - $.each([submitButton, pathTextbox, poolTextbox,
>>>>> volTextbox], function(i, c) {
>>>>> - $(c).prop('disabled', false);
>>>>> - });
>>>>> -
>>>>> $(submitButton).removeClass('loading').text(i18n['KCHVMCD6002M']);
>>>>> - });
>>>>> -
>>>>> + if(bNewDisk === 'false'){
>>>>> + addStorage(settings);
>>>>> + }
>>>>> event.preventDefault();
>>>>> };
>>>>>
>>>>> @@ -224,5 +441,8 @@ kimchi.guest_storage_add_main = function() {
>>>>> volTextbox.on('change propertychange', function (event) {
>>>>> $(submitButton).prop('disabled', $(this).val() === '');
>>>>> });
>>>>> + capacityTextbox.on('change input propertychange',
>>>>> function(event) {
>>>>> + $(submitButton).prop('disabled', $(this).val() === '');
>>>>> + });
>>>>>
>>>>> };
>>>>> diff --git a/ui/pages/guest-storage-add.html.tmpl
>>>>> b/ui/pages/guest-storage-add.html.tmpl
>>>>> index bde0eee..660c274 100644
>>>>> --- a/ui/pages/guest-storage-add.html.tmpl
>>>>> +++ b/ui/pages/guest-storage-add.html.tmpl
>>>>> @@ -1,7 +1,7 @@
>>>>> #*
>>>>> * Project Kimchi
>>>>> *
>>>>> - * Copyright IBM, Corp. 2014
>>>>> + * Copyright IBM, Corp. 2014-2016
>>>>> *
>>>>> * Licensed under the Apache License, Version 2.0 (the "License");
>>>>> * you may not use this file except in compliance with the License.
>>>>> @@ -41,18 +41,50 @@
>>>>> </select>
>>>>> <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("The device type. Currently, \"cdrom\" and
>>>>> \"disk\" are supported.")</p>
>>>>> </div>
>>>>> - <div class="volume-section hidden">
>>>>> - <div class="form-group">
>>>>> - <label>$_("Storage Pool")</label>
>>>>> - <select id="guest-disk-pool"
>>>>> class="selectpicker col-md-12 col-lg-12">
>>>>> - </select>
>>>>> - <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("Storage pool which volume located in")</p>
>>>>> + <div class="volume-section hidden form-group">
>>>>> + <div class="template-modal-container">
>>>>> + <div>
>>>>> + <span id="alert-modal-container"></span>
>>>>> + <input type="radio" checked="checked"
>>>>> name="disk-btn" id="new-disk" value="new-disk" class="wok-radio">
>>>>> + <label for="new-disk">$_("Create a new
>>>>> disk")</label>
>>>>> + <input type="radio" name="disk-btn"
>>>>> id="existing-disk" value="existing-disk" class="wok-radio">
>>>>> + <label for="existing-disk">$_("Select
>>>>> an existing disk")</label>
>>>>> + </div>
>>>>> </div>
>>>>> - <div class="form-group">
>>>>> - <label>$_("Storage Volume")</label>
>>>>> - <select id="guest-disk-vol"
>>>>> class="selectpicker col-md-12 col-lg-12">
>>>>> - </select>
>>>>> - <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("Storage volume to be attached")</p>
>>>>> + <div class="template-pager">
>>>>> + <div class="page" id="new-disk-box">
>>>>> + <div class="form-group">
>>>>> + <label>$_("Storage Pool")</label>
>>>>> + <select id="guest-disk-pool-new"
>>>>> class="selectpicker col-md-12 col-lg-12">
>>>>> + </select>
>>>>> + <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("Storage pool to create the volume in")</p>
>>>>> + </div>
>>>>> + <div class="form-group">
>>>>> + <label>$_("Disk Size (GB)")</label>
>>>>> + <input type="number"
>>>>> class="form-control" name="capacity" min="1" id="capacity" />
>>>>> + <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("New disk size to be created")</p>
>>>>> + </div>
>>>>> + <div class="form-group">
>>>>> + <label>$_("Format")</label>
>>>>> + <select id="guest-disk-format-new"
>>>>> class="selectpicker col-md-12 col-lg-12">
>>>>> + </select>
>>>>> + <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("Format of the new disk to be created")</p>
>>>>> + </div>
>>>>> + </div>
>>>>> + <div class="page" id="existing-disk-box">
>>>>> + <div class="form-group">
>>>>> + <label>$_("Storage Pool")</label>
>>>>> + <select id="guest-disk-pool"
>>>>> class="selectpicker col-md-12 col-lg-12">
>>>>> + </select>
>>>>> + <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("Storage pool in which the volume is
>>>>> located in")</p>
>>>>> + </div>
>>>>> + <div class="form-group">
>>>>> + <label>$_("Storage Volume")</label>
>>>>> + <select id="guest-disk-vol"
>>>>> class="selectpicker col-md-12 col-lg-12">
>>>>> + </select>
>>>>> + <p class="help-block"><i class="fa
>>>>> fa-info-circle"></i> $_("Storage volume to be attached")</p>
>>>>> + </div>
>>>>> + </div>
>>>>> </div>
>>>>> </div>
>>>>> <div class="path-section form-group">
>>>>> @@ -72,4 +104,4 @@
>>>>> kimchi.guest_storage_add_main();
>>>>> </script>
>>>>> </body>
>>>>> -</html>
>>>>> \ No newline at end of file
>>>>> +</html>
>>>>>
>>>> _______________________________________________
>>>> Kimchi-devel mailing list
>>>> Kimchi-devel at ovirt.org
>>>> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>>>>
>
More information about the Kimchi-devel
mailing list