basic OperationEngine service: Implement a runnable service
Implement a runnable service basic OperationEngine service. I take creating a scheduled_operation for an example. To show RPC call between api service and OperationEngine service. Change-Id: I24038513bdb545567b308a6daeac7b0d86d5e29e Closes-Bug: #1527097
This commit is contained in:
parent
62833b5d2b
commit
bcaa976c74
@ -18,6 +18,7 @@ ENABLED_SERVICES+=,c-api,c-vol,c-sch,c-bak,horizon
|
||||
|
||||
#Add the smaug services
|
||||
enable_service smaug-api
|
||||
enable_service smaug-operationengine
|
||||
|
||||
#disable the default services you don't want to use
|
||||
disable_service n-net
|
||||
|
@ -50,6 +50,7 @@ function configure_smaug_api {
|
||||
iniset $SMAUG_API_CONF DEFAULT use_syslog $SYSLOG
|
||||
echo "Configuring Smaug API Database"
|
||||
iniset $SMAUG_API_CONF database connection `database_connection_url smaug`
|
||||
iniset_rpc_backend smaug $SMAUG_API_CONF
|
||||
|
||||
setup_colorized_logging $SMAUG_API_CONF DEFAULT
|
||||
echo "Configuring Smaug API colorized"
|
||||
@ -113,6 +114,9 @@ if [[ "$Q_ENABLE_SMAUG" == "True" ]]; then
|
||||
if is_service_enabled smaug-api; then
|
||||
run_process smaug-api "$SMAUG_BIN_DIR/smaug-api --config-file $SMAUG_API_CONF"
|
||||
fi
|
||||
if is_service_enabled smaug-operationengine; then
|
||||
run_process smaug-operationengine "$SMAUG_BIN_DIR/smaug-operationengine --config-file $SMAUG_API_CONF"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$1" == "unstack" ]]; then
|
||||
@ -120,5 +124,8 @@ if [[ "$Q_ENABLE_SMAUG" == "True" ]]; then
|
||||
if is_service_enabled smaug-api; then
|
||||
stop_process smaug-api
|
||||
fi
|
||||
if is_service_enabled smaug-operationengine; then
|
||||
stop_process smaug-operationengine
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -21,3 +21,11 @@
|
||||
#auth_strategy = noauth
|
||||
#log_dir = /var/log/
|
||||
#rpc_backend = rabbit
|
||||
|
||||
#[database]
|
||||
#connection = mysql+pymysql://root:stackdb@127.0.0.1/smaug?charset=utf8
|
||||
|
||||
#[oslo_messaging_rabbit]
|
||||
#rabbit_userid = stackrabbit
|
||||
#rabbit_password = stackqueue
|
||||
#rabbit_hosts = 10.229.50.225
|
@ -33,7 +33,7 @@ data_files =
|
||||
console_scripts =
|
||||
smaug-api = smaug.cmd.api:main
|
||||
smaug-manage = smaug.cmd.manage:main
|
||||
|
||||
smaug-operationengine = smaug.cmd.operationengine:main
|
||||
smaug.database.migration_backend =
|
||||
sqlalchemy = oslo_db.sqlalchemy.migration
|
||||
|
||||
|
@ -19,7 +19,7 @@ from webob import exc
|
||||
|
||||
from smaug.api.openstack import wsgi
|
||||
from smaug.i18n import _LI
|
||||
|
||||
from smaug.operationengine import api as operationengine_api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -28,6 +28,7 @@ class PlansController(wsgi.Controller):
|
||||
"""The Plans API controller for the OpenStack API."""
|
||||
|
||||
def __init__(self):
|
||||
self.operationengine_api = operationengine_api.API()
|
||||
super(PlansController, self).__init__()
|
||||
|
||||
def show(self, req, id):
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
from smaug.api.openstack import ProjectMapper
|
||||
from smaug.api.v1 import plans
|
||||
from smaug.api.v1 import scheduled_operations
|
||||
from smaug.wsgi import common as wsgi_common
|
||||
|
||||
|
||||
@ -22,9 +23,13 @@ class APIRouter(wsgi_common.Router):
|
||||
|
||||
def __init__(self, mapper):
|
||||
plans_resources = plans.create_resource()
|
||||
scheduled_operation_resources = scheduled_operations.create_resource()
|
||||
mapper.resource("plan", "plans",
|
||||
controller=plans_resources,
|
||||
collection={'detail': 'GET'},
|
||||
member={'action': 'POST'})
|
||||
|
||||
mapper.resource("scheduled_operation", "scheduled_operations",
|
||||
controller=scheduled_operation_resources,
|
||||
collection={'detail': 'GET'},
|
||||
member={'action': 'POST'})
|
||||
super(APIRouter, self).__init__(mapper)
|
||||
|
100
smaug/api/v1/scheduled_operations.py
Normal file
100
smaug/api/v1/scheduled_operations.py
Normal file
@ -0,0 +1,100 @@
|
||||
# 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.
|
||||
|
||||
"""The ScheduledOperations api."""
|
||||
|
||||
|
||||
from oslo_log import log as logging
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from smaug.api.openstack import wsgi
|
||||
from smaug.i18n import _LI
|
||||
from smaug.operationengine import api as operationengine_api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ScheduledOperationsController(wsgi.Controller):
|
||||
"""The ScheduledOperations API controller for the OpenStack API."""
|
||||
|
||||
def __init__(self):
|
||||
self.operationengine_api = operationengine_api.API()
|
||||
super(ScheduledOperationsController, self).__init__()
|
||||
|
||||
def show(self, req, id):
|
||||
"""Return data about the given scheduled_operation."""
|
||||
context = req.environ['smaug.context']
|
||||
LOG.info(_LI("Show ScheduledOperation with id: %s"), id,
|
||||
context=context)
|
||||
# TODO(chenying)
|
||||
return {'Smaug': "ScheduledOperations show."}
|
||||
|
||||
def delete(self, req, id):
|
||||
"""Delete a scheduled_operation."""
|
||||
context = req.environ['smaug.context']
|
||||
|
||||
LOG.info(_LI("Delete ScheduledOperations with id: %s"), id,
|
||||
context=context)
|
||||
|
||||
# TODO(chenying)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
def index(self, req):
|
||||
"""Returns a summary list of ScheduledOperations."""
|
||||
|
||||
# TODO(chenying)
|
||||
|
||||
return {'scheduled_operation': "ScheduledOperations index."}
|
||||
|
||||
def detail(self, req):
|
||||
"""Returns a detailed list of ScheduledOperations."""
|
||||
|
||||
# TODO(chenying)
|
||||
|
||||
return {'scheduled_operation': "ScheduledOperations detail."}
|
||||
|
||||
def create(self, req, body):
|
||||
"""Creates a new ScheduledOperation."""
|
||||
|
||||
LOG.debug('Create ScheduledOperations request body: %s', body)
|
||||
context = req.environ['smaug.context']
|
||||
request_spec = {'resource': 'ScheduledOperations',
|
||||
'method': 'create'}
|
||||
self.operationengine_api.create_scheduled_operation(context,
|
||||
request_spec)
|
||||
LOG.debug('Create ScheduledOperations request context: %s', context)
|
||||
|
||||
# TODO(chenying)
|
||||
|
||||
return {'scheduled_operation': "Create a ScheduledOperation."}
|
||||
|
||||
def update(self, req, id, body):
|
||||
"""Update a scheduled_operation."""
|
||||
context = req.environ['smaug.context']
|
||||
|
||||
if not body:
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
|
||||
if 'scheduled_operation' not in body:
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
|
||||
scheduled_operation = body['scheduled_operation']
|
||||
|
||||
LOG.info(_LI("Update ScheduledOperation : %s"), scheduled_operation,
|
||||
context=context)
|
||||
|
||||
return {'scheduled_operation': "Update a ScheduledOperation."}
|
||||
|
||||
|
||||
def create_resource():
|
||||
return wsgi.Resource(ScheduledOperationsController())
|
42
smaug/cmd/operationengine.py
Normal file
42
smaug/cmd/operationengine.py
Normal file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
# 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.
|
||||
|
||||
"""Starter script for smaug OperationEngine."""
|
||||
|
||||
import eventlet
|
||||
eventlet.monkey_patch()
|
||||
|
||||
import sys
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from smaug import i18n
|
||||
i18n.enable_lazy()
|
||||
|
||||
# Need to register global_opts
|
||||
from smaug.common import config # noqa
|
||||
from smaug import service
|
||||
from smaug import version
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def main():
|
||||
CONF(sys.argv[1:], project='smaug',
|
||||
version=version.version_string())
|
||||
logging.setup(CONF, "smaug")
|
||||
server = service.Service.create(binary='smaug-operationengine')
|
||||
service.serve(server)
|
||||
service.wait()
|
@ -49,12 +49,12 @@ global_opts = [
|
||||
default=60,
|
||||
help='Maximum time since last check-in for a service to be '
|
||||
'considered up'),
|
||||
cfg.StrOpt('scheduler_topic',
|
||||
default='Smaug-scheduler',
|
||||
help='The topic that scheduler nodes listen on'),
|
||||
cfg.StrOpt('scheduler_manager',
|
||||
default='Smaug.scheduler.manager.SchedulerManager',
|
||||
help='Full class name for the Manager for scheduler'),
|
||||
cfg.StrOpt('operationengine_topic',
|
||||
default='smaug-operationengine',
|
||||
help='The topic that OperationEngine nodes listen on'),
|
||||
cfg.StrOpt('operationengine_manager',
|
||||
default='smaug.operationengine.manager.OperationEngineManager',
|
||||
help='Full class name for the Manager for OperationEngine'),
|
||||
cfg.StrOpt('host',
|
||||
default=socket.gethostname(),
|
||||
help='Name of this node. This can be an opaque identifier. '
|
||||
|
0
smaug/operationengine/__init__.py
Normal file
0
smaug/operationengine/__init__.py
Normal file
38
smaug/operationengine/api.py
Normal file
38
smaug/operationengine/api.py
Normal file
@ -0,0 +1,38 @@
|
||||
# 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.
|
||||
|
||||
"""Handles all requests relating to OperationEngine."""
|
||||
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from smaug.db import base
|
||||
from smaug.operationengine import rpcapi as operationengine_rpcapi
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class API(base.Base):
|
||||
"""API for interacting with the OperationEngine manager."""
|
||||
|
||||
def __init__(self, db_driver=None):
|
||||
self.operationengine_rpcapi = operationengine_rpcapi.\
|
||||
OperationEngineAPI()
|
||||
super(API, self).__init__(db_driver)
|
||||
|
||||
def create_scheduled_operation(self, context, request_spec):
|
||||
self.operationengine_rpcapi.create_scheduled_operation(context,
|
||||
request_spec)
|
42
smaug/operationengine/manager.py
Normal file
42
smaug/operationengine/manager.py
Normal file
@ -0,0 +1,42 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
OperationEngine Service
|
||||
"""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import oslo_messaging as messaging
|
||||
|
||||
from smaug import manager
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OperationEngineManager(manager.Manager):
|
||||
"""Smaug OperationEngine Manager."""
|
||||
|
||||
RPC_API_VERSION = '1.0'
|
||||
|
||||
target = messaging.Target(version=RPC_API_VERSION)
|
||||
|
||||
def __init__(self, service_name=None,
|
||||
*args, **kwargs):
|
||||
super(OperationEngineManager, self).__init__(*args, **kwargs)
|
||||
|
||||
def create_scheduled_operation(self, context, request_spec=None):
|
||||
LOG.debug("Received a rpc call from a api service."
|
||||
"request_spec:%s", request_spec)
|
51
smaug/operationengine/rpcapi.py
Normal file
51
smaug/operationengine/rpcapi.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Copyright 2012, Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Client side of the OperationEngine manager RPC API.
|
||||
"""
|
||||
|
||||
from oslo_config import cfg
|
||||
import oslo_messaging as messaging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from smaug import rpc
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class OperationEngineAPI(object):
|
||||
"""Client side of the OperationEngine rpc API.
|
||||
|
||||
API version history:
|
||||
|
||||
1.0 - Initial version.
|
||||
"""
|
||||
|
||||
RPC_API_VERSION = '1.0'
|
||||
|
||||
def __init__(self):
|
||||
super(OperationEngineAPI, self).__init__()
|
||||
target = messaging.Target(topic=CONF.operationengine_topic,
|
||||
version=self.RPC_API_VERSION)
|
||||
self.client = rpc.get_client(target, version_cap=None)
|
||||
|
||||
def create_scheduled_operation(self, ctxt, request_spec=None):
|
||||
request_spec_p = jsonutils.to_primitive(request_spec)
|
||||
cctxt = self.client.prepare(version='1.0')
|
||||
return cctxt.cast(
|
||||
ctxt,
|
||||
'create_scheduled_operation',
|
||||
request_spec=request_spec_p)
|
@ -48,7 +48,7 @@ service_opts = [
|
||||
cfg.IntOpt('periodic_fuzzy_delay',
|
||||
default=60,
|
||||
help='Range, in seconds, to randomly delay when starting the'
|
||||
' periodic task scheduler to reduce stampeding.'
|
||||
' periodic task OperationEngine to reduce stampeding.'
|
||||
' (Disable by setting to 0)'),
|
||||
cfg.StrOpt('osapi_smaug_listen',
|
||||
default="0.0.0.0",
|
||||
|
Loading…
x
Reference in New Issue
Block a user