[Kimchi-devel] [PATCH] [Kimchi] [RFC] Create new volume and attach to VM

Socorro Stoppler socorro at linux.vnet.ibm.com
Fri Feb 5 16:10:01 UTC 2016


Thank you for the comments!  Sending v2 shortly.

On 02/05/2016 04:40 AM, Paulo Ricardo Paz Vital wrote:
>
> 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
>>>>>
> _______________________________________________
> 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