Custom Search

Thursday, January 29, 2015

How to OpenStack load Drivers Extensions and Plugins using stevedore

1)
Create a virtual environment

#virtualenv venv
#source venv/bin/activate




2)
Install stevedore
#pip install stevedore

3)
Open Python console

#python
>>> from stevedore import driver
>>> p=driver.DriverManager(namespace="stevedore.example.formatter", name='simple')


* Means, load the driver "simple" from then namespace "stevedore.example.formatter"".

* "namespace" is defined in setup.py as "entry_points".
https://github.com/openstack/stevedore/blob/master/stevedore/example/setup.py

* Driver file "simple"
https://github.com/openstack/stevedore/blob/master/stevedore/example/simple.py

* For more info
http://docs.openstack.org/developer/stevedore/tutorial/creating_plugins.html

4)
"entry_points" from neutron project.
https://github.com/openstack/neutron/blob/master/setup.cfg

==== Custom Example=======

1)
Create a new project named "myproject" and create following files


a)
#setup.py


import setuptools
setuptools.setup(setup_requires=['pbr'], pbr=True)


b)

#setup.cfg

[metadata]
name = myproject

[files]
packages = myproject

[entry_points]
myproject.driver =
    simple_driver1 = myproject.my_driver:SimpleDriver1
    simple_driver2 = myproject.my_driver:SimpleDriver2

myproject.extension =
    simple_extension1 = myproject.my_extension:SimpleExtension1
    simple_extension2 = myproject.my_extension:SimpleExtension2


c)
Inside the "myproject" directory create an another directory with same name
and create following "my_driver.py" and "my_extension.py" files in it.

#mkdir myproject
#cd  myproject

d)
#vim my_driver.py


class SimpleDriver1:

    def get_name(self):
        return "This is SimpleDriver1"

class SimpleDriver2:

    def get_name(
self):
        return "This is SimpleDriver2"

      
e)
#vim my_extension.py


class SimpleExtension1:

    def get_name(
self):
        return "This is SimpleExtension1"

class SimpleExtension2:

    def get_name(
self):
        return "This is SimpleExtension2"


2)
Create a virtual environment

#virtualenv venv
#source venv/bin/activate


3)

Install stevedore
#pip install stevedore
     
4)
Goto "myproject" directory and install the project/module using setup.py script.
#cd myproject
#git init    
#python setup.py install    
  
      
5)
Goto python console, import stevedore and load the drivers and extensions from "myproject" module.

a)
Load the driver named "simple_driver1" and invokes the method "get_name"

>>> from stevedore import driver
>>> mydriver = driver.DriverManager(namespace="myproject.driver", name='simple_driver1')
>>> mydriver.driver
>>> mydriver.driver().get_name()
OR
>>> mydriver.extensions[0].plugin().get_name()


b)
Load all the extensions from the namespace "myproject.extension"

>>> from stevedore import extension
>>> extension = extension.ExtensionManager(namespace="myproject.extension")
>>> extension.extensions
>>> extension.extensions[0].plugin().get_name()
>>> extension.extensions[1].plugin().get_name()



Tuesday, January 27, 2015

Setting up Apt-Cache Server Using Apt-Cacher-NG Ubuntu

1)
Install apt-cacher-ng
#sudo apt-get install apt-cacher-ng

2)
Check CacheDir and LogDir

#sudo vim /etc/apt-cacher-ng/acng.conf

Example:
CacheDir: /var/cache/apt-cacher-ng
LogDir: /var/log/apt-cacher-ng

3)
Access the report page of apt-cacher-ng in web interface

http://192.168.56.101:3142

* Replace  "192.168.56.101" with IP of the machine where you installed "apt-cacher-ng"

4)
Create a apt.conf file with following content

#sudo vim /etc/apt/apt.conf
Acquire::http { Proxy "http://192.168.56.101:3142"; };


* Replace  "192.168.56.101" with IP of the machine where you installed "apt-cacher-ng"

5)
Install some software using apt-get.

#sudo apt-get install git

6)
Check the CacheDir

#ls /var/cache/apt-cacher-ng

==== Some Tips ====

