Custom Search

Monday, July 7, 2014

OpenStack heat-api flow of stack-create action

#heat --os-username admin --os-password nova --os-tenant-name admin --os-auth-url http://192.168.56.102:35357/v2.0 --heat-url http://127.0.0.1:8004/v1/5864a59a240e4a43bc3c17fcbd6cfd83 --os-no-client-auth --debug stack-create stk1 -f https://raw.githubusercontent.com/openstack/heat-templates/master/hot/hello_world.yaml -P "db_password=P23456" -P "KeyName=k2" -P "ImageId=13ad8950-1f00-4587-8d3c-dd726265de08"

* Please note --heat-url http://127.0.0.1:8004/v1/5864a59a240e4a43bc3c17fcbd6cfd83

* "8004" is the port where "heat-api" is running

1)

/usr/lib/python2.7/dist-packages/heat/api/openstack/v1/__init__.py

from heat.api.openstack.v1 import stacks

class API(wsgi.Router):
    def __init__(self, conf, **local_conf):
   
        stacks_resource = stacks.create_resource(conf) <====IMP
       
        with mapper.submapper(controller=stacks_resource,
                              path_prefix="/{tenant_id}") as stack_mapper:   
   
            stack_mapper.connect("stack_create",
                                 "/stacks",
                                 action="create", <====IMP
                                 conditions={'method': 'POST'})


2)
/usr/lib/python2.7/dist-packages/heat/api/openstack/v1/stacks.py

def create_resource(options):
    return wsgi.Resource(StackController(options), deserializer, serializer)

class StackController(object):

    REQUEST_SCOPE = 'stacks'

    def __init__(self, options):
        self.options = options
        self.rpc_client = rpc_client.EngineClient() <====IMP

    @util.policy_enforce
    def create(self, req, body):
        """
        Create a new stack
        """
        data = InstantiationData(body)

        import pdb
        pdb.set_trace()

        result = self.rpc_client.create_stack(req.context,
                                              data.stack_name(),
                                              data.template(),
                                              data.environment(),
                                              data.files(),
                                              data.args())

        formatted_stack = stacks_view.format_stack(
            req,
            {engine_api.STACK_ID: result}
        )
        return {'stack': formatted_stack}

IMP (Debug)
===============

a)
Add pdb.set_trace()

b)
* Stop "heat-api"
#sudo service heat-api stop

c)
Start "heat-api" manually

#sudo /usr/bin/heat-api --config-file /etc/heat/heat.conf

d)
Run the "#heat create-stack" command and you can see the "pdb" prompt.

e)
(Pdb) req


(Pdb) req.context


(Pdb) req.context.request_id
'req-fb22b0df-d05a-4b35-9b73-f9300097e067'

(Pdb) dir(req.context)
blabla

-------

(Pdb) data


(Pdb) dir(data)
blabla

(Pdb) type(data.data)

* data.data will contains all data from the template

(Pdb) dir(req)
blabla

--------

(Pdb) self.rpc_client


(Pdb) dir(self.rpc_client)
blabla

--------

3)
/usr/lib/python2.7/dist-packages/heat/rpc/client.py

from heat.rpc import api
import heat.openstack.common.rpc.proxy

class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):

    def create_stack(self, ctxt, stack_name, template, params, files, args):
        return self.call(ctxt,
                         self.make_msg('create_stack', stack_name=stack_name,
                                       template=template,
                                       params=params, files=files, args=args))


3a)
/usr/lib/python2.7/dist-packages/heat/openstack/common/rpc/proxy.py

class RpcProxy(object):

    def call(self, context, msg, topic=None, version=None, timeout=None):
        """
        rpc.call() a remote method.
        :param context: The request context <===
        :param msg: The message to send, including the method and args. <===
        :param topic: Override the topic for this message.  <===
        """
        import pdb
        pdb.set_trace()
       
        real_topic = self._get_topic(topic)
        result = rpc.call(context, real_topic, msg, timeout)


    def multicall(self, context, msg, topic=None, version=None, timeout=None):
        """rpc.multicall() a remote method.""

    def cast(self, context, msg, topic=None, version=None):
        """rpc.cast() a remote method.""
       
    def fanout_cast(self, context, msg, topic=None, version=None):
        """rpc.fanout_cast() a remote method."""       
       
    def cast_to_server(self, context, server_params, msg, topic=None, version=None):
        """rpc.cast_to_server() a remote method."""

    def fanout_cast_to_server(self, context, server_params, msg, topic=None, version=None):
        """rpc.fanout_cast_to_server() a remote method."""

IMP (Debug)
===============


(Pdb) topic

(Pdb) real_topic
'engine' <===== IMP

(Pdb) context


(Pdb) context.request_id
'req-e979ea7d-d392-4a79-a6da-4c7a661cd2b7'

(Pdb) rpc


----

* Check the module level varibale "rpc_opts" of /usr/lib/python2.7/dist-packages/heat/openstack/common/rpc/__init__.py

(Pdb) rpc.rpc_opts
blabla

(Pdb) type(rpc.rpc_opts)


