Prechádzať zdrojové kódy

支持通过前端页面变更虚拟机带宽

James Iter 8 rokov pred
rodič
commit
c8d8b7ad2f

+ 59 - 0
api/guest.py

@@ -1103,3 +1103,62 @@ def r_reset_password(uuids, password):
     except ji.PreviewingError, e:
         return json.loads(e.message)
 
+
+@Utils.dumps2response
+def r_allocate_bandwidth(uuids, bandwidth, bandwidth_unit):
+
+    args_rules = [
+        Rules.UUIDS.value,
+        Rules.BANDWIDTH_IN_URL.value,
+        Rules.BANDWIDTH_UNIT.value,
+    ]
+
+    try:
+        ji.Check.previewing(args_rules, {'uuids': uuids, 'bandwidth': bandwidth, 'bandwidth_unit': bandwidth_unit})
+
+        bandwidth = int(bandwidth)
+
+        if bandwidth_unit == 'k':
+            bandwidth = bandwidth * 1000
+
+        elif bandwidth_unit == 'm':
+            bandwidth = bandwidth * 1000 ** 2
+
+        elif bandwidth_unit == 'g':
+            bandwidth = bandwidth * 1000 ** 3
+
+        else:
+            ret = dict()
+            ret['state'] = ji.Common.exchange_state(41203)
+            raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
+
+        guest = Guest()
+
+        # 检测所指定的 UUDIs 实例都存在
+        for uuid in uuids.split(','):
+            guest.uuid = uuid
+            guest.get_by('uuid')
+
+        for uuid in uuids.split(','):
+            guest.uuid = uuid
+            guest.get_by('uuid')
+            guest.bandwidth = bandwidth
+
+            message = {
+                '_object': 'guest',
+                'action': 'allocate_bandwidth',
+                'uuid': guest.uuid,
+                'node_id': guest.node_id,
+                'bandwidth': guest.bandwidth,
+                'passback_parameters': {'bandwidth': guest.bandwidth}
+            }
+
+            Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))
+
+        ret = dict()
+        ret['state'] = ji.Common.exchange_state(20000)
+        return ret
+
+    except ji.PreviewingError, e:
+        return json.loads(e.message)
+

+ 2 - 0
api_route_table.py

@@ -105,6 +105,8 @@ add_rule_api(guest.blueprint, '/<uuid>', api_func='guest.r_update', methods=['PA
 add_rule_api(guest.blueprints, '/<uuids>', api_func='guest.r_delete', methods=['DELETE'])
 add_rule_api(guest.blueprints, '/_reset_password/<uuids>/<password>', api_func='guest.r_reset_password',
              methods=['PUT'])
+add_rule_api(guest.blueprints, '/_allocate_bandwidth/<uuids>/<bandwidth>/<bandwidth_unit>',
+             api_func='guest.r_allocate_bandwidth', methods=['PUT'])
 add_rule_api(guest.blueprints, '/_distribute_count', api_func='guest.r_distribute_count', methods=['GET'])
 
 # Disk操作

+ 1 - 0
docs/todo.md

@@ -83,4 +83,5 @@
 - [ ] 实现通过 JimV-C 修改主机名(当前为备注的地方),同步到具体 Guest 上
 - [ ] 修正创建虚拟机时,VNC 端口不够用时的 bug。创建失败时,需要返还对应的 IP 与 VNC 端口资源
 - [ ] 根据计算节点 CPU 是否支持 VT-X,来确定虚拟机是使用 KVM 还是 QEMU
+- [ ] 修复在大磁盘虚拟机创建快照时,等待时间过长的问题
 

+ 7 - 0
models/event_processor.py

@@ -233,6 +233,13 @@ class EventProcessor(object):
                 if state == ResponseState.success.value:
                     pass
 
+            elif action == 'allocate_bandwidth':
+                if state == ResponseState.success.value:
+                    cls.guest.uuid = uuid
+                    cls.guest.get_by('uuid')
+                    cls.guest.bandwidth = cls.message['message']['passback_parameters']['bandwidth']
+                    cls.guest.update()
+
         elif _object == 'disk':
             if action == 'create':
                 cls.disk.uuid = uuid

+ 1 - 0
models/rules.py

@@ -57,6 +57,7 @@ class Rules(Enum):
     BPS_MAX = (int, 'iops_max')
     BPS_MAX_LENGTH = (int, 'iops_max_length')
     BANDWIDTH = (int, 'bandwidth')
+    BANDWIDTH_IN_URL = (REG_NUMBER, 'bandwidth')
     BANDWIDTH_UNIT = (basestring, 'bandwidth_unit', ['k', 'm', 'g'])
 
     SSH_KEY_ID_EXT = (REG_NUMBER, 'ssh_key_id')

+ 59 - 0
static/utils.js

@@ -117,3 +117,62 @@ RandomPassword.prototype.trim = function(s) {
 	else
 		return s.trim();
 };
+
+function render_bandwidth_slider(bandwidth_slider ,action, bandwidth_unit) {
+
+    if (action === 'create') {
+        bandwidth_slider.ionRangeSlider({
+            min: 0,
+            max: 1000,
+            from: 200,
+            from_min: 1,
+            from_max: 999,
+            step: 1,
+            grid: true,
+            grid_num: 10,
+            postfix: ' Mbps'
+        });
+
+    } else if (action === 'update') {
+        var bandwitdh_slider_instance = bandwidth_slider.data("ionRangeSlider");
+        if (bandwidth_unit === 'g') {
+            bandwitdh_slider_instance.update({
+                min: 0,
+                max: 100,
+                from: 1,
+                from_min: 1,
+                from_max: 100,
+                step: 1,
+                grid: true,
+                grid_num: 10,
+                postfix: ' Gbps'
+            });
+
+        } else if (bandwidth_unit === 'm') {
+            bandwitdh_slider_instance.update({
+                min: 0,
+                max: 1000,
+                from: 200,
+                from_min: 1,
+                from_max: 999,
+                step: 1,
+                grid: true,
+                grid_num: 10,
+                postfix: ' Mbps'
+            });
+
+        } else if (bandwidth_unit === 'k') {
+            bandwitdh_slider_instance.update({
+                min: 0,
+                max: 1000,
+                from: 512,
+                from_min: 8,
+                from_max: 992,
+                step: 8,
+                grid: true,
+                grid_num: 10,
+                postfix: ' Kbps'
+            });
+        }
+    }
+}

+ 2 - 62
templates/guest_create.html

@@ -110,10 +110,10 @@
         refresh_ssh_keys_checkboxer($('#ssh_keys_id_div'));
 
         $('#bandwidth_unit').on('changed.bs.select', function (me) {
-            render_bandwidth_slider('update', $('#bandwidth_unit').val())
+            render_bandwidth_slider($("#bandwidth"), 'update', $('#bandwidth_unit').val())
         });
 
-        render_bandwidth_slider('create', 'm');
+        render_bandwidth_slider($("#bandwidth"), 'create', 'm');
     });
 
     function get_os_templates_profile_mapping_by_id() {
@@ -201,66 +201,6 @@
             $('#node_id').parent().parent().css('display', 'unset');
         }
     }
