From ffa6fc88249aa080aa31811a45569a45e567418a Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Thu, 2 Dec 2021 22:36:37 -0600
Subject: [PATCH] Fix exception when no activator found (#1129)

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

Given that there are additional network management tools that we haven't
yet supported with activators, we should log a warning and continue
without network activation here, especially since this was a no-op for
years.

LP: #1948681
---
 cloudinit/distros/__init__.py          | 7 ++++++-
 cloudinit/net/activators.py            | 6 +++++-
 tests/unittests/test_net_activators.py | 5 +++--
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index cf6aad14..fe44f20e 100755
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -228,7 +228,12 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
         # Now try to bring them up
         if bring_up:
             LOG.debug('Bringing up newly configured network interfaces')
-            network_activator = activators.select_activator()
+            try:
+                network_activator = activators.select_activator()
+            except activators.NoActivatorException:
+                LOG.warning("No network activator found, not bringing up "
+                            "network interfaces")
+                return True
             network_activator.bring_up_all_interfaces(network_state)
         else:
             LOG.debug("Not bringing up newly configured network interfaces")
diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py
index 11149548..137338d8 100644
--- a/cloudinit/net/activators.py
+++ b/cloudinit/net/activators.py
@@ -16,6 +16,10 @@ from cloudinit.net.sysconfig import NM_CFG_FILE
 LOG = logging.getLogger(__name__)
 
 
+class NoActivatorException(Exception):
+    pass
+
+
 def _alter_interface(cmd, device_name) -> bool:
     LOG.debug("Attempting command %s for device %s", cmd, device_name)
     try:
@@ -271,7 +275,7 @@ def select_activator(priority=None, target=None) -> Type[NetworkActivator]:
         tmsg = ""
         if target and target != "/":
             tmsg = " in target=%s" % target
-        raise RuntimeError(
+        raise NoActivatorException(
             "No available network activators found%s. Searched "
             "through list: %s" % (tmsg, priority))
     selected = found[0]
diff --git a/tests/unittests/test_net_activators.py b/tests/unittests/test_net_activators.py
index f63a8b74..9da21195 100644
--- a/tests/unittests/test_net_activators.py
+++ b/tests/unittests/test_net_activators.py
@@ -12,7 +12,8 @@ from cloudinit.net.activators import (
     IfUpDownActivator,
     NetplanActivator,
     NetworkManagerActivator,
-    NetworkdActivator
+    NetworkdActivator,
+    NoActivatorException,
 )
 from cloudinit.net.network_state import parse_net_config_data
 from cloudinit.safeyaml import load
@@ -99,7 +100,7 @@ class TestSearchAndSelect:
         resp = search_activator()
         assert resp == []
 
-        with pytest.raises(RuntimeError):
+        with pytest.raises(NoActivatorException):
             select_activator()
 
 
-- 
2.33.0


