Parcourir la source

调整 on_host 为 node_id

James Iter il y a 8 ans
Parent
commit
dbe6eaa299

+ 1 - 1
api/config.py

@@ -321,7 +321,7 @@ def r_update_quota():
                         'action': 'quota',
                         'uuid': disk.uuid,
                         'guest_uuid': disk.guest_uuid,
-                        'hostname': disk.on_host,
+                        'node_id': disk.node_id,
                         'disks': [disk.__dict__]
                     }
 

+ 35 - 27
api/disk.py

@@ -46,7 +46,6 @@ def r_create():
     args_rules = [
         Rules.DISK_SIZE.value,
         Rules.REMARK.value,
-        Rules.DISK_ON_HOST.value,
         Rules.QUANTITY.value
     ]
 
@@ -54,19 +53,36 @@ def r_create():
     config.id = 1
     config.get()
 
-    if config.storage_mode in [StorageMode.shared_mount.value, StorageMode.ceph.value,
-                               StorageMode.glusterfs.value]:
-        request.json['on_host'] = 'shared_storage'
+    # 非共享模式,必须指定 node_id
+    if config.storage_mode not in [StorageMode.shared_mount.value, StorageMode.ceph.value,
+                                   StorageMode.glusterfs.value]:
+        args_rules.append(
+            Rules.NODE_ID.value
+        )
 
     try:
         ji.Check.previewing(args_rules, request.json)
 
+        size = request.json['size']
+        quantity = request.json['quantity']
+
         ret = dict()
         ret['state'] = ji.Common.exchange_state(20000)
 
-        size = request.json['size']
-        quantity = request.json['quantity']
-        on_host = request.json['on_host']
+        # 如果是共享模式,则让负载最轻的计算节点去创建磁盘
+        if config.storage_mode in [StorageMode.shared_mount.value, StorageMode.ceph.value,
+                                   StorageMode.glusterfs.value]:
+            available_hosts = Host.get_available_hosts()
+
+            if available_hosts.__len__() == 0:
+                ret['state'] = ji.Common.exchange_state(50351)
+                return ret
+
+            # 在可用计算节点中平均分配任务
+            chosen_host = available_hosts[quantity % available_hosts.__len__()]
+            request.json['node_id'] = chosen_host['node_id']
+
+        node_id = request.json['node_id']
 
         if size < 1:
             ret['state'] = ji.Common.exchange_state(41255)
@@ -79,7 +95,7 @@ def r_create():
             disk.size = size
             disk.uuid = uuid4().__str__()
             disk.remark = request.json.get('remark', '')
-            disk.on_host = on_host
+            disk.node_id = node_id
             disk.sequence = -1
             disk.format = 'qcow2'
             disk.path = config.storage_path + '/' + disk.uuid + '.' + disk.format
@@ -91,22 +107,11 @@ def r_create():
                 'uuid': disk.uuid,
                 'storage_mode': config.storage_mode,
                 'dfs_volume': config.dfs_volume,
-                'hostname': disk.on_host,
+                'node_id': disk.node_id,
                 'image_path': disk.path,
                 'size': disk.size
             }
 
-            if disk.on_host == 'shared_storage':
-                available_hosts = Host.get_available_hosts()
-
-                if available_hosts.__len__() == 0:
-                    ret['state'] = ji.Common.exchange_state(50351)
-                    return ret
-
-                # 在可用计算节点中平均分配任务
-                chosen_host = available_hosts[quantity % available_hosts.__len__()]
-                message['hostname'] = chosen_host['hostname']
-
             Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))
 
             disk.create()
@@ -155,14 +160,15 @@ def r_resize(uuid, size):
             'storage_mode': config.storage_mode,
             'size': disk.size,
             'dfs_volume': config.dfs_volume,
-            'hostname': disk.on_host,
+            'node_id': disk.node_id,
             'image_path': disk.path,
             'disks': [disk.__dict__],
             'passback_parameters': {'size': disk.size}
         }
 
-        if disk.on_host == 'shared_storage':
-            message['hostname'] = Guest.get_lightest_host()['hostname']
+        if config.storage_mode in [StorageMode.shared_mount.value, StorageMode.ceph.value,
+                                   StorageMode.glusterfs.value]:
+            message['node_id'] = Host.get_lightest_host()['node_id']
 
         if disk.guest_uuid.__len__() == 36:
             message['device_node'] = dev_table[disk.sequence]