-
-    function render_bandwidth_slider(action, bandwidth_unit) {
-        var bandwidth_slider = $("#bandwidth");
-
-        if (action === 'create') {
-            bandwidth_slider.ionRangeSlider({
-                min: 0,
-                max: 1000,
-                from: 200,
-                from_min: 1,
-                from_max: 999,
-                step: 1,
-                grid: true,
-                grid_num: 10,
-                postfix: ' Mbps'
-            });
-
-        } else if (action === 'update') {
-            var bandwitdh_slider_instance = bandwidth_slider.data("ionRangeSlider");
-            if (bandwidth_unit === 'g') {
-                bandwitdh_slider_instance.update({
-                    min: 0,
-                    max: 100,
-                    from: 1,
-                    from_min: 1,
-                    from_max: 100,
-                    step: 1,
-                    grid: true,
-                    grid_num: 10,
-                    postfix: ' Gbps'
-                });
-
-            } else if (bandwidth_unit === 'm') {
-                bandwitdh_slider_instance.update({
-                    min: 0,
-                    max: 1000,
-                    from: 200,
-                    from_min: 1,
-                    from_max: 999,
-                    step: 1,
-                    grid: true,
-                    grid_num: 10,
-                    postfix: ' Mbps'
-                });
-
-            } else if (bandwidth_unit === 'k') {
-                bandwitdh_slider_instance.update({
-                    min: 0,
-                    max: 1000,
-                    from: 512,
-                    from_min: 8,
-                    from_max: 992,
-                    step: 8,
-                    grid: true,
-                    grid_num: 10,
-                    postfix: ' Kbps'
-                });
-            }
-        }
-    }
 </script>
 <div class="container" style="padding-top: 100px;">
     <div class="panel">

+ 155 - 11
templates/guests_show.html

@@ -2,6 +2,16 @@
 {% block head %}
     {{ super() }}
     <style type="text/css">
+        @media (min-width: 768px) {
+            .form-horizontal .control-label {
+                text-align: left;
+            }
+        }
+
+        label>span {
+            color: deepskyblue;
+        }
+
         .table {
             font-size: 12px;
             border-width: 1px;
@@ -176,6 +186,22 @@
             $('#new_password').val('');
             $('#new_password').attr({type: "password"});
         });