a)
Restart apt-cacher-ng service

#sudo /etc/init.d/apt-cacher-ng restart

b)
http://www.tecmint.com/apt-cache-server-in-ubuntu/

c)
apt-get default cache location

#/var/cache/apt/archives/


How to https://review.openstack.org Find Jenkins FAILURE Causes

How to https://review.openstack.org Find Jenkins FAILURE Causes

1)
Select Patch under review


2)
Select the failed Jenkins Job


3)
Click on "console.html.gz"


4)
Search for "... FAILED"


5)
Copy the name of the test-case and search again to see the "traceback"
Example: test_snapshot_create_with_volume_in_use

Monday, January 26, 2015

Mocking Python builtin file open function

1)
Return custom text when invoking 'open("myfile.txt")'

>>>
>>> import mock
>>>
>>> open_mock = mock.mock_open(read_data='\nHello World\n')
>>>

>>>#* Here the target '__builtin__.open' is replaces with a new 'open_mock' object.
>>> with mock.patch('__builtin__.open', open_mock):
...     open("myfile.txt").read()

...
'\nHello World\n'
>>>
>>>


2)
Raise custom Exception when invoking 'open("myfile.txt")'
 
>>>
>>> with mock.patch('__builtin__.open') as open_mock:
...     open_mock.side_effect = IOError
...     open("myfile.txt").read()

...
Traceback (most recent call last):
  File "", line 3, in
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 955, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1010, in _mock_call
    raise effect
IOError
>>>
>>>



Python Standard errno system symbols

>>>
>>> import errno
>>>
>>> help(errno)

>>>
>>> errno.ENOENT
2
>>>
>>> errno.errorcode[2]
'ENOENT'
>>>
>>>
>>>
>>> import os
>>>
>>>
>>> os.strerror(2)
'No such file or directory'
>>>
>>>
>>> for x in range(140):
...     x, '-->', os.strerror(x)

