diff options
| -rw-r--r-- | cloudinit/sources/DataSourceCloudStack.py | 51 | 
1 files changed, 30 insertions, 21 deletions
| diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py index 076dba5a..82e1e130 100644 --- a/cloudinit/sources/DataSourceCloudStack.py +++ b/cloudinit/sources/DataSourceCloudStack.py @@ -3,10 +3,12 @@  #    Copyright (C) 2012 Canonical Ltd.  #    Copyright (C) 2012 Cosmin Luta  #    Copyright (C) 2012 Yahoo! Inc. +#    Copyright (C) 2012 Gerard Dethier  #  #    Author: Cosmin Luta <q4break@gmail.com>  #    Author: Scott Moser <scott.moser@canonical.com>  #    Author: Joshua Harlow <harlowja@yahoo-inc.com> +#    Author: Gerard Dethier <g.dethier@gmail.com>  #  #    This program is free software: you can redistribute it and/or modify  #    it under the terms of the GNU General Public License version 3, as @@ -20,9 +22,6 @@  #    You should have received a copy of the GNU General Public License  #    along with this program.  If not, see <http://www.gnu.org/licenses/>. -from socket import inet_ntoa -from struct import pack -  import os  import time @@ -40,24 +39,12 @@ class DataSourceCloudStack(sources.DataSource):          sources.DataSource.__init__(self, sys_cfg, distro, paths)          self.seed_dir = os.path.join(paths.seed_dir, 'cs')          # Cloudstack has its metadata/userdata URLs located at -        # http://<default-gateway-ip>/latest/ +        # http://<virtual-router-ip>/latest/          self.api_ver = 'latest' -        gw_addr = self.get_default_gateway() -        if not gw_addr: -            raise RuntimeError("No default gateway found!") -        self.metadata_address = "http://%s/" % (gw_addr) - -    def get_default_gateway(self): -        """Returns the default gateway ip address in the dotted format.""" -        lines = util.load_file("/proc/net/route").splitlines() -        for line in lines: -            items = line.split("\t") -            if items[1] == "00000000": -                # Found the default route, get the gateway -                gw = inet_ntoa(pack("<L", int(items[2], 16))) -                LOG.debug("Found default route, gateway is %s", gw) -                return gw -        return None +        vr_addr = get_vr_address() +        if not vr_addr: +            raise RuntimeError("No virtual router found!") +        self.metadata_address = "http://%s/" % (vr_addr)      def __str__(self):          return util.obj_name(self) @@ -90,7 +77,7 @@ class DataSourceCloudStack(sources.DataSource):          (max_wait, timeout) = self._get_url_settings() -        urls = [self.metadata_address] +        urls = [self.metadata_address + "/latest/meta-data/instance-id"]          start_time = time.time()          url = uhelp.wait_for_url(urls=urls, max_wait=max_wait,                                  timeout=timeout, status_cb=LOG.warn) @@ -135,6 +122,28 @@ class DataSourceCloudStack(sources.DataSource):          return self.metadata['availability-zone'] +def get_vr_address(): +    # get the address of the virtual router via dhcp responses +    # see http://bit.ly/T76eKC for documentation on the virtual router. +    dhclient_d = "/var/lib/dhclient" +    addresses = set() +    dhclient_files = os.listdir(dhclient_d) +    for file_name in dhclient_files: +        if file_name.endswith(".lease") or file_name.endswith(".leases"): +            with open(os.path.join(dhclient_d, file_name), "r") as fd: +                for line in fd: +                    if "dhcp-server-identifier" in line: +                        words = line.strip(" ;\r\n").split(" ") +                        if len(words) > 2: +                            dhcp = words[2] +                            LOG.debug("Found DHCP identifier %s", dhcp) +                            addresses.add(dhcp) +    if len(addresses) != 1: +        # No unique virtual router found +        return None +    return addresses.pop() + +  # Used to match classes to dependencies  datasources = [    (DataSourceCloudStack, (sources.DEP_FILESYSTEM, sources.DEP_NETWORK)), | 
