Skip to content

Commit

Permalink
sources/azure: remove unnecessary hostname bounce
Browse files Browse the repository at this point in the history
Thanks to [1], the hostname is set prior to network bring-up.

The Azure data source has been bouncing the hostname during
setup(), occurring after the hostname has already been
properly configured.

Note that this doesn't prevent leaking the image's hostname
during Azure's _get_data() when it brings up ephemeral DHCP.
However, as are not guaranteed to have the hostname metadata
available from a truly "local" source, this behavior is to
be expected unless we disable `send host-name` from dhclient
config.

133ad2c

Signed-off-by: Chris Patterson <cpatterson@microsoft.com>
  • Loading branch information
cjp256 committed Dec 9, 2021
1 parent 0ed00ad commit 6b4598f
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 415 deletions.
126 changes: 0 additions & 126 deletions cloudinit/sources/DataSourceAzure.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import base64
from collections import namedtuple
import contextlib
import crypt
from functools import partial
import os
Expand Down Expand Up @@ -52,20 +51,10 @@

DS_NAME = 'Azure'
DEFAULT_METADATA = {"instance-id": "iid-AZURE-NODE"}
BOUNCE_COMMAND_IFUP = [
'sh', '-xc',
"i=$interface; x=0; ifdown $i || x=$?; ifup $i || x=$?; exit $x"
]
BOUNCE_COMMAND_FREEBSD = [
'sh', '-xc',
("i=$interface; x=0; ifconfig down $i || x=$?; "
"ifconfig up $i || x=$?; exit $x")
]

# azure systems will always have a resource disk, and 66-azure-ephemeral.rules
# ensures that it gets linked to this path.
RESOURCE_DISK_PATH = '/dev/disk/cloud/azure_resource'
DEFAULT_PRIMARY_NIC = 'eth0'
LEASE_FILE = '/var/lib/dhcp/dhclient.eth0.leases'
DEFAULT_FS = 'ext4'
# DMI chassis-asset-tag is set static for all azure instances
Expand Down Expand Up @@ -247,7 +236,6 @@ def get_resource_disk_on_freebsd(port_id):

# update the FreeBSD specific information
if util.is_FreeBSD():
DEFAULT_PRIMARY_NIC = 'hn0'
LEASE_FILE = '/var/db/dhclient.leases.hn0'
DEFAULT_FS = 'freebsd-ufs'
res_disk = get_resource_disk_on_freebsd(1)
Expand All @@ -261,13 +249,6 @@ def get_resource_disk_on_freebsd(port_id):

