← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~ma-brothier/cloud-init:interfaces-order into cloud-init:master


Marc Brothier has proposed merging ~ma-brothier/cloud-init:interfaces-order into cloud-init:master.

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

For more details, see:

The code deciding which interface to choose as the default to request the IP address through DHCP does not sort the interfaces correctly. On Ubuntu Xenial images for example, the interfaces are named ens1, ens2, ens3..., ens11, ... depending on the pci bus address. The python sorting will list 'ens11' before 'ens3' for example despite the fact that 'ens3' should be before 'ens11'.

This patch address this issue and sort the interface names according to a human sorting as describe in the util method.
Your team cloud-init commiters is requested to review the proposed merge of ~ma-brothier/cloud-init:interfaces-order into cloud-init:master.
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index 8c6cd05..ed02479 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -169,7 +169,7 @@ def generate_fallback_config():
     # if eth0 exists use it above anything else, otherwise get the interface
     # that we can read 'first' (using the sorted defintion of first).
-    names = list(sorted(potential_interfaces))
+    names = list(sorted(potential_interfaces, key=util.natural_sort_key))
         names.insert(0, DEFAULT_PRIMARY_INTERFACE)
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 135e460..c5853fc 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -2508,4 +2508,15 @@ def load_shell_content(content, add_empty=False, empty_val=None):
     return data
+def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
+    """Sorting for Humans: natural sort order. Can be use as the key to sort
+    functions.
+    This will sort ['eth0', 'ens3', 'ens10', 'ens12', 'ens8', 'ens0'] as
+    ['ens0', 'ens3', 'ens8', 'ens10', 'ens12', 'eth0'] instead of the simple
+    python way which will produce ['ens0', 'ens10', 'ens12', 'ens3', 'ens8',
+    'eth0']."""
+    return [int(text) if text.isdigit() else text.lower()
+            for text in re.split(_nsre, s)]
 # vi: ts=4 expandtab

Follow ups