...
(0, '-->', 'Success')
(1, '-->', 'Operation not permitted')
(2, '-->', 'No such file or directory')
(3, '-->', 'No such process')
(4, '-->', 'Interrupted system call')
(5, '-->', 'Input/output error')
(6, '-->', 'No such device or address')
(7, '-->', 'Argument list too long')
(8, '-->', 'Exec format error')
(9, '-->', 'Bad file descriptor')
(10, '-->', 'No child processes')
(11, '-->', 'Resource temporarily unavailable')
(12, '-->', 'Cannot allocate memory')
(13, '-->', 'Permission denied')
(14, '-->', 'Bad address')
(15, '-->', 'Block device required')
(16, '-->', 'Device or resource busy')
(17, '-->', 'File exists')
(18, '-->', 'Invalid cross-device link')
(19, '-->', 'No such device')
(20, '-->', 'Not a directory')
(21, '-->', 'Is a directory')
(22, '-->', 'Invalid argument')
(23, '-->', 'Too many open files in system')
(24, '-->', 'Too many open files')
(25, '-->', 'Inappropriate ioctl for device')
(26, '-->', 'Text file busy')
(27, '-->', 'File too large')
(28, '-->', 'No space left on device')
(29, '-->', 'Illegal seek')
(30, '-->', 'Read-only file system')
(31, '-->', 'Too many links')
(32, '-->', 'Broken pipe')
(33, '-->', 'Numerical argument out of domain')
(34, '-->', 'Numerical result out of range')
(35, '-->', 'Resource deadlock avoided')
(36, '-->', 'File name too long')
(37, '-->', 'No locks available')
(38, '-->', 'Function not implemented')
(39, '-->', 'Directory not empty')
(40, '-->', 'Too many levels of symbolic links')
(41, '-->', 'Unknown error 41')
(42, '-->', 'No message of desired type')
(43, '-->', 'Identifier removed')
(44, '-->', 'Channel number out of range')
(45, '-->', 'Level 2 not synchronized')
(46, '-->', 'Level 3 halted')
(47, '-->', 'Level 3 reset')
(48, '-->', 'Link number out of range')
(49, '-->', 'Protocol driver not attached')
(50, '-->', 'No CSI structure available')
(51, '-->', 'Level 2 halted')
(52, '-->', 'Invalid exchange')
(53, '-->', 'Invalid request descriptor')
(54, '-->', 'Exchange full')
(55, '-->', 'No anode')
(56, '-->', 'Invalid request code')
(57, '-->', 'Invalid slot')
(58, '-->', 'Unknown error 58')
(59, '-->', 'Bad font file format')
(60, '-->', 'Device not a stream')
(61, '-->', 'No data available')
(62, '-->', 'Timer expired')
(63, '-->', 'Out of streams resources')
(64, '-->', 'Machine is not on the network')
(65, '-->', 'Package not installed')
(66, '-->', 'Object is remote')
(67, '-->', 'Link has been severed')
(68, '-->', 'Advertise error')
(69, '-->', 'Srmount error')
(70, '-->', 'Communication error on send')
(71, '-->', 'Protocol error')
(72, '-->', 'Multihop attempted')
(73, '-->', 'RFS specific error')
(74, '-->', 'Bad message')
(75, '-->', 'Value too large for defined data type')
(76, '-->', 'Name not unique on network')
(77, '-->', 'File descriptor in bad state')
(78, '-->', 'Remote address changed')
(79, '-->', 'Can not access a needed shared library')
(80, '-->', 'Accessing a corrupted shared library')
(81, '-->', '.lib section in a.out corrupted')
(82, '-->', 'Attempting to link in too many shared libraries')
(83, '-->', 'Cannot exec a shared library directly')
(84, '-->', 'Invalid or incomplete multibyte or wide character')
(85, '-->', 'Interrupted system call should be restarted')
(86, '-->', 'Streams pipe error')
(87, '-->', 'Too many users')
(88, '-->', 'Socket operation on non-socket')
(89, '-->', 'Destination address required')
(90, '-->', 'Message too long')
(91, '-->', 'Protocol wrong type for socket')
(92, '-->', 'Protocol not available')
(93, '-->', 'Protocol not supported')
(94, '-->', 'Socket type not supported')
(95, '-->', 'Operation not supported')
(96, '-->', 'Protocol family not supported')
(97, '-->', 'Address family not supported by protocol')
(98, '-->', 'Address already in use')
(99, '-->', 'Cannot assign requested address')
(100, '-->', 'Network is down')
(101, '-->', 'Network is unreachable')
(102, '-->', 'Network dropped connection on reset')
(103, '-->', 'Software caused connection abort')
(104, '-->', 'Connection reset by peer')
(105, '-->', 'No buffer space available')
(106, '-->', 'Transport endpoint is already connected')
(107, '-->', 'Transport endpoint is not connected')
(108, '-->', 'Cannot send after transport endpoint shutdown')
(109, '-->', 'Too many references: cannot splice')
(110, '-->', 'Connection timed out')
(111, '-->', 'Connection refused')
(112, '-->', 'Host is down')
(113, '-->', 'No route to host')
(114, '-->', 'Operation already in progress')
(115, '-->', 'Operation now in progress')
(116, '-->', 'Stale NFS file handle')
(117, '-->', 'Structure needs cleaning')
(118, '-->', 'Not a XENIX named type file')
(119, '-->', 'No XENIX semaphores available')
(120, '-->', 'Is a named type file')
(121, '-->', 'Remote I/O error')
(122, '-->', 'Disk quota exceeded')
(123, '-->', 'No medium found')
(124, '-->', 'Wrong medium type')
(125, '-->', 'Operation canceled')
(126, '-->', 'Required key not available')
(127, '-->', 'Key has expired')
(128, '-->', 'Key has been revoked')
(129, '-->', 'Key was rejected by service')
(130, '-->', 'Owner died')
(131, '-->', 'State not recoverable')
(132, '-->', 'Operation not possible due to RF-kill')
(133, '-->', 'Memory page has hardware error')
(134, '-->', 'Unknown error 134')
(135, '-->', 'Unknown error 135')
(136, '-->', 'Unknown error 136')
(137, '-->', 'Unknown error 137')
(138, '-->', 'Unknown error 138')
(139, '-->', 'Unknown error 139')
>>>

