瀏覽代碼

实现性能配额全局变配,并且影响到现有实例

James Iter 8 年之前
父節點
當前提交
89ec2f458e
共有 5 個文件被更改,包括 137 次插入23 次删除
  1. 77 17
      api/config.py
  2. 1 0
      api_route_table.py
  3. 10 2
      models/guest.py
  4. 1 0
      models/rules.py
  5. 48 4
      templates/config_show.html

+ 77 - 17
api/config.py

@@ -7,7 +7,7 @@ from flask import request
 import jimit as ji
 import json
 
-from models import Config
+from models import Config, Disk, Guest
 from models import Rules
 from models import Utils
 
@@ -181,6 +181,54 @@ def r_update():
             Rules.DNS2.value,
         )
 
+    if args_rules.__len__() < 1:
+        ret = dict()
+        ret['state'] = ji.Common.exchange_state(20000)
+        return ret
+
+    try:
+        config.id = 1
+        ji.Check.previewing(args_rules, request.json)
+        config.get()
+
+        config.jimv_edition = int(request.json.get('jimv_edition', config.jimv_edition))
+        config.storage_mode = int(request.json.get('storage_mode', config.storage_mode))
+        config.dfs_volume = request.json.get('dfs_volume', config.dfs_volume)
+        config.storage_path = request.json.get('storage_path', config.storage_path)
+        config.vm_network = request.json.get('vm_network', config.vm_network)
+        config.vm_manage_network = request.json.get('vm_manage_network', config.vm_manage_network)
+        config.start_ip = request.json.get('start_ip', config.start_ip)
+        config.end_ip = request.json.get('end_ip', config.end_ip)
+        config.start_vnc_port = int(request.json.get('start_vnc_port', config.start_vnc_port))
+        config.netmask = request.json.get('netmask', config.netmask)
+        config.gateway = request.json.get('gateway', config.gateway)
+        config.dns1 = request.json.get('dns1', config.dns1)
+        config.dns2 = request.json.get('dns2', config.dns2)
+
+        config.check_ip()
+        config.generate_available_ip2set()
+        config.generate_available_vnc_port()
+        config.update()
+        config.update_global_config()
+
+        config.get()
+
+        ret = dict()
+        ret['state'] = ji.Common.exchange_state(20000)
+        ret['data'] = config.__dict__
+        return ret
+    except ji.PreviewingError, e:
+        return json.loads(e.message)
+
+
+@Utils.dumps2response
+def r_update_quota():
+
+    config = Config()
+
+    args_rules = [
+    ]
+
     if 'iops_base' in request.json:
         args_rules.append(
             Rules.IOPS_BASE.value,
@@ -231,6 +279,11 @@ def r_update():
             Rules.BPS_MAX_LENGTH.value,
         )
 
+    if 'influence_current_guest' in request.json:
+        args_rules.append(
+            Rules.INFLUENCE_CURRENT_GUEST.value,
+        )
+
     if args_rules.__len__() < 1:
         ret = dict()
         ret['state'] = ji.Common.exchange_state(20000)
@@ -241,19 +294,6 @@ def r_update():
         ji.Check.previewing(args_rules, request.json)
         config.get()
 
-        config.jimv_edition = int(request.json.get('jimv_edition', config.jimv_edition))
-        config.storage_mode = int(request.json.get('storage_mode', config.storage_mode))
-        config.dfs_volume = request.json.get('dfs_volume', config.dfs_volume)
-        config.storage_path = request.json.get('storage_path', config.storage_path)
-        config.vm_network = request.json.get('vm_network', config.vm_network)
-        config.vm_manage_network = request.json.get('vm_manage_network', config.vm_manage_network)
-        config.start_ip = request.json.get('start_ip', config.start_ip)
-        config.end_ip = request.json.get('end_ip', config.end_ip)
-        config.start_vnc_port = int(request.json.get('start_vnc_port', config.start_vnc_port))
-        config.netmask = request.json.get('netmask', config.netmask)
-        config.gateway = request.json.get('gateway', config.gateway)
-        config.dns1 = request.json.get('dns1', config.dns1)
-        config.dns2 = request.json.get('dns2', config.dns2)
         config.iops_base = int(request.json.get('iops_base', config.iops_base))
         config.iops_pre_unit = int(request.json.get('iops_pre_unit', config.iops_pre_unit))
         config.iops_cap = int(request.json.get('iops_cap', config.iops_cap))
@@ -265,9 +305,28 @@ def r_update():
         config.bps_max = int(request.json.get('bps_max', config.bps_max))
         config.bps_max_length = int(request.json.get('bps_max_length', config.bps_max_length))
 
-        config.check_ip()
-        config.generate_available_ip2set()
-        config.generate_available_vnc_port()
+        if request.json.get('influence_current_guest', False):
+            disks, _ = Disk.get_all()
+
+            disk = Disk()
+            for disk_info in disks:
+                disk.id = disk_info['id']
+                disk.get()
+                disk.quota(config=config)
+                disk.update()
+
+                if disk.sequence >= 0:
+                    message = {
+                        '_object': 'disk',
+                        'action': 'quota',
+                        'uuid': disk.uuid,
+                        'guest_uuid': disk.guest_uuid,
+                        'hostname': disk.on_host,
+                        'disks': [disk.__dict__]
+                    }
+
+                    Guest.emit_instruction(message=json.dumps(message))
+
         config.update()
         config.update_global_config()
 
