summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/sources/DataSourceCloudStack.py51
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)),