summaryrefslogtreecommitdiff
path: root/cloudinit/sources
diff options
context:
space:
mode:
authorGerard Dethier <g.dethier@gmail.com>2012-12-19 09:27:33 -0500
committerScott Moser <smoser@ubuntu.com>2012-12-19 09:27:33 -0500
commit8abbeae7ce15a6fb7a08adc697205d614f868a98 (patch)
treeb84c531029c4fa9012a3830dbd1d590b66c8a9d3 /cloudinit/sources
parent6f96b922886c8d607a6be69ae8bc0ce1caf75d04 (diff)
downloadvyos-cloud-init-8abbeae7ce15a6fb7a08adc697205d614f868a98.tar.gz
vyos-cloud-init-8abbeae7ce15a6fb7a08adc697205d614f868a98.zip
DataSourceCloudStack: use virtual router rather than default route
In CloudStack's documentation, it is stated that meta/user-data can be retrieved from CloudStack's Virtual Router [1]. However, cloud-init retrieves these information from default gateway. VR and default gateway may be the same machine (i.e. have the same address) in some cases, but that is not be always true (actually, in my case, it is not). This change searches the lease files in /var/lib/dhclient to pick out the dhcp-server-identifier. It admittedly does make this specific to dhclient. -- [1] http://incubator.apache.org/cloudstack/docs/en-US/Apache_CloudStack/4.0.0-incubating/html/Admin_Guide/user-data-and-meta-data.html). LP: #1089989
Diffstat (limited to 'cloudinit/sources')
-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)),