@@ -276,6 +335,7 @@ def r_update():
         ret = dict()
         ret['state'] = ji.Common.exchange_state(20000)
         ret['data'] = config.__dict__
+
         return ret
     except ji.PreviewingError, e:
         return json.loads(e.message)

+ 1 - 0
api_route_table.py

@@ -26,6 +26,7 @@ __copyright__ = '(c) 2017 by James Iter.'
 add_rule_api(config.blueprint, '', api_func='config.r_create', methods=['POST'])
 # 只有一条记录,所以不指定 id
 add_rule_api(config.blueprint, '', api_func='config.r_update', methods=['PATCH'])
+add_rule_api(config.blueprint, '/_quota', api_func='config.r_update_quota', methods=['PATCH'])
 add_rule_api(config.blueprint, '', api_func='config.r_get', methods=['GET'])
 
 # 用户管理

+ 10 - 2
models/guest.py

@@ -174,7 +174,11 @@ class Disk(ORM):
         from models import Config
         assert isinstance(config, Config)
 
-        self.iops = config.iops_base + config.iops_pre_unit * self.size
+        # 系统盘 IOPS 默认不计算增益
+        if self.sequence != 0:
+            self.iops = config.iops_base + config.iops_pre_unit * self.size
+        else:
+            self.iops = config.iops_base
 
         if self.iops > config.iops_cap:
             self.iops = config.iops_cap
@@ -184,7 +188,11 @@ class Disk(ORM):
         self.iops_rd = 0
         self.iops_wr = 0
 
-        self.bps = config.bps_base + config.bps_pre_unit * self.size
+        # 系统盘 BPS 默认不计算增益
+        if self.sequence != 0:
+            self.bps = config.bps_base + config.bps_pre_unit * self.size
+        else:
+            self.bps = config.bps_base
 
         if self.bps > config.bps_cap:
             self.bps = config.bps_cap

+ 1 - 0
models/rules.py

@@ -80,6 +80,7 @@ class Rules(Enum):
     BPS = (int, 'bps')
     BPS_RD = (int, 'bps_rd')
     BPS_WR = (int, 'bps_wr')
+    INFLUENCE_CURRENT_GUEST = (bool, 'influence_current_guest')
 
     REMARK = (basestring, 'remark')
     USE_FOR = (int, 'use_for')

+ 48 - 4
templates/config_show.html

@@ -48,7 +48,11 @@
 
             register_iops_bps_event();
         });
-        
+
+        function refresh() {
+            window.location.href=window.location.pathname;
+        }
+
         function select_this(me) {
             $(me).parent().parent().children().removeClass('active');
             $(me).parent().addClass('active');
@@ -198,6 +202,36 @@
             });
         }
 
+        function update_quota() {
+            $.ajax({
+                url : '/api/config/_quota',
+                type : 'PATCH',
+                contentType: "application/json; charset=utf-8",
+                data : JSON.stringify({
+                    iops_base: parseInt($('#iops_base').val()),
+                    iops_pre_unit: parseInt($('#iops_pre_unit').val()),
+                    iops_cap: parseInt($('#iops_cap').val()),
+                    iops_max: parseInt($('#iops_max').val()),
+                    iops_max_length: parseInt($('#iops_max_length').val()),
+                    bps_base: parseInt($('#bps_base').val()) * 1024 * 1024,
+                    bps_pre_unit: parseFloat($('#bps_pre_unit').val()) * 1024 * 1024,
+                    bps_cap: parseInt($('#bps_cap').val()) * 1024 * 1024,
+                    bps_max: parseInt($('#bps_max').val()) * 1024 * 1024,
+                    bps_max_length: parseInt($('#bps_max_length').val()),
+                    influence_current_guest: $('#influence_current_guest').prop('checked')
+                }),
+                error : function() {
+                    alter_danger('性能配额更新失败!');
+                },
+                success : function() {
+                    alter_success('性能配额更新成功!');
+                    setTimeout(function() {
+                        refresh();
+                    }, 1000);
+                }
+            });
+        }
+
     </script>
     <div class="panel">
         <div class="panel-body">
@@ -355,10 +389,20 @@
                         </div>
                         <span class="col-sm-1"></span>
                     </div>
+                    <div class="form-group" style="margin-bottom: 0;">
+                        <div class="col-sm-6">
+                            <label>
+                                <input id="influence_current_guest" type="checkbox" name="influence_current_guest">
+                                同时更新已存在的实例
+                            </label>
+                        </div>
+                        <div class="col-sm-6">
+                            <div style="padding: 0; text-align: right;">
+                                <button type="button" class="btn btn-sm btn-primary" style="right: 10%;" onclick="update_quota();">更新</button>
+                            </div>
+                        </div>
+                    </div>
                 </form>
-                <div style="padding: 15px; text-align: right; border-top: 1px solid #dfe8f1;">
-                    <button type="button" class="btn btn-sm btn-primary" style="right: 10%;" onclick="batch_change_disk_quota();">更新</button>
-                </div>
             </div>
         </div>
     </div>