(Pdb) dir(rpc.rpc_opts[0])
blabla

(Pdb) [(x.name,x.default) for x in rpc.rpc_opts] <=== IMP

[
('rpc_backend', 'heat.openstack.common.rpc.impl_kombu'),  <===
('rpc_thread_pool_size', 64), ('rpc_conn_pool_size', 30),
('rpc_response_timeout', 60), ('rpc_cast_timeout', 30),
('allowed_rpc_exception_modules', ['nova.exception', 'cinder.exception', 'exceptions']),
('fake_rabbit', False), ('control_exchange', 'heat')
]

* Note the "rpc_backend"

------

* Check the module level varibale "CONF" of /usr/lib/python2.7/dist-packages/heat/openstack/common/rpc/__init__.py

(Pdb) rpc.CONF


(Pdb) dir(rpc.CONF)
blabla

##Get all registered Configs
(Pdb) from pprint import pprint as pp
(Pdb) pp(rpc.CONF.items()) <====

blabla

(Pdb) rpc.CONF.rpc_backend
'heat.openstack.common.rpc.impl_kombu'


* Note the "rpc_backend"

3b)
/usr/lib/python2.7/dist-packages/heat/openstack/common/rpc/__init__.py

from oslo.config import cfg

rpc_opts = [blabla] <====
CONF = cfg.CONF
CONF.register_opts(rpc_opts) <====

def cast(context, topic, msg):
def fanout_cast(context, topic, msg):
def multicall(context, topic, msg, timeout=None):
def notify(context, topic, msg, envelope=False):
def cast_to_server(context, server_params, topic, msg):
def fanout_cast_to_server(context, server_params, topic, msg):

def call(context, topic, msg, timeout=None):

    """
    Invoke a remote method that returns something.

    :param context: Information that identifies the user that has made this
                    request.
    :param topic: The topic to send the rpc message to.  This correlates to the
                  topic argument of
                  openstack.common.rpc.common.Connection.create_consumer()
                  and only applies when the consumer was created with
                  fanout=False.
    :param msg: This is a dict in the form { "method" : "method_to_invoke",
                                             "args" : dict_of_kwargs }
    """
    return _get_impl().call(CONF, context, topic, msg, timeout)


def _get_impl():
    _RPCIMPL = importutils.import_module(CONF.rpc_backend)
    return _RPCIMPL

* Note, here "CONF.rpc_backend" is 'heat.openstack.common.rpc.impl_kombu'

3c)
Since, "CONF.rpc_backend" is 'heat.openstack.common.rpc.impl_kombu'

http://kombu.readthedocs.org/en/latest/
http://kombu.readthedocs.org/en/latest/userguide/examples.html

/usr/lib/python2.7/dist-packages/heat/openstack/common/rpc/impl_kombu.py

import kombu
import kombu.connection
import kombu.entity
import kombu.messaging

from heat.openstack.common.rpc import amqp as rpc_amqp <===
from oslo.config import cfg

kombu_opts = [blabla] <===
cfg.CONF.register_opts(kombu_opts)

def call(conf, context, topic, msg, timeout=None):
    """Sends a message on a topic and wait for a response."""
    return rpc_amqp.call(
        conf, context, topic, msg, timeout,
        rpc_amqp.get_connection_pool(conf, Connection)) <===



def multicall(conf, context, topic, msg, timeout=None):
    """Make a call that returns multiple times."""

def cast(conf, context, topic, msg):
    """Sends a message on a topic without waiting for a response."""

def fanout_cast(conf, context, topic, msg):
    """Sends a message on a fanout exchange without waiting for a response."""

def cast_to_server(conf, context, server_params, topic, msg):
    """Sends a message on a topic to a specific server."""

def fanout_cast_to_server(conf, context, server_params, topic, msg):
    """Sends a message on a fanout exchange to a specific server."""

def notify(conf, context, topic, msg, envelope):
    """Sends a notification event on a topic."""

class Connection(object):
    blabla

3d)
/usr/lib/python2.7/dist-packages/heat/openstack/common/rpc/amqp.py

def multicall(conf, context, topic, msg, timeout, connection_pool):
    """Make a call that returns multiple times."""
    conn.topic_send(topic, rpc_common.serialize_msg(msg), timeout)

def call(conf, context, topic, msg, timeout, connection_pool):
    """Sends a message on a topic and wait for a response."""

def cast(conf, context, topic, msg, connection_pool):
    """Sends a message on a topic without waiting for a response."""

def fanout_cast(conf, context, topic, msg, connection_pool):
    """Sends a message on a fanout exchange without waiting for a response."""

def cast_to_server(conf, context, server_params, topic, msg, connection_pool):
    """Sends a message on a topic to a specific server."""

def fanout_cast_to_server(conf, context, server_params, topic, msg,
                          connection_pool):

def notify(conf, context, topic, msg, connection_pool, envelope):
    """Sends a notification event on a topic."""

4)
Learn kombu.

http://kombu.readthedocs.org/en/latest/
http://kombu.readthedocs.org/en/latest/userguide/examples.html


No comments:

Post a Comment