+
+        $('#allocate_bandwidth_modal').on('show.bs.modal', function (me) {
+            $('#bandwidth_unit').on('changed.bs.select', function (me) {
+                render_bandwidth_slider($("#bandwidth"), 'update', $('#bandwidth_unit').val())
+            });
+
+            render_bandwidth_slider($("#bandwidth"), 'create', 'm');
+        });
+
+        $('#batch_allocate_bandwidth_modal').on('show.bs.modal', function (me) {
+            $('#batch_bandwidth_unit').on('changed.bs.select', function (me) {
+                render_bandwidth_slider($("#batch_bandwidth"), 'update', $('#batch_bandwidth_unit').val())
+            });
+
+            render_bandwidth_slider($("#batch_bandwidth"), 'create', 'm');
+        });
     });
 
     function refresh() {
@@ -376,6 +402,20 @@
         });
     }
 
+    function allocate_bandwidth(uuids, bandwidth, bandwidth_unit) {
+        $.ajax({
+            url : '/api/guests/_allocate_bandwidth/' + uuids.join(',') + '/' + bandwidth + '/' + bandwidth_unit,
+            type : 'PUT',
+            contentType: "application/json; charset=utf-8",
+            error : function() {
+                alter_danger('实例分配带宽指令发送失败!');
+            },
+            success : function() {
+                alter_success('实例分配带宽指令发送成功!');
+            }
+        });
+    }
+
     function remove(uuids) {
         $.ajax({
             url : '/api/guests/' + uuids.join(','),
@@ -467,6 +507,12 @@
         $('#resume_modal').modal('hide');
     }
 
+    function allocate_bandwidth_at(me) {
+        var uuid = $('#instance_uuid').val();
+        allocate_bandwidth([uuid], $('#bandwidth').val(), $('#bandwidth_unit').val());
+        $('#allocate_bandwidth_modal').modal('hide');
+    }
+
     function delete_at(me) {
         var uuid = $('#instance_uuid').val();
         remove([uuid]);
@@ -578,6 +624,14 @@
         $('#batch_resume_modal').modal('hide');
     }
 
+    function batch_allocate_bandwidth() {
+        var uuids = get_checked_uuids();
+        if (uuids) {
+            allocate_bandwidth(uuids, $('#batch_bandwidth').val(), $('#batch_bandwidth_unit').val());
+        }
+        $('#batch_allocate_bandwidth_modal').modal('hide');
+    }
+
     function batch_delete() {
         var uuids = get_checked_uuids();
         if (uuids) {
@@ -676,10 +730,10 @@
                     <td>
                         CPU :&nbsp;&nbsp;{{ item.cpu }}&nbsp;核<br />
                         内存 :&nbsp;&nbsp;{{ item.memory }}&nbsp;GB<br />
-                        带宽 :&nbsp;&nbsp;
+                        带宽 :&nbsp;
                             {% if item.bandwidth == 0 %}
-                                <span style="font-size: 16px;">
-                                ∞
+                                <span style="font-size: 16px;" title="无限带宽">
+                                &nbsp;
                                 </span>
                             {% elif item.bandwidth > 0 and item.bandwidth < 1000**2 %}
                                 {{ item.bandwidth // 1000 }}
@@ -774,6 +828,14 @@
                                     <a href="/guest/vnc/{{ item.uuid }}" target="_blank">远程连接</a>
                                 </li>
                                 <li class="divider"></li>
+                                <li class="">
+                                    <a href="javascript:;" data-toggle="modal" data-target="#allocate_bandwidth_modal"
+                                       onclick="$('#instance_uuid').val($($(this).parent().parent().parent().parent().parent().children()[0]).text());
+                                                $('#allocate_bandwidth_instance_desc').text($($(this).parent().parent().parent().parent().parent().children()[2]).find('div a')[0].textContent + '/' + $($(this).parent().parent().parent().parent().parent().children()[2]).find('div p')[0].textContent)">
+                                       分配带宽
+                                    </a>
+                                </li>
+                                <li class="divider"></li>
                                 <li class="">
                                     <a href="javascript:;" data-toggle="modal" data-target="#reset_password_modal"
                                        onclick="$('#reset_password_type').val('single')">
@@ -836,6 +898,10 @@
                                                 </a>
                                             </li>
                                             <li class="divider"></li>
+                                            <li>
+                                                <a href="javascript:;" data-toggle="modal" data-target="#batch_allocate_bandwidth_modal">分配带宽</a>
+                                            </li>
+                                            <li class="divider"></li>
                                             <li>
                                                 <a href="javascript:;" data-toggle="modal" data-target="#batch_force_shutdown_modal">强制停止</a>
                                             </li>
@@ -975,7 +1041,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>删除的虚拟机将无法找回,上面数据将永久消失。您确定要执行批量删除选的虚拟机吗?</p>
+                <p>删除的虚拟机将无法找回,上面数据将永久消失。您确定要执行批量删除选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_delete();">确定</button>
@@ -1011,7 +1077,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>您确定要执行批量重启选的虚拟机吗?</p>
+                <p>您确定要执行批量重启选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_reboot();">确定</button>
@@ -1047,7 +1113,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>您确定要执行批量强制重启选的虚拟机吗?</p>
+                <p>您确定要执行批量强制重启选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_force_reboot();">确定</button>
@@ -1083,7 +1149,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>您确定要执行批量停止选的虚拟机吗?</p>
+                <p>您确定要执行批量停止选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_shutdown();">确定</button>
@@ -1119,7 +1185,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>您确定要执行批量强制停止选的虚拟机吗?</p>
+                <p>您确定要执行批量强制停止选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_force_shutdown();">确定</button>
@@ -1175,7 +1241,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>您确定要执行批量暂停选的虚拟机吗?</p>
+                <p>您确定要执行批量暂停选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_suspend();">确定</button>
@@ -1211,7 +1277,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>您确定要执行批量恢复暂停的选的虚拟机吗?</p>
+                <p>您确定要执行批量恢复暂停的选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_resume();">确定</button>
@@ -1247,7 +1313,7 @@
             </div>
             <div class="modal-body">
                 <p></p>
-                <p>您确定要执行批量启动选的虚拟机吗?</p>
+                <p>您确定要执行批量启动选的虚拟机吗?</p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-primary" onclick="batch_boot();">确定</button>
@@ -1256,4 +1322,82 @@
         </div>
     </div>
 </div>
+
+<div class="modal" id="allocate_bandwidth_modal" tabindex="-1" role="dialog" style="margin-top: 100px;">
+    <div class="modal-dialog modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h4 class="modal-title">给虚拟机重新分配带宽:</h4>
+            </div>
+            <div class="modal-body" style="padding-top: 0;">
+                <div class="example-box-wrapper">
+                    <form class="form-horizontal bordered-row">
+                        <div class="form-group">
+                            <div class="col-sm-1"></div>
+                            <label class="col-sm-2 control-label"><span class="glyph-icon icon-elusive-compass-circled"></span>&nbsp;&nbsp;实例名称</label>
+                            <div class="col-sm-9">
+                                <h3 style="color: orangered;" id="allocate_bandwidth_instance_desc"></h3>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <div class="col-sm-1"></div>
+                            <label class="col-sm-2 control-label"><span class="glyph-icon icon-signal"></span>&nbsp;&nbsp;内网带宽</label>
+                            <div class="col-sm-7">
+                                <input id="bandwidth" title="内网带宽" type="text" name="bandwidth">
+                            </div>
+                            <div class="col-sm-2" style="bottom: -10px;">
+                                <select id="bandwidth_unit" name="bandwidth_unit" title="单位..." class="selectpicker" data-width="80%">
+                                    <option value="k">&nbsp;&nbsp;Kbps</option>
+                                    <option value="m" selected>&nbsp;&nbsp;Mbps</option>
+                                    <option value="g">&nbsp;&nbsp;Gbps</option>
+                                </select>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-primary" onclick="allocate_bandwidth_at();">确定</button>
+                <button type="button" class="btn btn-sm btn-default" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div class="modal" id="batch_allocate_bandwidth_modal" tabindex="-1" role="dialog" style="margin-top: 100px;">
+    <div class="modal-dialog modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h4 class="modal-title">批量分配带宽给虚拟机:</h4>
+            </div>
+            <div class="modal-body">
+                <p></p>
+                <p>您确定要给选定的虚拟机重新分配带宽吗?</p>
+                <p></p>
+                <div class="example-box-wrapper">
+                    <form class="form-horizontal bordered-row">
+                        <div class="form-group">
+                            <div class="col-sm-1"></div>
+                            <label class="col-sm-2 control-label"><span class="glyph-icon icon-signal"></span>&nbsp;&nbsp;内网带宽</label>
+                            <div class="col-sm-7">
+                                <input id="batch_bandwidth" title="内网带宽" type="text" name="batch_bandwidth">
+                            </div>
+                            <div class="col-sm-2" style="bottom: -10px;">
+                                <select id="batch_bandwidth_unit" name="batch_bandwidth_unit" title="单位..." class="selectpicker" data-width="80%">
+                                    <option value="k">&nbsp;&nbsp;Kbps</option>
+                                    <option value="m" selected>&nbsp;&nbsp;Mbps</option>
+                                    <option value="g">&nbsp;&nbsp;Gbps</option>
+                                </select>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-primary" onclick="batch_allocate_bandwidth();">确定</button>
+                <button type="button" class="btn btn-sm btn-default" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
 {% endblock content %}