Fixed H404 and related pep8 errors

This commit is contained in:
tengqm
2015-02-02 09:52:44 +08:00
parent 8fd21a1ca3
commit f215cfcf92
48 changed files with 352 additions and 486 deletions

View File

@@ -37,7 +37,8 @@ class VersionNegotiationFilter(wsgi.Middleware):
super(VersionNegotiationFilter, self).__init__(app) super(VersionNegotiationFilter, self).__init__(app)
def process_request(self, req): def process_request(self, req):
""" """Process WSGI requests.
If there is a version identifier in the URI, simply If there is a version identifier in the URI, simply
return the correct API controller, otherwise, if we return the correct API controller, otherwise, if we
find an Accept: header, process it find an Accept: header, process it
@@ -104,10 +105,11 @@ class VersionNegotiationFilter(wsgi.Middleware):
return None return None
def _match_version_string(self, subject, req): def _match_version_string(self, subject, req):
""" """Do version matching.
Given a subject string, tries to match a major and/or
minor version number. If found, sets the api.major_version Given a subject string, tries to match a major and/or minor version
and api.minor_version environ variables. number. If found, sets the api.major_version and api.minor_version
environ variables.
Returns True if there was a match, false otherwise. Returns True if there was a match, false otherwise.

View File

@@ -24,10 +24,7 @@ from senlin.common import wsgi
class API(wsgi.Router): class API(wsgi.Router):
'''WSGI router for Cluster v1 ReST API requests.'''
"""
WSGI router for Cluster v1 ReST API requests.
"""
def __init__(self, conf, **local_conf): def __init__(self, conf, **local_conf):
self.conf = conf self.conf = conf

View File

