Cloudstack: API and Template Building Tip #1


The tip I have for you this time is to use CloudStacks interface for accessing meta-data about you instance from within the instance. It’s very simple to use and can be very useful. In this tip I’ll show how you can use the meta-data to rename a CentOS 6.4 linux instance automatically after it is created. But first lets introduce the meta-data interface for CloudStack.

To see what meta-data is available from within your instance, in this case linux, type:
“curl http:///latest/meta-data/” where the is your virtual router. And don’t forget the “/“ after meta-data.

curl http://<dhcp server>/latest/meta-data/
service-offering
availability-zone
local-ipv4
local-hostname
public-ipv4
public-hostname
instance-id
vm-id
public-keys
cloud-identifier

So you may be wondering how can we make use of this information. Well in order to get the information, lets say “local-hostname”, just type:

curl http://<dhcp server>/latest/meta-data/local-hostname
centos64_tmpl

Follow the same formatting to get any of the other meta-data from CloudStack. It doesn’t get any simpler than that. Now lets get to changing the name in the OS of our CentOS 6.4 instance. All of the following is done in my template.

First thing to do is find out what the dhcp server ip address is.
Second thing is to get the “local-hostname” using the method shown above.
Last thing is to change the hostname and reboot.

This is all shown in the a script I put together below. How to setup:

cp /usr/bin/cs_setinstancename.py
chmod +x /usr/bin/cs_setinstancename.py
vi /etc/rc.local and add /usr/bin/cs_setinstancename.py to the end of the file

Script “cs_setinstancename.py”

#! /usr/bin/env python
# Get the instance name from CloudStack and update instance
# How to setup
# cp /usr/bin/cs_setinstancename.py
# chmod +x /usr/bin/cs_setinstancename.py
# vi /etc/rc.local and add /usr/bin/cs_setinstancename.py to the end of the file
#

import os,sys
import pycurl

search = 'dhcp-server-identifier'
dhcpclient = open('/var/lib/dhclient/dhclient.leases').readlines()
netfile = open('/etc/sysconfig/network').readlines()


# Get and return the results from the CloudStack api for the local-hostname
class Results:
    def __init__(self):
        self.contents = ''

    def body_callback(self, buf):
        self.contents = self.contents + buf

# Change the local hostname of the instance if it's different from what's in Cloudstack
def changeName(oldname,newname):
	reboot = 0
	netfileupdate = open('/etc/sysconfig/network','w')
	for l in netfile:
		if oldname in l:
			print('Changed hostname.')
			netfileupdate.write(l.replace(oldname,newname))
			reboot = 1
		else:
			netfileupdate.write(l)
	netfileupdate.close()
	if reboot == 1:os.system('reboot')

# Get the current Cloudstack local hostname for the instance and compare it with the actual hostname in the OS.
def getName(dhcp_server):
	cs = Results()
	pycs = pycurl.Curl()
	#print('http://%s/latest/local-hostname' % dhcp_server)
	pycs.setopt(pycs.URL, 'http://%s/latest/local-hostname' % dhcp_server)
	pycs.setopt(pycs.WRITEFUNCTION, cs.body_callback)
	pycs.perform()
	pycs.close()

	if os.uname()[1].split('.')[0] == cs.contents.strip():pass
	else:
		oldname = os.uname()[1].split('.')[0]
		newname = cs.contents.strip()
		print('Need to change hostname')
		changeName(oldname, newname)

# Lets get started. Read the dhclient file to get the current dhcp (virual router) ip address for the instance
if __name__ == '__main__':
	for l in dhcpclient:
		if search in l:
			dhcp_server = l.split(" ")[-1].replace(';','').strip()
			#print(dhcp_server)
			getName(dhcp_server)
			break

 

Now every time you create an instance from this template the correct instance name will be changed in the OS. Just note that this check will happen every time the instance boots up.