Add support of Session Manager for Rest API
1. Add support of Session Manager for Rest API; 2. Add Rest API for getting periodical report; 3. Add Rest API for getting console logs; 4. Fix KB-PROXY placement bug when topology file is provided; 5. Fix the logic for consolidating samples; 6. Refine Swagger definition files for Rest API; 7. Set the -c parameter in kb_gen_chart.py to required; Known Issue / TODO: 1. The Pecan server logs will be dumped to clients; 2. The RestAPI "log" need remember the offset and only gets the incremental Change-Id: If912fbfcabc73a04caa0122ffe942405a667608d
This commit is contained in:
parent
8aaa12d2b0
commit
0d30c860fc
1
.gitignore
vendored
1
.gitignore
vendored
@ -60,5 +60,4 @@ kb*.log
|
||||
*.html
|
||||
*.qcow2
|
||||
scale/dib/kloudbuster.d/
|
||||
|
||||
.vagrant/
|
||||
|
@ -87,9 +87,7 @@ class BaseCompute(object):
|
||||
return instance
|
||||
if instance.status == 'ERROR':
|
||||
LOG.error('Instance creation error:' + instance.fault['message'])
|
||||
break
|
||||
# print "[%s] VM status=%s, retrying %s of %s..." \
|
||||
# % (vmname, instance.status, (retry_attempt + 1), retry_count)
|
||||
return None
|
||||
time.sleep(2)
|
||||
|
||||
def get_server_list(self):
|
||||
|
@ -20,6 +20,7 @@ import log as logging
|
||||
from oslo_config import cfg
|
||||
|
||||
import credentials
|
||||
import kb_vm_agent
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -109,6 +110,13 @@ class KBConfig(object):
|
||||
self.client_cfg['vms_per_network'] =\
|
||||
self.get_total_vm_count(self.server_cfg) + 1
|
||||
|
||||
# Use the default image name for Glance
|
||||
# defaults to something like "kloudbuster_v3"
|
||||
if not self.server_cfg['image_name']:
|
||||
self.server_cfg['image_name'] = kb_vm_agent.get_image_name()
|
||||
if not self.client_cfg['image_name']:
|
||||
self.client_cfg['image_name'] = kb_vm_agent.get_image_name()
|
||||
|
||||
def init_with_cli(self):
|
||||
self.get_credentials()
|
||||
self.get_configs()
|
||||
|
@ -183,7 +183,7 @@ def main():
|
||||
parser = argparse.ArgumentParser(description='KloudBuster Chart Generator V' + __version__)
|
||||
|
||||
parser.add_argument('-c', '--chart', dest='chart',
|
||||
action='store',
|
||||
action='store', required=True,
|
||||
help='create and save chart in html file',
|
||||
metavar='<file>')
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
from collections import deque
|
||||
from distutils.version import LooseVersion
|
||||
from sets import Set
|
||||
import threading
|
||||
import time
|
||||
|
||||
@ -22,7 +21,7 @@ import log as logging
|
||||
import redis
|
||||
|
||||
# A set of warned VM version mismatches
|
||||
vm_version_mismatches = Set()
|
||||
vm_version_mismatches = set()
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -55,6 +54,7 @@ class KBRunner(object):
|
||||
self.tool_result = {}
|
||||
self.expected_agent_version = expected_agent_version
|
||||
self.agent_version = None
|
||||
self.report = {'seq': 0, 'report': None}
|
||||
|
||||
# Redis
|
||||
self.redis_obj = None
|
||||
@ -180,7 +180,10 @@ class KBRunner(object):
|
||||
LOG.info(log_msg)
|
||||
|
||||
if sample_count != 0:
|
||||
print http_tool.consolidate_samples(samples, len(self.client_dict))
|
||||
report = http_tool.consolidate_samples(samples, len(self.client_dict))
|
||||
self.report['seq'] = self.report['seq'] + 1
|
||||
self.report['report'] = report
|
||||
LOG.info('Periodical report: %s.' % str(self.report))
|
||||
samples = []
|
||||
retry = retry + 1
|
||||
|
||||
|
@ -25,10 +25,10 @@ app = {
|
||||
'static_root': '%(confdir)s/public',
|
||||
'template_path': '%(confdir)s/kb_server/templates',
|
||||
'debug': True,
|
||||
'errors': {
|
||||
404: '/error/404',
|
||||
'__force_dict__': True
|
||||
}
|
||||
# 'errors': {
|
||||
# 404: '/error/404',
|
||||
# '__force_dict__': True
|
||||
# }
|
||||
}
|
||||
|
||||
logging = {
|
||||
|
@ -12,36 +12,57 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import traceback
|
||||
kb_main_path = os.path.split(os.path.abspath(__file__))[0] + "/../../.."
|
||||
sys.path.append(kb_main_path)
|
||||
|
||||
from credentials import Credentials
|
||||
from kb_session import KBSession
|
||||
from kb_session import KBSessionManager
|
||||
import log as logging
|
||||
|
||||
from configure import Configuration
|
||||
from kb_config import KBConfig
|
||||
from pecan import expose
|
||||
from pecan import response
|
||||
|
||||
lock = threading.Lock()
|
||||
kb_config = KBConfig()
|
||||
|
||||
class ConfigController(object):
|
||||
|
||||
@expose(generic=True)
|
||||
def running_config(self):
|
||||
def default_config(self):
|
||||
kb_config = KBConfig()
|
||||
# @TODO(Bug in Python???)
|
||||
# return json.dumps(dict(kb_config.config_scale))
|
||||
return str(kb_config.config_scale)
|
||||
|
||||
@expose(generic=True)
|
||||
def running_config(self, *args):
|
||||
if len(args):
|
||||
session_id = args[0]
|
||||
else:
|
||||
response.status = 400
|
||||
response.text = u"Please specify the session_id."
|
||||
return response.text
|
||||
if KBSessionManager.has(session_id):
|
||||
kb_config_obj = KBSessionManager.get(session_id).kb_config
|
||||
config_scale = kb_config_obj.config_scale
|
||||
config_scale['server'] = kb_config_obj.server_cfg
|
||||
config_scale['client'] = kb_config_obj.client_cfg
|
||||
config_scale = dict(config_scale)
|
||||
# @TODO(Bug in Python???)
|
||||
# return json.dumps(config_scale)
|
||||
return str(config_scale)
|
||||
else:
|
||||
response.status = 404
|
||||
response.text = u"Session ID is not found or invalid."
|
||||
return response.text
|
||||
|
||||
@running_config.when(method='POST')
|
||||
def running_config_POST(self, arg):
|
||||
if not lock.acquire(False):
|
||||
response.status = 403
|
||||
response.text = u"An instance of KloudBuster is running, you cannot change"\
|
||||
"the config until the run is finished!"
|
||||
return response.text
|
||||
|
||||
try:
|
||||
# Expectation:
|
||||
# {
|
||||
@ -51,7 +72,7 @@ class ConfigController(object):
|
||||
# 'topo_cfg': {<TOPOLOGY_CONFIGS>}
|
||||
# 'tenants_cfg': {<TENANT_AND_USER_LISTS_FOR_REUSING>}
|
||||
# }
|
||||
user_config = eval(arg)
|
||||
user_config = json.loads(arg)
|
||||
|
||||
# Parsing credentials from application input
|
||||
cred_config = user_config['credentials']
|
||||
@ -65,6 +86,13 @@ class ConfigController(object):
|
||||
# Use the same openrc file for both cases
|
||||
cred_testing = cred_tested
|
||||
|
||||
session_id = hashlib.md5(str(cred_config)).hexdigest()
|
||||
kb_config = KBConfig()
|
||||
if KBSessionManager.has(session_id):
|
||||
response.status = 403
|
||||
response.text = u"Session is already existed."
|
||||
return response.text
|
||||
|
||||
# Parsing server and client configs from application input
|
||||
# Save the public key into a temporary file
|
||||
if 'public_key' in user_config['kb_cfg']:
|
||||
@ -74,6 +102,9 @@ class ConfigController(object):
|
||||
f.close()
|
||||
kb_config.config_scale['public_key_file'] = pubkey_filename
|
||||
|
||||
if 'prompt_before_run' in user_config['kb_cfg']:
|
||||
kb_config.config_scale['prompt_before_run'] = False
|
||||
|
||||
if user_config['kb_cfg']:
|
||||
alt_config = Configuration.from_string(user_config['kb_cfg']).configure()
|
||||
kb_config.config_scale = kb_config.config_scale.merge(alt_config)
|
||||
@ -89,16 +120,58 @@ class ConfigController(object):
|
||||
tenants_list = Configuration.from_string(user_config['tenants_list']).configure()
|
||||
else:
|
||||
tenants_list = None
|
||||
except Exception as e:
|
||||
response.status = 403
|
||||
response.text = u"Error while parsing configurations: %s" % (e.message)
|
||||
lock.release()
|
||||
except Exception:
|
||||
response.status = 400
|
||||
response.text = u"Error while parsing configurations: \n%s" % (traceback.format_exc)
|
||||
return response.text
|
||||
|
||||
logging.setup("kloudbuster", logfile="/tmp/kb_log_%s" % session_id)
|
||||
kb_config.init_with_rest_api(cred_tested=cred_tested,
|
||||
cred_testing=cred_testing,
|
||||
topo_cfg=topo_cfg,
|
||||
tenants_list=tenants_list)
|
||||
lock.release()
|
||||
|
||||
return "OK!"
|
||||
kb_session = KBSession()
|
||||
kb_session.kb_config = kb_config
|
||||
KBSessionManager.add(session_id, kb_session)
|
||||
|
||||
return str(session_id)
|
||||
|
||||
@running_config.when(method='PUT')
|
||||
def running_config_PUT(self, *args):
|
||||
# @TODO(Not completed! ENOTSUP)
|
||||
if len(args):
|
||||
session_id = args[0]
|
||||
else:
|
||||
response.status = 400
|
||||
response.text = u"Please specify the session_id."
|
||||
return response.text
|
||||
if KBSessionManager.has(session_id):
|
||||
# kb_session = KBSessionManager.get(session_id)
|
||||
#
|
||||
#
|
||||
#
|
||||
return "OK!"
|
||||
else:
|
||||
response.status = 404
|
||||
response.text = u"Session ID is not found or invalid."
|
||||
return response.text
|
||||
|
||||
@running_config.when(method='DELETE')
|
||||
def running_config_DELETE(self, *args):
|
||||
if len(args):
|
||||
session_id = args[0]
|
||||
else:
|
||||
response.status = 400
|
||||
response.text = u"Please specify the session_id."
|
||||
return response.text
|
||||
if KBSessionManager.has(session_id):
|
||||
kb_session = KBSessionManager.get(session_id)
|
||||
if kb_session.kloudbuster:
|
||||
kb_session.kloudbuster.dispose()
|
||||
KBSessionManager.delete(session_id)
|
||||
return "OK!"
|
||||
else:
|
||||
response.status = 404
|
||||
response.text = u"Session ID is not found or invalid."
|
||||
return response.text
|
||||
|
@ -12,14 +12,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import threading
|
||||
kb_main_path = os.path.split(os.path.abspath(__file__))[0] + "/../../.."
|
||||
sys.path.append(kb_main_path)
|
||||
|
||||
from api_cfg import kb_config as kb_config
|
||||
from api_cfg import lock as kb_config_lock
|
||||
from kb_session import KBSessionManager
|
||||
from kloudbuster import __version__ as kb_version
|
||||
from kloudbuster import KloudBuster
|
||||
|
||||
from pecan import expose
|
||||
@ -28,37 +29,109 @@ from pecan import response
|
||||
class KBController(object):
|
||||
|
||||
def __init__(self):
|
||||
self.kb_status = 'READY'
|
||||
|
||||
@expose(generic=True)
|
||||
def status(self):
|
||||
return self.kb_status
|
||||
|
||||
@expose(generic=True)
|
||||
def run(self):
|
||||
if (not kb_config.cred_tested) or (not kb_config.cred_testing):
|
||||
response.status = 403
|
||||
response.text = u"Credentials to the cloud are missing."\
|
||||
"(Forgot to provide the config?)"
|
||||
return response.text
|
||||
if not kb_config_lock.acquire(False):
|
||||
response.status = 403
|
||||
response.text = u"An instance of KloudBuster is running, you cannot "\
|
||||
"change the config until the run is finished!"
|
||||
return response.text
|
||||
self.kb_thread = None
|
||||
|
||||
def kb_thread_handler(self, session_id):
|
||||
kb_session = KBSessionManager.get(session_id)
|
||||
kb_session.kb_status = 'RUNNING'
|
||||
kb_config = kb_session.kb_config
|
||||
try:
|
||||
kloudbuster = KloudBuster(
|
||||
kb_config.cred_tested, kb_config.cred_testing,
|
||||
kb_config.server_cfg, kb_config.client_cfg,
|
||||
kb_config.topo_cfg, kb_config.tenants_list)
|
||||
kb_session.kloudbuster = kloudbuster
|
||||
|
||||
if kloudbuster.check_and_upload_images():
|
||||
kloudbuster.run()
|
||||
kb_session.kb_status = 'READY'
|
||||
except Exception:
|
||||
response.status = 403
|
||||
response.text = u"Error while running KloudBuster:\n%s" % traceback.format_exc()
|
||||
kb_config_lock.release()
|
||||
kb_session.kb_status = 'ERROR'
|
||||
|
||||
@expose(generic=True)
|
||||
def status(self, *args):
|
||||
if len(args):
|
||||
session_id = args[0]
|
||||
else:
|
||||
response.status = 400
|
||||
response.text = u"Please specify the session_id."
|
||||
return response.text
|
||||
|
||||
kb_config_lock.release()
|
||||
if KBSessionManager.has(session_id):
|
||||
status = KBSessionManager.get(session_id).kb_status
|
||||
return status
|
||||
else:
|
||||
response.status = 404
|
||||
response.text = u"Session ID is not found or invalid."
|
||||
return response.text
|
||||
|
||||
@expose(generic=True)
|
||||
def log(self, *args):
|
||||
if len(args):
|
||||
session_id = args[0]
|
||||
else:
|
||||
response.status = 400
|
||||
response.text = u"Please specify the session_id."
|
||||
return response.text
|
||||
|
||||
if KBSessionManager.has(session_id):
|
||||
kb_session = KBSessionManager.get(session_id)
|
||||
plog = kb_session.kloudbuster.dump_logs(offset=0)\
|
||||
if kb_session.kloudbuster else ""
|
||||
return json.dumps(plog)
|
||||
else:
|
||||
response.status = 404
|
||||
response.text = u"Session ID is not found or invalid."
|
||||
return response.text
|
||||
|
||||
@expose(generic=True)
|
||||
def report(self, *args):
|
||||
if len(args):
|
||||
session_id = args[0]
|
||||
else:
|
||||
response.status = 400
|
||||
response.text = u"Please specify the session_id."
|
||||
return response.text
|
||||
|
||||
if KBSessionManager.has(session_id):
|
||||
kb_session = KBSessionManager.get(session_id)
|
||||
preport = kb_session.kloudbuster.kb_runner.report\
|
||||
if kb_session.kloudbuster and kb_session.kloudbuster.kb_runner else ""
|
||||
return json.dumps(preport)
|
||||
else:
|
||||
response.status = 404
|
||||
response.text = u"Session ID is not found or invalid."
|
||||
return response.text
|
||||
|
||||
@expose(generic=True)
|
||||
def version(self):
|
||||
return kb_version
|
||||
|
||||
@expose(generic=True)
|
||||
def run(self, *args):
|
||||
response.status = 400
|
||||
response.text = u"Please POST to this resource."
|
||||
return response.text
|
||||
|
||||
@run.when(method='POST')
|
||||
def run_POST(self, *args):
|
||||
if len(args):
|
||||
session_id = args[0]
|
||||
else:
|
||||
response.status = 400
|
||||
response.text = u"Please specify the session_id."
|
||||
return response.text
|
||||
if not KBSessionManager.has(session_id):
|
||||
response.status = 404
|
||||
response.text = u"Session ID is not found or invalid."
|
||||
return response.text
|
||||
if KBSessionManager.get(session_id).kb_status == 'RUNNING':
|
||||
response.status = 403
|
||||
response.text = u"An instance of KloudBuster is already running."
|
||||
return response.text
|
||||
|
||||
self.kb_thread = threading.Thread(target=self.kb_thread_handler, args=[session_id])
|
||||
self.kb_thread.daemon = True
|
||||
self.kb_thread.start()
|
||||
|
||||
return "OK!"
|
||||
|
53
kloudbuster/kb_server/kb_server/controllers/kb_session.py
Normal file
53
kloudbuster/kb_server/kb_server/controllers/kb_session.py
Normal file
@ -0,0 +1,53 @@
|
||||
# Copyright 2015 Cisco Systems, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import threading
|
||||
|
||||
KB_SESSIONS = {}
|
||||
KB_SESSIONS_LOCK = threading.Lock()
|
||||
|
||||
class KBSessionManager(object):
|
||||
|
||||
@staticmethod
|
||||
def has(session_id):
|
||||
global KB_SESSIONS
|
||||
return True if session_id in KB_SESSIONS else False
|
||||
|
||||
@staticmethod
|
||||
def get(session_id):
|
||||
global KB_SESSIONS
|
||||
return KB_SESSIONS[session_id] if KBSessionManager.has(session_id) else None
|
||||
|
||||
@staticmethod
|
||||
def add(session_id, new_session):
|
||||
global KB_SESSIONS
|
||||
global KB_SESSIONS_LOCK
|
||||
KB_SESSIONS_LOCK.acquire()
|
||||
KB_SESSIONS[session_id] = new_session
|
||||
KB_SESSIONS_LOCK.release()
|
||||
|
||||
@staticmethod
|
||||
def delete(session_id):
|
||||
global KB_SESSIONS
|
||||
global KB_SESSIONS_LOCK
|
||||
KB_SESSIONS_LOCK.acquire()
|
||||
KB_SESSIONS.pop(session_id)
|
||||
KB_SESSIONS_LOCK.release()
|
||||
|
||||
|
||||
class KBSession(object):
|
||||
def __init__(self):
|
||||
self.kb_status = 'READY'
|
||||
self.kb_config = None
|
||||
self.kloudbuster = None
|
@ -6,7 +6,7 @@ info:
|
||||
data plane.
|
||||
version: "0.1.0"
|
||||
host: 127.0.0.1:8080
|
||||
basePath: /api/v1
|
||||
basePath: /api
|
||||
schemes:
|
||||
- http
|
||||
- https
|
||||
@ -15,6 +15,19 @@ consumes:
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
/config/default_config:
|
||||
get:
|
||||
description: |
|
||||
Get the default KloudBuster configuration from server
|
||||
tags:
|
||||
- config
|
||||
responses:
|
||||
200:
|
||||
description: The default configuration
|
||||
schema:
|
||||
type: string
|
||||
format: json
|
||||
|
||||
/config/running_config:
|
||||
post:
|
||||
description: |
|
||||
@ -40,6 +53,8 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
description: Errors in details
|
||||
403:
|
||||
description: Session is already existed
|
||||
|
||||
/config/running_config/{session_id}:
|
||||
get:
|
||||
@ -65,6 +80,7 @@ paths:
|
||||
|
||||
put:
|
||||
description: |
|
||||
(NOT IMPLEMENTED)
|
||||
Update KloudBuster configuration for an existing session
|
||||
parameters:
|
||||
- name: session_id
|
||||
@ -108,6 +124,18 @@ paths:
|
||||
404:
|
||||
description: The session_id is not found or invalid
|
||||
|
||||
/kloudbuster/version:
|
||||
get:
|
||||
description: Get KloudBuster server version
|
||||
tags:
|
||||
- kloudbuster
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
description: The version of the KloudBuster server
|
||||
|
||||
/kloudbuster/status/{session_id}:
|
||||
get:
|
||||
description: |
|
||||
@ -130,9 +158,17 @@ paths:
|
||||
404:
|
||||
description: The session_id is not found or invalid
|
||||
|
||||
/kloudbuster/version:
|
||||
/kloudbuster/console_log/{session_id}:
|
||||
get:
|
||||
description: Get KloudBuster server version
|
||||
description: |
|
||||
Get KloudBuster console log for a given session
|
||||
parameters:
|
||||
- name: session_id
|
||||
type: string
|
||||
format: md5sum
|
||||
in: path
|
||||
description: The session to be queried
|
||||
required: true
|
||||
tags:
|
||||
- kloudbuster
|
||||
responses:
|
||||
@ -140,7 +176,32 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
description: The version of the KloudBuster server
|
||||
description: The console log of the given session
|
||||
404:
|
||||
description: The session_id is not found or invalid
|
||||
|
||||
/kloudbuster/report/{session_id}:
|
||||
get:
|
||||
description: |
|
||||
Get KloudBuster periodical report for a given session. Only
|
||||
last report will be returned.
|
||||
parameters:
|
||||
- name: session_id
|
||||
type: string
|
||||
format: md5sum
|
||||
in: path
|
||||
description: The session to be queried
|
||||
required: true
|
||||
tags:
|
||||
- kloudbuster
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
description: The periodical report of the given session
|
||||
404:
|
||||
description: The session_id is not found or invalid
|
||||
|
||||
/kloudbuster/run/{session_id}:
|
||||
post:
|
||||
@ -162,6 +223,8 @@ paths:
|
||||
403:
|
||||
description: |
|
||||
KloudBuster is already running on the given session
|
||||
404:
|
||||
description: The session_id is not found or invalid
|
||||
|
||||
definitions:
|
||||
Configuration_New:
|
@ -232,6 +232,8 @@ class KloudBuster(object):
|
||||
self.final_result = None
|
||||
self.server_vm_create_thread = None
|
||||
self.client_vm_create_thread = None
|
||||
self.kb_runner = None
|
||||
self.fp_logfile = None
|
||||
|
||||
def check_and_upload_images(self):
|
||||
keystone_list = [create_keystone_client(self.server_cred)[0],
|
||||
@ -256,8 +258,8 @@ class KloudBuster(object):
|
||||
kb_image_name = 'dib/' + kb_vm_agent.get_image_name() + '.qcow2'
|
||||
if not os.path.exists(kb_image_name):
|
||||
LOG.error("VM Image not in Glance and could not find " + kb_image_name +
|
||||
" to upload, please refer "
|
||||
"to dib/README.rst for how to build image for KloudBuster.")
|
||||
" to upload, please refer to dib/README.rst for how to build"
|
||||
" image for KloudBuster.")
|
||||
return False
|
||||
LOG.info("Image is not found in %s, uploading %s..." % (kloud, kb_image_name))
|
||||
with open(kb_image_name) as fimage:
|
||||
@ -330,7 +332,6 @@ class KloudBuster(object):
|
||||
"""
|
||||
The runner for KloudBuster Tests
|
||||
"""
|
||||
kbrunner = None
|
||||
vm_creation_concurrency = self.client_cfg.vm_creation_concurrency
|
||||
try:
|
||||
tenant_quota = self.calc_tenant_quota()
|
||||
@ -349,16 +350,19 @@ class KloudBuster(object):
|
||||
self.kb_proxy.user_data['role'] = 'KB-PROXY'
|
||||
self.kb_proxy.boot_info['flavor_type'] = 'kb.proxy' if \
|
||||
not self.tenants_list['client'] else self.testing_kloud.flavor_to_use
|
||||
if self.testing_kloud.placement_az:
|
||||
self.kb_proxy.boot_info['avail_zone'] = "%s:%s" %\
|
||||
(self.testing_kloud.placement_az, self.topology.clients_rack.split()[0])
|
||||
if self.topology:
|
||||
proxy_hyper = self.topology.clients_rack.split()[0]
|
||||
self.kb_proxy.boot_info['avail_zone'] =\
|
||||
"%s:%s" % (self.testing_kloud.placement_az, proxy_hyper)\
|
||||
if self.testing_kloud.placement_az else "nova:%s" % (proxy_hyper)
|
||||
|
||||
self.kb_proxy.boot_info['user_data'] = str(self.kb_proxy.user_data)
|
||||
self.testing_kloud.create_vm(self.kb_proxy)
|
||||
|
||||
kbrunner = KBRunner(client_list, self.client_cfg,
|
||||
kb_vm_agent.get_image_version(),
|
||||
self.single_cloud)
|
||||
kbrunner.setup_redis(self.kb_proxy.fip_ip)
|
||||
self.kb_runner = KBRunner(client_list, self.client_cfg,
|
||||
kb_vm_agent.get_image_version(),
|
||||
self.single_cloud)
|
||||
self.kb_runner.setup_redis(self.kb_proxy.fip_ip)
|
||||
|
||||
if self.single_cloud:
|
||||
# Find the shared network if the cloud used to testing is same
|
||||
@ -392,11 +396,11 @@ class KloudBuster(object):
|
||||
self.print_provision_info()
|
||||
|
||||
# Run the runner to perform benchmarkings
|
||||
kbrunner.run()
|
||||
self.final_result = kbrunner.tool_result
|
||||
self.kb_runner.run()
|
||||
self.final_result = self.kb_runner.tool_result
|
||||
self.final_result['total_server_vms'] = len(server_list)
|
||||
self.final_result['total_client_vms'] = len(client_list)
|
||||
# self.final_result['host_stats'] = kbrunner.host_stats
|
||||
# self.final_result['host_stats'] = self.kb_runner.host_stats
|
||||
LOG.info(self.final_result)
|
||||
except KeyboardInterrupt:
|
||||
traceback.format_exc()
|
||||
@ -418,6 +422,17 @@ class KloudBuster(object):
|
||||
traceback.print_exc()
|
||||
KBResLogger.dump_and_save('clt', self.testing_kloud.res_logger.resource_list)
|
||||
|
||||
def dump_logs(self, offset=0):
|
||||
if not self.fp_logfile:
|
||||
self.fp_logfile = open(CONF.log_file)
|
||||
|
||||
self.fp_logfile.seek(offset)
|
||||
return self.fp_logfile.read()
|
||||
|
||||
def dispose(self):
|
||||
self.fp_logfile.close()
|
||||
logging.delete_logfile('kloudbuster')
|
||||
|
||||
def get_tenant_vm_count(self, config):
|
||||
return (config['users_per_tenant'] * config['routers_per_user'] *
|
||||
config['networks_per_router'] * config['vms_per_network'])
|
||||
@ -563,13 +578,6 @@ def main():
|
||||
LOG.error('Error parsing the configuration file')
|
||||
sys.exit(1)
|
||||
|
||||
# Use the default image name for Glance
|
||||
# defaults to something like "kloudbuster_v3"
|
||||
if not kb_config.server_cfg['image_name']:
|
||||
kb_config.server_cfg['image_name'] = kb_vm_agent.get_image_name()
|
||||
if not kb_config.client_cfg['image_name']:
|
||||
kb_config.client_cfg['image_name'] = kb_vm_agent.get_image_name()
|
||||
|
||||
# The KloudBuster class is just a wrapper class
|
||||
# levarages tenant and user class for resource creations and deletion
|
||||
kloudbuster = KloudBuster(
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import handlers
|
||||
@ -41,11 +42,15 @@ KBDEBUG = logging.KBDEBUG
|
||||
WARN = logging.WARN
|
||||
WARNING = logging.WARNING
|
||||
|
||||
def setup(product_name, version="unknown"):
|
||||
def setup(product_name, logfile=None):
|
||||
dbg_color = handlers.ColorHandler.LEVEL_COLORS[logging.DEBUG]
|
||||
handlers.ColorHandler.LEVEL_COLORS[logging.KBDEBUG] = dbg_color
|
||||
|
||||
oslogging.setup(CONF, product_name, version)
|
||||
if logfile:
|
||||
if os.path.exists(logfile):
|
||||
os.remove(logfile)
|
||||
CONF.log_file = logfile
|
||||
oslogging.setup(CONF, product_name)
|
||||
|
||||
if CONF.kb_debug:
|
||||
oslogging.getLogger(
|
||||
@ -59,6 +64,14 @@ def getLogger(name="unknown", version="unknown"):
|
||||
"version": version})
|
||||
return oslogging._loggers[name]
|
||||
|
||||
def delete_logfile(product_name):
|
||||
if CONF.log_file and os.path.exists(CONF.log_file):
|
||||
os.remove(CONF.log_file)
|
||||
# Reset the logging to default (stdout)
|
||||
CONF.log_file = None
|
||||
oslogging.setup(CONF, product_name)
|
||||
|
||||
|
||||
class KloudBusterContextAdapter(oslogging.KeywordArgumentAdapter):
|
||||
|
||||
def kbdebug(self, msg, *args, **kwargs):
|
||||
|
@ -129,10 +129,10 @@ class WrkTool(PerfTool):
|
||||
@staticmethod
|
||||
def consolidate_samples(results, vm_count):
|
||||
all_res = WrkTool.consolidate_results(results)
|
||||
total_count = len(results) / vm_count
|
||||
total_count = float(len(results)) / vm_count
|
||||
if not total_count:
|
||||
return all_res
|
||||
|
||||
all_res['http_rps'] = all_res['http_rps'] / total_count
|
||||
all_res['http_throughput_kbytes'] = all_res['http_throughput_kbytes'] / total_count
|
||||
all_res['http_rps'] = int(all_res['http_rps'] / total_count)
|
||||
all_res['http_throughput_kbytes'] = int(all_res['http_throughput_kbytes'] / total_count)
|
||||
return all_res
|
||||
|
Loading…
x
Reference in New Issue
Block a user