Showing posts with label nova. Show all posts
Showing posts with label nova. Show all posts

Tuesday, September 30, 2014

Using python to connect remotely to Openstack

In order to beef up my DevOps skills I decided to see if I could connect through a REST API using python. I found out that there are some python modules built specifically for this.

One such module is called novaclient. You would need pip on your machine to do this.

sudo easy_install pip


Then you can use pip to install the nova client.

sudo pip install python-novaclient


If you want to look at the details of the python module it can be found here:

https://github.com/openstack/python-novaclient

This is where I look more into the code and found out it’s capabilities

You can pass parameters to the “client” function.

def __init__(self, username=None, api_key=None, project_id=None,
auth_url=None, insecure=False, timeout=None,
proxy_tenant_id=None, proxy_token=None, region_name=None,
endpoint_type='publicURL', extensions=None,
service_type='compute', service_name=None,
volume_service_name=None, timings=False, bypass_url=None,
os_cache=False, no_cache=True, http_log_debug=False,
auth_system='keystone', auth_plugin=None, auth_token=None,
cacert=None, tenant_id=None, user_id=None,
connection_pool=False, session=None, auth=None,
completion_cache=None):

First I built a login function that will pass these parameters which I can call from my main script.


login.py
-----------
def get_nova_credentials():
 cred =  {}
 cred['username'] = "admin"
 cred['api_key'] = “password”
 cred['auth_url'] = "http://<openstack-ip>:5000/v2.0"
 cred['project_id'] = "demo"
 cred['service_type'] = "compute"
 return cred

Now in my main script I can import the client and my credentials

server-list.py
-----------------
#!/usr/bin/env python

import novaclient
from novaclient.v1_1 import client
from login import get_nova_credentials
credentials = get_nova_credentials()

#Pass credentials to the client function.

nova = client.Client(**credentials)

#grab the list of servers and print out the id, names and status

vms = nova.servers.list(detailed=True)
for vm in vms:
  print vm.id, vm.name, vm.status

—————
script in action.

laptop$ python server-list.py 
f5801333-5d81-496c-b257-e589ca36e944 Cirros-VM2 ACTIVE
098270e0-e5fb-4ea6-a1f1-2dfca11a409d Cirros-VM1 ACTIVE

So what's the big deal? Why do this when you can use the Horizon web ui?



Now that I have a basic understanding of this module, I can start automating things such as building VMs, virtual networks, etc in a scaled and precise manner.



Wednesday, August 20, 2014

Another way to delete a VM instance in Openstack

For some reason I could not delete a VM in my Openstack Cloud Platform. I tried to terminate the instance in the Horizon GUI but that did not work. I also tried to do it from the cli via:

# nova delete <uuid>

That did not work either. So I researched in on the web and noticed that the instances are kept in two places. The first place is in the nova directory:

/var/lib/nova/instances
[root@sdnnode2 instances]# ls
51426435-9f72-4077-91a4-6c89ea53894f 58fd794e-048a-4135-b064-17fb6bb3682b  bbc44d49-62f7-4cdc-8e7f-564190c6f043  locks _base d0ce9950-752c-406f-91e0-3bd0ff0f488d  snapshots

looking into those uuid directory names contained the following:

[root@sdnnode2 51426435-9f72-4077-91a4-6c89ea53894f]# ls
console.log  disk  libvirt.xml

However deleting these files still would not delete the VM from appearing in the Horizon GUI. These are the files that Openstack would use to spin up the VM.

The vm existed in MySQL.

I found a handy sql_guide to brush me up on SQL commands. Then I had to access the SQL server with the correct credentials. If you don't remember it you can find it in the nova.conf file located in:

/etc/nova/nova.conf

[root@sdnnode2 nova]# cat nova.conf | grep sql
sql_connection = mysql://nova:<mypassword>@10.161.38.4/nova

Then to access the SQL server:
[root@sdnnode2 nova]# sudo mysql -u nova -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 166
Server version: 5.1.73 Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

show databases gives us.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| nova               |
| test               |
+--------------------+



mysql> use nova;

 Database changed
mysql> show tables;
+--------------------------------------------+
| Tables_in_nova                             |
+--------------------------------------------+
| agent_builds                               |
| aggregate_hosts                            |
| aggregate_metadata                         |
| aggregates                                 |
| block_device_mapping                       |
| bw_usage_cache                             |
<TRUNCATED>
| volume_usage_cache                         |
| volumes                                    |
+--------------------------------------------+
115 rows in set (0.00 sec)


Here we can then find the instance uuid. First you could figure out the fields in a particular table:


mysql> describe key_pairs;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| created_at  | datetime     | YES  |     | NULL    |                |
| updated_at  | datetime     | YES  |     | NULL    |                |
| deleted_at  | datetime     | YES  |     | NULL    |                |
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| name        | varchar(255) | YES  |     | NULL    |                |
| user_id     | varchar(255) | YES  | MUL | NULL    |                |
| fingerprint | varchar(255) | YES  |     | NULL    |                |
| public_key  | mediumtext   | YES  |     | NULL    |                |
| deleted     | int(11)      | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)



Then you can list the objects that are in the field you are searching.

mysql> select name from key_pairs;
+----------+
| name     |
+----------+
| my-key   |
| root-key |
+----------+
2 rows in set (0.00 sec)


I found out there are 5 tables you need to modify to get delete the VM and the should be done in this order:
security_group_instance_association
block_device_mapping
instance_info_caches
fixed_ips
instances

So I needed to find the uuid of the VM I was going to delete.

mysql> select uuid,hostname from instances where deleted=0;
+--------------------------------------+-----------+
| uuid                                 | hostname  |
+--------------------------------------+-----------+
| bbc44d49-62f7-4cdc-8e7f-564190c6f043 | right-vm1 |
| d0ce9950-752c-406f-91e0-3bd0ff0f488d | left-vm1  |
| 51426435-9f72-4077-91a4-6c89ea53894f | test-vm    |
| 58fd794e-048a-4135-b064-17fb6bb3682b | left-vm2  |
+--------------------------------------+-----------+
4 rows in set (0.00 sec)

I then started my process. I checked to see if the instance was not already marked deleted by checking for the condition of "deleted=0";

mysql> select instance_uuid from security_group_instance_association where deleted=0;
Empty set (0.00 sec)

I didn't have a security group association so I proceeded with the next step.

mysql>  DELETE FROM block_device_mapping WHERE instance_uuid = "51426435-9f72-4077-91a4-6c89ea53894f";


Query OK, 1 row affected (0.00 sec)


I then followed the other steps

mysql> select instance_uuid from instance_info_caches where deleted=0;
DELETE FROM instance_info_caches WHERE instance_uuid = "51426435-9f72-4077-91a4-6c89ea53894f";
Query OK, 1 row affected (0.00 sec)

mysql>select instance_uuid from fixed_ips where deleted=0;
Empty set (0.00 sec)

I didn't have a fixed_ip so I went to the last step, which was to changed the "deleted" field.
You need to make sure the deleted number matches the id.

mysql> select id,deleted,uuid from instances;
+----+---------+--------------------------------------+
| id | deleted | uuid                                 |
+----+---------+--------------------------------------+
| 31 |      31 | 028ff14b-55f2-4aa2-8fd9-37d70ff26a3b |
| 11 |      11 | 4c60dd0a-ae81-45e0-931b-c996e89b10d7 |
| 47 |      47 | 4ca2687f-35a4-4248-9777-24d9317e4c20 |
| 25 |      25 | 512747be-b608-423e-ac81-54f2ebcd7e58 |
| 35 |      0 | 51426435-9f72-4077-91a4-6c89ea53894f |

mysql> UPDATE instances SET deleted = 40 where uuid = "51426435-9f72-4077-91a4-6c89ea53894f";Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select id,deleted,uuid from instances;
+----+---------+--------------------------------------+
| id | deleted | uuid                                 |
+----+---------+--------------------------------------+
| 31 |      31 | 028ff14b-55f2-4aa2-8fd9-37d70ff26a3b |
| 11 |      11 | 4c60dd0a-ae81-45e0-931b-c996e89b10d7 |
| 47 |      47 | 4ca2687f-35a4-4248-9777-24d9317e4c20 |
| 25 |      25 | 512747be-b608-423e-ac81-54f2ebcd7e58 |
| 35 |      35 | 51426435-9f72-4077-91a4-6c89ea53894f |


Finally the instance was no longer in my Openstack server.

[root@sdnserver1 nova]# nova show 51426435-9f72-4077-91a4-6c89ea53894f
ERROR: No server with a name or ID of '51426435-9f72-4077-91a4-6c89ea53894f' exists.




Tuesday, May 6, 2014

Doing reverse lookups of information in order to find things in Openstack

One of the most annoying things I find in Openstack is the lack of use of user friendly names. It's very tedious to reverse lookup information for troubleshooting and configuration.

For example, say I want to find out which tap port on my VM is connected to an openvswitch bridge. I would have to look up the VM in nova and find the corresponding IP assigned to it.

