Pārlūkot izejas kodu

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

James Iter 7 gadi atpakaļ
vecāks
revīzija
e6ce76931f

+ 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.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 Database as db
 from jimvc.models import Config
@@ -116,10 +119,6 @@ def r_create():
                 filter_str='os_template_initialize_operate_set_id:eq:' +
                            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)
 
         # 默认只取可随机分配虚拟机的 hosts
@@ -184,6 +183,28 @@ def r_create():
 
         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:
             quantity -= 1
             guest = Guest()
@@ -200,15 +221,11 @@ def r_create():
             if guest.password is None or guest.password.__len__() < 1:
                 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.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)
 
             disk = Disk()
@@ -249,7 +266,7 @@ def r_create():
                     ssh_key_guest_mapping.create()
 
             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)
@@ -257,19 +274,19 @@ def r_create():
                 _os_template_initialize_operates[k]['content'] = v['content'].replace('{IP}', guest.ip).\
                     replace('{HOSTNAME}', guest.label). \
                     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))
 
                 _os_template_initialize_operates[k]['command'] = v['command'].replace('{IP}', guest.ip). \
                     replace('{HOSTNAME}', guest.label). \
                     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))
 
             message = {

+ 0 - 10
jimvc/models/event_processor.py

@@ -191,16 +191,6 @@ class EventProcessor(object):
                     cls.config.get()
                     cls.guest.uuid = 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()
 
                     # TODO: 加入是否删除使用的数据磁盘开关,如果为True,则顺便删除使用的磁盘。否则解除该磁盘被使用的状态。

+ 0 - 4
jimvc/models/initialize.py

@@ -34,10 +34,6 @@ class Init(object):
         'log_cycle': 'D',
         'instruction_channel': 'C:Instruction',
         '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',
         'upstream_queue': 'Q:Upstream',
         '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 +
                     " 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)
         if where_str != '':
             sql_stmt = ("SELECT * FROM " + cls._table_name + " WHERE " + where_str + " ORDER BY " + order_by + " " +
                         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()
         cursor = cnx.cursor(dictionary=True, buffered=True)
         try:
             cursor.execute(sql_stmt, {'offset': offset, 'limit': limit})
             rows = cursor.fetchall()
-            return rows, rows.__len__()
+            cursor.execute(sql_stmt_count)
+            count = cursor.fetchone()
+            return rows, count["count(" + cls._primary_key + ")"]
         finally:
             cursor.close()
             cnx.close()
@@ -290,6 +294,7 @@ class ORM(object):
         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 +
                     " 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})
         cnx = db.cnxpool.get_connection()
@@ -297,7 +302,9 @@ class ORM(object):
         try:
             cursor.execute(sql_stmt, _kv)
             rows = cursor.fetchall()
-            return rows, rows.__len__()
+            cursor.execute(sql_stmt_count, _kv)
+            count = cursor.fetchone()
+            return rows, count["count(" + cls._primary_key + ")"]
         finally:
             cursor.close()
             cnx.close()
@@ -308,13 +315,16 @@ class ORM(object):
             order_by = cls._primary_key
 
         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()
         cursor = cnx.cursor(dictionary=True, buffered=True)
         try:
             cursor.execute(sql_stmt)
             rows = cursor.fetchall()
-            return rows, rows.__len__()
+            cursor.execute(sql_stmt_count)
+            count = cursor.fetchone()
+            return rows, count["count(" + cls._primary_key + ")"]
         finally:
             cursor.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