Эх сурвалжийг харах

实现guest增删设备时更新guest在JimV-C数据库中的xml信息

James Iter 9 жил өмнө
parent
commit
fef8d15b2f

+ 3 - 3
api/guest.py

@@ -411,7 +411,7 @@ def r_attach_disk(uuid, disk_uuid):
         # 取出该 guest 已挂载的磁盘,来做出决定,确定该磁盘的序列
         disk.guest_uuid = guest.uuid
         disks, count = disk.get_by_filter(filter_str='guest_uuid:in:' + guest.uuid)
-        disk.sequence = count + 1
+        disk.sequence = count
 
         config = Config()
         config.id = 1
@@ -420,7 +420,7 @@ def r_attach_disk(uuid, disk_uuid):
         xml = """
             <disk type='network' device='disk'>
                 <driver name='qemu' type='qcow2' cache='none'/>
-                <source protocol='gluster' name='{0}/DiskPool/{1}.{2}'>
+                <source protocol='gluster' name='{0}/Images/{1}.{2}'>
                     <host name='127.0.0.1' port='24007'/>
                 </source>
                 <target dev='{3}' bus='virtio'/>
@@ -477,7 +477,7 @@ def r_detach_disk(disk_uuid):
         xml = """
             <disk type='network' device='disk'>
                 <driver name='qemu' type='qcow2' cache='none'/>
-                <source protocol='gluster' name='{0}/DiskPool/{1}.{2}'>
+                <source protocol='gluster' name='{0}/Images/{1}.{2}'>
                     <host name='127.0.0.1' port='24007'/>
                 </source>
                 <target dev='{3}' bus='virtio'/>

+ 22 - 0
misc/init.sql

@@ -32,6 +32,28 @@ ALTER TABLE guest ADD INDEX (on_host);
 ALTER TABLE guest ADD INDEX (ip);
 
 