Tuesday, January 20, 2015

How to Test and Debug OpenContrail APIs using OpenStack neutron Client

1)
Fire API request using OpenStack neutron Client

#neutron net-list

2)
Check OpenContrail API Log

#tail -f /var/log/contrail/contrail-api-0.log

3)
Check OpenContrail APIs

http://opencontrail-api-server:9100/
http://opencontrail-api-server:9100/xxxxx





Friday, January 16, 2015

How to debug OpenStack nova-api

How to debug OpenStack and EC2 APIs

1)
Find "nova-api" process and copy the command

#ps -aux | grep nova-api

2)
Stop "nova-api"

#sudo /etc/init.d/nova-api stop

3)
Add debug statements


a)
Debug EC2 API


Goto:
nova/api/ec2/cloud.py

Add pdb in "run_instances" method:
def run_instances:
    import pdb; pdb.set_trace()

   
b)
Debug OpenStack API


Goto:
nova/api/openstack/compute/servers.py

Add pdb in "create" method:

def create(self, req, body):
    import pdb; pdb.set_trace()


4)
Start "nova-api" using the command you copied

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

5)
Fire an EC2 or OpenStack API call and start debugging



Wednesday, January 14, 2015

OpenStack agens should use RPC to communicate with server

For example Neutron agens should use RPC to communicate with Neutron server.

Agent Push and Pull data from RPC queue (Eg:rabbitmq).

Some neutron agents
----------------------------------
neutron-dhcp-agent

neutron-l3-agent

neutron-metering-agent



Tuesday, January 13, 2015

OpenStack nova-api Find Process ID Ports and Files

OpenStack Services Find Process ID Ports and Files

1)
Find "nova-api" processes

#ps -aux | grep nova-api

2)
Find port number of a process

#sudo netstat -tuplen | grep [process-id]

3)
Find children of the process


#pstree -p [process-id]
OR
#ps --ppid [process-id]
OR
#cat /proc/[process-id]/task/[process-id]/children


4)
To list open files for a process

#ls -l /proc/[process-id]/fd
OR
#lsof -p [process-id]


5)
get a list of open files, sockets, and pipes for a process

#lsof -p [process-id]

6)
Find the files used to start the service using the PID.
#ps -f --pid  [process-id] | fold -s -w 80



Devstack Multinode with Neutron VirtualBox










OpenStack boto VPC example





import boto
import boto, boto.ec2
region = boto.ec2.regioninfo.RegionInfo(name="nova",endpoint="192.168.56.101")
print region
conn = boto.connect_vpc(aws_access_key_id="b56adadedd394b5f8093d4bdfe858bf8",
                        aws_secret_access_key="bf541989b3f845e88ff5e66b3e98dcbe",
                        is_secure=False,
                        region=region,
                        port=8773,
                        path="/services/Cloud")

#print dir(conn)
print conn.get_all_vpcs()



Friday, January 9, 2015

Convert XML HTML Entities into Unicode String in Python

1)
Goto Python console and Open XML or HTML file
>>> fp = open("myfile.html")

2)
Read it 
>>> content = fp.read()

3)
Convert
>>> u_content = unicode(content, 'utf-8')

4)
Print and copy
>>> u_content





Thursday, January 8, 2015

Rspec puppet tests

OpenStack Heat VPC Resources (Virtual Private Cloud)

0)
a) CreateVPC == Create Virtual Network

b) CreateSubnet == Create Subnet in Virtual Network(VPC)

c) CreateInternetGateway == Get external network defined in the Project

d) AttachInternetGateway ==  Connect external network to routers in the Virtual Network(VPC)

e) CreateRouteTable == Create a router and attach to Virtual Network(VPC)

f) AssociateRouteTable == Attach subnet to router

g) CreateEIP == Attach floating ip to instance



1)
heat/heat/engine/resource.py


