James Iter преди 9 години
родител
ревизия
01db10fccb
променени са 7 файла, в които са добавени 89 реда и са изтрити 34 реда
  1. 3 0
      misc/init.sql
  2. 5 2
      models/__init__.py
  3. 36 3
      models/event_processor.py
  4. 3 1
      models/guest.py
  5. 14 0
      models/status.py
  6. 25 25
      tests/test_guest.py
  7. 3 3
      views/disk.py

+ 3 - 0
misc/init.sql

@@ -11,6 +11,7 @@ CREATE TABLE IF NOT EXISTS guest(
     remark VARCHAR(255) NOT NULL DEFAULT '',
     os_template_id BIGINT UNSIGNED NOT NULL,
     create_time BIGINT UNSIGNED NOT NULL,
+    -- 运行时的状态用 status;
     status TINYINT UNSIGNED NOT NULL DEFAULT 0,
     on_host VARCHAR(128) NOT NULL DEFAULT '',
     cpu TINYINT UNSIGNED NOT NULL,
@@ -38,6 +39,8 @@ CREATE TABLE IF NOT EXISTS guest_disk(
     size INT UNSIGNED NOT NULL,
     sequence TINYINT NOT NULL,
     format CHAR(16) NOT NULL DEFAULT 'qcow2',
+    -- 实例固有的状态用 state;
+    state TINYINT UNSIGNED NOT NULL DEFAULT 0,
     guest_uuid CHAR(36) NOT NULL,
     PRIMARY KEY (id))
     ENGINE=InnoDB

+ 5 - 2
models/__init__.py

@@ -50,6 +50,8 @@ from os_template import (
 from status import (
     EmitKind,
     GuestState,
+    ResponseState,
+    DiskState,
     LogLevel
 )
 
@@ -69,8 +71,9 @@ __copyright__ = '(c) 2017 by James Iter.'
 
 
 __all__ = [
-    'Rules', 'Utils', 'Init', 'Database', 'FilterFieldType', 'Filter', 'EmitKind', 'GuestState', 'LogLevel', 'ORM',
-    'Config', 'Guest', 'GuestDisk', 'OSInit', 'OSInitWrite', 'OSTemplate', 'GuestXML', 'Log', 'EventProcessor'
+    'Rules', 'Utils', 'Init', 'Database', 'FilterFieldType', 'Filter', 'EmitKind', 'GuestState', 'DiskState',
+    'LogLevel', 'ORM', 'Config', 'Guest', 'GuestDisk', 'OSInit', 'OSInitWrite', 'OSTemplate', 'GuestXML', 'Log',
+    'EventProcessor', 'ResponseState'
 ]
 
 

+ 36 - 3
models/event_processor.py

@@ -7,9 +7,11 @@ import time
 
 from models import Database as db
 from models import Guest
+from models import GuestDisk
 from models import Log
 from models import Utils
 from models import EmitKind
+from models import ResponseState, GuestState, DiskState
 from models.initialize import app, logger
 
 
@@ -23,6 +25,7 @@ class EventProcessor(object):
     message = None
     log = Log()
     guest = Guest()
+    disk = GuestDisk()
 
     @classmethod
     def log_processor(cls):
@@ -39,6 +42,33 @@ class EventProcessor(object):
         cls.guest.on_host = cls.message['host']
         cls.guest.update()
 
+    @classmethod
+    def response_processor(cls):
+        action = cls.message['message']['action']
+        uuid = cls.message['message']['uuid']
+        state = cls.message['type']
+
+        if action == 'create_vm':
+            if state != ResponseState.success.value:
+                cls.guest.uuid = uuid
+                cls.guest.get_by('uuid')
+                cls.guest.status = GuestState.dirty.value
+                cls.guest.update()
+
+        elif action == 'create_disk':
+            cls.disk.uuid = uuid
+            cls.disk.get_by('uuid')
+            if state == ResponseState.success.value:
+                cls.disk.state = DiskState.idle.value
+
+            else:
+                cls.disk.state = DiskState.dirty.value
+
+            cls.disk.update()
+
+        else:
+            pass
+
     @classmethod
     def launch(cls):
         while True:
@@ -48,13 +78,13 @@ class EventProcessor(object):
                 return
 
             try:
-                host_log = db.r.lpop(app.config['upstream_queue'])
+                report = db.r.lpop(app.config['upstream_queue'])
 
-                if host_log is None:
+                if report is None:
                     time.sleep(1)
                     continue
 
-                cls.message = json.loads(host_log)
+                cls.message = json.loads(report)
 
                 if cls.message['kind'] == EmitKind.log.value:
                     cls.log_processor()
@@ -62,6 +92,9 @@ class EventProcessor(object):
                 elif cls.message['kind'] == EmitKind.event.value:
                     cls.event_processor()
 
+                elif cls.message['kind'] == EmitKind.response.value:
+                    cls.response_processor()
+
                 else:
                     pass
 

+ 3 - 1
models/guest.py

@@ -6,7 +6,7 @@ import jimit as ji
 
 from filter import FilterFieldType
 from orm import ORM
-from status import GuestState
+from status import GuestState, DiskState
 from database import Database as db
 from initialize import app
 
@@ -76,6 +76,7 @@ class GuestDisk(ORM):
         self.label = None
         self.size = None
         self.sequence = None
+        self.state = DiskState.pending.value
         self.format = 'qcow2'
         self.guest_uuid = None
 
@@ -85,6 +86,7 @@ class GuestDisk(ORM):
             'uuid': FilterFieldType.STR.value,
             'label': FilterFieldType.STR.value,
             'size': FilterFieldType.INT.value,
+            'state': FilterFieldType.INT.value,
             'guest_uuid': FilterFieldType.STR.value
         }
 

+ 14 - 0
models/status.py

@@ -14,6 +14,7 @@ __copyright__ = '(c) 2017 by James Iter.'
 class EmitKind(IntEnum):
     log = 0
     event = 1
+    response = 2
 
 
 class GuestState(IntEnum):
@@ -28,6 +29,7 @@ class GuestState(IntEnum):
     shutoff = 5
     crashed = 6
     pm_suspended = 7
+    dirty = 255
 
 
 class LogLevel(IntEnum):
@@ -37,3 +39,15 @@ class LogLevel(IntEnum):
     info = 3
     debug = 4
 
+
+class ResponseState(IntEnum):
+    success = True
+    failure = False
+
+
+class DiskState(IntEnum):
+    pending = 0
+    idle = 1
+    mounted = 2
+    dirty = 255
+

+ 25 - 25
tests/test_guest.py

@@ -117,31 +117,31 @@ class TestGuest(unittest.TestCase):
         print json.dumps(j_r, ensure_ascii=False)
         self.assertEqual('200', j_r['state']['code'])
 
-    def test_32_detach_disk(self):
-        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'])
-
-    # 删除Guest
-    # @unittest.skip('skip delete guest')
-    def test_41_delete(self):
-        url = TestGuest.base_url + '/guests/' + TestGuest.uuid
-        headers = {'content-type': 'application/json'}
-        r = requests.delete(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_42_delete_disk(self):
-        url = TestGuest.base_url + '/disk/' + TestGuest.disk_uuid
-        headers = {'content-type': 'application/json'}
-        r = requests.delete(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_32_detach_disk(self):
+    #     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'])
+    #
+    # # 删除Guest
+    # # @unittest.skip('skip delete guest')
+    # def test_41_delete(self):
+    #     url = TestGuest.base_url + '/guests/' + TestGuest.uuid
+    #     headers = {'content-type': 'application/json'}
+    #     r = requests.delete(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_42_delete_disk(self):
+    #     url = TestGuest.base_url + '/disk/' + TestGuest.disk_uuid
+    #     headers = {'content-type': 'application/json'}
+    #     r = requests.delete(url, headers=headers)
+    #     j_r = json.loads(r.content)
+    #     print json.dumps(j_r, ensure_ascii=False)
+    #     self.assertEqual('200', j_r['state']['code'])
 
 
 if __name__ == '__main__':

+ 3 - 3
views/disk.py

@@ -69,7 +69,7 @@ def r_create():
         image_path = '/'.join(['DiskPool', guest_disk.uuid + '.' + guest_disk.format])
 
         message = {'action': 'create_disk', 'glusterfs_volume': config.glusterfs_volume,
-                   'image_path': image_path, 'size': guest_disk.size}
+                   'image_path': image_path, 'size': guest_disk.size, 'uuid': guest_disk.uuid}
 
         db.r.rpush(app.config['downstream_queue'], json.dumps(message, ensure_ascii=False))
 
@@ -111,10 +111,10 @@ def r_resize(uuid, size):
         guest_disk.size = size
         guest_disk.update()
 
-        message = {'action': 'resize_disk', 'size': size}
+        message = {'action': 'resize_disk', 'size': size, 'guest_uuid': guest_disk.guest_uuid,
+                   'disk_uuid': guest_disk.uuid}
 
         if used:
-            message['uuid'] = guest_disk.guest_uuid
             message['device_node'] = dev_table[guest_disk.sequence]
             Guest.emit_instruction(message=json.dumps(message))
         else: