diff options
author | Gerard Dethier <g.dethier@gmail.com> | 2012-12-19 09:27:33 -0500 |
---|---|---|
committer | Scott Moser <smoser@ubuntu.com> | 2012-12-19 09:27:33 -0500 |
commit | 8abbeae7ce15a6fb7a08adc697205d614f868a98 (patch) | |
tree | b84c531029c4fa9012a3830dbd1d590b66c8a9d3 /cloudinit/sources | |
parent | 6f96b922886c8d607a6be69ae8bc0ce1caf75d04 (diff) | |
download | vyos-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.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)), |