|
|
20a859 |
From 9c2b33562da7e5ca3359a2e70b893d19c44eb66c Mon Sep 17 00:00:00 2001
|
|
|
20a859 |
From: Brent Baude <bbaude@redhat.com>
|
|
|
20a859 |
Date: Mon, 20 Mar 2017 12:31:15 -0500
|
|
|
20a859 |
Subject: [PATCH] Bounce network interface for Azure when using the built-in
|
|
|
20a859 |
path.
|
|
|
20a859 |
|
|
|
20a859 |
When deploying on Azure and using only cloud-init, you must "bounce" the
|
|
|
20a859 |
network interface to trigger a DDNS update. This allows dhclient to
|
|
|
20a859 |
register the hostname with Azure so that DNS works correctly on their
|
|
|
20a859 |
private networks (i.e. between vm and vm).
|
|
|
20a859 |
|
|
|
20a859 |
The agent path was already doing the bounce so this creates parity
|
|
|
20a859 |
between the built-in path and the agent.
|
|
|
20a859 |
|
|
|
20a859 |
LP: #1674685
|
|
|
20a859 |
Resolves: rhbz#1434109
|
|
|
20a859 |
(cherry picked from commit 86715c88aab8561e1ddadac95671f6095d16f9e7)
|
|
|
20a859 |
---
|
|
|
20a859 |
cloudinit/sources/DataSourceAzure.py | 78 +++++++++++++++++++++---------------
|
|
|
20a859 |
cloudinit/sources/__init__.py | 2 +-
|
|
|
20a859 |
2 files changed, 47 insertions(+), 33 deletions(-)
|
|
|
20a859 |
|
|
|
20a859 |
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
|
|
20a859 |
index c5af8b8..48a3e1d 100644
|
|
|
20a859 |
--- a/cloudinit/sources/DataSourceAzure.py
|
|
|
20a859 |
+++ b/cloudinit/sources/DataSourceAzure.py
|
|
|
20a859 |
@@ -111,50 +111,62 @@ class DataSourceAzureNet(sources.DataSource):
|
|
|
20a859 |
root = sources.DataSource.__str__(self)
|
|
|
20a859 |
return "%s [seed=%s]" % (root, self.seed)
|
|
|
20a859 |
|
|
|
20a859 |
- def get_metadata_from_agent(self):
|
|
|
20a859 |
- temp_hostname = self.metadata.get('local-hostname')
|
|
|
20a859 |
+ def bounce_network_with_azure_hostname(self):
|
|
|
20a859 |
+ # When using cloud-init to provision, we have to set the hostname from
|
|
|
20a859 |
+ # the metadata and "bounce" the network to force DDNS to update via
|
|
|
20a859 |
+ # dhclient
|
|
|
20a859 |
+ azure_hostname = self.metadata.get('local-hostname')
|
|
|
20a859 |
+ LOG.debug("Hostname in metadata is {}".format(azure_hostname))
|
|
|
20a859 |
hostname_command = self.ds_cfg['hostname_bounce']['hostname_command']
|
|
|
20a859 |
- agent_cmd = self.ds_cfg['agent_command']
|
|
|
20a859 |
- LOG.debug("Getting metadata via agent. hostname=%s cmd=%s",
|
|
|
20a859 |
- temp_hostname, agent_cmd)
|
|
|
20a859 |
- with temporary_hostname(temp_hostname, self.ds_cfg,
|
|
|
20a859 |
+
|
|
|
20a859 |
+ with temporary_hostname(azure_hostname, self.ds_cfg,
|
|
|
20a859 |
hostname_command=hostname_command) \
|
|
|
20a859 |
as previous_hostname:
|
|
|
20a859 |
if (previous_hostname is not None and
|
|
|
20a859 |
- util.is_true(self.ds_cfg.get('set_hostname'))):
|
|
|
20a859 |
+ util.is_true(self.ds_cfg.get('set_hostname'))):
|
|
|
20a859 |
cfg = self.ds_cfg['hostname_bounce']
|
|
|
20a859 |
+
|
|
|
20a859 |
+ # "Bouncing" the network
|
|
|
20a859 |
try:
|
|
|
20a859 |
- perform_hostname_bounce(hostname=temp_hostname,
|
|
|
20a859 |
+ perform_hostname_bounce(hostname=azure_hostname,
|
|
|
20a859 |
cfg=cfg,
|
|
|
20a859 |
prev_hostname=previous_hostname)
|
|
|
20a859 |
except Exception as e:
|
|
|
20a859 |
LOG.warn("Failed publishing hostname: %s", e)
|
|
|
20a859 |
util.logexc(LOG, "handling set_hostname failed")
|
|
|
20a859 |
|
|
|
20a859 |
- try:
|
|
|
20a859 |
- invoke_agent(agent_cmd)
|
|
|
20a859 |
- except util.ProcessExecutionError:
|
|
|
20a859 |
- # claim the datasource even if the command failed
|
|
|
20a859 |
- util.logexc(LOG, "agent command '%s' failed.",
|
|
|
20a859 |
- self.ds_cfg['agent_command'])
|
|
|
20a859 |
-
|
|
|
20a859 |
- ddir = self.ds_cfg['data_dir']
|
|
|
20a859 |
-
|
|
|
20a859 |
- fp_files = []
|
|
|
20a859 |
- key_value = None
|
|
|
20a859 |
- for pk in self.cfg.get('_pubkeys', []):
|
|
|
20a859 |
- if pk.get('value', None):
|
|
|
20a859 |
- key_value = pk['value']
|
|
|
20a859 |
- LOG.debug("ssh authentication: using value from fabric")
|
|
|
20a859 |
- else:
|
|
|
20a859 |
- bname = str(pk['fingerprint'] + ".crt")
|
|
|
20a859 |
- fp_files += [os.path.join(ddir, bname)]
|
|
|
20a859 |
- LOG.debug("ssh authentication: "
|
|
|
20a859 |
- "using fingerprint from fabirc")
|
|
|
20a859 |
-
|
|
|
20a859 |
- missing = util.log_time(logfunc=LOG.debug, msg="waiting for files",
|
|
|
20a859 |
- func=wait_for_files,
|
|
|
20a859 |
- args=(fp_files,))
|
|
|
20a859 |
+ def get_metadata_from_agent(self):
|
|
|
20a859 |
+ temp_hostname = self.metadata.get('local-hostname')
|
|
|
20a859 |
+ agent_cmd = self.ds_cfg['agent_command']
|
|
|
20a859 |
+ LOG.debug("Getting metadata via agent. hostname=%s cmd=%s",
|
|
|
20a859 |
+ temp_hostname, agent_cmd)
|
|
|
20a859 |
+
|
|
|
20a859 |
+ self.bounce_network_with_azure_hostname()
|
|
|
20a859 |
+
|
|
|
20a859 |
+ try:
|
|
|
20a859 |
+ invoke_agent(agent_cmd)
|
|
|
20a859 |
+ except util.ProcessExecutionError:
|
|
|
20a859 |
+ # claim the datasource even if the command failed
|
|
|
20a859 |
+ util.logexc(LOG, "agent command '%s' failed.",
|
|
|
20a859 |
+ self.ds_cfg['agent_command'])
|
|
|
20a859 |
+
|
|
|
20a859 |
+ ddir = self.ds_cfg['data_dir']
|
|
|
20a859 |
+
|
|
|
20a859 |
+ fp_files = []
|
|
|
20a859 |
+ key_value = None
|
|
|
20a859 |
+ for pk in self.cfg.get('_pubkeys', []):
|
|
|
20a859 |
+ if pk.get('value', None):
|
|
|
20a859 |
+ key_value = pk['value']
|
|
|
20a859 |
+ LOG.debug("ssh authentication: using value from fabric")
|
|
|
20a859 |
+ else:
|
|
|
20a859 |
+ bname = str(pk['fingerprint'] + ".crt")
|
|
|
20a859 |
+ fp_files += [os.path.join(ddir, bname)]
|
|
|
20a859 |
+ LOG.debug("ssh authentication: "
|
|
|
20a859 |
+ "using fingerprint from fabirc")
|
|
|
20a859 |
+
|
|
|
20a859 |
+ missing = util.log_time(logfunc=LOG.debug, msg="waiting for files",
|
|
|
20a859 |
+ func=wait_for_files,
|
|
|
20a859 |
+ args=(fp_files,))
|
|
|
20a859 |
if len(missing):
|
|
|
20a859 |
LOG.warn("Did not find files, but going on: %s", missing)
|
|
|
20a859 |
|
|
|
20a859 |
@@ -220,6 +232,8 @@ class DataSourceAzureNet(sources.DataSource):
|
|
|
20a859 |
write_files(ddir, files, dirmode=0o700)
|
|
|
20a859 |
|
|
|
20a859 |
if self.ds_cfg['agent_command'] == AGENT_START_BUILTIN:
|
|
|
20a859 |
+ self.bounce_network_with_azure_hostname()
|
|
|
20a859 |
+
|
|
|
20a859 |
metadata_func = partial(get_metadata_from_fabric,
|
|
|
20a859 |
fallback_lease_file=self.
|
|
|
20a859 |
dhclient_lease_file)
|
|
|
20a859 |
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
|
|
|
20a859 |
index 3d01072..1829450 100644
|
|
|
20a859 |
--- a/cloudinit/sources/__init__.py
|
|
|
20a859 |
+++ b/cloudinit/sources/__init__.py
|
|
|
20a859 |
@@ -210,7 +210,7 @@ class DataSource(object):
|
|
|
20a859 |
else:
|
|
|
20a859 |
hostname = toks[0]
|
|
|
20a859 |
|
|
|
20a859 |
- if fqdn:
|
|
|
20a859 |
+ if fqdn and domain != defdomain:
|
|
|
20a859 |
return "%s.%s" % (hostname, domain)
|
|
|
20a859 |
else:
|
|
|
20a859 |
return hostname
|