← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~chad.smith/cloud-init:xenial/dont-render-network-from-imds into cloud-init:ubuntu/xenial

 

Chad Smith has proposed merging ~chad.smith/cloud-init:xenial/dont-render-network-from-imds into cloud-init:ubuntu/xenial.

Commit message:
xenial-azure: Disable rendering network from IMDS

In Xenial we already have hotplug scripts delivered in stock
cloud-images. Disable rendering network information from IMDS and avoid
deleting Ubuntu cloud-image udev add scripts which create
/etc/network/interface configuration for the hotplugged network
interfaces.

Requested reviews:
  cloud-init commiters (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~chad.smith/cloud-init/+git/cloud-init/+merge/356888
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~chad.smith/cloud-init:xenial/dont-render-network-from-imds into cloud-init:ubuntu/xenial.
diff --git a/debian/patches/azure-dont-render-imds-network.patch b/debian/patches/azure-dont-render-imds-network.patch
new file mode 100644
index 0000000..9beb2ff
--- /dev/null
+++ b/debian/patches/azure-dont-render-imds-network.patch
@@ -0,0 +1,115 @@
+Description: Disable rendering network from Azure IMDS and script cleanup
+ Xenial Azure images already contain working udev script which react to
+ hotplug network interface adds and write /etc/network/interface config
+ for the new interfaces.
+ .
+ This patch disables the cloud-init logic needed on Bionic or later which
+ renders network configuration to netplan from Azure's IMDS. It also
+ avoids removing any of the cloud-image udev hotplug scripts which work as
+ designed in Xenial.
+Forwarded: not-needed
+Author: Chad Smith <chad.smith@xxxxxxxxxxxxx>
+
+diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
+index 783445e..d5726ab 100644
+--- a/cloudinit/sources/DataSourceAzure.py
++++ b/cloudinit/sources/DataSourceAzure.py
+@@ -56,12 +56,7 @@ IMDS_URL = "http://169.254.169.254/metadata/";
+ 
+ # List of static scripts and network config artifacts created by
+ # stock ubuntu suported images.
+-UBUNTU_EXTENDED_NETWORK_SCRIPTS = [
+-    '/etc/netplan/90-azure-hotplug.yaml',
+-    '/usr/local/sbin/ephemeral_eth.sh',
+-    '/etc/udev/rules.d/10-net-device-added.rules',
+-    '/run/network/interfaces.ephemeral.d',
+-]
++UBUNTU_EXTENDED_NETWORK_SCRIPTS = []  # Remove no network scipts on Xenial
+ 
+ 
+ def find_storvscid_from_sysctl_pnpinfo(sysctl_out, deviceid):
+@@ -611,7 +606,9 @@ class DataSourceAzure(sources.DataSource):
+               the blacklisted devices.
+         """
+         if not self._network_config:
+-            self._network_config = parse_network_config(self._metadata_imds)
++            # Xenial-only, use fallback network config not IMDS because
++            # ubuntu images contain the necessary ifup/down hotplug goodness
++            self._network_config = parse_network_config(None)
+         return self._network_config
+ 
+ 
+diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py
+index 4e428b7..5e9cf08 100644
+--- a/tests/unittests/test_datasource/test_azure.py
++++ b/tests/unittests/test_datasource/test_azure.py
+@@ -501,20 +501,6 @@ fdescfs            /dev/fd          fdescfs rw              0 0
+         self.assertTrue(ret)
+         self.assertEqual(data['agent_invoked'], cfg['agent_command'])
+ 
+-    def test_network_config_set_from_imds(self):
+-        """Datasource.network_config returns IMDS network data."""
+-        odata = {}
+-        data = {'ovfcontent': construct_valid_ovf_env(data=odata)}
+-        expected_network_config = {
+-            'ethernets': {
+-                'eth0': {'set-name': 'eth0',
+-                         'match': {'macaddress': '00:0d:3a:04:75:98'},
+-                         'dhcp4': True}},
+-            'version': 2}
+-        dsrc = self._get_ds(data)
+-        dsrc.get_data()
+-        self.assertEqual(expected_network_config, dsrc.network_config)
+-
+     def test_user_cfg_set_agent_command(self):
+         # set dscfg in via base64 encoded yaml
+         cfg = {'agent_command': "my_command"}
+@@ -780,26 +766,37 @@ fdescfs            /dev/fd          fdescfs rw              0 0
+         self.assertEqual(
+             [mock.call("/dev/cd0")], m_check_fbsd_cdrom.call_args_list)
+ 
++    @mock.patch('cloudinit.net.get_interface_mac')
++    @mock.patch('cloudinit.net.get_devicelist')
++    @mock.patch('cloudinit.net.device_driver')
+     @mock.patch('cloudinit.net.generate_fallback_config')
+-    def test_imds_network_config(self, mock_fallback):
+-        """Network config is generated from IMDS network data when present."""
++    def test_imds_network_config_ignored_on_xenial(self, mock_fallback, mock_dd,
++                                                   mock_devlist, mock_get_mac):
++        """Network config ignores IMDS network data on Xenial. Use fallback."""
+         odata = {'HostName': "myhost", 'UserName': "myuser"}
+         data = {'ovfcontent': construct_valid_ovf_env(data=odata),
+                 'sys_cfg': {}}
+ 
++        fallback_config = {
++            'version': 1,
++            'config': [{
++                'type': 'physical', 'name': 'eth0',
++                'mac_address': '00:11:22:33:44:55',
++                'params': {'driver': 'hv_netsvc'},
++                'subnets': [{'type': 'dhcp'}],
++            }]
++        }
++        mock_fallback.return_value = fallback_config
++        mock_devlist.return_value = ['eth0']
++        mock_dd.return_value = ['hv_netsvc']
++        mock_get_mac.return_value = '00:11:22:33:44:55'
++
+         dsrc = self._get_ds(data)
+         ret = dsrc.get_data()
+         self.assertTrue(ret)
+ 
+-        expected_cfg = {
+-            'ethernets': {
+-                'eth0': {'dhcp4': True,
+-                         'match': {'macaddress': '00:0d:3a:04:75:98'},
+-                         'set-name': 'eth0'}},
+-            'version': 2}
+-
+-        self.assertEqual(expected_cfg, dsrc.network_config)
+-        mock_fallback.assert_not_called()
++        self.assertEqual(fallback_config, dsrc.network_config)
++        mock_fallback.assert_called_once()
+ 
+     @mock.patch('cloudinit.net.get_interface_mac')
+     @mock.patch('cloudinit.net.get_devicelist')

Follow ups