Skip to content

Commit

Permalink
Allow disabling of network activation
Browse files Browse the repository at this point in the history
In canonical#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.
  • Loading branch information
TheRealFalcon committed Oct 5, 2021
1 parent 81a8f0a commit d6afffa
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
9 changes: 7 additions & 2 deletions cloudinit/cmd/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ def main_init(name, args):
util.del_file(os.path.join(path_helper.get_cpath("data"), "no-net"))

# Stage 5
if util.get_cfg_option_bool(init.cfg, 'disable_network_activation'):
bring_up_interfaces = False
else:
bring_up_interfaces = not args.local
LOG.debug(bring_up_interfaces)
try:
init.fetch(existing=existing)
# if in network mode, and the datasource is local
Expand All @@ -367,7 +372,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, [])
Expand All @@ -388,7 +393,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:
Expand Down
3 changes: 3 additions & 0 deletions cloudinit/distros/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,11 @@ def apply_network_config(self, netconfig, bring_up=False) -> bool:

# 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):
Expand Down
40 changes: 40 additions & 0 deletions tests/integration_tests/datasources/test_network_dependency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pytest

from tests.integration_tests.clouds import IntegrationCloud
from tests.integration_tests.conftest import get_validated_source


def _setup_custom_image(session_cloud: IntegrationCloud):
"""Like `setup_image` in conftest.py, but with customized content."""
source = get_validated_source(session_cloud)
if not source.installs_new_version():
return
client = session_cloud.launch()

# Insert our "disable_network_activation" file here
client.write_to_file(
'/etc/cloud/cloud.cfg.d/99-disable-network-activation.cfg',
'disable_network_activation: true\n',
)

client.install_new_cloud_init(source)
# Even if we're keeping instances, we don't want to keep this
# one around as it was just for image creation
client.destroy()


# This test should be able to work on any cloud whose datasource specifies
# a NETWORK dependency
@pytest.mark.gce
@pytest.mark.ubuntu # Because netplan
def test_network_activation_disabled(session_cloud: IntegrationCloud):
"""Test that the network is not activated during init mode."""
_setup_custom_image(session_cloud)
with session_cloud.launch() as client:
assert client.execute('systemctl is-active google-guest-agent').ok
log = client.read_from_file('/var/log/cloud-init.log')

assert "Running command ['netplan', 'apply']" not in log

assert 'Not bringing up newly configured network interfaces' in log
assert 'Bringing up newly configured network interfaces' not in log

0 comments on commit d6afffa

Please sign in to comment.