+CREATE TABLE IF NOT EXISTS guest_migrate_info(
+    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
+    uuid CHAR(36) NOT NULL,
+    type TINYINT UNSIGNED NOT NULL DEFAULT 0,
+    time_elapsed BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    time_remaining BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    data_total BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    data_processed BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    data_remaining BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    mem_total BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    mem_processed BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    mem_remaining BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    file_total BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    file_processed BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    file_remaining BIGINT UNSIGNED NOT NULL DEFAULT 0,
+    PRIMARY KEY (id))
+    ENGINE=InnoDB
+    DEFAULT CHARSET=utf8;
+
+ALTER TABLE guest_migrate_info ADD INDEX (uuid);
+
+
 CREATE TABLE IF NOT EXISTS disk(
     id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
     uuid CHAR(36) NOT NULL,

+ 45 - 1
models/event_processor.py

@@ -14,6 +14,7 @@ from models import Log
 from models import Utils
 from models import EmitKind
 from models import ResponseState, GuestState, DiskState
+from models.guest import GuestMigrateInfo
 from models.initialize import app, logger
 
 
@@ -27,6 +28,7 @@ class EventProcessor(object):
     message = None
     log = Log()
     guest = Guest()
+    guest_migrate_info = GuestMigrateInfo()
     disk = Disk()
     config = Config()
 
@@ -41,8 +43,50 @@ class EventProcessor(object):
     def guest_event_processor(cls):
         cls.guest.uuid = cls.message['message']['uuid']
         cls.guest.get_by('uuid')
-        cls.guest.status = cls.message['type']
         cls.guest.on_host = cls.message['host']
+        cls.guest.status = cls.message['type']
+
+        if cls.guest.status == GuestState.update.value:
+            cls.guest.xml = cls.message['message']['xml']
+
+        elif cls.guest.status == GuestState.migrating.value:
+            try:
+                cls.guest_migrate_info.uuid = cls.guest.uuid
+                cls.guest_migrate_info.get_by('uuid')
+
+                cls.guest_migrate_info.type = cls.message['message']['migrating_info']['type']
+                cls.guest_migrate_info.time_elapsed = cls.message['message']['migrating_info']['time_elapsed']
+                cls.guest_migrate_info.time_remaining = cls.message['message']['migrating_info']['time_remaining']
+                cls.guest_migrate_info.data_total = cls.message['message']['migrating_info']['data_total']
+                cls.guest_migrate_info.data_processed = cls.message['message']['migrating_info']['data_processed']
+                cls.guest_migrate_info.data_remaining = cls.message['message']['migrating_info']['data_remaining']
+                cls.guest_migrate_info.mem_total = cls.message['message']['migrating_info']['mem_total']
+                cls.guest_migrate_info.mem_processed = cls.message['message']['migrating_info']['mem_processed']
+                cls.guest_migrate_info.mem_remaining = cls.message['message']['migrating_info']['mem_remaining']
+                cls.guest_migrate_info.file_total = cls.message['message']['migrating_info']['file_total']
+                cls.guest_migrate_info.file_processed = cls.message['message']['migrating_info']['file_processed']
+                cls.guest_migrate_info.file_remaining = cls.message['message']['migrating_info']['file_remaining']
+
+                cls.guest_migrate_info.update()
+
+            except ji.PreviewingError as e:
+                ret = json.loads(e.message)
+                if ret['state']['code'] == '404':
+                    cls.guest_migrate_info.type = cls.message['message']['migrating_info']['type']
+                    cls.guest_migrate_info.time_elapsed = cls.message['message']['migrating_info']['time_elapsed']
+                    cls.guest_migrate_info.time_remaining = cls.message['message']['migrating_info']['time_remaining']
+                    cls.guest_migrate_info.data_total = cls.message['message']['migrating_info']['data_total']
+                    cls.guest_migrate_info.data_processed = cls.message['message']['migrating_info']['data_processed']
+                    cls.guest_migrate_info.data_remaining = cls.message['message']['migrating_info']['data_remaining']
+                    cls.guest_migrate_info.mem_total = cls.message['message']['migrating_info']['mem_total']
+                    cls.guest_migrate_info.mem_processed = cls.message['message']['migrating_info']['mem_processed']
+                    cls.guest_migrate_info.mem_remaining = cls.message['message']['migrating_info']['mem_remaining']
+                    cls.guest_migrate_info.file_total = cls.message['message']['migrating_info']['file_total']
+                    cls.guest_migrate_info.file_processed = cls.message['message']['migrating_info']['file_processed']
+                    cls.guest_migrate_info.file_remaining = cls.message['message']['migrating_info']['file_remaining']
+
+                    cls.guest_migrate_info.create()
+
         cls.guest.update()
 
     @classmethod

+ 36 - 0
models/guest.py

@@ -103,4 +103,40 @@ class Disk(ORM):
         return ['label', 'size']
 
 
+class GuestMigrateInfo(ORM):
+
+    _table_name = 'guest_migrate_info'
+    _primary_key = 'id'
+
+    def __init__(self):
+        super(GuestMigrateInfo, self).__init__()
+        self.id = 0
+        self.uuid = None
+        self.type = None
+        self.time_elapsed = None
+        self.time_remaining = None
+        self.data_total = None
+        self.data_processed = None
+        self.data_remaining = None
+        self.mem_total = None
+        self.mem_processed = None
+        self.mem_remaining = None
+        self.file_total = None
+        self.file_processed = None
+        self.file_remaining = None
+
+    @staticmethod
+    def get_filter_keywords():
+        return {
+            'id': FilterFieldType.INT.value,
+            'uuid': FilterFieldType.STR.value
+        }
+
+    @staticmethod
+    def get_allow_update_keywords():
+        return []
+
+    @staticmethod
+    def get_allow_content_search_keywords():
+        return []
 

+ 2 - 0
models/status.py

@@ -30,6 +30,8 @@ class GuestState(IntEnum):
     shutoff = 5
     crashed = 6
     pm_suspended = 7
+    migrating = 8
+    update = 9
     dirty = 255
 
 

+ 5 - 0
models/utils.py

@@ -189,6 +189,11 @@ def utility_processor():
             icon = 'glyph-icon icon-anchor'
             desc = '悬挂'
 
+        elif status == GuestState.migrating.value:
+            color = '1CF5E7'
+            icon = 'glyph-icon icon-space-shuttle'
+            desc = '迁移中'
+
         elif status == GuestState.dirty.value:
             color = 'FCFF07'
             icon = 'glyph-icon icon-remove'

+ 27 - 25
tests/test_guest.py

@@ -28,23 +28,23 @@ class TestGuest(unittest.TestCase):
 
     # 创建Guest
     # @unittest.skip('skip create guest')
-    def test_11_create(self):
-        payload = {
-            "cpu": 4,
-            "memory": 4,
-            "os_template_id": 1,
-            "quantity": 2,
-            "name": "",
-            "password": "pswd.com",
-            "lease_term": 100
-        }
-
-        url = TestGuest.base_url + '/guest'
-        headers = {'content-type': 'application/json'}
-        r = requests.post(url, data=json.dumps(payload), headers=headers)
-        j_r = json.loads(r.content)
-        print json.dumps(j_r, ensure_ascii=False)
-        self.assertEqual('200', j_r['state']['code'])
+    # def test_11_create(self):
+    #     payload = {
+    #         "cpu": 4,
+    #         "memory": 4,
+    #         "os_template_id": 1,
+    #         "quantity": 2,
+    #         "name": "",
+    #         "password": "pswd.com",
+    #         "lease_term": 100
+    #     }
+    #
+    #     url = TestGuest.base_url + '/guest'
+    #     headers = {'content-type': 'application/json'}
+    #     r = requests.post(url, data=json.dumps(payload), headers=headers)
+    #     j_r = json.loads(r.content)
+    #     print json.dumps(j_r, ensure_ascii=False)
+    #     self.assertEqual('200', j_r['state']['code'])
 
     # 获取 Guest 列表
     # def test_12_get_list(self):
@@ -211,6 +211,8 @@ class TestGuest(unittest.TestCase):
     #     print json.dumps(j_r, ensure_ascii=False)
 
     # def test_58_attach_disk(self):
+    #     TestGuest.uuid = 'ba38a067-83cb-49e8-bfc1-7dce7d5e34e6'
+    #     TestGuest.disk_uuid = '23d09c24-3bf3-4b05-bde4-e9fe5de317e8'
     #     url = TestGuest.base_url + '/guest/_attach_disk/' + TestGuest.uuid + '/' + TestGuest.disk_uuid
     #     headers = {'content-type': 'application/json'}
     #     r = requests.put(url, headers=headers)
@@ -218,14 +220,14 @@ class TestGuest(unittest.TestCase):
     #     print json.dumps(j_r, ensure_ascii=False)
     #     self.assertEqual('200', j_r['state']['code'])
 
-    # def test_59_detach_disk(self):
-    #     TestGuest.disk_uuid = '234670cb-3ce4-4ef9-ba23-12bed636184c'
-    #     url = TestGuest.base_url + '/guest/_detach_disk/' + TestGuest.disk_uuid
-    #     headers = {'content-type': 'application/json'}
-    #     r = requests.put(url, headers=headers)
-    #     j_r = json.loads(r.content)
-    #     print json.dumps(j_r, ensure_ascii=False)
-    #     self.assertEqual('200', j_r['state']['code'])
+    def test_59_detach_disk(self):
+        TestGuest.disk_uuid = '23d09c24-3bf3-4b05-bde4-e9fe5de317e8'
+        url = TestGuest.base_url + '/guest/_detach_disk/' + TestGuest.disk_uuid
+        headers = {'content-type': 'application/json'}
+        r = requests.put(url, headers=headers)
+        j_r = json.loads(r.content)
+        print json.dumps(j_r, ensure_ascii=False)
+        self.assertEqual('200', j_r['state']['code'])
 
     # def test_60_delete(self):
     #     url = TestGuest.base_url + '/guests/' + TestGuest.uuid