[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