James Iter 9 роки тому
батько
коміт
b33bbddf62
11 змінених файлів з 195 додано та 140 видалено
  1. 0 40
      config.json
  2. 5 1
      docs/todo.md
  3. 10 6
      gunicorn_config.py
  4. 16 0
      jimvc.conf
  5. 25 2
      main.py
  6. 1 1
      models/database.py
  7. 30 10
      models/initialize.py
  8. 2 2
      models/orm.py
  9. 79 75
      templates/config_init.html
  10. 3 3
      views/config.py
  11. 24 0
      views/error_pages.py

+ 0 - 40
config.json

@@ -1,40 +0,0 @@
-{
-  "jimv_listen": "0.0.0.0",
-  "jimv_port": 8008,
-  "db_name": "jimv",
-  "db_host": "localhost",
-  "db_port": 3306,
-  "db_user": "root",
-  "db_password": "jimpswd.com",
-  "db_pool_size": 10,
-  "db_charset": "utf8",
-  "redis_host": "localhost",
-  "redis_port": 2501,
-  "redis_password": "IwNAQSew5FDlmjcL7LlvAurl3gqpFKxu7FCYK0CN0xKErYlew78R2ZNV9lsiFbPaMByHmTygScndOWhlDY8lhTJGqyp9RHMqnxMwlYgE375N0GddYV2AEDZsfarfE0T0",
-  "redis_dbid": 0,
-  "debug": false,
-  "log_file_dir": "logs",
-  "log_cycle": "D",
-  "token_ttl": 604800,
-  "jwt_secret": "kcMsj4qj0EAvAvj3nlFlPZd2x7P9kBBQ$deae64883a03982913e6c5f0ba265c2c5dfd0cfx'",
-  "jwt_algorithm": "HS512",
-  "SESSION_TYPE": "filesystem",
-  "SESSION_PERMANENT": true,
-  "SESSION_USE_SIGNER": true,
-  "SESSION_FILE_DIR": "../cache",
-  "SESSION_FILE_THRESHOLD": 100,
-  "SESSION_COOKIE_NAME": "sid",
-  "SESSION_COOKIE_SECURE": false,
-  "SECRET_KEY": "QSYI73re6x553wmcNwT9tk4OCNK9OUS9xNUulDShEcvRw00YhCKaqHhEGYOGKOSB",
-  "PERMANENT_SESSION_LIFETIME": 604800,
-  "instruction_channel": "C:Instruction",
-  "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",
-  "hosts_info": "H:HostsInfo",
-  "guest_boot_jobs": "S:GuestBootJobs",
-  "guest_boot_jobs_wait_time": 600
-}

+ 5 - 1
docs/todo.md

@@ -34,4 +34,8 @@
 - [x] 重新设计创建虚拟机时的机制,虚拟机创建分配由 JimV-C 角色实现
 - [ ] 虚拟机状态变化时时展现在前端页面上
 - [ ] 迁移时计算出剩余时间
-- [ ] 重新设计 JimV-N 到 JimV-C 的回调机制,现有实现比较混乱。改进为基于对象的回调
+- [x] 重新设计 JimV-N 到 JimV-C 的回调机制,现有实现比较混乱。改进为基于对象的回调
+- [ ] 重新设计创建虚拟机机制,批量创建虚拟机时,依照宿主机负载大小,倒序依次挨个分配虚拟机的创建任务,并且在计算节点上,创建虚拟机的任务单独开辟独立的线程
+- [ ] 规范日志路径。把日志路径调整至 /var/log/ 下
+- [ ] 初始化页面检测redis、mysql是否准备好
+- [ ] 允许删除创建失败的虚拟机

+ 10 - 6
gunicorn_config.py

@@ -13,21 +13,25 @@ __contact__ = 'james.iter.cn@gmail.com'
 __copyright__ = '(c) 2017 by James Iter.'
 
 
-with open('./config.json', 'r') as f:
+with open('/etc/jimvc.conf', 'r') as f:
     _config = json.load(f)
 
-if not os.path.isdir(_config['log_file_dir']):
-    os.makedirs(_config['log_file_dir'], 0755)
+log_file_dir = os.path.dirname(_config['log_file_path'])
 