BUILTIN_DS_CONFIG = {
'data_dir': AGENT_SEED_DIR,
'set_hostname': True,
'hostname_bounce': {
'interface': DEFAULT_PRIMARY_NIC,
'policy': True,
'command': 'builtin',
'hostname_command': 'hostname',
},
'disk_aliases': {'ephemeral0': RESOURCE_DISK_PATH},
'dhclient_lease_file': LEASE_FILE,
'apply_network_config': True, # Use IMDS published network configuration
Expand All @@ -293,46 +274,6 @@ def get_resource_disk_on_freebsd(port_id):
DEF_PASSWD_REDACTION = 'REDACTED'


def get_hostname(hostname_command='hostname'):
if not isinstance(hostname_command, (list, tuple)):
hostname_command = (hostname_command,)
return subp.subp(hostname_command, capture=True)[0].strip()


def set_hostname(hostname, hostname_command='hostname'):
subp.subp([hostname_command, hostname])


@azure_ds_telemetry_reporter
@contextlib.contextmanager
def temporary_hostname(temp_hostname, cfg, hostname_command='hostname'):
"""
Set a temporary hostname, restoring the previous hostname on exit.
Will have the value of the previous hostname when used as a context
manager, or None if the hostname was not changed.
"""
policy = cfg['hostname_bounce']['policy']
previous_hostname = get_hostname(hostname_command)
if (not util.is_true(cfg.get('set_hostname')) or
util.is_false(policy) or
(previous_hostname == temp_hostname and policy != 'force')):
yield None
return
try:
set_hostname(temp_hostname, hostname_command)
except Exception as e:
report_diagnostic_event(
'Failed setting temporary hostname: %s' % e,
logger_func=LOG.warning)
yield None
return
try:
yield previous_hostname
finally:
set_hostname(previous_hostname, hostname_command)


class DataSourceAzure(sources.DataSource):

dsname = 'Azure'
Expand Down Expand Up @@ -369,34 +310,6 @@ def __str__(self):
root = sources.DataSource.__str__(self)
return "%s [seed=%s]" % (root, self.seed)

@azure_ds_telemetry_reporter
def bounce_network_with_azure_hostname(self):
# When using cloud-init to provision, we have to set the hostname from
# the metadata and "bounce" the network to force DDNS to update via
# dhclient
azure_hostname = self.metadata.get('local-hostname')
LOG.debug("Hostname in metadata is %s", azure_hostname)
hostname_command = self.ds_cfg['hostname_bounce']['hostname_command']

with temporary_hostname(azure_hostname, self.ds_cfg,
hostname_command=hostname_command) \
as previous_hn:
if (previous_hn is not None and
util.is_true(self.ds_cfg.get('set_hostname'))):
cfg = self.ds_cfg['hostname_bounce']

# "Bouncing" the network
try:
return perform_hostname_bounce(hostname=azure_hostname,
cfg=cfg,
prev_hostname=previous_hn)
except Exception as e:
report_diagnostic_event(
"Failed publishing hostname: %s" % e,
logger_func=LOG.warning)
util.logexc(LOG, "handling set_hostname failed")
return False

def _get_subplatform(self):
"""Return the subplatform metadata source details."""
if self.seed.startswith('/dev'):
Expand Down Expand Up @@ -1502,9 +1415,6 @@ def _negotiate(self):
On success, returns a dictionary including 'public_keys'.
On failure, returns False.
"""

self.bounce_network_with_azure_hostname()

pubkey_info = None
ssh_keys_and_source = self._get_public_ssh_keys_and_source()

Expand Down Expand Up @@ -1763,42 +1673,6 @@ def address_ephemeral_resize(devpath=RESOURCE_DISK_PATH,
return


@azure_ds_telemetry_reporter
def perform_hostname_bounce(hostname, cfg, prev_hostname):
# set the hostname to 'hostname' if it is not already set to that.
# then, if policy is not off, bounce the interface using command
# Returns True if the network was bounced, False otherwise.
command = cfg['command']
interface = cfg['interface']
policy = cfg['policy']

msg = ("hostname=%s policy=%s interface=%s" %
(hostname, policy, interface))
env = os.environ.copy()
env['interface'] = interface
env['hostname'] = hostname
env['old_hostname'] = prev_hostname

if command == "builtin":
if util.is_FreeBSD():
command = BOUNCE_COMMAND_FREEBSD
elif subp.which('ifup'):
command = BOUNCE_COMMAND_IFUP
else:
LOG.debug(
"Skipping network bounce: ifupdown utils aren't present.")
# Don't bounce as networkd handles hostname DDNS updates
return False
LOG.debug("pubhname: publishing hostname [%s]", msg)
shell = not isinstance(command, (list, tuple))
# capture=False, see comments in bug 1202758 and bug 1206164.
util.log_time(logfunc=LOG.debug, msg="publishing hostname",
get_uptime=True, func=subp.subp,
kwargs={'args': command, 'shell': shell, 'capture': False,
'env': env})
return True


@azure_ds_telemetry_reporter
def write_files(datadir, files, dirmode=None):

Expand Down
6 changes: 0 additions & 6 deletions doc/examples/cloud-config-datasources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ datasource:
instance-id: i-87018aed
local-hostname: myhost.internal

Azure:
set_hostname: True
hostname_bounce:
interface: eth0
policy: on # [can be 'on', 'off' or 'force']

SmartOS:
# For KVM guests:
# Smart OS datasource works over a serial console interacting with
Expand Down
20 changes: 0 additions & 20 deletions doc/rtd/topics/datasources/azure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,6 @@ The settings that may be configured are:
custom DHCP option 245 from Azure fabric.
* **disk_aliases**: A dictionary defining which device paths should be
interpreted as ephemeral images. See cc_disk_setup module for more info.
* **hostname_bounce**: A dictionary Azure hostname bounce behavior to react to
metadata changes. The '``hostname_bounce: command``' entry can be either
the literal string 'builtin' or a command to execute. The command will be
invoked after the hostname is set, and will have the 'interface' in its
environment. If ``set_hostname`` is not true, then ``hostname_bounce``
will be ignored. An example might be:

``command: ["sh", "-c", "killall dhclient; dhclient $interface"]``

* **hostname_bounce**: A dictionary Azure hostname bounce behavior to react to
metadata changes. Azure will throttle ifup/down in some cases after metadata
has been updated to inform dhcp server about updated hostnames.
* **set_hostname**: Boolean set to True when we want Azure to set the hostname
based on metadata.

Configuration for the datasource can also be read from a
``dscfg`` entry in the ``LinuxProvisioningConfigurationSet``. Content in
Expand All @@ -91,12 +77,6 @@ An example configuration with the default values is provided below:
dhclient_lease_file: /var/lib/dhcp/dhclient.eth0.leases
disk_aliases:
ephemeral0: /dev/disk/cloud/azure_resource
hostname_bounce:
interface: eth0
command: builtin
policy: true
hostname_command: hostname
set_hostname: true


Userdata
Expand Down
Loading

0 comments on commit 6b4598f

Please sign in to comment.