class Resource(object):
    @scheduler.wrappertask
    def create(self):
        '''
        Create the resource. Subclasses should provide a handle_create() method
        to customise creation.
        '''

    @scheduler.wrappertask
    def update(self, after, before=None, prev_resource=None):
        '''
        update the resource. Subclasses should provide a handle_update() method
        to customise update, the base-class handle_update will fail by default.
        '''
       
    def resource_id_set(self, inst):
        self.resource_id = inst

    def action_handler_task(self, action, args=[], action_prefix=None):
        '''
        A task to call the Resource subclass's handler methods for an action.

        Calls the handle_() method for the given action and then calls
        the check__complete() method with the result in a loop until it
        returns True. If the methods are not provided, the call is omitted.

        Any args provided are passed to the handler.

        If a prefix is supplied, the handler method handle__()
        is called instead.
        '''

    def physical_resource_name(self):
        name = '%s-%s-%s' % (self.stack.name,
                             self.name,
                             short_id.get_id(self.id))
        return name

    def neutron(self):
        return self.client('neutron')

2)
heat/heat/engine/resources/vpc.py


class VPC(resource.Resource):

    PROPERTIES = (
        CIDR_BLOCK, INSTANCE_TENANCY, TAGS,
    ) = (
        'CidrBlock', 'InstanceTenancy', 'Tags',
    )

    properties_schema = { .... }

    def handle_create(self):
        client = self.neutron()
        # The VPC's net and router are associated by having identical names.
        net_props = {'name': self.physical_resource_name()}
        router_props = {'name': self.physical_resource_name()}
        net = client.create_network({'network': net_props})['network']
        self.resource_id_set(net['id'])
        client.create_router({'router': router_props})['router']

    def check_create_complete(self, *args):
        ....
       
    def handle_delete(self):
        ....
       
    def resource_mapping():        return {
            'AWS::EC2::VPC': VPC,
        }

3)
heat/heat/engine/resources/subnet.py


class Subnet(resource.Resource):

    PROPERTIES = (
        AVAILABILITY_ZONE, CIDR_BLOCK, VPC_ID, TAGS,
    ) = (
        'AvailabilityZone', 'CidrBlock', 'VpcId', 'Tags',
    )

    properties_schema = { .... }
   
    def handle_create(self):

        client = self.neutron()
        # TODO(sbaker) Verify that this CidrBlock is within the vpc CidrBlock
        network_id = self.properties.get(self.VPC_ID)
        props = {
            'network_id': network_id,
            'cidr': self.properties.get(self.CIDR_BLOCK),
            'name': self.physical_resource_name(),
            'ip_version': 4
        }
        subnet = client.create_subnet({'subnet': props})['subnet']
        self.resource_id_set(subnet['id'])
        router = vpc.VPC.router_for_vpc(self.neutron(), network_id)
        if router:
            client.add_interface_router(
                router['id'],
                {'subnet_id': subnet['id']})
       
    def handle_delete(self):
        ....   
   
    def resource_mapping():
        return {
            'AWS::EC2::Subnet': Subnet,
        }

4)
heat/heat/engine/resources/route_table.py


class RouteTable(resource.Resource):

    PROPERTIES = (
        VPC_ID, TAGS,
    ) = (
        'VpcId', 'Tags',
    )

    properties_schema = { .... }

    def handle_create(self):
        client = self.client()
        props = {'name': self.physical_resource_name()}
        router = client.create_router({'router': props})['router']
        self.resource_id_set(router['id'])

    def check_create_complete(self, *args):
        client.add_gateway_router(self.resource_id, {
                        'network_id': external_network_id})
        return True
       
    def handle_delete(self):
        ....


class SubnetRouteTableAssociation(resource.Resource):

    PROPERTIES = (
        ROUTE_TABLE_ID, SUBNET_ID,
    ) = (
        'RouteTableId', 'SubnetId',
    )

    properties_schema = { .... }

    def handle_create(self):
        client = self.client()
        subnet_id = self.properties.get(self.SUBNET_ID)
        router_id = self.properties.get(self.ROUTE_TABLE_ID)
        #remove the default router association for this subnet.
        try:
            previous_router = self._router_for_subnet(subnet_id)
            if previous_router:
                client.remove_interface_router(
                    previous_router['id'],
                    {'subnet_id': subnet_id})
        except Exception as ex:
            self.client_plugin().ignore_not_found(ex)

        client.add_interface_router(
            router_id, {'subnet_id': subnet_id})
       
    def handle_delete(self):
        ....   