+if not os.path.isdir(log_file_dir):
+    os.makedirs(log_file_dir, 0755)
 
-bind = _config['jimid_listen'] + ':' + _config['jimid_port'].__str__()
+
+bind = _config['listen'] + ':' + _config['port'].__str__()
 workers = multiprocessing.cpu_count() * 2 + 1
 worker_class = 'eventlet'
 worker_connections = 1000
 daemon = True
 
-accesslog = './logs/access.log'
-errorlog = './logs/error.log'
+accesslog = '/'.join([log_file_dir, 'access.log'])
+errorlog = '/'.join([log_file_dir, 'error.log'])
 loglevel = 'info'
 
 pidfile = './jimid.pid'
+
+

+ 16 - 0
jimvc.conf

@@ -0,0 +1,16 @@
+{
+  "listen": "127.0.0.1",
+  "port": 8008,
+  "db_name": "jimv",
+  "db_host": "localhost",
+  "db_port": 3306,
+  "db_user": "root",
+  "db_password": "jimpswd.com",
+  "redis_host": "localhost",
+  "redis_port": 2501,
+  "redis_password": "IwNAQSew5FDlmjcL7LlvAurl3gqpFKxu7FCYK0CN0xKErYlew78R2ZNV9lsiFbPaMByHmTygScndOWhlDY8lhTJGqyp9RHMqnxMwlYgE375N0GddYV2AEDZsfarfE0T0",
+  "redis_dbid": 0,
+  "log_file_path": "/var/log/jimv/jimvc.log",
+  "jwt_secret": "kcMsj4qj0EAvAvj3nlFlPZd2x7P9kBBQ$deae64883a03982913e6c5f0ba265c2c5dfd0cfx'",
+  "SECRET_KEY": "QSYI73re6x553wmcNwT9tk4OCNK9OUS9xNUulDShEcvRw00YhCKaqHhEGYOGKOSB"
+}

+ 25 - 2
main.py

@@ -11,7 +11,7 @@ import json
 
 import os
 import threading
-from flask import g
+from flask import g, request, redirect, url_for, Response
 
 from models import Utils
 from models.event_processor import EventProcessor
@@ -19,6 +19,7 @@ from models.initialize import app, logger, q_ws, Init
 import api_route_table
 import views_route_table
 from models import Database as db
+from models import Config
 from api.boot_job import blueprint as boot_job_blueprint
 from api.boot_job import blueprints as boot_job_blueprints
 from api.operate_rule import blueprint as operate_rule_blueprint
@@ -39,6 +40,7 @@ from api.performance import blueprints as performance_blueprints
 from api.host_performance import blueprint as host_performance_blueprint
 from api.host_performance import blueprints as host_performance_blueprints
 
+from views.error_pages import *
 from views.config import blueprint as view_config_blueprint
 from views.dashboard import blueprint as view_dashboard_blueprint
 from views.guest import blueprint as view_guest_blueprint
@@ -87,14 +89,35 @@ def ws_engine_for_vnc():
         q_ws.task_done()
 
 
+def is_not_need_to_auth(endpoint):
+    not_auth_table = [
+        'api_config.r_get',
+        'api_config.r_create',
+        'v_config.create'
+    ]
+
+    if endpoint in not_auth_table:
+        return True
+
+    return False
+
+
 @app.before_request
 @Utils.dumps2response
 def r_before_request():
     try:
         g.ts = ji.Common.ts()
+        if not is_not_need_to_auth(request.endpoint) and request.blueprint is not None and request.method != 'OPTIONS':
+            g.config = Config()
+            g.config.id = 1
+            g.config.get()
 
     except ji.JITError, e:
         ret = json.loads(e.message)
+
+        if ret['state']['code'] == '404':
+            return redirect(location=url_for('v_config.create'), Response=Response)
+
         return ret
 
 
@@ -167,7 +190,7 @@ if __name__ == '__main__':
             for t in threads:
                 t.start()
 
