From 6b3042e91a03dfd5c1c1498d9c00d6ae765381b6 Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Mon, 15 Aug 2022 16:35:13 -0500
Subject: [PATCH 3/3] Workaround net_setup_link race with udev (#1655)

Reference:https://github.com/canonical/cloud-init/commit/7136109df5a7b3c75dfb05a853fc4485fed25b5f
Conflict:NA

LP: #1983516
---
 cloudinit/net/netplan.py | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py
index 894b5db..7d6740d 100644
--- a/cloudinit/net/netplan.py
+++ b/cloudinit/net/netplan.py
@@ -264,10 +264,27 @@ class Renderer(renderer.Renderer):
             LOG.debug("netplan net_setup_link postcmd disabled")
             return
         setup_lnk = ['udevadm', 'test-builtin', 'net_setup_link']
-        for cmd in [setup_lnk + [SYS_CLASS_NET + iface]
-                    for iface in get_devicelist() if
-                    os.path.islink(SYS_CLASS_NET + iface)]:
-            subp.subp(cmd, capture=True)
+
+         # It's possible we can race a udev rename and attempt to run
+        # net_setup_link on a device that no longer exists. When this happens,
+        # we don't know what the device was renamed to, so re-gather the
+        # entire list of devices and try again.
+        last_exception = Exception
+        for _ in range(5):
+            try:
+                for iface in get_devicelist():
+                    if os.path.islink(SYS_CLASS_NET + iface):
+                        subp.subp(
+                            setup_lnk + [SYS_CLASS_NET + iface], capture=True
+                        )
+                break
+            except subp.ProcessExecutionError as e:
+                last_exception = e
+        else:
+            raise RuntimeError(
+                "'udevadm test-builtin net_setup_link' unable to run "
+                "successfully for all devices."
+            ) from last_exception
 
     def _render_content(self, network_state: NetworkState):
 
-- 
2.40.0

