Home > Articles > Web Services > Cloud Computing

  • Print
  • + Share This
From the author of Automation of Client Configuration

Automation of Client Configuration

IBM SmartCloud Enterprise and some other cloud providers give a framework for injecting data and scripts into virtual machines at provisioning time. We'll use the SCE framework here for automation of the DNS and other network configurations, explaining the features as we use them. If your cloud doesn't support dynamic injection of scripts and data during provisioning, another way to automate the configuration is to create a virtual machine instance, copying the automation files manually, and then save it as a base image.

Externalization of the virtual machine network customization from the image binary is a critical step. It allows you adapt to a changed network environment without creating a new image binary, and it enables you to inject different network configurations into an image binary that already exists. The image binary is opaque to us unless we provision an instance of it, so externalizing critical settings is an important advantage.

However you customize the image, a Python script will be used to make file changes and a configuration file will be created to store the network settings. We'll use Python to automate the steps that we've described above in the client configuration. Python is part of the Linux Standard Base and is an excellent choice for image-customization scripts. The version of Python shipped in RHEL 6.2 and most Linux systems is Python 2.6.6. There are some differences between this version and Python 3, but the scripts shown here are mostly compatible with Python 3 (with the exception of the ConfigParser class). Listing 13 shows the Python configuration script.

Listing 13—Python script for automated network and DNS client configuration. Python keywords are in bold.

import ConfigParser
import re
import shutil

def update_file(filename, patterns, replacements):
    ''' Update file with lines matching given patterns '''
    backup = filename + '.bak'
    shutil.copyfile(filename, backup)
    f = open(backup, 'r')
    text = ""
    for line in f:
        if (len(line.strip()) == 0) or (line[0] == '#'):
            text += line
        else:
            matched = False
            for i in range(len(patterns)):
                if re.match(patterns[i], line):
                    text += replacements[i] + '\n'
                    matched = True
            if not matched:
                text += line
    f.close()
    f = open(filename, 'w')
    f.write(text)
    f.close()

def configure():
    ''' Make configuration changes '''
    print("Make configuration changes")
    config = ConfigParser.ConfigParser()
    config.read('/etc/cloud/dns.conf')
    replacement = 'GATEWAY={0}'.format(config.get('Network','gateway'))
    update_file('/etc/sysconfig/network-scripts/ifcfg-eth0', ['GATEWAY'], [replacement])
    replacement = 'default table route_eth0 via {0} dev eth0'.format(config.get('Network','gateway'))
    update_file('/etc/sysconfig/network-scripts/route-eth0', ['default'], [replacement])
    patterns = ['domain', 'nameserver']
    replacements = ['domain {0}'.format(config.get('Network','domain')),
                    'nameserver {0}'.format(config.get('Network','nameserver'))]
    update_file('/etc/resolv.conf', patterns, replacements)

if __name__ == '__main__':
    configure()

The entry point to this program from the command line is the if __name__ statement, which calls the configure() function. You can copy this script into any editor and save it. I developed it on my Windows workstation with the Eclipse PyDev plug-in and then tested it on a Linux machine that was already running before inserting it into the virtual machine instance-provisioning process.

The Python script will read the network settings in dns.conf and inject the values stored there into the virtual machine files for setting the gateway and DNS server. The dns.conf file is shown in Listing 14.

Listing 14—Configuration file dns.conf.

# Network configuration file
[Network]
gateway: <gateway_ip>
domain: sceexample.com
nameserver: <dns_server_ip>

Replace the values of <gateway_ip>, sceexample.com, and <dns_server_ip> with appropriate values for your own environment.

To add this script and configuration file to a virtual machine image, we make a clone of an image in the public image catalog and add the scripts as image metadata. This step is essential because we need ownership of the image to change the metadata. In the SCE web portal, navigate to the Control Panel > Images tab and click the Add Image button, as shown in Figure 4.

Figure 4 Cloning an image in IBM SmartCloud Enterprise.

The next screen allows you to choose an image to clone. In this example, we'll use Red Hat Enterprise Linux 6 (64-bit) in the Singapore data center. After adding the image clone, the image will appear under My Assets in the My Dashboard of the cloud Asset Catalog, as shown in Figure 5.

Figure 5 The cloned image appears under My Assets.

Clicking the name of the image in My Assets will lead you to the metadata for the image, as shown in Figure 6. Make a note of the image ID, which we'll use later when creating an instance of the image with the command-line tool.

Figure 6 Cloned image metadata.

Navigate to the activation_scripts folder (see Figure 7) and download the files it contains. Place these files in a directory called activation_scripts on your local workstation, adding dns_client_config.py and dns.conf to it.

Figure 7 Image metadata contents.

Edit the cloud-startup script to call our Python script dns_client_config.py, as shown in Listing 15.

Listing 15—Modification of the startup script cloud-startup3.txt.

    start)
    . . .
        if [ -e /etc/cloud/dns_client_config.py ] ; then
            echo " [cloud-startup] Performing network configuration ..."
            /usr/bin/python /etc/cloud/dns_client_config.py
        fi
        ;;
    stop)

Edit scripts.txt to define the location where dns_client_config.py and dns.conf will be copied during instance-provisioning time, as shown in Listing 16.

Listing 16—Modification of scripts.txt.

cloud-startup3.txt=/etc/init.d/cloud-startup3.sh
activate.txt=/etc/cloud/activate.sh
dns.conf=/etc/cloud/dns.conf
dns_client_config.py=/etc/cloud/dns_client_config.py

After making the changes to scripts.txt, zip the activation_scripts directory. Click the pencil icon in the upper-right corner of the Asset Catalog tab (marked in Figure 7) to edit the asset metadata. Upload activation_scripts to the image catalog and save to update the image asset. The Contents should look like those in Figure 8.

Figure 8 Updated image metadata.

To test our automation script, we provision an instance with the SCE command-line tool and check the network settings. Execute the ic-create-instance command:

>ic-create-instance.cmd -u <user_id> -g <password_file> -w <passphrase>
 -k 20069951 -n "RHEL Clone Instance" -t "COP64.2/4096/60" -L 141 -x <vlan_id>
. . .
ID: 326329
Name: RHEL Clone Instance
. . .

In the command above, the -k parameter is the image ID of the image that you've customized, -n is the cloud display name of the virtual machine, -t is the server size, -L is the data center (Singapore), and -x is the VLAN ID. After the instance has become active, log in with SSH and check the resolv.conf and other network configuration files to make sure that your script injected the settings as expected. Use the nslookup command to exercise the DNS server as shown below:

$ dig http://www.yahoo.com
. . .
;; ANSWER SECTION:
http://www.yahoo.com.          300     IN      CNAME   fd-fp3.wg1.b.yahoo.com.
fd-fp3.wg1.b.yahoo.com. 300     IN      CNAME   ds-fp3.wg1.b.yahoo.com.
ds-fp3.wg1.b.yahoo.com. 60      IN      CNAME   ds-any-fp3-lfb.wa1.b.yahoo.com.
ds-any-fp3-lfb.wa1.b.yahoo.com. 300 IN  CNAME   ds-any-fp3-real.wa1.b.yahoo.com.
ds-any-fp3-real.wa1.b.yahoo.com. 60 IN  A       72.30.38.140

If the dig command can find the IP address of the Yahoo! server, you've successfully automated the network configuration of a Linux client on a private VLAN.

  • + Share This
  • 🔖 Save To Your Account