Просмотр исходного кода

实现从 IP 池分配 IP 给虚拟机

James Iter 7 лет назад
Родитель
Сommit
e6ce76931f
5 измененных файлов с 56 добавлено и 37 удалено
  1. 37 20
      jimvc/api/guest.py
  2. 0 10
      jimvc/models/event_processor.py
  3. 0 4
      jimvc/models/initialize.py
  4. 13 3
      jimvc/models/orm.py
  5. 6 0
      misc/v0.7_to_v0.8/upgrade.sh

+ 37 - 20
jimvc/api/guest.py

@@ -16,7 +16,10 @@ from flask import Blueprint, url_for, request
 
 
 from jimvc.api.base import Base
 from jimvc.api.base import Base
 from jimvc.models.initialize import dev_table
 from jimvc.models.initialize import dev_table
-from jimvc.models import app_config, GuestState, Service
+from jimvc.models import app_config
+from jimvc.models import GuestState
+from jimvc.models import Service
+from jimvc.models import IPPool
 from jimvc.models import DiskState, Host
 from jimvc.models import DiskState, Host
 from jimvc.models import Database as db
 from jimvc.models import Database as db
 from jimvc.models import Config
 from jimvc.models import Config
@@ -116,10 +119,6 @@ def r_create():
                 filter_str='os_template_initialize_operate_set_id:eq:' +
                 filter_str='os_template_initialize_operate_set_id:eq:' +
                            os_template_profile.os_template_initialize_operate_set_id.__str__())
                            os_template_profile.os_template_initialize_operate_set_id.__str__())
 
 
-        if db.r.scard(app_config['ip_available_set']) < 1:
-            ret['state'] = ji.Common.exchange_state(50350)
-            return ret
-
         node_id = request.json.get('node_id', None)
         node_id = request.json.get('node_id', None)
 
 
         # 默认只取可随机分配虚拟机的 hosts
         # 默认只取可随机分配虚拟机的 hosts
@@ -184,6 +183,28 @@ def r_create():
 
 
         quantity = request.json.get('quantity')
         quantity = request.json.get('quantity')
 
 
+        occupied_ips = list()
+        occupied_vnc_ports = list()
+
+        rows, count = Guest.get_all()
+
+        for row in rows:
+            occupied_ips.append(row['ip'])
+            occupied_vnc_ports.append(row['vnc_port'])
+
+        rows, count = IPPool.get_by_filter(filter_str=':'.join(['activity', 'eq', '1']))
+        if count < 1:
+            ret['state'] = ji.Common.exchange_state(50350)
+            return ret
+
+        ip_pool = IPPool()
+        ip_pool.id = rows[0]['id']
+        ip_pool.get()
+        assert isinstance(ip_pool, IPPool)
+
+        guest_ip_generator = ip_pool.ip_generator(occupied_ips=occupied_ips)
+        guest_vnc_port_generator = ip_pool.vnc_port_generator(occupied_vnc_ports=occupied_vnc_ports)
+
         while quantity:
         while quantity:
             quantity -= 1
             quantity -= 1
             guest = Guest()
             guest = Guest()
@@ -200,15 +221,11 @@ def r_create():
             if guest.password is None or guest.password.__len__() < 1:
             if guest.password is None or guest.password.__len__() < 1:
                 guest.password = ji.Common.generate_random_code(length=16)
                 guest.password = ji.Common.generate_random_code(length=16)
 
 
-            guest.ip = db.r.spop(app_config['ip_available_set'])
-            db.r.sadd(app_config['ip_used_set'], guest.ip)
+            guest.ip = guest_ip_generator.next()
+            guest.vnc_port = guest_vnc_port_generator.next()
 
 
             guest.network = config.vm_network
             guest.network = config.vm_network
             guest.manage_network = config.vm_manage_network
             guest.manage_network = config.vm_manage_network
-
-            guest.vnc_port = db.r.spop(app_config['vnc_port_available_set'])
-            db.r.sadd(app_config['vnc_port_used_set'], guest.vnc_port)
-
             guest.vnc_password = ji.Common.generate_random_code(length=16)
             guest.vnc_password = ji.Common.generate_random_code(length=16)
 
 
             disk = Disk()
             disk = Disk()
@@ -249,7 +266,7 @@ def r_create():
                     ssh_key_guest_mapping.create()
                     ssh_key_guest_mapping.create()
 
 
             if os_template_profile.os_distro == 'coreos':
             if os_template_profile.os_distro == 'coreos':
-                config.netmask = IP(guest.ip).make_net(config.netmask).prefixlen().__str__()
+                ip_pool.netmask = IP(guest.ip).make_net(ip_pool.netmask).prefixlen().__str__()
 
 
             # 替换占位符为有效内容
             # 替换占位符为有效内容
             _os_template_initialize_operates = copy.deepcopy(os_template_initialize_operates)
             _os_template_initialize_operates = copy.deepcopy(os_template_initialize_operates)