-            app.run(host=app.config['jimv_listen'], port=app.config['jimv_port'], use_reloader=False, threaded=True)
+            app.run(host=app.config['listen'], port=app.config['port'], use_reloader=False, threaded=True)
 
             while True:
                 if Utils.exit_flag:

+ 1 - 1
models/database.py

@@ -35,7 +35,7 @@ class Database(object):
                 password=app.config["db_password"],
                 port=app.config["db_port"],
                 database=app.config["db_name"],
-                raise_on_warnings=app.config["debug"],
+                raise_on_warnings=app.config["DEBUG"],
                 pool_size=app.config["db_pool_size"],
                 charset=app.config["db_charset"]
             )

+ 30 - 10
models/initialize.py

@@ -33,7 +33,31 @@ app = Flask(__name__, template_folder='../templates', static_folder='../static')
 
 class Init(object):
     config = {
-        'config_file': '/etc/jimvc.conf'
+        'config_file': '/etc/jimvc.conf',
+        'log_cycle': 'D',
+        'instruction_channel': 'C:Instruction',
+        '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',
+        'hosts_info': 'H:HostsInfo',
+        'guest_boot_jobs': 'S:GuestBootJobs',
+        'guest_boot_jobs_wait_time': 600,
+        'db_charset': 'utf8',
+        'db_pool_size': 10,
+        'DEBUG': False,
+        'jwt_algorithm': 'HS512',
+        'token_ttl': 604800,
+        'SESSION_TYPE': 'filesystem',
+        'SESSION_PERMANENT': True,
+        'SESSION_USE_SIGNER': True,
+        'SESSION_FILE_DIR': '/tmp/jimv',
+        'SESSION_FILE_THRESHOLD': 5000,
+        'SESSION_COOKIE_NAME': 'sid',
+        'SESSION_COOKIE_SECURE': False,
+        'PERMANENT_SESSION_LIFETIME': 604800
     }
 
     @classmethod
@@ -70,23 +94,19 @@ class Init(object):
 
     @classmethod
     def init_logger(cls):
-        cls.config['log_file_base'] = '/'.join([sys.path[0], cls.config['log_file_dir'], 'log'])
-        log_dir = os.path.dirname(cls.config['log_file_base'])
+        log_dir = os.path.dirname(cls.config['log_file_path'])
         if not os.path.isdir(log_dir):
             os.makedirs(log_dir, 0755)
 
-        process_title = 'JimV-C'
-        log_file_path = '.'.join([cls.config['log_file_base'], process_title])
-        _logger = logging.getLogger(log_file_path)
+        _logger = logging.getLogger(cls.config['log_file_path'])
 
-        if cls.config['debug']:
-            cls.config['DEBUG'] = True
+        if cls.config['DEBUG']:
             _logger.setLevel(logging.DEBUG)
         else:
-            cls.config['DEBUG'] = False
             _logger.setLevel(logging.INFO)
 
-        fh = TimedRotatingFileHandler(log_file_path, when=cls.config['log_cycle'], interval=1, backupCount=7)
+        fh = TimedRotatingFileHandler(cls.config['log_file_path'], when=cls.config['log_cycle'],
+                                      interval=1, backupCount=7)
         formatter = logging.Formatter(
             '%(asctime)s - %(name)s - %(levelname)s - %(funcName)s - %(lineno)s - %(message)s')
         fh.setFormatter(formatter)

+ 2 - 2
models/orm.py

@@ -111,8 +111,8 @@ class ORM(object):
         else:
             ret = dict()
             ret['state'] = ji.Common.exchange_state(40401)
-            ret['state']['sub']['zh-cn'] = ': '.join([ret['state']['sub']['zh-cn'], self._primary_key.__str__(),
-                                                      self.__getattribute__(self._primary_key)])
+            ret['state']['sub']['zh-cn'] = ': '.join([ret['state']['sub']['zh-cn'], self._primary_key,
+                                                      self.__getattribute__(self._primary_key).__str__()])
             raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
 
     def exist(self):

+ 79 - 75
templates/config_init.html

@@ -13,6 +13,10 @@
         .form-control {
             border-radius: 0;
         }
