Przeglądaj źródła

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

James Iter 9 lat temu
rodzic
commit
fef8d15b2f
7 zmienionych plików z 140 dodań i 29 usunięć
  1. 3 3
      api/guest.py
  2. 22 0
      misc/init.sql
  3. 45 1
      models/event_processor.py
  4. 36 0
      models/guest.py
  5. 2 0
      models/status.py
  6. 5 0
      models/utils.py
  7. 27 25
      tests/test_guest.py

+ 3 - 3
api/guest.py

@@ -411,7 +411,7 @@ def r_attach_disk(uuid, disk_uuid):
         # 取出该 guest 已挂载的磁盘,来做出决定,确定该磁盘的序列
         # 取出该 guest 已挂载的磁盘,来做出决定,确定该磁盘的序列
         disk.guest_uuid = guest.uuid
         disk.guest_uuid = guest.uuid
         disks, count = disk.get_by_filter(filter_str='guest_uuid:in:' + 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 = Config()
         config.id = 1
         config.id = 1
@@ -420,7 +420,7 @@ def r_attach_disk(uuid, disk_uuid):
         xml = """
         xml = """
             <disk type='network' device='disk'>
             <disk type='network' device='disk'>
                 <driver name='qemu' type='qcow2' cache='none'/>
                 <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'/>
                     <host name='127.0.0.1' port='24007'/>
                 </source>
                 </source>
                 <target dev='{3}' bus='virtio'/>
                 <target dev='{3}' bus='virtio'/>
@@ -477,7 +477,7 @@ def r_detach_disk(disk_uuid):
         xml = """
         xml = """
             <disk type='network' device='disk'>
             <disk type='network' device='disk'>
                 <driver name='qemu' type='qcow2' cache='none'/>
                 <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'/>
                     <host name='127.0.0.1' port='24007'/>
                 </source>
                 </source>
                 <target dev='{3}' bus='virtio'/>
                 <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);
 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(
 CREATE TABLE IF NOT EXISTS disk(
     id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
     id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
     uuid CHAR(36) NOT NULL,
     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 Utils
 from models import EmitKind
 from models import EmitKind
 from models import ResponseState, GuestState, DiskState
 from models import ResponseState, GuestState, DiskState
+from models.guest import GuestMigrateInfo
 from models.initialize import app, logger
 from models.initialize import app, logger
 
 
 
 
@@ -27,6 +28,7 @@ class EventProcessor(object):
     message = None
     message = None
     log = Log()
     log = Log()
     guest = Guest()
     guest = Guest()
+    guest_migrate_info = GuestMigrateInfo()
     disk = Disk()
     disk = Disk()
     config = Config()
     config = Config()
 
 
@@ -41,8 +43,50 @@ class EventProcessor(object):
     def guest_event_processor(cls):
     def guest_event_processor(cls):
         cls.guest.uuid = cls.message['message']['uuid']
         cls.guest.uuid = cls.message['message']['uuid']
         cls.guest.get_by('uuid')
         cls.guest.get_by('uuid')
-        cls.guest.status = cls.message['type']
         cls.guest.on_host = cls.message['host']
         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()
         cls.guest.update()
 
 
     @classmethod
     @classmethod

+ 36 - 0
models/guest.py

@@ -103,4 +103,40 @@ class Disk(ORM):
         return ['label', 'size']
         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
     shutoff = 5
     crashed = 6
     crashed = 6
     pm_suspended = 7
     pm_suspended = 7
+    migrating = 8
+    update = 9
     dirty = 255
     dirty = 255
 
 
 
 

+ 5 - 0
models/utils.py

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

+ 27 - 25
tests/test_guest.py

@@ -28,23 +28,23 @@ class TestGuest(unittest.TestCase):
 
 
     # 创建Guest
     # 创建Guest
     # @unittest.skip('skip create 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 列表
     # 获取 Guest 列表
     # def test_12_get_list(self):
     # def test_12_get_list(self):
@@ -211,6 +211,8 @@ class TestGuest(unittest.TestCase):
     #     print json.dumps(j_r, ensure_ascii=False)
     #     print json.dumps(j_r, ensure_ascii=False)
 
 
     # def test_58_attach_disk(self):
     # 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
     #     url = TestGuest.base_url + '/guest/_attach_disk/' + TestGuest.uuid + '/' + TestGuest.disk_uuid
     #     headers = {'content-type': 'application/json'}
     #     headers = {'content-type': 'application/json'}
     #     r = requests.put(url, headers=headers)
     #     r = requests.put(url, headers=headers)
@@ -218,14 +220,14 @@ class TestGuest(unittest.TestCase):
     #     print json.dumps(j_r, ensure_ascii=False)
     #     print json.dumps(j_r, ensure_ascii=False)
     #     self.assertEqual('200', j_r['state']['code'])
     #     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):
     # def test_60_delete(self):
     #     url = TestGuest.base_url + '/guests/' + TestGuest.uuid
     #     url = TestGuest.base_url + '/guests/' + TestGuest.uuid