@@ -195,6 +201,7 @@ def r_delete(uuids):
             disk.uuid = uuid
             disk.get_by('uuid')
 
+            # 判断磁盘是否与虚拟机处于离状态
             if disk.state != DiskState.idle.value:
                 ret['state'] = ji.Common.exchange_state(41256)
                 return ret
@@ -214,12 +221,13 @@ def r_delete(uuids):
                 'uuid': disk.uuid,
                 'storage_mode': config.storage_mode,
                 'dfs_volume': config.dfs_volume,
-                'hostname': disk.on_host,
+                'node_id': disk.node_id,
                 'image_path': disk.path
             }
 
-            if disk.on_host == 'shared_storage':
-                message['hostname'] = Guest.get_lightest_host()['hostname']
+            if config.storage_mode in [StorageMode.shared_mount.value, StorageMode.ceph.value,
+                                       StorageMode.glusterfs.value]:
+                message['node_id'] = Host.get_lightest_host()['node_id']
 
             Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))
 
@@ -386,7 +394,7 @@ def r_update(uuids):
                     'action': 'quota',
                     'uuid': disk.uuid,
                     'guest_uuid': disk.guest_uuid,
-                    'hostname': disk.on_host,
+                    'node_id': disk.node_id,
                     'disks': [disk.__dict__]
                 }
 

+ 26 - 26
api/guest.py

@@ -59,9 +59,9 @@ def r_create():
         Rules.LEASE_TERM.value
     ]
 
-    if 'on_host' in request.json:
+    if 'node_id' in request.json:
         args_rules.append(
-            Rules.GUEST_ON_HOST.value,
+            Rules.NODE_ID.value,
         )
 
     try:
@@ -93,20 +93,20 @@ def r_create():
             ret['state'] = ji.Common.exchange_state(50350)
             return ret
 
-        on_host = request.json.get('on_host', None)
+        node_id = request.json.get('node_id', None)
 
         # 默认只取可随机分配虚拟机的 hosts
         available_hosts = Host.get_available_hosts(nonrandom=False)
 
         # 当指定了 host 时,取全部活着的 hosts
-        if on_host is not None:
+        if node_id is not None:
             available_hosts = Host.get_available_hosts(nonrandom=None)
 
         if available_hosts.__len__() == 0:
             ret['state'] = ji.Common.exchange_state(50351)
             return ret
 
-        if on_host is not None and on_host not in [host['hostname'] for host in available_hosts]:
+        if node_id is not None and node_id not in [host['node_id'] for host in available_hosts]:
             ret['state'] = ji.Common.exchange_state(50351)
             return ret
 
@@ -147,7 +147,7 @@ def r_create():
             disk.path = config.storage_path + '/' + disk.uuid + '.' + disk.format
             disk.guest_uuid = ''
             disk.quota(config=config)
-            # disk.on_host 由 guest 事件处理机更新。涉及迁移时,其所属 on_host 会变更。参见 models/event_processory.py:111 附近。
+            # disk.node_id 由 guest 事件处理机更新。涉及迁移时,其所属 node_id 会变更。参见 models/event_processory.py:111 附近。
             disk.create()
 
             guest_xml = GuestXML(guest=guest, disk=disk, config=config, os_type=os_template.os_type)
@@ -155,10 +155,10 @@ def r_create():
 
             # 在可用计算节点中平均分配任务
             chosen_host = available_hosts[quantity % available_hosts.__len__()]
-            guest.on_host = chosen_host['hostname']
+            guest.node_id = chosen_host['node_id']
 
-            if on_host is not None:
-                guest.on_host = on_host
+            if node_id is not None:
+                guest.node_id = node_id
 
             guest.create()
 
@@ -187,7 +187,7 @@ def r_create():
                 'uuid': guest.uuid,
                 'storage_mode': config.storage_mode,
                 'dfs_volume': config.dfs_volume,
-                'hostname': guest.on_host,
+                'node_id': guest.node_id,
                 'name': guest.label,
                 'template_path': os_template.path,
                 'os_type': os_template.os_type,
@@ -230,7 +230,7 @@ def r_reboot(uuids):
                 '_object': 'guest',
                 'action': 'reboot',
                 'uuid': uuid,