@@ -257,19 +274,19 @@ def r_create():
                 _os_template_initialize_operates[k]['content'] = v['content'].replace('{IP}', guest.ip).\
                 _os_template_initialize_operates[k]['content'] = v['content'].replace('{IP}', guest.ip).\
                     replace('{HOSTNAME}', guest.label). \
                     replace('{HOSTNAME}', guest.label). \
                     replace('{PASSWORD}', guest.password). \
                     replace('{PASSWORD}', guest.password). \
-                    replace('{NETMASK}', config.netmask).\
-                    replace('{GATEWAY}', config.gateway).\
-                    replace('{DNS1}', config.dns1).\
-                    replace('{DNS2}', config.dns2). \
+                    replace('{NETMASK}', ip_pool.netmask).\
+                    replace('{GATEWAY}', ip_pool.gateway).\
+                    replace('{DNS1}', ip_pool.dns1).\
+                    replace('{DNS2}', ip_pool.dns2). \
                     replace('{SSH-KEY}', '\n'.join(ssh_keys))
                     replace('{SSH-KEY}', '\n'.join(ssh_keys))
 
 
                 _os_template_initialize_operates[k]['command'] = v['command'].replace('{IP}', guest.ip). \
                 _os_template_initialize_operates[k]['command'] = v['command'].replace('{IP}', guest.ip). \
                     replace('{HOSTNAME}', guest.label). \
                     replace('{HOSTNAME}', guest.label). \
                     replace('{PASSWORD}', guest.password). \
                     replace('{PASSWORD}', guest.password). \