def resource_mapping():
    return {
        'AWS::EC2::RouteTable': RouteTable,
        'AWS::EC2::SubnetRouteTableAssociation': SubnetRouteTableAssociation,
    }

5)
heat/heat/engine/resources/internet_gateway.py


class InternetGateway(resource.Resource):


    PROPERTIES = (
        TAGS,
    ) = (
        'Tags',
    )

    properties_schema = { .... }

    def handle_create(self):
        self.resource_id_set(self.physical_resource_name())

    def handle_delete(self):
        pass

    @staticmethod
    def get_external_network_id(client):
        ext_filter = {'router:external': True}
        ext_nets = client.list_networks(**ext_filter)['networks']
        if len(ext_nets) != 1:
            # TODO(sbaker) if there is more than one external network
            # add a heat configuration variable to set the ID of
            # the default one
            raise exception.Error(
                _('Expected 1 external network, found %d') % len(ext_nets))
        external_network_id = ext_nets[0]['id']
        return external_network_id

class VPCGatewayAttachment(resource.Resource):

    PROPERTIES = (
        VPC_ID, INTERNET_GATEWAY_ID, VPN_GATEWAY_ID,
    ) = (
        'VpcId', 'InternetGatewayId', 'VpnGatewayId',
    )

    properties_schema = { .... }

    def handle_create(self):
        client = self.neutron()
        external_network_id = InternetGateway.get_external_network_id(client)
        for router in self._vpc_route_tables():
            client.add_gateway_router(router.resource_id, {
                'network_id': external_network_id})

    def handle_delete(self):
        .... 

    def resource_mapping():
        return {
            'AWS::EC2::InternetGateway': InternetGateway,
            'AWS::EC2::VPCGatewayAttachment': VPCGatewayAttachment,
        }

6)
heat/heat/engine/resources/eip.py

class ElasticIp(resource.Resource):


    PROPERTIES = (
        DOMAIN, INSTANCE_ID,
    ) = (
        'Domain', 'InstanceId',
    )

    properties_schema = { .... }

    def handle_create(self):
        """Allocate a floating IP for the current tenant."""
        ips = None
        if self.properties[self.DOMAIN]:
            from heat.engine.resources import internet_gateway

            ext_net = internet_gateway.InternetGateway.get_external_network_id(
                self.neutron())
            props = {'floating_network_id': ext_net}
            ips = self.neutron().create_floatingip({
                'floatingip': props})['floatingip']
            self.ipaddress = ips['floating_ip_address']
            self.resource_id_set(ips['id'])
            LOG.info(_LI('ElasticIp create %s'), str(ips))
        else:
            try:
                ips = self.nova().floating_ips.create()
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    if self.client_plugin('nova').is_not_found(e):
                        LOG.error(_LE("No default floating IP pool configured."
                                      " Set 'default_floating_pool' in "
                                      "nova.conf."))

            if ips:
                self.ipaddress = ips.ip
                self.resource_id_set(ips.id)
                LOG.info(_LI('ElasticIp create %s'), str(ips))

        instance_id = self.properties[self.INSTANCE_ID]
        if instance_id:
            server = self.nova().servers.get(instance_id)
            server.add_floating_ip(self._ipaddress())

    def handle_delete(self):
        .... 