-                'hostname': guest.on_host
+                'node_id': guest.node_id
             }
 
             Utils.emit_instruction(message=json.dumps(message))
@@ -267,7 +267,7 @@ def r_force_reboot(uuids):
                 '_object': 'guest',
                 'action': 'force_reboot',
                 'uuid': uuid,
-                'hostname': guest.on_host,
+                'node_id': guest.node_id,
                 'disks': disks
             }
 
@@ -304,7 +304,7 @@ def r_shutdown(uuids):
                 '_object': 'guest',
                 'action': 'shutdown',
                 'uuid': uuid,
-                'hostname': guest.on_host
+                'node_id': guest.node_id
             }
 
             Utils.emit_instruction(message=json.dumps(message))
@@ -340,7 +340,7 @@ def r_force_shutdown(uuids):
                 '_object': 'guest',
                 'action': 'force_shutdown',
                 'uuid': uuid,
-                'hostname': guest.on_host
+                'node_id': guest.node_id
             }
 
             Utils.emit_instruction(message=json.dumps(message))
@@ -409,7 +409,7 @@ def r_boot(uuids):
                 'action': 'boot',
                 'uuid': uuid,
                 'boot_jobs': boot_jobs,
-                'hostname': guest.on_host,
+                'node_id': guest.node_id,
                 'passback_parameters': {'boot_jobs_id': boot_jobs_id},
                 'disks': disks
             }
@@ -447,7 +447,7 @@ def r_suspend(uuids):
                 '_object': 'guest',
                 'action': 'suspend',
                 'uuid': uuid,
-                'hostname': guest.on_host
+                'node_id': guest.node_id
             }
 
             Utils.emit_instruction(message=json.dumps(message))
@@ -483,7 +483,7 @@ def r_resume(uuids):
                 '_object': 'guest',
                 'action': 'resume',
                 'uuid': uuid,
-                'hostname': guest.on_host
+                'node_id': guest.node_id
             }
 
             Utils.emit_instruction(message=json.dumps(message))
@@ -528,7 +528,7 @@ def r_delete(uuids):
                 'uuid': uuid,
                 'storage_mode': config.storage_mode,
                 'dfs_volume': config.dfs_volume,
-                'hostname': guest.on_host
+                'node_id': guest.node_id
             }
 
             Utils.emit_instruction(message=json.dumps(message))
@@ -589,7 +589,7 @@ def r_attach_disk(uuid, disk_uuid):
 
         # 判断 Guest 与 磁盘是否在同一宿主机上
         if config.storage_mode in [status.StorageMode.local.value, status.StorageMode.shared_mount.value]:
-            if guest.on_host != disk.on_host:
+            if guest.node_id != disk.node_id:
                 ret['state'] = ji.Common.exchange_state(41260)
                 return ret
 
@@ -615,7 +615,7 @@ def r_attach_disk(uuid, disk_uuid):
             '_object': 'guest',
             'action': 'attach_disk',
             'uuid': uuid,
-            'hostname': guest.on_host,
+            'node_id': guest.node_id,
             'xml': guest_xml.get_disk(),
             'passback_parameters': {'disk_uuid': disk.uuid, 'sequence': disk.sequence},
             'disks': [disk.__dict__]
@@ -672,7 +672,7 @@ def r_detach_disk(disk_uuid):
             '_object': 'guest',
             'action': 'detach_disk',
             'uuid': disk.guest_uuid,
-            'hostname': guest.on_host,
+            'node_id': guest.node_id,
             'xml': guest_xml.get_disk(),
             'passback_parameters': {'disk_uuid': disk.uuid}
         }
@@ -716,7 +716,7 @@ def r_migrate(uuids, destination_host):
                 '_object': 'guest',
                 'action': 'migrate',
                 'uuid': uuid,
-                'hostname': guest.on_host,
+                'node_id': guest.node_id,
                 'storage_mode': config.storage_mode,
                 'duri': 'qemu+ssh://' + destination_host + '/system'
             }
