diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py index 8374cfcc8789..3793fd11c412 100644 --- a/cloudinit/net/network_manager.py +++ b/cloudinit/net/network_manager.py @@ -71,6 +71,53 @@ def _set_default(self, section, option, value): if not self.config.has_option(section, option): self.config[section][option] = value + def _config_option_is_set(self, section, option): + """ + Checks if a config option is set. Returns True if it is, + else returns False. + """ + return self.config.has_section(section) and self.config.has_option( + section, option + ) + + def _get_config_option(self, section, option): + """ + Returns the value of a config option if its set, + else returns None. + """ + if self._config_option_is_set(section, option): + return self.config[section][option] + else: + return None + + def _change_set_config_option(self, section, option, value): + """ + Overrides the value of a config option if its already set. + Else, if the config option is not set, it does nothing. + """ + if self._config_option_is_set(section, option): + self.config[section][option] = value + + def _set_mayfail_true_if_both_false(self): + """ + If for both ipv4 and ipv6, 'may-fail' is set to be False, + set it to True for both of them. + """ + for family in ["ipv4", "ipv6"]: + if not self._config_option_is_set(family, "may-fail"): + # if either ipv4 or ipv6 sections are not set/configured, + # do not do anything. + return + if self._get_config_option(family, "may-fail") == "true": + # if for either ipv4 or ipv6, 'may-fail' is 'true', do + # not do anything. + return + + # if we landed here, it means both ipv4 and ipv6 are configured + # and both have 'may-fail' set to 'false'. So set both to 'true'. + for family in ["ipv4", "ipv6"]: + self._change_set_config_option(family, "may-fail", "true") + def _set_ip_method(self, family, subnet_type): """ Ensures there's appropriate [ipv4]/[ipv6] for given family @@ -116,6 +163,14 @@ def _set_ip_method(self, family, subnet_type): self.config[family]["method"] = method self._set_default(family, "may-fail", "false") + # we do not want to set may-fail to false for both ipv4 and ipv6 at the + # at the same time. This will make the network configuration work only + # when both ipv4 and ipv6 succeeds. This may not be what we want. + # If we have configured both ipv4 and ipv6, any one succeeding should + # be enough. Therefore, if "may-fail" is set to False for both ipv4 + # and ipv6, set them both to True. + self._set_mayfail_true_if_both_false() + def _add_numbered(self, section, key_prefix, value): """ Adds a numbered property, such as address or route, ensuring diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py index 3e8f721f098b..5ad910ee9b2e 100644 --- a/tests/unittests/test_net.py +++ b/tests/unittests/test_net.py @@ -1425,11 +1425,11 @@ [ipv4] method=auto - may-fail=false + may-fail=true [ipv6] method=auto - may-fail=false + may-fail=true """ ), @@ -1558,12 +1558,12 @@ [ipv4] method=manual - may-fail=false + may-fail=true address1=192.168.14.2/24 [ipv6] method=manual - may-fail=false + may-fail=true address1=2001:1::1/64 """ @@ -1598,11 +1598,11 @@ [ipv6] method=auto - may-fail=false + may-fail=true [ipv4] method=auto - may-fail=false + may-fail=true """ ), @@ -2876,12 +2876,12 @@ [ipv4] method=manual - may-fail=false + may-fail=true address1=192.168.14.2/24 [ipv6] method=manual - may-fail=false + may-fail=true address1=2001:1::1/64 route1=::/0,2001:4800:78ff:1b::1 @@ -3537,7 +3537,7 @@ [ipv4] method=manual - may-fail=false + may-fail=true address1=192.168.0.2/24 gateway=192.168.0.1 route1=10.1.3.0/24,192.168.0.3 @@ -3545,7 +3545,7 @@ [ipv6] method=manual - may-fail=false + may-fail=true address1=2001:1::1/92 route1=2001:67c::/32,2001:67c:1562::1 route2=3001:67c::/32,3001:67c:15::1 @@ -3659,14 +3659,14 @@ [ipv4] method=manual - may-fail=false + may-fail=true address1=192.168.2.2/24 address2=192.168.1.2/24 gateway=192.168.1.1 [ipv6] method=manual - may-fail=false + may-fail=true address1=2001:1::bbbb/96 route1=::/0,2001:1::1