-                    replace('{NETMASK}', config.netmask). \
-                    replace('{GATEWAY}', config.gateway). \
-                    replace('{DNS1}', config.dns1). \
-                    replace('{DNS2}', config.dns2). \
+                    replace('{NETMASK}', ip_pool.netmask). \
+                    replace('{GATEWAY}', ip_pool.gateway). \
+                    replace('{DNS1}', ip_pool.dns1). \
+                    replace('{DNS2}', ip_pool.dns2). \
                     replace('{SSH-KEY}', '\n'.join(ssh_keys))
                     replace('{SSH-KEY}', '\n'.join(ssh_keys))
 
 
             message = {
             message = {

+ 0 - 10
jimvc/models/event_processor.py

@@ -191,16 +191,6 @@ class EventProcessor(object):
                     cls.config.get()
                     cls.config.get()
                     cls.guest.uuid = uuid
                     cls.guest.uuid = uuid
                     cls.guest.get_by('uuid')
                     cls.guest.get_by('uuid')
-
-                    if IP(cls.config.start_ip).int() <= IP(cls.guest.ip).int() <= IP(cls.config.end_ip).int():
-                        if db.r.srem(app_config['ip_used_set'], cls.guest.ip):
-                            db.r.sadd(app_config['ip_available_set'], cls.guest.ip)
-
-                    if (cls.guest.vnc_port - cls.config.start_vnc_port) <= \
-                            (IP(cls.config.end_ip).int() - IP(cls.config.start_ip).int()):
-                        if db.r.srem(app_config['vnc_port_used_set'], cls.guest.vnc_port):
-                            db.r.sadd(app_config['vnc_port_available_set'], cls.guest.vnc_port)
-
                     cls.guest.delete()
                     cls.guest.delete()
 
 
                     # TODO: 加入是否删除使用的数据磁盘开关,如果为True,则顺便删除使用的磁盘。否则解除该磁盘被使用的状态。
                     # TODO: 加入是否删除使用的数据磁盘开关,如果为True,则顺便删除使用的磁盘。否则解除该磁盘被使用的状态。

+ 0 - 4
jimvc/models/initialize.py

@@ -34,10 +34,6 @@ class Init(object):
         'log_cycle': 'D',
         'log_cycle': 'D',
         'instruction_channel': 'C:Instruction',
         'instruction_channel': 'C:Instruction',
         'global_config': 'H:GlobalConfig',
         'global_config': 'H:GlobalConfig',
-        'ip_available_set': 'S:IP:Available',
-        'ip_used_set': 'S:IP:Used',
-        'vnc_port_available_set': 'S:VNCPort:Available',
-        'vnc_port_used_set': 'S:VNCPort:Used',
         'downstream_queue': 'Q:Downstream',
         'downstream_queue': 'Q:Downstream',
         'upstream_queue': 'Q:Upstream',
         'upstream_queue': 'Q:Upstream',
         'ipc_queue': 'Q:IPC',
         'ipc_queue': 'Q:IPC',

+ 13 - 3
jimvc/models/orm.py

@@ -206,18 +206,22 @@ class ORM(object):
 
 
         sql_stmt = ("SELECT * FROM " + cls._table_name + " ORDER BY " + order_by + " " + order +
         sql_stmt = ("SELECT * FROM " + cls._table_name + " ORDER BY " + order_by + " " + order +
                     " LIMIT %(offset)s, %(limit)s")
                     " LIMIT %(offset)s, %(limit)s")
+        sql_stmt_count = ("SELECT count(" + cls._primary_key + ") FROM " + cls._table_name)
 
 
         where_str = Filter.filter_str_to_sql(allow_keywords=cls.get_filter_keywords(), filter_str=filter_str)
         where_str = Filter.filter_str_to_sql(allow_keywords=cls.get_filter_keywords(), filter_str=filter_str)
         if where_str != '':
         if where_str != '':
             sql_stmt = ("SELECT * FROM " + cls._table_name + " WHERE " + where_str + " ORDER BY " + order_by + " " +
             sql_stmt = ("SELECT * FROM " + cls._table_name + " WHERE " + where_str + " ORDER BY " + order_by + " " +
                         order + " LIMIT %(offset)s, %(limit)s")
                         order + " LIMIT %(offset)s, %(limit)s")
+            sql_stmt_count = ("SELECT count(" + cls._primary_key + ") FROM " + cls._table_name + " WHERE " + where_str)
 
 
         cnx = db.cnxpool.get_connection()
         cnx = db.cnxpool.get_connection()
         cursor = cnx.cursor(dictionary=True, buffered=True)
         cursor = cnx.cursor(dictionary=True, buffered=True)
         try:
         try:
             cursor.execute(sql_stmt, {'offset': offset, 'limit': limit})
             cursor.execute(sql_stmt, {'offset': offset, 'limit': limit})
             rows = cursor.fetchall()
             rows = cursor.fetchall()
-            return rows, rows.__len__()
+            cursor.execute(sql_stmt_count)
+            count = cursor.fetchone()
+            return rows, count["count(" + cls._primary_key + ")"]
         finally:
         finally:
             cursor.close()
             cursor.close()
             cnx.close()
             cnx.close()
@@ -290,6 +294,7 @@ class ORM(object):
         where_str = ' OR '.join([k + ' LIKE %(' + k + ')s' for k in _kv.keys()])
         where_str = ' OR '.join([k + ' LIKE %(' + k + ')s' for k in _kv.keys()])
         sql_stmt = ("SELECT * FROM " + cls._table_name + " WHERE " + where_str + " ORDER BY " + order_by + " " + order +
         sql_stmt = ("SELECT * FROM " + cls._table_name + " WHERE " + where_str + " ORDER BY " + order_by + " " + order +
                     " LIMIT %(offset)s, %(limit)s")
                     " LIMIT %(offset)s, %(limit)s")
+        sql_stmt_count = ("SELECT count(" + cls._primary_key + ") FROM " + cls._table_name + " WHERE " + where_str)
 
 
         _kv.update({'offset': offset, 'limit': limit})
         _kv.update({'offset': offset, 'limit': limit})
         cnx = db.cnxpool.get_connection()
         cnx = db.cnxpool.get_connection()
@@ -297,7 +302,9 @@ class ORM(object):
         try:
         try:
             cursor.execute(sql_stmt, _kv)
             cursor.execute(sql_stmt, _kv)
             rows = cursor.fetchall()
             rows = cursor.fetchall()
-            return rows, rows.__len__()
+            cursor.execute(sql_stmt_count, _kv)
+            count = cursor.fetchone()
+            return rows, count["count(" + cls._primary_key + ")"]
         finally:
         finally:
             cursor.close()
             cursor.close()
             cnx.close()
             cnx.close()
@@ -308,13 +315,16 @@ class ORM(object):
             order_by = cls._primary_key
             order_by = cls._primary_key
 
 
         sql_stmt = ("SELECT * FROM " + cls._table_name + " ORDER BY " + order_by + " " + order)
         sql_stmt = ("SELECT * FROM " + cls._table_name + " ORDER BY " + order_by + " " + order)
+        sql_stmt_count = ("SELECT count(" + cls._primary_key + ") FROM " + cls._table_name)
 
 
         cnx = db.cnxpool.get_connection()
         cnx = db.cnxpool.get_connection()
         cursor = cnx.cursor(dictionary=True, buffered=True)
         cursor = cnx.cursor(dictionary=True, buffered=True)
         try:
         try:
             cursor.execute(sql_stmt)
             cursor.execute(sql_stmt)
             rows = cursor.fetchall()
             rows = cursor.fetchall()
-            return rows, rows.__len__()
+            cursor.execute(sql_stmt_count)
+            count = cursor.fetchone()
+            return rows, count["count(" + cls._primary_key + ")"]
         finally:
         finally:
             cursor.close()
             cursor.close()
             cnx.close()
             cnx.close()

+ 6 - 0
misc/v0.7_to_v0.8/upgrade.sh

@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+DEL S:IP:Used
+DEL S:IP:Available
+DEL S:VNCPort:Used
+DEL S:VNCPort:Available