+
+        .form-horizontal > .form-group {
+            margin: 0;
+        }
     </style>
 {% endblock head %}
 {% block body %}
@@ -36,90 +40,90 @@
         });
     });
 </script>
-<div class="container" style="padding-top: 100px;">
-    <div class="panel">
-        <div class="panel-body">
-            <h3 class="title-hero" style="text-transform: unset;">
-                初始化 JimV
-            </h3>
-            <div class="example-box-wrapper">
-                <form class="form-horizontal bordered-row" action="/config/create" method="post">
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label">网桥(业务网络)</label>
-                        <div class="col-sm-3">
-                            <input title="Guest 业务网络" class="form-control" name="vm_network" type="text" value="net-br0">
-                        </div>
-                        <label class="col-sm-2 control-label">网桥(管理网络)</label>
-                        <div class="col-sm-3">
-                            <input title="Guest 管理网络" class="form-control" name="vm_manage_network" type="text" value="net-br0">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label">起始 IP</label>
-                        <div class="col-sm-3">
-                            <input title="起始 IP" class="form-control" name="start_ip" type="text" value="10.10.0.1">
-                        </div>
-                        <label class="col-sm-2 control-label">截止 IP</label>
-                        <div class="col-sm-3">
-                            <input title="截止 IP" class="form-control" name="end_ip" type="text" value="10.10.15.253">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label">子网掩码</label>
-                        <div class="col-sm-3">
-                            <input title="子网掩码" class="form-control" name="netmask" type="text" value="255.255.240.0">
-                        </div>
-                        <label class="col-sm-2 control-label">网关</label>
-                        <div class="col-sm-3">
-                            <input title="网关" class="form-control" name="gateway" type="text" value="10.10.15.254">
+    <div class="container" style="padding-top: 100px;">
+        <div class="panel">
+            <div class="panel-body">
+                <h3 class="title-hero" style="text-transform: unset;">
+                    初始化 JimV
+                </h3>
+                <div class="example-box-wrapper">
+                    <form class="form-horizontal bordered-row" action="/config/create" method="post">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">网桥(业务网络)</label>
+                            <div class="col-sm-3">
+                                <input title="Guest 业务网络" class="form-control" name="vm_network" type="text" value="net-br0">
+                            </div>
+                            <label class="col-sm-2 control-label">网桥(管理网络)</label>
+                            <div class="col-sm-3">
+                                <input title="Guest 管理网络" class="form-control" name="vm_manage_network" type="text" value="net-br0">
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label">DNS1</label>
-                        <div class="col-sm-3">
-                            <input title="DNS1" class="form-control" name="dns1" type="text" value="223.5.5.5">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">起始 IP</label>
+                            <div class="col-sm-3">
+                                <input title="起始 IP" class="form-control" name="start_ip" type="text" value="10.10.0.1">
+                            </div>
+                            <label class="col-sm-2 control-label">截止 IP</label>
+                            <div class="col-sm-3">
+                                <input title="截止 IP" class="form-control" name="end_ip" type="text" value="10.10.15.253">
+                            </div>
                         </div>
-                        <label class="col-sm-2 control-label">DNS2</label>
-                        <div class="col-sm-3">
-                            <input title="DNS2" class="form-control" name="dns2" type="text" value="8.8.8.8">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">子网掩码</label>
+                            <div class="col-sm-3">
+                                <input title="子网掩码" class="form-control" name="netmask" type="text" value="255.255.240.0">
+                            </div>
+                            <label class="col-sm-2 control-label">网关</label>
+                            <div class="col-sm-3">
+                                <input title="网关" class="form-control" name="gateway" type="text" value="10.10.15.254">
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label">起始 VNC 端口</label>
-                        <div class="col-sm-3">
-                            <input title="起始 VNC 端口" class="form-control" name="start_vnc_port" type="text" value="15900">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">DNS1</label>
+                            <div class="col-sm-3">
+                                <input title="DNS1" class="form-control" name="dns1" type="text" value="223.5.5.5">
+                            </div>
+                            <label class="col-sm-2 control-label">DNS2</label>
+                            <div class="col-sm-3">
+                                <input title="DNS2" class="form-control" name="dns2" type="text" value="8.8.8.8">
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label">虚拟机磁盘存储模式</label>
-                        <div class="col-sm-3">
-                            <select id="storage_mode" title="虚拟机磁盘存储模式" class="selectpicker" name="storage_mode" data-width="100%">
-                                <option value="0">本地存储</option>
-                                <option value="1" data-subtext="NFS">挂载共享</option>
-                                <option value="2">Ceph</option>
-                                <option value="3">Glusterfs</option>
-                            </select>
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">起始 VNC 端口</label>
+                            <div class="col-sm-3">
+                                <input title="起始 VNC 端口" class="form-control" name="start_vnc_port" type="text" value="15900">
+                            </div>
                         </div>
