cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #03504
[Merge] ~xnox/cloud-init:networkd into cloud-init:master
Dimitri John Ledkov has proposed merging ~xnox/cloud-init:networkd into cloud-init:master.
Commit message:
azure: discover datasource from networkd lease files
LP: #1718029
Requested reviews:
cloud-init commiters (cloud-init-dev)
Related bugs:
Bug #1718029 in cloud-init (Ubuntu): "cloudstack and azure datasources broken when using netplan/systemd-networkd"
https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1718029
For more details, see:
https://code.launchpad.net/~xnox/cloud-init/+git/cloud-init/+merge/331642
azure: discover datasource from networkd lease files
LP: #1718029
--
Your team cloud-init commiters is requested to review the proposed merge of ~xnox/cloud-init:networkd into cloud-init:master.
diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
index 28ed0ae..f4028a7 100644
--- a/cloudinit/sources/helpers/azure.py
+++ b/cloudinit/sources/helpers/azure.py
@@ -1,5 +1,6 @@
# This file is part of cloud-init. See LICENSE file for license information.
+import glob
import json
import logging
import os
@@ -15,6 +16,8 @@ from xml.etree import ElementTree
from cloudinit import util
+from six.moves.configparser import ConfigParser
+from six.moves import cStringIO as StringIO
LOG = logging.getLogger(__name__)
@@ -239,6 +242,20 @@ class WALinuxAgentShim(object):
return socket.inet_ntoa(packed_bytes)
@staticmethod
+ def _get_value_from_networkd_leases(_leases='/run/systemd/netif/leases/*'):
+ for lease in glob.iglob(_leases):
+ cp = ConfigParser()
+ try:
+ if hasattr(cp, 'read_string'):
+ cp.read_string('[LEASE]\n' + util.load_file(lease))
+ else:
+ cp.readfp(StringIO('[LEASE]\n' + util.load_file(lease))) # noqa pylint: disable=deprecated-method
+ return cp.get('LEASE', 'OPTION_245')
+ except Exception:
+ pass
+ return None
+
+ @staticmethod
def _get_value_from_leases_file(fallback_lease_file):
leases = []
content = util.load_file(fallback_lease_file)
@@ -287,12 +304,15 @@ class WALinuxAgentShim(object):
@staticmethod
def find_endpoint(fallback_lease_file=None):
- LOG.debug('Finding Azure endpoint...')
value = None
- # Option-245 stored in /run/cloud-init/dhclient.hooks/<ifc>.json
- # a dhclient exit hook that calls cloud-init-dhclient-hook
- dhcp_options = WALinuxAgentShim._load_dhclient_json()
- value = WALinuxAgentShim._get_value_from_dhcpoptions(dhcp_options)
+ LOG.debug('Finding Azure endpoint from networkd...')
+ value = WALinuxAgentShim._get_value_from_networkd_leases()
+ if value is None:
+ # Option-245 stored in /run/cloud-init/dhclient.hooks/<ifc>.json
+ # a dhclient exit hook that calls cloud-init-dhclient-hook
+ LOG.debug('Finding Azure endpoint from hook json...')
+ dhcp_options = WALinuxAgentShim._load_dhclient_json()
+ value = WALinuxAgentShim._get_value_from_dhcpoptions(dhcp_options)
if value is None:
# Fallback and check the leases file if unsuccessful
LOG.debug("Unable to find endpoint in dhclient logs. "
diff --git a/tests/unittests/test_datasource/test_azure_helper.py b/tests/unittests/test_datasource/test_azure_helper.py
index 44b99ec..10cd7f4 100644
--- a/tests/unittests/test_datasource/test_azure_helper.py
+++ b/tests/unittests/test_datasource/test_azure_helper.py
@@ -1,6 +1,8 @@
# This file is part of cloud-init. See LICENSE file for license information.
import os
+import shutil
+import tempfile
from cloudinit.sources.helpers import azure as azure_helper
from cloudinit.tests.helpers import ExitStack, mock, TestCase
@@ -135,6 +137,45 @@ class TestExtractIpAddressFromLeaseValue(TestCase):
))
+class TestExtractIpAddressFromNetworkd(TestCase):
+
+ def setUp(self):
+ super(TestExtractIpAddressFromNetworkd, self).setUp()
+ lease_dir = tempfile.mkdtemp()
+ self.leases = lease_dir + '/*'
+ ifindex = '2'
+ self.lease_file = os.path.join(lease_dir, ifindex)
+ self.addCleanup(shutil.rmtree, lease_dir, ignore_errors=True)
+
+ def test_none(self):
+ value = None
+ self.assertEqual(
+ value,
+ azure_helper.WALinuxAgentShim._get_value_from_networkd_leases(
+ self.leases
+ ))
+
+ def test_typical(self):
+ value = '624c3620'
+ with open(self.lease_file, 'w') as f:
+ f.write('OPTION_245=%s\n' % value)
+ self.assertEqual(
+ value,
+ azure_helper.WALinuxAgentShim._get_value_from_networkd_leases(
+ self.leases
+ ))
+
+ def test_malformed(self):
+ value = None
+ with open(self.lease_file, 'w') as f:
+ f.write('OPTION_246=624c3620\n')
+ self.assertEqual(
+ value,
+ azure_helper.WALinuxAgentShim._get_value_from_networkd_leases(
+ self.leases
+ ))
+
+
class TestGoalStateParsing(TestCase):
default_parameters = {
References