[root@centos-6-5-openstack ~(keystone_admin)]# nova list
+--------------------------------------+------+--------+------------+-------------+---------------------+
| ID                                   | Name | Status | Task State | Power State | Networks            |
+--------------------------------------+------+--------+------------+-------------+---------------------+
| 8b3ecae9-7b59-4b6f-a0a0-bbd5ab5aa629 | aa   | ACTIVE | -          | Running     | net1=192.168.251.10 |

| a679f6f9-bd7d-4e31-95a6-9776c44f0a4a | bb   | ACTIVE | -          | Running     | net1=192.168.251.12 |

Then I would list the ports in neutron.

[root@centos-6-5-openstack ~(keystone_admin)]# neutron port-list
+--------------------------------------+-------------+-------------------+---------------------------------------------------------------------------------------+
| id                                   | name        | mac_address       | fixed_ips                                                                             |
+--------------------------------------+-------------+-------------------+---------------------------------------------------------------------------------------+
| 014d6bba-7ab9-4028-9cd9-dbe27bd51b83 |             | fa:16:3e:1b:19:7d | {"subnet_id": "8942189b-8fbf-44e9-adbb-d62dd0d27015", "ip_address": "192.168.250.10"} |
| 1d3246d7-adb1-4b18-a911-b36562c278e0 |             | fa:16:3e:bd:e9:69 | {"subnet_id": "0147052f-2a0b-4a5b-9930-1d4e258e0c1a", "ip_address": "192.168.251.10"} |
| 40b988aa-c016-4e85-b9cf-beeb4332ab04 |             | fa:16:3e:e1:7e:57 | {"subnet_id": "0147052f-2a0b-4a5b-9930-1d4e258e0c1a", "ip_address": "192.168.251.12"} |
| cb867d96-a4ed-449d-a35a-f3670a14e710 |             | fa:16:3e:ce:a5:7e | {"subnet_id": "0147052f-2a0b-4a5b-9930-1d4e258e0c1a", "ip_address": "192.168.251.11"} |
| d267267b-5630-43df-8a07-05793fd831d0 |             | fa:16:3e:61:84:91 | {"subnet_id": "8942189b-8fbf-44e9-adbb-d62dd0d27015", "ip_address": "192.168.250.11"} |
| f434c257-5bbf-42a6-9136-072d1104fa19 |               | fa:16:3e:24:18:08 | {"subnet_id": "0147052f-2a0b-4a5b-9930-1d4e258e0c1a", "ip_address": "192.168.251.1"}  |

+--------------------------------------+-------------+-------------------+---------------------------------------------------------------------------------------+

Next I would need to look at the mac address and do a lookup in ip address

After coming through the list I can then verify the tap address with ip address show tapxxxx

[root@centos-6-5-openstack ~(keystone_admin)]# ip a show tap40b988aa-c0
30: tap40b988aa-c0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500
    link/ether fe:16:3e:e1:7e:57 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc16:3eff:fee1:7e57/64 scope link 
       valid_lft forever preferred_lft forever


And now I can do something useful like see which bridge the tap interface belongs to and verify the mac in the mac table.

[root@centos-6-5-openstack ~(keystone_admin)]# brctl show
bridge name bridge id STP enabled interfaces
qbr1d3246d7-ad 8000.4a04d0b90d18 no qvb1d3246d7-ad
tap1d3246d7-ad
qbr40b988aa-c0 8000.de752effa37c no qvb40b988aa-c0
tap40b988aa-c0
qbr7316a274-16 8000.8671bda4d699 no qvb7316a274-16
tap7316a274-16
qbrd06fccba-ad 8000.4613c3848432 no qvbd06fccba-ad
tapd06fccba-ad
[root@centos-6-5-openstack ~(keystone_admin)]# brctl showmacs qbr40b988aa-c0
port no mac addr is local? ageing timer
  1 de:75:2e:ff:a3:7c yes   0.00
  2 fe:16:3e:e1:7e:57 yes   0.00

or look at the openvswitch table and find out which bridge it belongs to

[root@centos-6-5-openstack ~(keystone_admin)]# ovs-vsctl list-ifaces br-int
int-br-ex
qr-87202226-14
qr-ba3e1c3b-49
qr-f2b01b2b-ad
qr-f434c257-5b
qvo1d3246d7-ad
qvo40b988aa-c0
qvo7316a274-16
qvod06fccba-ad
tapafe229a7-2e
tapca265ec6-29
tapcb867d96-a4
tape4751034-2c


This looks like a to do scripting project to get this information. 

Here I could create a table that would give me:

Nova ID
VM name
VM IP
VM Mac address
Neutron ID
tap interface
bridge mac table
openvswitch bridge