@@ -25,6 +25,7 @@ LOG = logging.getLogger(__name__)
class ActionData(object): class ActionData(object):
'''All required data fields for an action.''' '''All required data fields for an action.'''
PARAMS = ( PARAMS = (
NAME, TARGET, ACTION, NAME, TARGET, ACTION,
) = ( ) = (
@@ -55,9 +56,8 @@ class ActionData(object):
class ActionController(object): class ActionController(object):
""" '''WSGI controller for Actions in Senlin v1 API.'''
WSGI controller for Actions in Senlin v1 API
"""
# Define request scope (must match what is in policy.json) # Define request scope (must match what is in policy.json)
REQUEST_SCOPE = 'actions' REQUEST_SCOPE = 'actions'
@@ -120,9 +120,8 @@ class ActionController(object):
def create_resource(options): def create_resource(options):
""" '''Actions factory method.'''
Actions factory method.
"""
return wsgi.Resource(ActionController(options), return wsgi.Resource(ActionController(options),
wsgi.JSONRequestDeserializer(), wsgi.JSONRequestDeserializer(),
serializers.JSONResponseSerializer()) serializers.JSONResponseSerializer())

View File

@@ -20,10 +20,10 @@ from senlin.rpc import client as rpc_client
class BuildInfoController(object): class BuildInfoController(object):
""" '''WSGI controller for BuildInfo in Senlin v1 API.
WSGI controller for BuildInfo in Senlin v1 API
Returns build information for current app Returns build information for current app
""" '''
# Define request scope (must match what is in policy.json) # Define request scope (must match what is in policy.json)
REQUEST_SCOPE = 'build_info' REQUEST_SCOPE = 'build_info'
@@ -43,9 +43,8 @@ class BuildInfoController(object):
def create_resource(options): def create_resource(options):
""" '''BuildInfo factory method.'''
BuildInfo factory method.
"""
deserializer = wsgi.JSONRequestDeserializer() deserializer = wsgi.JSONRequestDeserializer()
serializer = serializers.JSONResponseSerializer() serializer = serializers.JSONResponseSerializer()
return wsgi.Resource(BuildInfoController(options), deserializer, return wsgi.Resource(BuildInfoController(options), deserializer,

View File

@@ -31,9 +31,8 @@ LOG = logging.getLogger(__name__)
class InstantiationData(object): class InstantiationData(object):
""" '''The data accompanying a PUT/POST request to create/update a cluster.'''
The data accompanying a PUT or POST request to create or update a cluster.
"""
PARAMS = ( PARAMS = (
attr.CLUSTER_NAME, attr.CLUSTER_SIZE, attr.CLUSTER_PROFILE, attr.CLUSTER_NAME, attr.CLUSTER_SIZE, attr.CLUSTER_PROFILE,
attr.CLUSTER_TAGS, attr.CLUSTER_TIMEOUT attr.CLUSTER_TAGS, attr.CLUSTER_TIMEOUT
@@ -69,10 +68,8 @@ class InstantiationData(object):
class ClusterController(object): class ClusterController(object):
""" '''WSGI controller for clusters resource in Senlin v1 API.'''
WSGI controller for clusters resource in Senlin v1 API
Implements the API actions
"""
# Define request scope (must match what is in policy.json) # Define request scope (must match what is in policy.json)
REQUEST_SCOPE = 'clusters' REQUEST_SCOPE = 'clusters'
@@ -112,9 +109,8 @@ class ClusterController(object):
@util.policy_enforce @util.policy_enforce
def create(self, req, body): def create(self, req, body):
""" '''Create a new cluster.'''
Create a new cluster
"""
data = InstantiationData(body) data = InstantiationData(body)
action = self.rpc_client.cluster_create(req.context, data.name(), action = self.rpc_client.cluster_create(req.context, data.name(),
@@ -126,9 +122,7 @@ class ClusterController(object):
@util.policy_enforce @util.policy_enforce
def get(self, req, cluster_id): def get(self, req, cluster_id):
""" '''Gets detailed information for a cluster.'''
Gets detailed information for a cluster
"""
cluster = self.rpc_client.cluster_get(req.context, cluster = self.rpc_client.cluster_get(req.context,
cluster_id) cluster_id)
@@ -139,9 +133,8 @@ class ClusterController(object):
@util.policy_enforce @util.policy_enforce
def update(self, req, cluster_id, body): def update(self, req, cluster_id, body):
""" '''Update an existing cluster with new parameters.'''
Update an existing cluster with new parameters
"""
data = InstantiationData(body) data = InstantiationData(body)
self.rpc_client.cluster_update(req.context, self.rpc_client.cluster_update(req.context,
@@ -164,9 +157,8 @@ class ClusterController(object):
def create_resource(options): def create_resource(options):
""" '''Clusters resource factory method.'''
Clusters resource factory method.
"""
return wsgi.Resource(ClusterController(options), return wsgi.Resource(ClusterController(options),
wsgi.JSONRequestDeserializer(), wsgi.JSONRequestDeserializer(),
serializers.JSONResponseSerializer()) serializers.JSONResponseSerializer())

View File

@@ -27,9 +27,7 @@ LOG = logging.getLogger(__name__)
class InstantiationData(object): class InstantiationData(object):
""" '''The data accompanying a PUT/POST request to create/update a node.'''
The data accompanying a PUT or POST request to create or update a cluster.
"""
PARAMS = ( PARAMS = (
NAME, CLUSTER_ID, PROFILE_ID, ROLE, TAGS, NAME, CLUSTER_ID, PROFILE_ID, ROLE, TAGS,
@@ -69,9 +67,7 @@ class InstantiationData(object):
class NodeController(object): class NodeController(object):
''' '''WSGI controller for nodes resource in Senlin v1 API.'''
WSGI controller for nodes resource in Senlin v1 API
'''
REQUEST_SCOPE = 'nodes' REQUEST_SCOPE = 'nodes'
@@ -149,9 +145,8 @@ class NodeController(object):
def create_resource(options): def create_resource(options):
""" '''Nodes resource factory method.'''
Nodes resource factory method.
"""
return wsgi.Resource(NodeController(options), return wsgi.Resource(NodeController(options),
wsgi.JSONRequestDeserializer(), wsgi.JSONRequestDeserializer(),
serializers.JSONResponseSerializer()) serializers.JSONResponseSerializer())

View File

@@ -26,9 +26,7 @@ LOG = logging.getLogger(__name__)
class PolicyTypeController(object): class PolicyTypeController(object):
''' '''WSGI controller for policy types resource in Senlin v1 API.'''
WSGI controller for policy types resource in Senlin v1 API
'''
# Define request scope (must match what is in policy.json) # Define request scope (must match what is in policy.json)
REQUEST_SCOPE = 'policy_types' REQUEST_SCOPE = 'policy_types'
@@ -62,9 +60,8 @@ class PolicyTypeController(object):
def create_resource(options): def create_resource(options):
''' '''Policy type resource factory method.'''
Policy type resource factory method.
'''
return wsgi.Resource(PolicyTypeController(options), return wsgi.Resource(PolicyTypeController(options),
wsgi.JSONRequestDeserializer(), wsgi.JSONRequestDeserializer(),
serializers.JSONResponseSerializer()) serializers.JSONResponseSerializer())

View File

@@ -27,9 +27,8 @@ LOG = logging.getLogger(__name__)
class ProfileTypeController(object): class ProfileTypeController(object):
''' '''WSGI controller for profile types resource in Senlin v1 API.'''
WSGI controller for profile types resource in Senlin v1 API
'''
# Define request scope (must match what is in policy.json) # Define request scope (must match what is in policy.json)
REQUEST_SCOPE = 'profile_types' REQUEST_SCOPE = 'profile_types'
@@ -47,9 +46,7 @@ class ProfileTypeController(object):
@util.policy_enforce @util.policy_enforce
def spec(self, req, type_name): def spec(self, req, type_name):
''' '''Gets the interface schema for a specified profile type.'''
Gets the interface schema for a specified profile type.
'''
spec = self.rpc_client.profile_type_spec(req.context, type_name) spec = self.rpc_client.profile_type_spec(req.context, type_name)
if not spec: if not spec:
raise exc.HTTPInternalServerError() raise exc.HTTPInternalServerError()
@@ -58,9 +55,8 @@ class ProfileTypeController(object):
@util.policy_enforce @util.policy_enforce
def template(self, req, type_name): def template(self, req, type_name):
''' '''Gets the template representation for a specified profile type.'''
Gets the template representation for a specified profile type.
'''
tmpl = self.rpc_client.profile_type_template(req.context, type_name) tmpl = self.rpc_client.profile_type_template(req.context, type_name)
if not tmpl: if not tmpl:
raise exc.HTTPInternalServerError() raise exc.HTTPInternalServerError()
@@ -69,9 +65,8 @@ class ProfileTypeController(object):
def create_resource(options): def create_resource(options):
''' '''Profiles resource factory method.'''
Profiles resource factory method.
'''
return wsgi.Resource(ProfileTypeController(options), return wsgi.Resource(ProfileTypeController(options),
wsgi.JSONRequestDeserializer(), wsgi.JSONRequestDeserializer(),
serializers.JSONResponseSerializer()) serializers.JSONResponseSerializer())

View File

@@ -27,9 +27,7 @@ LOG = logging.getLogger(__name__)
class ProfileData(object): class ProfileData(object):
""" '''The data accompanying a PUT/POST request to create/update a profile.'''
The data accompanying a PUT or POST request to create or update a cluster.
"""
PARAMS = ( PARAMS = (
NAME, SPEC, TYPE, PERMISSION, TAGS, NAME, SPEC, TYPE, PERMISSION, TAGS,
@@ -67,8 +65,7 @@ class ProfileData(object):
class ProfileController(object): class ProfileController(object):
'''WSGI controller for profiles resource in Senlin v1 API. '''WSGI controller for profiles resource in Senlin v1 API.'''
'''
# Define request scope (must match what is in policy.json) # Define request scope (must match what is in policy.json)
REQUEST_SCOPE = 'profiles' REQUEST_SCOPE = 'profiles'
@@ -158,9 +155,8 @@ class ProfileController(object):
def create_resource(options): def create_resource(options):
""" '''Profiles resource factory method.'''
Profiles resource factory method.
"""
return wsgi.Resource(ProfileController(options), return wsgi.Resource(ProfileController(options),
wsgi.JSONRequestDeserializer(), wsgi.JSONRequestDeserializer(),
serializers.JSONResponseSerializer()) serializers.JSONResponseSerializer())

View File

@@ -22,10 +22,7 @@ import webob.dec
class Controller(object): class Controller(object):
'''A controller that produces information on the senlin API versions.'''
"""
A controller that produces information on the senlin API versions.
"""
def __init__(self, conf): def __init__(self, conf):
self.conf = conf self.conf = conf

View File

@@ -34,17 +34,15 @@ def do_db_version():
def do_db_sync(): def do_db_sync():
""" """Place a database under migration control and upgrade,
Place a database under migration control and upgrade,
creating first if necessary. creating first if necessary.
""" """
api.db_sync(api.get_engine(), CONF.command.version) api.db_sync(api.get_engine(), CONF.command.version)
def purge_deleted(): def purge_deleted():
""" """Remove database records that have been previously soft deleted."""
Remove database records that have been previously soft deleted
"""
utils.purge_deleted(CONF.command.age, CONF.command.granularity) utils.purge_deleted(CONF.command.age, CONF.command.granularity)

View File

@@ -20,8 +20,7 @@ from webob import exc
class KeystonePasswordAuthProtocol(object): class KeystonePasswordAuthProtocol(object):
""" """Alternative authentication middleware that uses username and password
Alternative authentication middleware that uses username and password
to authenticate against Keystone instead of validating existing auth token. to authenticate against Keystone instead of validating existing auth token.
The benefit being that you no longer require admin/service token to The benefit being that you no longer require admin/service token to
authenticate users. authenticate users.

View File

@@ -123,8 +123,7 @@ for group, opts in list_opts():
def _get_deployment_flavor(): def _get_deployment_flavor():
""" """Retrieve the paste_deploy.flavor config item, formatted appropriately
Retrieve the paste_deploy.flavor config item, formatted appropriately
for appending to the application name. for appending to the application name.
""" """
flavor = cfg.CONF.paste_deploy.flavor flavor = cfg.CONF.paste_deploy.flavor
@@ -132,8 +131,7 @@ def _get_deployment_flavor():
def _get_deployment_config_file(): def _get_deployment_config_file():
""" """Retrieve the deployment_config_file config item, formatted as an
Retrieve the deployment_config_file config item, formatted as an
absolute pathname. absolute pathname.
""" """
config_path = cfg.CONF.find_file( config_path = cfg.CONF.find_file(
@@ -145,8 +143,7 @@ def _get_deployment_config_file():
def load_paste_app(app_name=None): def load_paste_app(app_name=None):
""" """Builds and returns a WSGI app from a paste config file.
Builds and returns a WSGI app from a paste config file.
We assume the last config file specified in the supplied ConfigOpts We assume the last config file specified in the supplied ConfigOpts
object is the paste config file. object is the paste config file.

View File

@@ -24,10 +24,11 @@ LOG = logging.getLogger(__name__)
class RequestContext(context.RequestContext): class RequestContext(context.RequestContext):
""" '''Stores information about the security context.
Stores information about the security context under which the user
The context encapsulates information related to the user
accesses the system, as well as additional request information. accesses the system, as well as additional request information.
""" '''
def __init__(self, auth_token=None, auth_token_info=None, def __init__(self, auth_token=None, auth_token_info=None,
username=None, user_id=None, password=None, is_admin=None, username=None, user_id=None, password=None, is_admin=None,
@@ -37,10 +38,10 @@ class RequestContext(context.RequestContext):
region_name=None, roles=None, region_name=None, roles=None,
read_only=False, show_deleted=False, read_only=False, show_deleted=False,
request_id=None, **kwargs): request_id=None, **kwargs):
""" '''Initializer of request context.
:param kwargs: Extra arguments that might be present, but we ignore :param kwargs: Extra arguments that might be present, but we ignore
because they possibly came in from older rpc messages. because they possibly came in from older rpc messages.
""" '''
super(RequestContext, self).__init__(auth_token=auth_token, super(RequestContext, self).__init__(auth_token=auth_token,
user=username, user=username,
tenant=tenant, tenant=tenant,
@@ -124,16 +125,15 @@ class ContextMiddleware(wsgi.Middleware):
super(ContextMiddleware, self).__init__(app) super(ContextMiddleware, self).__init__(app)
def make_context(self, *args, **kwargs): def make_context(self, *args, **kwargs):
""" '''Create a context with the given arguments.'''
Create a context with the given arguments.
"""
return self.ctxcls(*args, **kwargs) return self.ctxcls(*args, **kwargs)
def process_request(self, req): def process_request(self, req):
""" '''Extract any authentication information in the request and
Extract any authentication information in the request and
construct an appropriate context from it. construct an appropriate context from it.
""" '''
headers = req.headers headers = req.headers
environ = req.environ environ = req.environ
try: try:
@@ -179,9 +179,8 @@ class ContextMiddleware(wsgi.Middleware):
def ContextMiddleware_filter_factory(global_conf, **local_conf): def ContextMiddleware_filter_factory(global_conf, **local_conf):
""" '''Factory method for paste.deploy'''
Factory method for paste.deploy
"""
conf = global_conf.copy() conf = global_conf.copy()
conf.update(local_conf) conf.update(local_conf)

View File

@@ -1,4 +1,3 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
@@ -17,10 +16,10 @@ from senlin.common.i18n import _
def extract_bool(subject): def extract_bool(subject):
''' '''Convert any true/false string to its corresponding boolean value,
Convert any true/false string to its corresponding boolean value,
regardless of case. regardless of case.
''' '''
if str(subject).lower() not in ('true', 'false'): if str(subject).lower() not in ('true', 'false'):
raise ValueError(_('Unrecognized value "%(value)s", acceptable ' raise ValueError(_('Unrecognized value "%(value)s", acceptable '
'values are: true, false.') % {'value': subject}) 'values are: true, false.') % {'value': subject})

View File

@@ -114,8 +114,7 @@ def get_bind_addr(conf, default_port=None):
def get_socket(conf, default_port): def get_socket(conf, default_port):
""" '''Bind socket to bind ip:port in conf
Bind socket to bind ip:port in conf
note: Mostly comes from Swift with a few small changes... note: Mostly comes from Swift with a few small changes...
@@ -124,7 +123,8 @@ def get_socket(conf, default_port):
:returns : a socket object as returned from socket.listen or :returns : a socket object as returned from socket.listen or
ssl.wrap_socket if conf specifies cert_file ssl.wrap_socket if conf specifies cert_file
""" '''
bind_addr = get_bind_addr(conf, default_port) bind_addr = get_bind_addr(conf, default_port)
# TODO(jaypipes): eventlet's greened socket module does not actually # TODO(jaypipes): eventlet's greened socket module does not actually
@@ -179,13 +179,12 @@ class Server(object):
self.running = True self.running = True
def start(self, application, conf, default_port): def start(self, application, conf, default_port):
""" '''Run a WSGI server with the given application.
Run a WSGI server with the given application.
:param application: The application to run in the WSGI server :param application: The application to run in the WSGI server
:param conf: a cfg.ConfigOpts object :param conf: a cfg.ConfigOpts object
:param default_port: Port to bind to if none is specified in conf :param default_port: Port to bind to if none is specified in conf
""" '''
def kill_children(*args): def kill_children(*args):
"""Kills the entire process group.""" """Kills the entire process group."""
self.LOG.error(_LE('SIGTERM received')) self.LOG.error(_LE('SIGTERM received'))
@@ -194,9 +193,8 @@ class Server(object):
os.killpg(0, signal.SIGTERM) os.killpg(0, signal.SIGTERM)
def hup(*args): def hup(*args):
""" # Shuts down the server(s), but allows running requests to complete
Shuts down the server(s), but allows running requests to complete
"""
self.LOG.error(_LE('SIGHUP received')) self.LOG.error(_LE('SIGHUP received'))
signal.signal(signal.SIGHUP, signal.SIG_IGN) signal.signal(signal.SIGHUP, signal.SIG_IGN)
os.killpg(0, signal.SIGHUP) os.killpg(0, signal.SIGHUP)
@@ -291,25 +289,24 @@ class Server(object):
class Middleware(object): class Middleware(object):
""" '''Base WSGI middleware wrapper.
Base WSGI middleware wrapper. These classes require an application to be
initialized that will be called next. By default the middleware will These classes require an application to be initialized that will be called
simply call its wrapped app, or you can override __call__ to customize its next. By default the middleware will simply call its wrapped app, or you
behavior. can override __call__ to customize its behavior.
""" '''
def __init__(self, application): def __init__(self, application):
self.application = application self.application = application
def process_request(self, req): def process_request(self, req):
""" '''Called on each request.
Called on each request.
If this returns None, the next application down the stack will be If this returns None, the next application down the stack will be
executed. If it returns a response then that response will be returned executed. If it returns a response then that response will be returned
and execution will stop here. and execution will stop here.
'''
"""
return None return None
def process_response(self, response): def process_response(self, response):
@@ -326,10 +323,9 @@ class Middleware(object):
class Debug(Middleware): class Debug(Middleware):
""" '''Helper class that can be inserted into any WSGI application chain
Helper class that can be inserted into any WSGI application chain
to get information about the request and response. to get information about the request and response.
""" '''
@webob.dec.wsgify @webob.dec.wsgify
def __call__(self, req): def __call__(self, req):
@@ -350,10 +346,8 @@ class Debug(Middleware):
@staticmethod @staticmethod
def print_generator(app_iter): def print_generator(app_iter):
""" # Iterator that prints the contents of a wrapper string iterator
Iterator that prints the contents of a wrapper string iterator # when iterated.
when iterated.
"""
print(("*" * 40) + " BODY") print(("*" * 40) + " BODY")
for part in app_iter: for part in app_iter:
sys.stdout.write(part) sys.stdout.write(part)
@@ -367,13 +361,10 @@ def debug_filter(app, conf, **local_conf):
class Router(object): class Router(object):
""" '''WSGI middleware that maps incoming requests to WSGI apps.'''
WSGI middleware that maps incoming requests to WSGI apps.
"""
def __init__(self, mapper): def __init__(self, mapper):
""" '''Create a router for the given routes.Mapper.
Create a router for the given routes.Mapper.
Each route in `mapper` must specify a 'controller', which is a Each route in `mapper` must specify a 'controller', which is a
WSGI app to call. You'll probably want to specify an 'action' as WSGI app to call. You'll probably want to specify an 'action' as
@@ -394,27 +385,30 @@ class Router(object):
# {path_info:.*} parameter so the target app can be handed just that # {path_info:.*} parameter so the target app can be handed just that
# section of the URL. # section of the URL.
mapper.connect(None, "/v1.0/{path_info:.*}", controller=BlogApp()) mapper.connect(None, "/v1.0/{path_info:.*}", controller=BlogApp())
""" '''
self.map = mapper self.map = mapper
self._router = routes.middleware.RoutesMiddleware(self._dispatch, self._router = routes.middleware.RoutesMiddleware(self._dispatch,
self.map) self.map)
@webob.dec.wsgify @webob.dec.wsgify
def __call__(self, req): def __call__(self, req):
""" '''Route the incoming request to a controller based on self.map.
Route the incoming request to a controller based on self.map.
If no match, return a 404. If no match, return a 404.
""" '''
return self._router return self._router
@staticmethod @staticmethod
@webob.dec.wsgify @webob.dec.wsgify
def _dispatch(req): def _dispatch(req):
""" '''Called by self._router after matching the incoming request to
Called by self._router after matching the incoming request to a route a route and putting the information into req.environ.
and putting the information into req.environ. Either returns 404
or the routed WSGI app's response. Either returns 404 or the routed WSGI app's response.
""" '''
match = req.environ['wsgiorg.routing_args'][1] match = req.environ['wsgiorg.routing_args'][1]
if not match: if not match:
return webob.exc.HTTPNotFound() return webob.exc.HTTPNotFound()
@@ -477,11 +471,11 @@ def is_json_content_type(request):
class JSONRequestDeserializer(object): class JSONRequestDeserializer(object):
def has_body(self, request): def has_body(self, request):
""" '''Returns whether a Webob.Request object will possess an entity body.
Returns whether a Webob.Request object will possess an entity body.
:param request: Webob.Request object :param request: Webob.Request object
""" '''
if request.content_length > 0 and is_json_content_type(request): if request.content_length > 0 and is_json_content_type(request):
return True return True
@@ -507,8 +501,7 @@ class JSONRequestDeserializer(object):
class Resource(object): class Resource(object):
""" '''WSGI app that handles (de)serialization and controller dispatch.
WSGI app that handles (de)serialization and controller dispatch.
Reads routing information supplied by RoutesMiddleware and calls Reads routing information supplied by RoutesMiddleware and calls
the requested action method upon its deserializer, controller, the requested action method upon its deserializer, controller,
@@ -522,9 +515,10 @@ class Resource(object):
arguments that represent the keys returned by the Deserializer. They arguments that represent the keys returned by the Deserializer. They
may raise a webob.exc exception or return a dict, which will be may raise a webob.exc exception or return a dict, which will be
serialized by requested content type. serialized by requested content type.
""" '''
def __init__(self, controller, deserializer, serializer=None): def __init__(self, controller, deserializer, serializer=None):
""" """Initializer.
:param controller: object that implement methods created by routes lib :param controller: object that implement methods created by routes lib
:param deserializer: object that supports webob request deserialization :param deserializer: object that supports webob request deserialization
through controller-like actions through controller-like actions
@@ -647,7 +641,6 @@ def translate_exception(exc, locale):
class BasePasteFactory(object): class BasePasteFactory(object):
"""A base class for paste app and filter factories. """A base class for paste app and filter factories.
Sub-classes must override the KEY class attribute and provide Sub-classes must override the KEY class attribute and provide
@@ -684,7 +677,6 @@ class BasePasteFactory(object):
class AppFactory(BasePasteFactory): class AppFactory(BasePasteFactory):
"""A Generic paste.deploy app factory. """A Generic paste.deploy app factory.
This requires senlin.app_factory to be set to a callable which returns a This requires senlin.app_factory to be set to a callable which returns a

View File

@@ -113,8 +113,7 @@ def _paginate_query(context, query, model, limit=None, marker=None,
def soft_delete_aware_query(context, *args, **kwargs): def soft_delete_aware_query(context, *args, **kwargs):
""" """Object query helper that accounts for the `show_deleted` field.
Object query helper that accounts for the `show_deleted` field.
:param show_deleted: if True, overrides context's show_deleted field. :param show_deleted: if True, overrides context's show_deleted field.
""" """

View File

@@ -139,8 +139,7 @@ class Node(BASE, SenlinBase, SoftDelete):
class ClusterLock(BASE, SenlinBase): class ClusterLock(BASE, SenlinBase):
""" """Store cluster locks for actions performed by multiple workers.
Store cluster locks for actions performed by multiple workers.
Worker threads are able to grab this lock Worker threads are able to grab this lock
""" """
@@ -154,8 +153,7 @@ class ClusterLock(BASE, SenlinBase):
class NodeLock(BASE, SenlinBase): class NodeLock(BASE, SenlinBase):
""" """Store node locks for actions performed by multiple workers.
Store node locks for actions performed by multiple workers.
Worker threads are able to grab this lock Worker threads are able to grab this lock
""" """

View File

@@ -16,8 +16,7 @@ Base class for all drivers.
class DriverBase(object): class DriverBase(object):
''' '''Base class for all drivers.'''
Base class for all drivers.
'''
def __init__(self, context): def __init__(self, context):
self.context = context self.context = context

View File

@@ -16,9 +16,8 @@ from senlin.openstack.orchestration.v1 import stack
class HeatClient(base.DriverBase): class HeatClient(base.DriverBase):
''' '''Heat V1 driver.'''
Heat V1 driver.
'''
def __init__(self, context): def __init__(self, context):
conn = sdk.create_connection(context) conn = sdk.create_connection(context)
self.session = conn.session self.session = conn.session

View File

@@ -25,9 +25,8 @@ LOG = logging.getLogger(__name__)
class Action(object): class Action(object):
''' '''An action can be performed on a cluster or a node of a cluster.'''
An action can be performed on a cluster or a node of a cluster.
'''
RETURNS = ( RETURNS = (
RES_OK, RES_ERROR, RES_RETRY, RES_CANCEL, RES_TIMEOUT, RES_OK, RES_ERROR, RES_RETRY, RES_CANCEL, RES_TIMEOUT,
) = ( ) = (
@@ -132,9 +131,8 @@ class Action(object):
self.deleted_time = kwargs.get('deleted_time', None) self.deleted_time = kwargs.get('deleted_time', None)
def store(self, context): def store(self, context):
''' '''Store the action record into database table.'''
Store the action record into database table.
'''
values = { values = {
'name': self.name, 'name': self.name,
'context': self.context.to_dict(), 'context': self.context.to_dict(),
@@ -169,8 +167,8 @@ class Action(object):
@classmethod @classmethod
def _from_db_record(cls, record): def _from_db_record(cls, record):
''' '''Construct a action object from database record.
Construct a action object from database record.
:param context: the context used for DB operations; :param context: the context used for DB operations;
:param record: a DB action object that contains all fields. :param record: a DB action object that contains all fields.
''' '''
@@ -198,9 +196,8 @@ class Action(object):
@classmethod @classmethod
def load(cls, context, action_id): def load(cls, context, action_id):
''' '''Retrieve an action from database.'''
Retrieve an action from database.
'''
action = db_api.action_get(context, action_id) action = db_api.action_get(context, action_id)
if action is None: if action is None:
msg = _('No action with id "%s" exists') % action_id msg = _('No action with id "%s" exists') % action_id
@@ -211,9 +208,8 @@ class Action(object):
@classmethod @classmethod
def load_all(cls, context, filters=None, limit=None, marker=None, def load_all(cls, context, filters=None, limit=None, marker=None,
sort_keys=None, sort_dir=None, show_deleted=False): sort_keys=None, sort_dir=None, show_deleted=False):
''' '''Retrieve all actions of from database.'''
Retrieve all actions of from database.
'''
records = db_api.action_get_all(context, filters=filters, records = db_api.action_get_all(context, filters=filters,
limit=limit, marker=marker, limit=limit, marker=marker,
sort_keys=sort_keys, sort_keys=sort_keys,
@@ -228,8 +224,8 @@ class Action(object):
db_api.action_delete(context, action_id, force) db_api.action_delete(context, action_id, force)
def execute(self, **kwargs): def execute(self, **kwargs):
''' '''Execute the action.
Execute the action.
In theory, the action encapsulates all information needed for In theory, the action encapsulates all information needed for
execution. 'kwargs' may specify additional parameters. execution. 'kwargs' may specify additional parameters.
:param kwargs: additional parameters that may override the default :param kwargs: additional parameters that may override the default
@@ -241,8 +237,8 @@ class Action(object):
return NotImplemented return NotImplemented
def set_status(self, status): def set_status(self, status):
''' '''Set action status.
Set action status.
This is not merely about a db record update. This is not merely about a db record update.
''' '''
if status == self.SUCCEEDED: if status == self.SUCCEEDED:
@@ -260,8 +256,7 @@ class Action(object):
return action.status return action.status
def policy_check(self, cluster_id, target): def policy_check(self, cluster_id, target):
""" """Check all policies attached to cluster and give result.
Check all policies attached to cluster and give result
:param target: A tuple of ('when', action_name) :param target: A tuple of ('when', action_name)
""" """

View File

@@ -28,9 +28,8 @@ LOG = logging.getLogger(__name__)
class ClusterAction(base.Action): class ClusterAction(base.Action):
''' '''An action performed on a cluster.'''
An action performed on a cluster.
'''
ACTIONS = ( ACTIONS = (
CLUSTER_CREATE, CLUSTER_DELETE, CLUSTER_UPDATE, CLUSTER_CREATE, CLUSTER_DELETE, CLUSTER_UPDATE,
CLUSTER_ADD_NODES, CLUSTER_DEL_NODES, CLUSTER_ADD_NODES, CLUSTER_DEL_NODES,

View File

@@ -20,9 +20,8 @@ LOG = logging.getLogger(__name__)
class NodeAction(base.Action): class NodeAction(base.Action):
''' '''An action performed on a cluster member.'''
An action performed on a cluster member.
'''
ACTIONS = ( ACTIONS = (
NODE_CREATE, NODE_DELETE, NODE_UPDATE, NODE_CREATE, NODE_DELETE, NODE_UPDATE,
NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER, NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER,

View File

@@ -21,8 +21,7 @@ LOG = logging.getLogger(__name__)
class PolicyAction(base.Action): class PolicyAction(base.Action):
''' '''An action performed on a cluster policy.
An action performed on a cluster policy.
Note that these can be treated as cluster operations instead of operations Note that these can be treated as cluster operations instead of operations
on a policy itself. on a policy itself.

View File

@@ -21,8 +21,7 @@ from senlin.profiles import base as profiles
class Cluster(periodic_task.PeriodicTasks): class Cluster(periodic_task.PeriodicTasks):
''' '''A cluster is a set of homogeneous objects of the same profile.
A cluster is a set of homogeneous objects of the same profile.
All operations are performed without further checking because the All operations are performed without further checking because the
checkings are supposed to be de done before/after/during an action is checkings are supposed to be de done before/after/during an action is
@@ -38,10 +37,11 @@ class Cluster(periodic_task.PeriodicTasks):
) )
def __init__(self, name, profile_id, size=0, **kwargs): def __init__(self, name, profile_id, size=0, **kwargs):
''' '''Intialize a cluster object.
Intialize a cluster object.
The cluster defaults to have 0 nodes with no profile assigned. The cluster defaults to have 0 nodes with no profile assigned.
''' '''
self.id = kwargs.get('id', None) self.id = kwargs.get('id', None)
self.name = name self.name = name
self.profile_id = profile_id self.profile_id = profile_id
@@ -74,8 +74,8 @@ class Cluster(periodic_task.PeriodicTasks):
@classmethod @classmethod
def _from_db_record(cls, record): def _from_db_record(cls, record):
''' '''Construct a cluster object from database record.
Construct a cluster object from database record.
:param context: the context used for DB operations; :param context: the context used for DB operations;
:param record: a DB cluster object that will receive all fields; :param record: a DB cluster object that will receive all fields;
''' '''
@@ -107,9 +107,8 @@ class Cluster(periodic_task.PeriodicTasks):
@classmethod @classmethod
def load(cls, context, cluster_id, show_deleted=False): def load(cls, context, cluster_id, show_deleted=False):
''' '''Retrieve a cluster from database.'''
Retrieve a cluster from database.
'''
record = db_api.cluster_get(context, cluster_id, record = db_api.cluster_get(context, cluster_id,
show_deleted=show_deleted) show_deleted=show_deleted)
cluster = cls._from_db_record(record) cluster = cls._from_db_record(record)
@@ -120,9 +119,8 @@ class Cluster(periodic_task.PeriodicTasks):
def load_all(cls, context, limit=None, marker=None, sort_keys=None, def load_all(cls, context, limit=None, marker=None, sort_keys=None,
sort_dir=None, filters=None, tenant_safe=True, sort_dir=None, filters=None, tenant_safe=True,
show_deleted=False, show_nested=False): show_deleted=False, show_nested=False):
''' '''Retrieve all clusters from database.'''
Retrieve all clusters from database.
'''
records = db_api.cluster_get_all(context, limit, marker, sort_keys, records = db_api.cluster_get_all(context, limit, marker, sort_keys,
sort_dir, filters, tenant_safe, sort_dir, filters, tenant_safe,
show_deleted, show_nested) show_deleted, show_nested)
@@ -133,10 +131,11 @@ class Cluster(periodic_task.PeriodicTasks):
yield cluster yield cluster
def store(self, context): def store(self, context):
''' '''Store the cluster in database and return its ID.
Store the cluster in database and return its ID.
If the ID already exists, we do an update. If the ID already exists, we do an update.
''' '''
values = { values = {
'name': self.name, 'name': self.name,
'profile_id': self.profile_id, 'profile_id': self.profile_id,
@@ -194,9 +193,8 @@ class Cluster(periodic_task.PeriodicTasks):
return info return info
def set_status(self, context, status, reason=None): def set_status(self, context, status, reason=None):
''' '''Set status of the cluster.'''
Set status of the cluster.
'''
values = {} values = {}
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow()
if status == self.ACTIVE: if status == self.ACTIVE:
@@ -215,25 +213,25 @@ class Cluster(periodic_task.PeriodicTasks):
# generate event record # generate event record
def do_create(self, context, **kwargs): def do_create(self, context, **kwargs):
'''Invoked at the beginning of cluster creating progress to set
cluster status to CREATING.
''' '''
Invoked at the beginning of cluster creating
progress to set cluster status to CREATING.
'''
self.set_status(context, self.CREATING) self.set_status(context, self.CREATING)
return True return True
def do_delete(self, context, **kwargs): def do_delete(self, context, **kwargs):
''' '''Invoked at the end of entire cluster deleting
Invoked at the end of entire cluster deleting
progress to set cluster status to DELETED. progress to set cluster status to DELETED.
''' '''
self.set_status(context, self.DELETED) self.set_status(context, self.DELETED)
def do_update(self, context, new_profile_id, **kwargs): def do_update(self, context, new_profile_id, **kwargs):
''' '''Invoked at the beginning of cluster updating progress
Invoked at the beginning of cluster updating progress
to check profile and set cluster status to UPDATING. to check profile and set cluster status to UPDATING.
''' '''
self.set_status(self.UPDATING) self.set_status(self.UPDATING)
# Profile type checking is done here because the do_update logic can # Profile type checking is done here because the do_update logic can
# be triggered from API or Webhook # be triggered from API or Webhook
@@ -273,9 +271,8 @@ class Cluster(periodic_task.PeriodicTasks):
pass pass
def del_nodes(self, node_ids): def del_nodes(self, node_ids):
''' '''Remove nodes from current cluster.'''
Remove nodes from current cluster.
'''
deleted = [] deleted = []
for node_id in node_ids: for node_id in node_ids:
node = db_api.node_get(node_id) node = db_api.node_get(node_id)
@@ -284,9 +281,8 @@ class Cluster(periodic_task.PeriodicTasks):
return deleted return deleted
def attach_policy(self, policy_id): def attach_policy(self, policy_id):
''' '''Attach specified policy instance to this cluster.'''
Attach specified policy instance to this cluster.
'''
# TODO(Qiming): check conflicts with existing policies # TODO(Qiming): check conflicts with existing policies
self.policies.append(policy_id) self.policies.append(policy_id)
@@ -327,5 +323,6 @@ class Cluster(periodic_task.PeriodicTasks):
pass pass
def periodic_tasks(self, context, raise_on_error=False): def periodic_tasks(self, context, raise_on_error=False):
"""Tasks to be run at a periodic interval.""" '''Tasks to be run at a periodic interval.'''
return self.run_periodic_tasks(context, raise_on_error=raise_on_error) return self.run_periodic_tasks(context, raise_on_error=raise_on_error)

View File

@@ -26,9 +26,9 @@ LOG = logging.getLogger(__name__)
@profiler.trace_cls("rpc") @profiler.trace_cls("rpc")
class Dispatcher(service.Service): class Dispatcher(service.Service):
''' '''Listen on an AMQP queue named for the engine.
Listen on an AMQP queue named for the engine. Receive
notification from engine services and schedule actions. Receive notification from engine services and schedule actions.
''' '''
OPERATIONS = ( OPERATIONS = (
@@ -53,8 +53,7 @@ class Dispatcher(service.Service):
server.start() server.start()
def listening(self, context): def listening(self, context):
''' '''Respond affirmatively to confirm that the engine performing the
Respond affirmatively to confirm that the engine performing the
action is still alive. action is still alive.
''' '''
return True return True
@@ -86,13 +85,13 @@ class Dispatcher(service.Service):
def notify(context, call, engine_id, *args, **kwargs): def notify(context, call, engine_id, *args, **kwargs):
""" '''Send notification to dispatcher
Send notification to dispatcher
:param context: rpc request context :param context: rpc request context
:param call: remote method want to call :param call: remote method want to call
:param engine_id: dispatcher want to notify, if None, broadcast :param engine_id: dispatcher want to notify, if None, broadcast
""" '''
timeout = cfg.CONF.engine_life_check_timeout timeout = cfg.CONF.engine_life_check_timeout
client = rpc_messaging.get_rpc_client(version=attr.RPC_API_VERSION) client = rpc_messaging.get_rpc_client(version=attr.RPC_API_VERSION)

View File

@@ -38,9 +38,8 @@ def global_env():
class Environment(object): class Environment(object):
''' '''An object that contains all profiles, policies and customizations.'''
An object that contains all profiles, policies and customizations.
'''
SECTIONS = ( SECTIONS = (
PARAMETERS, CUSTOM_PROFILES, CUSTOM_POLICIES, PARAMETERS, CUSTOM_PROFILES, CUSTOM_POLICIES,
) = ( ) = (
@@ -48,8 +47,7 @@ class Environment(object):
) )
def __init__(self, env=None, is_global=False): def __init__(self, env=None, is_global=False):
''' '''Create an Environment from a dict.
Create an Environment from a dict.
:param env: the json environment :param env: the json environment
:param is_global: boolean indicating if this is a user created one. :param is_global: boolean indicating if this is a user created one.
@@ -75,9 +73,8 @@ class Environment(object):
self.policy_registry.load(custom_policies) self.policy_registry.load(custom_policies)
def parse(self, env_str): def parse(self, env_str):
''' '''Parse a string format environment file into a dictionary.'''
Parse a string format environment file into a dictionary.
'''
if env_str is None: if env_str is None:
return {} return {}
@@ -97,9 +94,8 @@ class Environment(object):
return env return env
def load(self, env_dict): def load(self, env_dict):
''' '''Load environment from the given dictionary.'''
Load environment from the given dictionary.
'''
self.params.update(env_dict.get(self.PARAMETERS, {})) self.params.update(env_dict.get(self.PARAMETERS, {}))
self.profile_registry.load(env_dict.get(self.CUSTOM_PROFILES, {})) self.profile_registry.load(env_dict.get(self.CUSTOM_PROFILES, {}))
self.policy_registry.load(env_dict.get(self.CUSTOM_POLICIES, {})) self.policy_registry.load(env_dict.get(self.CUSTOM_POLICIES, {}))
@@ -151,9 +147,8 @@ class Environment(object):
return self.policy_registry.get_types() return self.policy_registry.get_types()
def read_global_environment(self): def read_global_environment(self):
''' '''Read and parse global enviroment files.'''
Read and parse global enviroment files.
'''
cfg.CONF.import_opt('environment_dir', 'senlin.common.config') cfg.CONF.import_opt('environment_dir', 'senlin.common.config')
env_dir = cfg.CONF.environment_dir env_dir = cfg.CONF.environment_dir

View File

@@ -33,9 +33,8 @@ class_mapping = {
class Event(object): class Event(object):
''' '''Class capturing a cluster operation or state change.'''
Class capturing a cluster operation or state change.
'''
def __init__(self, level, context, entity, action, status, def __init__(self, level, context, entity, action, status,
timestamp=None, reason='', entity_type='CLUSTER'): timestamp=None, reason='', entity_type='CLUSTER'):
self.level = level self.level = level

View File

@@ -13,6 +13,7 @@
import datetime import datetime
from senlin.common import exception from senlin.common import exception
from senlin.common.i18n import _
from senlin.common.i18n import _LE from senlin.common.i18n import _LE
from senlin.common.i18n import _LW from senlin.common.i18n import _LW
from senlin.db import api as db_api from senlin.db import api as db_api
@@ -24,8 +25,7 @@ LOG = logging.getLogger(__name__)
class Node(object): class Node(object):
''' '''A node is an object that can belong to at most one single cluster.
A node is an object that can belong to at most one single cluster.
All operations are performed without further checking because the All operations are performed without further checking because the
checkings are supposed to be de done before/after/during an action is checkings are supposed to be de done before/after/during an action is
@@ -70,8 +70,7 @@ class Node(object):
} }
def store(self, context): def store(self, context):
''' '''Store the node record into database table.
Store the node record into database table.
The invocation of DB API could be a node_create or a node_update, The invocation of DB API could be a node_create or a node_update,
depending on whether node has an ID assigned. depending on whether node has an ID assigned.
@@ -108,8 +107,8 @@ class Node(object):
@classmethod @classmethod
def from_db_record(cls, context, record): def from_db_record(cls, context, record):
''' '''Construct a node object from database record.
Construct a node object from database record.
:param context: the context used for DB operations; :param context: the context used for DB operations;
:param record: a DB node object that contains all fields; :param record: a DB node object that contains all fields;
''' '''
@@ -132,9 +131,8 @@ class Node(object):
@classmethod @classmethod
def load(cls, context, node_id): def load(cls, context, node_id):
''' '''Retrieve a node from database.'''
Retrieve a node from database.
'''
record = db_api.node_get(context, node_id) record = db_api.node_get(context, node_id)
if record is None: if record is None:
@@ -147,9 +145,8 @@ class Node(object):
def load_all(cls, context, cluster_id=None, show_deleted=False, def load_all(cls, context, cluster_id=None, show_deleted=False,
limit=None, marker=None, sort_keys=None, sort_dir=None, limit=None, marker=None, sort_keys=None, sort_dir=None,
filters=None, tenant_safe=True): filters=None, tenant_safe=True):
''' '''Retrieve all nodes of from database.'''
Retrieve all nodes of from database.
'''
records = db_api.node_get_all(context, cluster_id=cluster_id, records = db_api.node_get_all(context, cluster_id=cluster_id,
show_deleted=show_deleted, show_deleted=show_deleted,
limit=limit, marker=marker, limit=limit, marker=marker,

View File

@@ -17,10 +17,10 @@ import six
from six.moves import urllib from six.moves import urllib
import yaml import yaml
from senlin.common import i18n from senlin.common.i18n import _
from senlin.common.i18n import _LE
from senlin.openstack.common import log as logging from senlin.openstack.common import log as logging
_LE = i18n._LE
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
# Try LibYAML if available # Try LibYAML if available
@@ -102,9 +102,8 @@ def simple_parse(in_str):
def parse_profile(profile_str): def parse_profile(profile_str):
''' '''Parse and validate the specified string as a profile.'''
Parse and validate the specified string as a profile.
'''
data = simple_parse(profile_str) data = simple_parse(profile_str)
# TODO(Qiming): # TODO(Qiming):
@@ -114,9 +113,8 @@ def parse_profile(profile_str):
def parse_policy(policy_str): def parse_policy(policy_str):
''' '''Parse and validate the specified string as a policy.'''
Parse and validate the specified string as a policy.
'''
data = simple_parse(policy_str) data = simple_parse(policy_str)
# TODO(Qiming): # TODO(Qiming):
@@ -126,9 +124,8 @@ def parse_policy(policy_str):
def parse_action(action): def parse_action(action):
''' '''Parse and validate the specified string as a action.'''
Parse and validate the specified string as a action.
'''
if not isinstance(action, six.string_types): if not isinstance(action, six.string_types):
# TODO(Qiming): Throw exception # TODO(Qiming): Throw exception
return None return None

View File

@@ -21,12 +21,11 @@ LOG = log.getLogger(__name__)
class PluginInfo(object): class PluginInfo(object):
''' '''Base mapping of plugin type to implementation.'''
Base mapping of plugin type to implementation.
'''
def __new__(cls, registry, name, plugin, **kwargs): def __new__(cls, registry, name, plugin, **kwargs):
''' '''Create a new PluginInfo of the appropriate class.
Create a new PluginInfo of the appropriate class.
Placeholder for class hierarchy extensibility Placeholder for class hierarchy extensibility
''' '''
return super(PluginInfo, cls).__new__(cls) return super(PluginInfo, cls).__new__(cls)
@@ -65,9 +64,7 @@ class PluginInfo(object):
class Registry(object): class Registry(object):
''' '''A registry for managing profile or policy classes.'''
A registry for managing profile or policy classes.
'''
def __init__(self, registry_name, global_registry=None): def __init__(self, registry_name, global_registry=None):
self.registry_name = registry_name self.registry_name = registry_name
@@ -76,8 +73,7 @@ class Registry(object):
self.global_registry = global_registry self.global_registry = global_registry
def _register_info(self, name, info): def _register_info(self, name, info):
''' '''place the new info in the correct location in the registry.
place the new info in the correct location in the registry.
:param path: a list of keys ['profiles', 'my_stack', 'os.heat.stack'], :param path: a list of keys ['profiles', 'my_stack', 'os.heat.stack'],
or ['policies', 'my_policy', 'ScalingPolicy'] or ['policies', 'my_policy', 'ScalingPolicy']
@@ -140,7 +136,7 @@ class Registry(object):
return info.plugin if info else None return info.plugin if info else None
def as_dict(self): def as_dict(self):
"""Return profiles in a dict format.""" '''Return profiles in a dict format.'''
def _as_dict(level): def _as_dict(level):
tmp = {} tmp = {}
for k, v in iter(level.items()): for k, v in iter(level.items()):

View File

@@ -34,8 +34,8 @@ ACTION_CONTROL_REQUEST = (
class ThreadGroupManager(object): class ThreadGroupManager(object):
""" '''Thread group manager.'''
"""
def __init__(self): def __init__(self):
super(ThreadGroupManager, self).__init__() super(ThreadGroupManager, self).__init__()
self.threads = {} self.threads = {}
@@ -46,10 +46,10 @@ class ThreadGroupManager(object):
self.add_timer(cfg.CONF.periodic_interval, self._service_task) self.add_timer(cfg.CONF.periodic_interval, self._service_task)
def _service_task(self): def _service_task(self):
''' '''Dummy task which gets queued on the service.Service threadgroup.
This is a dummy task which gets queued on the service.Service
threadgroup. Without this service.Service sees nothing running Without this service.Service sees nothing running i.e has nothing to
i.e has nothing to wait() on, so the process exits.. wait() on, so the process exits..
This could also be used to trigger periodic non-cluster-specific This could also be used to trigger periodic non-cluster-specific
housekeeping tasks housekeeping tasks
@@ -59,24 +59,20 @@ class ThreadGroupManager(object):
pass pass
def start(self, func, *args, **kwargs): def start(self, func, *args, **kwargs):
""" '''Run the given method in a sub-thread.'''
Run the given method in a sub-thread.
"""
return self.group.add_thread(func, *args, **kwargs) return self.group.add_thread(func, *args, **kwargs)
def start_action_thread(self, context, action, *args, **kwargs): def start_action_thread(self, context, action, *args, **kwargs):
""" '''Run the given action in a sub-thread and release the action lock
Run the given action in a sub-thread and release the action lock
when the thread finishes. when the thread finishes.
:param context: The context of rpc request :param context: The context of rpc request
:param action: The action to run in thread :param action: The action to run in thread
'''
"""
def release(gt, context, action): def release(gt, context, action):
""" '''Callback function that will be passed to GreenThread.link().'''
Callback function that will be passed to GreenThread.link().
"""
# Remove action thread from thread list # Remove action thread from thread list
self.threads.pop(action.id) self.threads.pop(action.id)
@@ -86,10 +82,11 @@ class ThreadGroupManager(object):
return th return th
def add_timer(self, interval, func, *args, **kwargs): def add_timer(self, interval, func, *args, **kwargs):
""" '''Define a periodic task, to be run in a separate thread, in the
Define a periodic task, to be run in a separate thread, in the target target threadgroups.
threadgroups. Periodicity is cfg.CONF.periodic_interval Interval is from cfg.CONF.periodic_interval
""" '''
self.group.add_timer(cfg.CONF.periodic_interval, func, *args, **kwargs) self.group.add_timer(cfg.CONF.periodic_interval, func, *args, **kwargs)
def stop_timers(self): def stop_timers(self):
@@ -116,13 +113,12 @@ class ThreadGroupManager(object):
def ActionProc(context, action, wait_time=1, **kwargs): def ActionProc(context, action, wait_time=1, **kwargs):
""" '''Start and run action progress.
Start and run action progress.
Action progress will sleep for `wait_time` seconds between Action progress will sleep for `wait_time` seconds between
each step. To avoid sleeping, pass `None` for `wait_time`. each step. To avoid sleeping, pass `None` for `wait_time`.
""" '''
# Do the first step
LOG.debug('Starting %s' % six.text_type(action.action)) LOG.debug('Starting %s' % six.text_type(action.action))
result = action.execute() result = action.execute()
@@ -145,14 +141,14 @@ def ActionProc(context, action, wait_time=1, **kwargs):
def start_action(context, action_id, engine_id, tgm): def start_action(context, action_id, engine_id, tgm):
""" '''Start an action execution progress using given ThreadGroupManager.
Start an action execution progress using given ThreadGroupManager
:param context: The context of rpc request :param context: The context of rpc request
:param action_id: The id of action to run in thread :param action_id: The id of action to run in thread
:param engine_id: The id of engine try to lock the action :param engine_id: The id of engine try to lock the action
:param tgm: The ThreadGroupManager of the engine :param tgm: The ThreadGroupManager of the engine
""" '''
action = base_action.Action.load(context, action_id) action = base_action.Action.load(context, action_id)
action.start_time = wallclock() action.start_time = wallclock()
@@ -173,46 +169,41 @@ def start_action(context, action_id, engine_id, tgm):
def suspend_action(context, action_id): def suspend_action(context, action_id):
""" '''Suspend an action execution progress.
Try to suspend an action execution progress
:param context: The context of rpc request :param context: The context of rpc request
:param action_id: The id of action to run in thread :param action_id: The id of action to run in thread
""" '''
# Set action control flag to suspend # Set action control flag to suspend
# TODO(anyone): need db_api support # TODO(anyone): need db_api support
db_api.action_control(context, action_id, ACTION_SUSPEND) db_api.action_control(context, action_id, ACTION_SUSPEND)
def resume_action(context, action_id): def resume_action(context, action_id):
""" '''Resume an action execution progress.
Try to resume an action execution progress
:param context: The context of rpc request :param context: The context of rpc request
:param action_id: The id of action to run in thread :param action_id: The id of action to run in thread
""" '''
# Set action control flag to suspend # Set action control flag to suspend
# TODO(anyone): need db_api support # TODO(anyone): need db_api support
db_api.action_control(context, action_id, ACTION_RESUME) db_api.action_control(context, action_id, ACTION_RESUME)
def cancel_action(context, action_id): def cancel_action(context, action_id):
""" '''Try to cancel an action execution progress.
Try to cancel an action execution progress
:param context: The context of rpc request :param context: The context of rpc request
:param action_id: The id of action to run in thread :param action_id: The id of action to run in thread
""" '''
# Set action control flag to cancel # Set action control flag to cancel
# TODO(anyone): need db_api support # TODO(anyone): need db_api support
db_api.action_control(context, action_id, ACTION_CANCEL) db_api.action_control(context, action_id, ACTION_CANCEL)
def action_control_flag(action): def action_control_flag(action):
""" '''Check whether there are some action control requests.'''
Check whether there are some action control requests
need to be handled.
"""
# Check timeout first, if true, return timeout message # Check timeout first, if true, return timeout message
if action.timeout is not None and action_timeout(action): if action.timeout is not None and action_timeout(action):
LOG.debug('Action %s run timeout' % action.id) LOG.debug('Action %s run timeout' % action.id)
@@ -225,9 +216,8 @@ def action_control_flag(action):
def action_cancelled(action): def action_cancelled(action):
""" '''Check whether an action is flagged to be cancelled.'''
Check whether an action's control flag is set to cancel
"""
if action_control_flag(action) == ACTION_CANCEL: if action_control_flag(action) == ACTION_CANCEL:
return True return True
else: else:
@@ -235,9 +225,8 @@ def action_cancelled(action):
def action_suspended(action): def action_suspended(action):
""" '''Check whether an action's control flag is set to suspend.'''
Check whether an action's control flag is set to suspend
"""
if action_control_flag(action) == ACTION_SUSPEND: if action_control_flag(action) == ACTION_SUSPEND:
return True return True
else: else:
@@ -245,9 +234,8 @@ def action_suspended(action):
def action_resumed(action): def action_resumed(action):
""" '''Check whether an action's control flag is set to resume.'''
Check whether an action's control flag is set to suspend
"""
if action_control_flag(action) == ACTION_RESUME: if action_control_flag(action) == ACTION_RESUME:
return True return True
else: else:
@@ -255,9 +243,8 @@ def action_resumed(action):
def action_timeout(action): def action_timeout(action):
""" '''Return True if an action has run timeout, False otherwise.'''
Return True if an action has run timeout, False otherwise.
"""
time_lapse = wallclock() - action.start_time time_lapse = wallclock() - action.start_time
if time_lapse > action.timeout: if time_lapse > action.timeout:
@@ -267,11 +254,11 @@ def action_timeout(action):
def reschedule(action, sleep_time=1): def reschedule(action, sleep_time=1):
""" '''Eventlet Sleep for the specified number of seconds.
Eventlet Sleep for the specified number of seconds.
:param sleep_time: seconds to sleep; if None, no sleep; :param sleep_time: seconds to sleep; if None, no sleep;
""" '''
if sleep_time is not None: if sleep_time is not None:
LOG.debug('Action %s sleep for %s seconds' % ( LOG.debug('Action %s sleep for %s seconds' % (
action.id, sleep_time)) action.id, sleep_time))
@@ -279,16 +266,14 @@ def reschedule(action, sleep_time=1):
def action_wait(action): def action_wait(action):
""" '''Keep waiting util action resume control flag is set.'''
Keep waiting util action resume control flag is set
"""
while not action_resumed(action): while not action_resumed(action):
reschedule(action, sleep_time=1) reschedule(action, sleep_time=1)
continue continue
def sleep(sleep_time): def sleep(sleep_time):
''' '''Interface for sleeping.'''
Interface for sleeping.
'''
eventlet.sleep(sleep_time) eventlet.sleep(sleep_time)

View File

@@ -31,6 +31,8 @@ LOG = logging.getLogger(__name__)
class BaseLock(object): class BaseLock(object):
'''Base class for locks.'''
def __init__(self, context, target, engine_id): def __init__(self, context, target, engine_id):
self.context = context self.context = context
self.target = target self.target = target
@@ -53,19 +55,19 @@ class BaseLock(object):
return str(uuid.uuid4()) return str(uuid.uuid4())
def try_acquire(self): def try_acquire(self):
""" '''Try to acquire a lock for target.
Try to acquire a lock for target, but don't raise an ActionInProgress
exception or try to steal lock. It won't raise an ActionInProgress exception or try to steal lock.
""" '''
return self.lock_create(self.target.id, self.engine_id) return self.lock_create(self.target.id, self.engine_id)
def acquire(self, retry=True): def acquire(self, retry=True):
""" '''Acquire a lock on the target.
Acquire a lock on the target.
:param retry: When True, retry if lock was released while stealing. :param retry: When True, retry if lock was released while stealing.
:type retry: boolean :type retry: boolean
""" '''
lock_engine_id = self.lock_create(self.target.id, self.engine_id) lock_engine_id = self.lock_create(self.target.id, self.engine_id)
if lock_engine_id is None: if lock_engine_id is None:
LOG.debug("Engine %(engine)s acquired lock on %(target_type)s " LOG.debug("Engine %(engine)s acquired lock on %(target_type)s "
@@ -135,11 +137,11 @@ class BaseLock(object):
@contextlib.contextmanager @contextlib.contextmanager
def thread_lock(self, target_id): def thread_lock(self, target_id):
""" '''Acquire a lock and release it only if there is an exception.
Acquire a lock and release it only if there is an exception. The
release method still needs to be scheduled to be run at the The release method still needs to be scheduled to be run at the
end of the thread using the Thread.link method. end of the thread using the Thread.link method.
""" '''
try: try:
self.acquire() self.acquire()
yield yield
@@ -149,11 +151,13 @@ class BaseLock(object):
@contextlib.contextmanager @contextlib.contextmanager
def try_thread_lock(self, target_id): def try_thread_lock(self, target_id):
""" '''Acquire the lock using try_acquire.
Similar to thread_lock, but acquire the lock using try_acquire Similar to thread_lock, but acquire the lock using try_acquire
and only release it upon any exception after a successful and only release it upon any exception after a successful
acquisition. acquisition.
""" '''
result = None result = None
try: try:
result = self.try_acquire() result = self.try_acquire()

View File

@@ -70,15 +70,15 @@ def request_context(func):
@profiler.trace_cls("rpc") @profiler.trace_cls("rpc")
class EngineService(service.Service): class EngineService(service.Service):
""" '''Manages the running instances from creation to destruction.
Manages the running instances from creation to destruction.
All the methods in here are called from the RPC backend. This is All the methods in here are called from the RPC backend. This is
all done dynamically so if a call is made via RPC that does not all done dynamically so if a call is made via RPC that does not
have a corresponding method here, an exception will be thrown when have a corresponding method here, an exception will be thrown when
it attempts to call into this class. Arguments to these methods it attempts to call into this class. Arguments to these methods
are also dynamically added and will be named as keyword arguments are also dynamically added and will be named as keyword arguments
by the RPC caller. by the RPC caller.
""" '''
def __init__(self, host, topic, manager=None, def __init__(self, host, topic, manager=None,
periodic_enable=None, periodic_fuzzy_delay=None, periodic_enable=None, periodic_fuzzy_delay=None,
@@ -244,9 +244,8 @@ class EngineService(service.Service):
@request_context @request_context
def cluster_find(self, context, identity): def cluster_find(self, context, identity):
''' '''Find a cluster with the given identity (could be name or ID).'''
Find a cluster with the given identity (could be name or ID).
'''
if uuidutils.is_uuid_like(identity): if uuidutils.is_uuid_like(identity):
db_cluster = db_api.cluster_get(context, identity, db_cluster = db_api.cluster_get(context, identity,
show_deleted=True) show_deleted=True)

View File

@@ -57,7 +57,8 @@ _levelNames = {
def getLevelName(level): def getLevelName(level):
''' '''Get a level name or number.
Return a level name if given a numeric value; or return a value if given Return a level name if given a numeric value; or return a value if given
a string. If level is not predefined, "Level %s" will be returned. a string. If level is not predefined, "Level %s" will be returned.
''' '''

View File

@@ -11,14 +11,14 @@
# under the License. # under the License.
from senlin.common import exception from senlin.common import exception
from senlin.common.i18n import _
from senlin.db import api as db_api from senlin.db import api as db_api
from senlin.engine import environment from senlin.engine import environment
class Policy(object): class Policy(object):
''' '''Base class for policies.'''
Base class for policies.
'''
ENFORCEMENT_LEVELS = ( ENFORCEMENT_LEVELS = (
CRITICAL, ERROR, WARNING, INFO, DEBUG, CRITICAL, ERROR, WARNING, INFO, DEBUG,
) = ( ) = (
@@ -32,9 +32,8 @@ class Policy(object):
) )
def __new__(cls, type_name, name, **kwargs): def __new__(cls, type_name, name, **kwargs):
''' '''Create a new policy of the appropriate class.'''
Create a new policy of the appropriate class.
'''
if cls != Policy: if cls != Policy:
PolicyClass = cls PolicyClass = cls
else: else:
@@ -54,8 +53,8 @@ class Policy(object):
self.data = kwargs.get('data', {}) self.data = kwargs.get('data', {})
def store(self): def store(self):
''' '''Store the policy object into database table.
Store the policy object into database table.
This could be a policy_create or a policy_update DB API invocation, This could be a policy_create or a policy_update DB API invocation,
depends on whether self.id is set. depends on whether self.id is set.
''' '''
@@ -77,11 +76,8 @@ class Policy(object):
@classmethod @classmethod
def from_db_record(cls, context, record): def from_db_record(cls, context, record):
''' '''Construct a policy object from a database record.'''
Construct a policy object from a database record.
:param context:
:param record:
'''
kwargs = { kwargs = {
'id': record.id, 'id': record.id,
'name': record.name, 'name': record.name,
@@ -96,9 +92,8 @@ class Policy(object):
@classmethod @classmethod
def load(cls, context, policy_id): def load(cls, context, policy_id):
''' '''Retrieve and reconstruct a policy object from DB.'''
Retrieve and reconstruct a policy object from DB.
'''
policy = db_api.policy_get(context, policy_id) policy = db_api.policy_get(context, policy_id)
if policy is None: if policy is None:
msg = _('No policy with id "%s" exists') % policy_id msg = _('No policy with id "%s" exists') % policy_id
@@ -107,23 +102,20 @@ class Policy(object):
return cls.from_db_record(context, policy) return cls.from_db_record(context, policy)
def pre_op(self, cluster_id, action, **kwargs): def pre_op(self, cluster_id, action, **kwargs):
''' '''Force all subclasses to implement an operation that will be invoked
Force all subclasses to implement an operation that will be invoked
before an action. before an action.
''' '''
return NotImplemented return NotImplemented
def enforce(self, cluster_id, action, **kwargs): def enforce(self, cluster_id, action, **kwargs):
''' '''Force all subclasses to implement an operation that can be called
Force all subclasses to implement an operation that can be called
during an action. during an action.
''' '''
return NotImplemented return NotImplemented
def post_op(self, cluster_id, action, **kwargs): def post_op(self, cluster_id, action, **kwargs):
''' '''Force all subclasses to implement an operation that will be
Force all subclasses to implement an operation that will be performed performed after an action.
after an action.
''' '''
return NotImplemented return NotImplemented

View File

@@ -18,9 +18,7 @@ from senlin.policies import base
class DeletionPolicy(base.Policy): class DeletionPolicy(base.Policy):
''' '''Policy for deleting member(s) from a cluster.'''
Policy for deleting member(s) from a cluster.
'''
__type_name__ = 'DeletionPolicy' __type_name__ = 'DeletionPolicy'
@@ -51,8 +49,7 @@ class DeletionPolicy(base.Policy):
random.seed() random.seed()
def pre_op(self, cluster_id, action, **kwargs): def pre_op(self, cluster_id, action, **kwargs):
''' '''The pre-op of a deletion policy returns the chosen victims
The pre-op of a deletion policy returns the chosen victims
that will be deleted. that will be deleted.
''' '''
data = kwargs.get('data') data = kwargs.get('data')

View File

@@ -15,9 +15,7 @@ from senlin.policies import base
class HealthPolicy(base.Policy): class HealthPolicy(base.Policy):
''' '''Policy for health checking for members of a cluster.'''
Policy for health checking for members of a cluster.
'''
__type_name__ = 'HealthPolicy' __type_name__ = 'HealthPolicy'

View File

@@ -15,8 +15,7 @@ from senlin.policies import base
class LoadBalancingPolicy(base.Policy): class LoadBalancingPolicy(base.Policy):
''' '''Policy for load balancing among members of a cluster.
Policy for load balancing among members of a cluster.
This policy is expected to be enforced after the member list of a cluster This policy is expected to be enforced after the member list of a cluster
is changed. We need to reload the load-balancer specified (or internally is changed. We need to reload the load-balancer specified (or internally

View File

@@ -15,8 +15,7 @@ from senlin.policies import base
class PlacementPolicy(base.Policy): class PlacementPolicy(base.Policy):
''' '''Policy for placing members of a cluster.
Policy for placing members of a cluster.
This policy is expected to be enforced before new member(s) added to an This policy is expected to be enforced before new member(s) added to an
existing cluster. existing cluster.

View File

@@ -16,8 +16,7 @@ from senlin.policies import base
class ScalingPolicy(base.Policy): class ScalingPolicy(base.Policy):
''' '''Policy for chaning the size of a cluster.
Policy for chaning the size of a cluster.
This policy is expected to be enforced before the member list of a cluster This policy is expected to be enforced before the member list of a cluster
is changed. is changed.

View File

@@ -15,8 +15,7 @@ from senlin.policies import base
class UpdatePolicy(base.Policy): class UpdatePolicy(base.Policy):
''' '''Policy for updating a cluster's node profile.
Policy for updating a cluster's node profile.
Note that we differentiate the updates to the size(scale) of a cluster from Note that we differentiate the updates to the size(scale) of a cluster from
the updates to the node profile. The former is handled by CreatePolicy, the updates to the node profile. The former is handled by CreatePolicy,

View File

@@ -17,8 +17,7 @@ __type_name__ = 'aws.autoscaling.launchconfig'
class LaunchConfigProfile(base.Profile): class LaunchConfigProfile(base.Profile):
''' '''Profile for an AWS AutoScaling LaunchConfiguration.
Profile for an AWS AutoScaling LaunchConfiguration.
When this profile is used, the whole cluster is a Heat stack where each When this profile is used, the whole cluster is a Heat stack where each
member is a YAML snippet that describes a member is a YAML snippet that describes a
@@ -44,9 +43,7 @@ class LaunchConfigProfile(base.Profile):
self.PlaementTenancy = kwargs.get('PlacementTenancy') self.PlaementTenancy = kwargs.get('PlacementTenancy')
def do_create(self): def do_create(self):
''' '''This method creates a YAML format Heat resource definition.'''
This method creates a YAML format Heat resource definition.
'''
return {} return {}
def do_delete(self): def do_delete(self):

View File

@@ -31,13 +31,11 @@ LOG = logging.getLogger(__name__)
class Profile(object): class Profile(object):
''' '''Base class for profiles.'''
Base class for profiles.
'''
def __new__(cls, type_name, name, **kwargs): def __new__(cls, type_name, name, **kwargs):
''' '''Create a new profile of the appropriate class.'''
Create a new profile of the appropriate class.
'''
if cls != Profile: if cls != Profile:
ProfileClass = cls ProfileClass = cls
else: else:
@@ -46,9 +44,8 @@ class Profile(object):
return super(Profile, cls).__new__(ProfileClass) return super(Profile, cls).__new__(ProfileClass)
def __init__(self, type_name, name, **kwargs): def __init__(self, type_name, name, **kwargs):
''' '''Initialize the profile with given parameters and a JSON object.'''
Initialize the profile with given parameters and a JSON object.
'''
self.name = name self.name = name
self.type = type_name self.type = type_name
self.id = kwargs.get('id', None) self.id = kwargs.get('id', None)
@@ -63,8 +60,8 @@ class Profile(object):
@classmethod @classmethod
def from_db_record(cls, context, record): def from_db_record(cls, context, record):
''' '''Construct a profile object from database record.
Construct a profile object from database record.
:param context: the context used for DB operations. :param context: the context used for DB operations.
:param record: a DB Profle object that contains all required fields. :param record: a DB Profle object that contains all required fields.
''' '''
@@ -83,18 +80,16 @@ class Profile(object):
@classmethod @classmethod
def load(cls, context, profile_id): def load(cls, context, profile_id):
''' '''Retrieve a profile object from database.'''
Retrieve a profile object from database.
'''
record = db_api.profile_get(context, profile_id) record = db_api.profile_get(context, profile_id)
return cls.from_db_record(context, record) return cls.from_db_record(context, record)
@classmethod @classmethod
def load_all(cls, context, limit=None, sort_keys=None, marker=None, def load_all(cls, context, limit=None, sort_keys=None, marker=None,
sort_dir=None, filters=None, show_deleted=False): sort_dir=None, filters=None, show_deleted=False):
''' '''Retrieve all profiles from database.'''
Retrieve all profiles from database.
'''
records = db_api.profile_get_all(context, limit=limit, marker=marker, records = db_api.profile_get_all(context, limit=limit, marker=marker,
sort_keys=sort_keys, sort_keys=sort_keys,
sort_dir=sort_dir, sort_dir=sort_dir,
@@ -109,9 +104,8 @@ class Profile(object):
db_api.profile_delete(context, profile_id) db_api.profile_delete(context, profile_id)
def store(self, context): def store(self, context):
''' '''Store the profile into database and return its ID.'''
Store the profile into database and return its ID.
'''
values = { values = {
'name': self.name, 'name': self.name,
'type': self.type, 'type': self.type,
@@ -141,27 +135,22 @@ class Profile(object):
return profile.do_update(obj, new_profile) return profile.do_update(obj, new_profile)
def do_create(self, obj): def do_create(self, obj):
''' '''For subclass to override.'''
For subclass to override.
'''
return NotImplemented return NotImplemented
def do_delete(self, obj): def do_delete(self, obj):
''' '''For subclass to override.'''
For subclass to override.
'''
return NotImplemented return NotImplemented
def do_update(self, obj, new_profile): def do_update(self, obj, new_profile):
''' '''For subclass to override.'''
For subclass to override.
'''
return NotImplemented return NotImplemented
def do_check(self, obj): def do_check(self, obj):
''' '''For subclass to override.'''
For subclass to override.
'''
return NotImplemented return NotImplemented
def healty_check(self, context): def healty_check(self, context):

View File

@@ -17,8 +17,8 @@ __type_name__ = 'os.heat.resource'
class ResourceProfile(base.Profile): class ResourceProfile(base.Profile):
''' '''Profile for an OpenStack Heat resource.
Profile for an OpenStack Heat resource.
When this profile is used, the whole cluster is Heat stack, composed When this profile is used, the whole cluster is Heat stack, composed
of resources initialzed from this profile. of resources initialzed from this profile.
''' '''
@@ -26,10 +26,6 @@ class ResourceProfile(base.Profile):
super(ResourceProfile, self).__init__(name, type_name, kwargs) super(ResourceProfile, self).__init__(name, type_name, kwargs)
def do_create(self): def do_create(self):
'''
A resource is represented as a YAML snippet that can be composed
into a Heat stack.
'''
return {} return {}
def do_delete(self, id): def do_delete(self, id):

View File

@@ -14,6 +14,7 @@ import six
from senlin.common import context from senlin.common import context
from senlin.common import exception from senlin.common import exception
from senlin.common.i18n import _
from senlin.drivers import heat_v1 as heatclient from senlin.drivers import heat_v1 as heatclient
from senlin.engine import scheduler from senlin.engine import scheduler
from senlin.openstack.common import log as logging from senlin.openstack.common import log as logging
@@ -23,8 +24,8 @@ LOG = logging.getLogger(__name__)
class StackProfile(base.Profile): class StackProfile(base.Profile):
''' '''Profile for an OpenStack Heat stack.
Profile for an OpenStack Heat stack.
When this profile is used, the whole cluster is a collection of Heat When this profile is used, the whole cluster is a collection of Heat
stacks. stacks.
''' '''
@@ -54,9 +55,8 @@ class StackProfile(base.Profile):
self.stack_id = None self.stack_id = None
def heat(self): def heat(self):
''' '''Construct heat client using the combined context.'''
Construct heat client using the combined context.
'''
if self.hc: if self.hc:
return self.hc return self.hc
@@ -69,9 +69,8 @@ class StackProfile(base.Profile):
return self.hc return self.hc
def do_validate(self, obj): def do_validate(self, obj):
''' '''Validate if the spec has provided info for stack creation.'''
Validate if the spec has provided reasonable info for stack creation.
'''
kwargs = { kwargs = {
'stack_name': obj.name, 'stack_name': obj.name,
'template': self.template, 'template': self.template,
@@ -117,9 +116,8 @@ class StackProfile(base.Profile):
reason=msg) reason=msg)
def do_create(self, obj): def do_create(self, obj):
''' '''Create a stack using the given profile.'''
Create a stack using the given profile.
'''
kwargs = { kwargs = {
'stack_name': obj.name, 'stack_name': obj.name,
'template': self.template, 'template': self.template,
@@ -160,7 +158,8 @@ class StackProfile(base.Profile):
return True return True
def do_update(self, obj, new_profile): def do_update(self, obj, new_profile):
''' '''Perform update on object.
:param obj: the node object to operate on :param obj: the node object to operate on
:param new_profile: the new profile used for updating :param new_profile: the new profile used for updating
''' '''

View File

@@ -58,21 +58,20 @@ class EngineClient(object):
return client.cast(ctxt, method, **kwargs) return client.cast(ctxt, method, **kwargs)
def local_error_name(self, error): def local_error_name(self, error):
""" '''Returns the name of the error with any _Remote postfix removed.
Returns the name of the error with any _Remote postfix removed.
:param error: Remote raised error to derive the name from. :param error: Remote raised error to derive the name from.
""" '''
error_name = error.__class__.__name__ error_name = error.__class__.__name__
return error_name.split('_Remote')[0] return error_name.split('_Remote')[0]
def ignore_error_named(self, error, name): def ignore_error_named(self, error, name):
""" '''Raises the error unless its local name matches the supplied name
Raises the error unless its local name matches the supplied name
:param error: Remote raised error to derive the local name from. :param error: Remote raised error to derive the local name from.
:param name: Name to compare local name to. :param name: Name to compare local name to.
""" '''
if self.local_error_name(error) != name: if self.local_error_name(error) != name:
raise error raise error
@@ -130,14 +129,13 @@ class EngineClient(object):
type_name=type_name)) type_name=type_name))
def identify_cluster(self, ctxt, cluster_name): def identify_cluster(self, ctxt, cluster_name):
""" '''Get the full cluster identifier for a single, live cluster given
The identify_cluster method returns the full cluster identifier for a the cluster name.
single, live cluster given the cluster name.
:param ctxt: RPC context. :param ctxt: RPC context.
:param cluster_name: Name of the cluster you want to see, :param cluster_name: Name of the cluster you want to see,
or None to see all or None to see all
""" '''
return self.call(ctxt, self.make_msg('identify_cluster', return self.call(ctxt, self.make_msg('identify_cluster',
cluster_name=cluster_name)) cluster_name=cluster_name))

View File

@@ -44,16 +44,11 @@ commands = python setup.py build_sphinx
# F812 list comprehension redefines variable # F812 list comprehension redefines variable
# H202 assertRaises Exception too broard # H202 assertRaises Exception too broard
# H233 Python 3.x incompatible use of print operator # H233 Python 3.x incompatible use of print operator
# H305 imports not grouped correctly
# H307 like imports should be grouped together # H307 like imports should be grouped together
# H402 one line docstring needs punctuation # H402 one line docstring needs punctuation
# H404 multi line docstring should start with a summary ignore = E251,E265,F402,F812,H202,H233,H307,H402
# H405 multi line docstring summary not separated with an empty line
# H803 no full stop at the end of the commit message
# H904 Wrap long lines in parentheses instead of a backslash
ignore = E251,E265,F402,F812,H202,H233,H305,H307,H402,H404,H405,H803,H904
show-source = true show-source = true
exclude=.venv,.git,.tox,dist,*openstack/common*,*lib/python*,*egg,tools,build exclude=.venv,.git,.tox,dist,*openstack/common*,*lib/python*,*egg,tools,build,*senlin/tests*
max-complexity=20 max-complexity=20
[hacking] [hacking]