summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorJames Falcon <james.falcon@canonical.com>2021-10-07 11:27:36 -0500
committerGitHub <noreply@github.com>2021-10-07 10:27:36 -0600
commit9c147e8341e287366790e60658f646cdcc59bef2 (patch)
tree7b4fe68c61d4e9630322e4903fc07f7e4b868cff /cloudinit
parent3d2bac8bf6d0c53f56e14cb2c15b0c695cf0a647 (diff)
downloadvyos-cloud-init-9c147e8341e287366790e60658f646cdcc59bef2.tar.gz
vyos-cloud-init-9c147e8341e287366790e60658f646cdcc59bef2.zip
Allow disabling of network activation (SC-307) (#1048)
In #919 (81299de), we refactored some of the code used to bring up networks across distros. Previously, the call to bring up network interfaces during 'init' stage unintentionally resulted in a no-op such that network interfaces were NEVER brought up by cloud-init, even if new network interfaces were found after crawling the metadata. The code was altered to bring up these discovered network interfaces. On ubuntu, this results in a 'netplan apply' call during 'init' stage for any ubuntu-based distro on a datasource that has a NETWORK dependency. On GCE, this additional 'netplan apply' conflicts with the google-guest-agent service, resulting in an instance that can no be connected to. This commit adds a 'disable_network_activation' option that can be enabled in /etc/cloud.cfg to disable the activation of network interfaces in 'init' stage. LP: #1938299
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/cmd/main.py11
-rw-r--r--cloudinit/cmd/tests/test_main.py23
-rwxr-xr-xcloudinit/distros/__init__.py3
3 files changed, 35 insertions, 2 deletions
diff --git a/cloudinit/cmd/main.py b/cloudinit/cmd/main.py
index 1de1de99..63186d34 100644
--- a/cloudinit/cmd/main.py
+++ b/cloudinit/cmd/main.py
@@ -239,6 +239,12 @@ def purge_cache_on_python_version_change(init):
util.write_file(python_version_path, current_python_version)
+def _should_bring_up_interfaces(init, args):
+ if util.get_cfg_option_bool(init.cfg, 'disable_network_activation'):
+ return False
+ return not args.local
+
+
def main_init(name, args):
deps = [sources.DEP_FILESYSTEM, sources.DEP_NETWORK]
if args.local:
@@ -348,6 +354,7 @@ def main_init(name, args):
util.del_file(os.path.join(path_helper.get_cpath("data"), "no-net"))
# Stage 5
+ bring_up_interfaces = _should_bring_up_interfaces(init, args)
try:
init.fetch(existing=existing)
# if in network mode, and the datasource is local
@@ -367,7 +374,7 @@ def main_init(name, args):
util.logexc(LOG, ("No instance datasource found!"
" Likely bad things to come!"))
if not args.force:
- init.apply_network_config(bring_up=not args.local)
+ init.apply_network_config(bring_up=bring_up_interfaces)
LOG.debug("[%s] Exiting without datasource", mode)
if mode == sources.DSMODE_LOCAL:
return (None, [])
@@ -388,7 +395,7 @@ def main_init(name, args):
# dhcp clients to advertize this hostname to any DDNS services
# LP: #1746455.
_maybe_set_hostname(init, stage='local', retry_stage='network')
- init.apply_network_config(bring_up=bool(mode != sources.DSMODE_LOCAL))
+ init.apply_network_config(bring_up=bring_up_interfaces)
if mode == sources.DSMODE_LOCAL:
if init.datasource.dsmode != mode:
diff --git a/cloudinit/cmd/tests/test_main.py b/cloudinit/cmd/tests/test_main.py
index 1f5975b0..2e380848 100644
--- a/cloudinit/cmd/tests/test_main.py
+++ b/cloudinit/cmd/tests/test_main.py
@@ -4,6 +4,9 @@ from collections import namedtuple
import copy
import os
from io import StringIO
+from unittest import mock
+
+import pytest
from cloudinit.cmd import main
from cloudinit import safeyaml
@@ -162,4 +165,24 @@ class TestMain(FilesystemMockingTestCase):
for log in expected_logs:
self.assertIn(log, self.stderr.getvalue())
+
+class TestShouldBringUpInterfaces:
+ @pytest.mark.parametrize('cfg_disable,args_local,expected', [
+ (True, True, False),
+ (True, False, False),
+ (False, True, False),
+ (False, False, True),
+ ])
+ def test_should_bring_up_interfaces(
+ self, cfg_disable, args_local, expected
+ ):
+ init = mock.Mock()
+ init.cfg = {'disable_network_activation': cfg_disable}
+
+ args = mock.Mock()
+ args.local = args_local
+
+ result = main._should_bring_up_interfaces(init, args)
+ assert result == expected
+
# vi: ts=4 expandtab
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index 63e78591..426a2cf4 100755
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -227,8 +227,11 @@ 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()
network_activator.bring_up_all_interfaces(network_state)
+ else:
+ LOG.debug("Not bringing up newly configured network interfaces")
return False
def apply_network_config_names(self, netconfig):