-                        <label id="dfs_volume_label" class="col-sm-2 control-label" style="display: none;">分布式文件系统存储卷</label>
-                        <div class="col-sm-3">
-                            <input id="dfs_volume" title="分布式文件系统存储卷" class="form-control" name="dfs_volume" type="text" style="display: none;">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">虚拟机磁盘存储模式</label>
+                            <div class="col-sm-3">
+                                <select id="storage_mode" title="虚拟机磁盘存储模式" class="selectpicker" name="storage_mode" data-width="100%">
+                                    <option value="0">本地存储</option>
+                                    <option value="1" data-subtext="NFS">挂载共享</option>
+                                    <option value="2">Ceph</option>
+                                    <option value="3">Glusterfs</option>
+                                </select>
+                            </div>
+                            <label id="dfs_volume_label" class="col-sm-2 control-label" style="display: none;">分布式文件系统存储卷</label>
+                            <div class="col-sm-3">
+                                <input id="dfs_volume" title="分布式文件系统存储卷" class="form-control" name="dfs_volume" type="text" style="display: none;">
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label">虚拟机磁盘存放路径</label>
-                        <div class="col-sm-3">
-                            <input title="虚拟机磁盘存放路径" class="form-control" name="storage_path" type="text" value="/Images">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">虚拟机磁盘存放路径</label>
+                            <div class="col-sm-3">
+                                <input title="虚拟机磁盘存放路径" class="form-control" name="storage_path" type="text" value="/Images">
+                            </div>
                         </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-2 control-label"></label>
-                        <div class="col-sm-3 pull-right">
-                            <button class="btn btn-blue-alt" style="width: 180px; height: 40px; font-size: 16px;">初始化</button>
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label"></label>
+                            <div class="col-sm-3 pull-right">
+                                <button class="btn btn-blue-alt" style="width: 180px; height: 40px; font-size: 16px;">初始化</button>
+                            </div>
                         </div>
-                    </div>
-                </form>
+                    </form>
+                </div>
             </div>
         </div>
     </div>
-</div>
 {% endblock body %}

+ 3 - 3
views/config.py

@@ -3,7 +3,7 @@
 
 
 import json
-from flask import Blueprint, render_template, request
+from flask import Blueprint, render_template, request, abort
 import requests
 
 
@@ -28,7 +28,7 @@ def show():
 
     # 检测 JimV 的配置是否已被初始化,只有未被初始化时,才展现初始化配置页面
     if config_ret['state']['code'] == '404':
-        return render_template('404.html'), 404
+        abort(404)
 
     return render_template('config_show.html', config_ret=config_ret)
 
@@ -70,5 +70,5 @@ def create():
         if config_ret['state']['code'] == '404':
             return render_template('config_init.html')
         else:
-            return render_template('404.html'), 404
+            abort(404)
 

+ 24 - 0
views/error_pages.py

@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+from flask import render_template
+from models.initialize import app
+
+
+__author__ = 'James Iter'
+__date__ = '2017/9/10'
+__contact__ = 'james.iter.cn@gmail.com'
+__copyright__ = '(c) 2017 by James Iter.'
+
+
+@app.errorhandler(404)
+def page_not_found(error):
+    return render_template('404.html'), 404
+
+
+@app.errorhandler(500)
+def page_not_found(error):
+    return render_template('500.html'), 500
+
+