@@ -757,7 +757,7 @@ def r_distribute_count():
     ret['data'] = {
         'os_template_id': dict(),
         'status': dict(),
-        'on_host': dict(),
+        'node_id': dict(),
         'cpu_memory': dict(),
         'cpu': 0,
         'memory': 0,
@@ -771,8 +771,8 @@ def r_distribute_count():
         if guest['status'] not in ret['data']['status']:
             ret['data']['status'][guest['status']] = 0
 
-        if guest['on_host'] not in ret['data']['on_host']:
-            ret['data']['on_host'][guest['on_host']] = 0
+        if guest['node_id'] not in ret['data']['node_id']:
+            ret['data']['node_id'][guest['node_id']] = 0
 
         cpu_memory = '_'.join([str(guest['cpu']), str(guest['memory'])])
         if cpu_memory not in ret['data']['cpu_memory']:
@@ -780,7 +780,7 @@ def r_distribute_count():
 
         ret['data']['os_template_id'][guest['os_template_id']] += 1
         ret['data']['status'][guest['status']] += 1
-        ret['data']['on_host'][guest['on_host']] += 1
+        ret['data']['node_id'][guest['node_id']] += 1
         ret['data']['cpu_memory'][cpu_memory] += 1
 
         ret['data']['cpu'] += guest['cpu']

+ 1 - 0
docs/todo.md

@@ -74,6 +74,7 @@
 - [x] 实现创建虚拟机时,手动指定计算节点功能
 - [x] 计算机节点加入是否接受自动分配虚拟机开关
 - [ ] 实现网络流量限速
+- [ ] 实现变配功能
 - [ ] 取消单独的初始化密码操作,合并入具体的操作系统初始化操作中
 - [ ] 替换 host 对象中的 node_id 为 hostname,统一主键。并消除 node_id
 - [ ] 考虑用管理接口的 IP 地址来区别计算节点,而不是用主机名

+ 4 - 4
misc/init.sql

@@ -37,7 +37,7 @@ CREATE TABLE IF NOT EXISTS guest(
     -- 运行时的状态用 status;
     status TINYINT UNSIGNED NOT NULL DEFAULT 0,
     progress TINYINT UNSIGNED NOT NULL DEFAULT 0,
-    on_host VARCHAR(128) NOT NULL DEFAULT '',
+    node_id BIGINT UNSIGNED NOT NULL,
     cpu TINYINT UNSIGNED NOT NULL,
     memory INT UNSIGNED NOT NULL,
     ip CHAR(15) NOT NULL,
@@ -52,7 +52,7 @@ CREATE TABLE IF NOT EXISTS guest(
 
 ALTER TABLE guest ADD INDEX (uuid);
 ALTER TABLE guest ADD INDEX (label);
-ALTER TABLE guest ADD INDEX (on_host);
+ALTER TABLE guest ADD INDEX (node_id);
 ALTER TABLE guest ADD INDEX (ip);
 ALTER TABLE guest ADD INDEX (remark);
 
@@ -84,7 +84,7 @@ CREATE TABLE IF NOT EXISTS disk(
     uuid CHAR(36) NOT NULL,
     path VARCHAR(255) NOT NULL,
     size INT UNSIGNED NOT NULL,
-    on_host VARCHAR(128) NOT NULL DEFAULT '',
+    node_id BIGINT UNSIGNED NOT NULL,
     remark VARCHAR(255) NOT NULL DEFAULT '',
     sequence TINYINT NOT NULL,
     format CHAR(16) NOT NULL DEFAULT 'qcow2',
@@ -108,7 +108,7 @@ CREATE TABLE IF NOT EXISTS disk(
 
 ALTER TABLE disk ADD INDEX (size);
 ALTER TABLE disk ADD INDEX (guest_uuid);
-ALTER TABLE disk ADD INDEX (on_host);
+ALTER TABLE disk ADD INDEX (node_id);
 ALTER TABLE disk ADD INDEX (remark);
 
 

+ 25 - 0
misc/v0.1_to_v0.2/update.sql

@@ -48,3 +48,28 @@ UPDATE disk, config SET
     disk.bps_max=config.bps_max, disk.bps_max_length=config.bps_max_length
 WHERE disk.sequence!=0 AND disk.size>1000 AND config.id=1;
 
+
+-- on_host 变更为 node_id
+ALTER TABLE guest ADD COLUMN node_id BIGINT UNSIGNED NOT NULL;
+ALTER TABLE disk ADD COLUMN node_id BIGINT UNSIGNED NOT NULL;
+ALTER TABLE guest ADD INDEX (node_id);
+ALTER TABLE disk ADD INDEX (node_id);
+
+-- import jimit as ji
+-- from models import Utils
+-- on_host=ji.Common.get_hostname()
+-- node_id=Utils.uuid_by_decimal(_str=ji.Common.get_hostname(), _len=16)
+-- UPDATE guest SET node_id='' WHERE on_host='';
+-- UPDATE disk SET node_id='' WHERE on_host='';
+
+-- 删除 on_host 字段
+-- ALTER TABLE guest DROP on_host;
+-- ALTER TABLE disk DROP on_host;
+
+-- 更新 旧 node_id 的值为新 node_id 值
+-- import uuid
+-- old_node_id=uuid.getnode()
+-- new_node_id=Utils.uuid_by_decimal(_str=ji.Common.get_hostname(), _len=16)
+-- UPDATE host_cpu_memory SET node_id=new_node_id WHERE node_id=old_node_id;
+-- UPDATE host_traffic SET node_id=new_node_id WHERE node_id=old_node_id;
+-- UPDATE host_disk_usage_io SET node_id=new_node_id WHERE node_id=old_node_id;

+ 2 - 2
models/event_processor.py

@@ -136,7 +136,7 @@ class EventProcessor(object):
         uuid = cls.message['message']['uuid']
         state = cls.message['type']
         data = cls.message['message']['data']
-        hostname = cls.message['host']
+        node_id = cls.message['node_id']
 
         if _object == 'guest':
             if action == 'create':
@@ -214,7 +214,7 @@ class EventProcessor(object):
             if action == 'create':
                 cls.disk.uuid = uuid
                 cls.disk.get_by('uuid')
-                cls.disk.on_host = hostname
+                cls.disk.node_id = node_id
                 if state == ResponseState.success.value:
                     cls.disk.state = DiskState.idle.value
 

+ 7 - 23
models/guest.py

@@ -34,7 +34,7 @@ class Guest(ORM):
         self.create_time = ji.Common.tus()
         self.status = GuestState.no_state.value
         self.progress = 0
-        self.on_host = ''
+        self.node_id = None
         self.cpu = None
         self.memory = None
         self.ip = None
@@ -51,7 +51,7 @@ class Guest(ORM):
             'uuid': FilterFieldType.STR.value,
             'label': FilterFieldType.STR.value,
             'remark': FilterFieldType.STR.value,
-            'on_host': FilterFieldType.STR.value,
+            'node_id': FilterFieldType.INT.value,
             'ip': FilterFieldType.STR.value
         }
 
@@ -61,7 +61,7 @@ class Guest(ORM):
 
     @staticmethod
     def get_allow_content_search_keywords():
-        return ['label', 'remark', 'on_host', 'ip']
+        return ['label', 'remark', 'node_id', 'ip']
 
     def get_boot_jobs_key(self):
         return ':'.join([app.config['guest_boot_jobs'], self.uuid])
@@ -97,22 +97,6 @@ class Guest(ORM):
 
         return uuids
 
-    @staticmethod
-    def get_lightest_host():
-        # 负载最小的宿主机
-        lightest_host = None
-        for k, v in db.r.hgetall(app.config['hosts_info']).items():
-            v = json.loads(v)
-
-            if lightest_host is None:
-                lightest_host = v
-
-            if float(lightest_host['system_load'][0]) / lightest_host['cpu'] > \
-                    float(v['system_load'][0]) / v['cpu']:
-                lightest_host = v
-
-        return lightest_host
-
 
 class Disk(ORM):
 
@@ -128,7 +112,7 @@ class Disk(ORM):
         self.size = None
         self.sequence = None
         self.state = DiskState.pending.value
-        self.on_host = ''
+        self.node_id = None
         self.format = 'qcow2'
         self.create_time = ji.Common.tus()
         self.guest_uuid = None
@@ -185,17 +169,17 @@ class Disk(ORM):
             'size': FilterFieldType.INT.value,
             'state': FilterFieldType.INT.value,
             'sequence': FilterFieldType.INT.value,
-            'on_host': FilterFieldType.STR.value,
+            'node_id': FilterFieldType.INT.value,
             'guest_uuid': FilterFieldType.STR.value
         }
 
     @staticmethod
     def get_allow_update_keywords():
-        return ['on_host', 'sequence', 'state', 'guest_uuid']
+        return ['node_id', 'sequence', 'state', 'guest_uuid']
 
     @staticmethod
     def get_allow_content_search_keywords():
-        return ['remark', 'size', 'guest_uuid', 'uuid', 'on_host']
+        return ['remark', 'size', 'guest_uuid', 'uuid', 'node_id']
 
 
 class GuestMigrateInfo(ORM):

+ 16 - 0
models/host.py

@@ -137,3 +137,19 @@ class Host(object):
         hosts.sort(key=lambda _k: _k['system_load_per_cpu'])
 
         return hosts
+
+    @staticmethod
+    def get_lightest_host():
+        # 负载最小的宿主机
+        lightest_host = None
+        for k, v in db.r.hgetall(app.config['hosts_info']).items():
+            v = json.loads(v)
+
+            if lightest_host is None:
+                lightest_host = v
+
+            if float(lightest_host['system_load'][0]) / lightest_host['cpu'] > \
+                    float(v['system_load'][0]) / v['cpu']:
+                lightest_host = v
+
+        return lightest_host

+ 1 - 3
models/rules.py

@@ -60,7 +60,7 @@ class Rules(Enum):
     RSA_PUBLIC = (basestring, 'rsa_public')
 
     UUID = (basestring, 'uuid', (36, 36))
-    NODE_ID = (basestring, 'node_id', (14, 15))
+    NODE_ID = (basestring, 'node_id', (16, 16))
     UUIDS = (REG_UUIDS, 'uuids')
     CPU = (int, 'cpu')
     MEMORY = (int, 'memory')
@@ -71,12 +71,10 @@ class Rules(Enum):
     LOGIN_NAME = (basestring, 'login_name')
     PASSWORD = (basestring, 'password')
     LEASE_TERM = (int, 'lease_term')
-    GUEST_ON_HOST = (basestring, 'on_host', (1, 128))
     DESTINATION_HOST = (basestring, 'destination_host', (5, 64))
     DISK_UUID = (basestring, 'disk_uuid', (36, 36))
     DISK_SIZE = (int, 'size')
     DISK_SIZE_STR = (REG_NUMBER, 'size')
-    DISK_ON_HOST = (basestring, 'on_host', (1, 128))
     IOPS = (int, 'iops')
     IOPS_RD = (int, 'iops_rd')
     IOPS_WR = (int, 'iops_wr')

+ 1 - 1
templates/disks_show.html

@@ -660,7 +660,7 @@
                         {{ item.guest.label }}/{{ item.guest.remark }}
                     {% endif %}</a>
                     </td>
-                    <td style="{% if not show_on_host %}display: none;{% endif %}">{{ item.on_host }}</td>
+                    <td style="{% if not show_on_host %}display: none;{% endif %}">{{ hosts_mapping_by_node_id[item.node_id].hostname }}</td>
                     <td>
                         {% if item.sequence == 0 %}
                             系统盘

+ 2 - 2
templates/guest_detail.html

@@ -1130,9 +1130,9 @@
                         </tr>
                         <tr>
                             <td>
-                                <span class="guest-label">所在计算节点:&nbsp;&nbsp;&nbsp;&nbsp;</span>
+                                <span class="guest-label">计算节点:&nbsp;&nbsp;&nbsp;&nbsp;</span>
                                 <span class="guest-desc">
-                                {{ guest_ret.data.on_host }}
+                                {{ hosts_mapping_by_node_id[guest_ret.data.node_id].hostname }}
                                 </span>
                             </td>
                         </tr>

+ 1 - 1
templates/guests_show.html

@@ -671,7 +671,7 @@
                     </td>
                     <td><span class="{{ os_templates_mapping_by_id[item.os_template_id].icon }}" title="{{ os_templates_mapping_by_id[item.os_template_id].label }}"></span></td>
                     <td>{{ format_guest_status(item.status, item.progress)|safe }}</td>
-                    <td>{{ item.on_host }}</td>
+                    <td>{{ hosts_mapping_by_node_id[item.node_id].hostname }}</td>
                     <td>CPU :&nbsp;&nbsp;{{ item.cpu }}&nbsp;核<br />内存 :&nbsp;&nbsp;{{ item.memory }}&nbsp;GB</td>
                     <td>{{ item.ip }}</td>
                     <td><span class="unreal_password">*********</span><span class="real_password" style="display: none;">{{ item.password }}</span></td>

+ 11 - 3
views/disk.py

@@ -88,8 +88,8 @@ def show():
 
     host_url = request.host_url.rstrip('/')
 
+    hosts_url = host_url + url_for('api_hosts.r_get_by_filter')
     disks_url = host_url + url_for('api_disks.r_get_by_filter')
-
     config_url = host_url + url_for('api_config.r_get')
 
     if keyword is not None:
@@ -97,6 +97,13 @@ def show():
         # 关键字检索,不支持显示域过滤
         show_area = 'all'
 
+    hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
+    hosts_ret = json.loads(hosts_ret.content)
+
+    hosts_mapping_by_node_id = dict()
+    for host in hosts_ret['data']:
+        hosts_mapping_by_node_id[int(host['node_id'])] = host
+
     if args.__len__() > 0:
         disks_url = disks_url + '?' + '&'.join(args)
 
@@ -150,8 +157,9 @@ def show():
             if i == last_page or last_page == 0:
                 break
 
-    return render_template('disks_show.html', disks_ret=disks_ret, resource_path=resource_path, page=page,
-                           page_size=page_size, keyword=keyword, pages=pages, order_by=order_by, order=order,
+    return render_template('disks_show.html', disks_ret=disks_ret, resource_path=resource_path,
+                           hosts_mapping_by_node_id=hosts_mapping_by_node_id,
+                           page=page, page_size=page_size, keyword=keyword, pages=pages, order_by=order_by, order=order,
                            last_page=last_page, show_area=show_area, config_ret=config_ret, show_on_host=show_on_host)
 
 

+ 18 - 0
views/guest.py

@@ -51,6 +51,7 @@ def show():
 
     host_url = request.host_url.rstrip('/')
 
+    hosts_url = host_url + url_for('api_hosts.r_get_by_filter')
     guests_url = host_url + url_for('api_guests.r_get_by_filter')
     if keyword is not None:
         guests_url = host_url + url_for('api_guests.r_content_search')
@@ -60,6 +61,13 @@ def show():
     if args.__len__() > 0:
         guests_url = guests_url + '?' + '&'.join(args)
 
+    hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
+    hosts_ret = json.loads(hosts_ret.content)
+
+    hosts_mapping_by_node_id = dict()
+    for host in hosts_ret['data']:
+        hosts_mapping_by_node_id[int(host['node_id'])] = host
+
     guests_ret = requests.get(url=guests_url, cookies=request.cookies)
     guests_ret = json.loads(guests_ret.content)
 
@@ -110,6 +118,7 @@ def show():
 
     return render_template('guests_show.html', guests_ret=guests_ret, resource_path=resource_path,
                            os_templates_mapping_by_id=os_templates_mapping_by_id,
+                           hosts_mapping_by_node_id=hosts_mapping_by_node_id,
                            guests_boot_jobs_ret=guests_boot_jobs_ret, page=page,
                            page_size=page_size, keyword=keyword, pages=pages, last_page=last_page)
 
@@ -221,8 +230,16 @@ def vnc(uuid):
 def detail(uuid):
     host_url = request.host_url.rstrip('/')
 
+    hosts_url = host_url + url_for('api_hosts.r_get_by_filter')
     guest_url = host_url + url_for('api_guests.r_get', uuids=uuid)
 
+    hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
+    hosts_ret = json.loads(hosts_ret.content)
+
+    hosts_mapping_by_node_id = dict()
+    for host in hosts_ret['data']:
+        hosts_mapping_by_node_id[int(host['node_id'])] = host
+
     guest_ret = requests.get(url=guest_url, cookies=request.cookies)
     guest_ret = json.loads(guest_ret.content)
 
@@ -240,6 +257,7 @@ def detail(uuid):
     config_ret = json.loads(config_ret.content)
 
     return render_template('guest_detail.html', uuid=uuid, guest_ret=guest_ret, os_template_ret=os_template_ret,
+                           hosts_mapping_by_node_id=hosts_mapping_by_node_id,
                            disks_ret=disks_ret, config_ret=config_ret)