class ElasticIpAssociation(resource.Resource):
    PROPERTIES = (
        INSTANCE_ID, EIP, ALLOCATION_ID, NETWORK_INTERFACE_ID,
    ) = (
        'InstanceId', 'EIP', 'AllocationId', 'NetworkInterfaceId',
    )

    properties_schema = { .... }

    def handle_create(self):
        """Add a floating IP address to a server."""
        if self.properties[self.EIP]:
            server = self.nova().servers.get(self.properties[self.INSTANCE_ID])
            server.add_floating_ip(self.properties[self.EIP])
            self.resource_id_set(self.properties[self.EIP])
            LOG.debug('ElasticIpAssociation '
                      '%(instance)s.add_floating_ip(%(eip)s)',
                      {'instance': self.properties[self.INSTANCE_ID],
                       'eip': self.properties[self.EIP]})
        elif self.properties[self.ALLOCATION_ID]:
            ni_id = self.properties[self.NETWORK_INTERFACE_ID]
            instance_id = self.properties[self.INSTANCE_ID]
            port_id, port_rsrc = self._get_port_info(ni_id, instance_id)
            if not port_id or not port_rsrc:
                LOG.warn(_LW('Skipping association, resource not specified'))
                return

            float_id = self.properties[self.ALLOCATION_ID]
            network_id = port_rsrc['network_id']
            self._neutron_add_gateway_router(float_id, network_id)

            self._neutron_update_floating_ip(float_id, port_id)

            self.resource_id_set(float_id)

    def handle_delete(self):
        .... 

    def resource_mapping():
        return {
            'AWS::EC2::EIP': ElasticIp,
            'AWS::EC2::EIPAssociation': ElasticIpAssociation,
        }

7)
heat/heat/tests/test_vpc.py


class VPCTestBase(common.HeatTestCase):

class VPCTest(VPCTestBase):

class SubnetTest(VPCTestBase):

class NetworkInterfaceTest(VPCTestBase):

class InternetGatewayTest(VPCTestBase):

class RouteTableTest(VPCTestBase):

8)
heat/heat/tests/test_eip.py


class EIPTest(common.HeatTestCase):

class AllocTest(common.HeatTestCase):

Tuesday, January 6, 2015

How to OpenStack Create Blueprint and Submit Patch Set

http://docs.openstack.org/training-guides/content/operator-getting-started-lab.html

https://wiki.openstack.org/wiki/Gerrit_Workflow

1)
* Install git and pip

#sudo apt-get install git
#sudo apt-get install python-pip




2)
* Install git-review

#sudo pip install git-review

3)
* Configure github


#git config -l

#git config --global user.name "Saju Madhavan"
#git config --global user.email "sajuptpm@gmail.com"
#git config --global core.editor "vim"

#git config -l


4)
Clone the project

#git clone https://github.com/openstack/neutron.git

5)
Goto project folder
#cd neutron

6)
* Test the ssh key setup


#git review -s
Enter your gerrit username: sajuptpm

7)
Goto Your Blueprint

https://blueprints.launchpad.net/neutron/+spec/opencontrail-ipam-extension

8)
Create a new git branch for your blueprint changes

#cd neutron
#git checkout -b blueprint/opencontrail-ipam-extension


9)
Confirm the branch

#git branch

11)
Make your changes and run unittest and pep8 test.


12)
Commit your changes

#git add file1 file2
#git commit -a


... commit message ...
....
....
Implements: blueprint opencontrail-ipam-extension

13)
Push changes to https://review.openstack.org

#git review

14)
Resubmit same patch after some modification
Run unit test and pep8 test.

#git commit -a --amend

15)
Push new changes to https://review.openstack.org

#git review

Thursday, January 1, 2015

How to Fix Patch in Merge Conflict https://review.openstack.org using checkout and rebase

1)
Clone the master branch of the project from github

#git clone https://github.com/stackforge/puppet-heat.git

2)
#cd puppet-heat



3)
Goto https://review.openstack.org/#/c/104795/
Click on "checkout" button and copy the link
Add " -b conflict_fix_branch" at the end of the link
#git fetch https://sajuptpm@review.openstack.org/stackforge/puppet-heat refs/changes/95/104795/4 && git checkout FETCH_HEAD -b conflict_fix_branch

4)
Confirm that you are in "conflict_fix_branch" branch

#git branch

5)
Run rebase

#git rebase -i master

6)
Fix the conflict


A conflict-marked area begins with <<<<<<< and ends with >>>>>>>.
These are also known as the conflict markers.
The two conflicting blocks themselves are divided by a =======.

<<<<<<< HEAD
     Changes in the 'master' branch.
=======
    Chnages in the working branch, Eg:conflict_fix_branch
>>>>>>> conflict_fix_branch

7)
Prepare the resolved files for commit

#git add name_of_modified_file(s)

8)
Continue rebase

#git rebase --continue

9)
Push the changes

#git review