Skip to content

Commit 240d7c2

Browse files
committed
parse-nm: Mark dhcp4/dhcp6 as dirty when method=manual (LP: #2160170)
When parsing NM keyfiles with method=manual, explicitly mark dhcp4/dhcp6 as dirty so the YAML serializer outputs "dhcp4: false" / "dhcp6: false". This fixes an issue in multi-file setups where an earlier YAML config with dhcp4:true would not be overridden by a NM keyfile with method=manual, because the false value was not being written to the netplan file. Also update test_keyfile_method_manual to verify the explicit false output.
1 parent e9dd90a commit 240d7c2

4 files changed

Lines changed: 53 additions & 7 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--- a/debian/tests/nm-netplan.py
2+
+++ b/debian/tests/nm-netplan.py
3+
@@ -266,8 +266,8 @@ class TestNetplan(unittest.TestCase):
4+
yaml_data = self._load_netplan_yaml_for_connection(connection)
5+
6+
# Validating some of the expected flags
7+
- self.assertNotIn('dhcp4', yaml_data['network']['bridges']['bridge0'])
8+
- self.assertNotIn('dhcp6', yaml_data['network']['bridges']['bridge0'])
9+
+ self.assertFalse(yaml_data['network']['bridges']['bridge0']['dhcp4'])
10+
+ self.assertFalse(yaml_data['network']['bridges']['bridge0']['dhcp6'])
11+
12+
addresses = yaml_data['network']['bridges']['bridge0']['addresses']
13+
expected_addresses = ['10.20.30.40/24', '10.20.30.41/24', 'dead:beef::1/64', 'dead:beef::2/64']

.github/workflows/network-manager.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ jobs:
6262
MIRROR=http://archive.ubuntu.com/ubuntu autopkgtest-build-lxd ubuntu-daily:resolute # LP: #2052639
6363
- name: Run autopkgtest
6464
run: |
65-
# When we introduce ABI breaking changes, we need to rebuild NM in DEP-8
66-
#pull-lp-source network-manager resolute
65+
# LP#2160170 - Patch NM test to expect dhcp4/dhcp6: false when NM file method=manual
66+
pull-lp-source network-manager resolute
67+
cd network-manager-*/
68+
patch -p1 < $GITHUB_WORKSPACE/.github/workflows/lp2160170-nm-netplan.patch
69+
cd ../
6770
autopkgtest -U \
6871
--env=DEB_BUILD_OPTIONS=nocheck \
6972
--apt-pocket=proposed=src:network-manager \
70-
debian/artifacts/*.deb network-manager -- lxd autopkgtest/ubuntu/resolute/amd64 || test $? -eq 2 # allow for skipped tests (exit code = 2)
73+
debian/artifacts/*.deb network-manager-*/ -- lxd autopkgtest/ubuntu/resolute/amd64 || test $? -eq 2 # allow for skipped tests (exit code = 2)

src/parse-nm.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,16 @@ kf_matches(GKeyFile* kf, const gchar* group, const gchar* key, const gchar* matc
105105
return g_strcmp0(kf_value, match) == 0;
106106
}
107107

108-
STATIC void
108+
STATIC gboolean
109109
set_true_on_match(GKeyFile* kf, const gchar* group, const gchar* key, const gchar* match, const void* dataptr)
110110
{
111111
g_assert(dataptr != NULL);
112112
if (kf_matches(kf, group, key, match)) {
113113
*((gboolean*) dataptr) = TRUE;
114114
_kf_clear_key(kf, group, key);
115+
return TRUE;
115116
}
117+
return FALSE;
116118
}
117119

118120
STATIC void
@@ -678,6 +680,9 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
678680
nd_id = g_strconcat("NM-", uuid, NULL);
679681
g_free(tmp_str);
680682
nd = netplan_netdef_new(npp, nd_id, nd_type, NETPLAN_BACKEND_NM);
683+
/* Required for explicit marking of 'false' values as dirty,
684+
* so they are written to YAML */
685+
npp->current.netdef = nd;
681686

682687
/* Handle uuid & NM name/id */
683688
nd->backend_settings.uuid = g_strdup(uuid);
@@ -754,9 +759,22 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
754759
nd->has_match = TRUE;
755760
}
756761

757-
/* DHCPv4/v6 */
758-
set_true_on_match(kf, "ipv4", "method", "auto", &nd->dhcp4);
759-
set_true_on_match(kf, "ipv6", "method", "auto", &nd->dhcp6);
762+
/* Handle IP Addressing method (auto or manual).
763+
* Explicitly mark dhcp4/dhcp6 as dirty when method=manual,
764+
* so the YAML serializer writes "dhcp4: false" / "dhcp6: false". */
765+
if (!set_true_on_match(kf, "ipv4", "method", "auto", &nd->dhcp4)) {
766+
g_autofree gchar *m4 = g_key_file_get_string(kf, "ipv4", "method", NULL);
767+
if (m4 && g_strcmp0(m4, "manual") == 0) {
768+
mark_data_as_dirty(npp, &nd->dhcp4);
769+
}
770+
}
771+
if (!set_true_on_match(kf, "ipv6", "method", "auto", &nd->dhcp6)) {
772+
g_autofree gchar *m6 = g_key_file_get_string(kf, "ipv6", "method", NULL);
773+
if (m6 && g_strcmp0(m6, "manual") == 0) {
774+
mark_data_as_dirty(npp, &nd->dhcp6);
775+
}
776+
}
777+
760778
parse_dhcp_overrides(kf, "ipv4", &nd->dhcp4_overrides);
761779
parse_dhcp_overrides(kf, "ipv6", &nd->dhcp6_overrides);
762780

tests/parser/test_keyfile.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ def test_keyfile_method_manual(self):
308308
- dead:beef::2
309309
gateway4: 6.6.6.6
310310
gateway6: 6:6::6
311+
dhcp4: false
312+
dhcp6: false
311313
ipv6-address-generation: "stable-privacy"
312314
ipv6-privacy: true
313315
routes:
@@ -358,6 +360,7 @@ def test_keyfile_dummy(self): # wokeignore:rule=dummy
358360
renderer: NetworkManager
359361
addresses:
360362
- "192.168.123.123/24"
363+
dhcp4: false
361364
networkmanager:
362365
uuid: "{}"
363366
name: "Test"
@@ -1035,6 +1038,7 @@ def test_keyfile_vlan(self):
10351038
renderer: NetworkManager
10361039
addresses:
10371040
- "1.2.3.4/24"
1041+
dhcp4: false
10381042
id: 1
10391043
link: "en1"
10401044
networkmanager:
@@ -1327,6 +1331,8 @@ def test_keyfile_netplan0103_compat(self):
13271331
- 4.2.2.2
13281332
- 1::cafe
13291333
- 2::cafe
1334+
dhcp4: false
1335+
dhcp6: false
13301336
ipv6-address-generation: "stable-privacy"
13311337
mtu: 900
13321338
routes:
@@ -1732,6 +1738,8 @@ def test_keyfile_dns_search_ip4_ip6_conflict(self):
17321738
- 4.2.2.2
17331739
- 1::cafe
17341740
- 2::cafe
1741+
dhcp4: false
1742+
dhcp6: false
17351743
mtu: 900
17361744
wakeonlan: true
17371745
networkmanager:
@@ -1776,6 +1784,7 @@ def test_keyfile_nm_140_default_ethernet_group(self):
17761784
renderer: NetworkManager
17771785
addresses:
17781786
- "1.2.3.4/24"
1787+
dhcp4: false
17791788
dhcp6: true
17801789
networkmanager:
17811790
uuid: "{}"
@@ -2433,6 +2442,7 @@ def test_nm_parse_advmss_method_manual(self):
24332442
name: "engreen"
24342443
addresses:
24352444
- "192.168.14.2/24"
2445+
dhcp4: false
24362446
routes:
24372447
- to: "10.10.10.0/24"
24382448
via: "192.168.1.20"
@@ -2506,6 +2516,7 @@ def test_ipv4_route_metric_is_overriden_when_dhcp4_is_disabled(self):
25062516
renderer: NetworkManager
25072517
addresses:
25082518
- "100.85.0.1/24"
2519+
dhcp4: false
25092520
dhcp4-overrides:
25102521
route-metric: 95
25112522
networkmanager:
@@ -2546,6 +2557,7 @@ def test_ipv6_route_metric_is_overriden_when_dhcp6_is_disabled(self):
25462557
renderer: NetworkManager
25472558
addresses:
25482559
- "fdeb:446c:912d:8da::/64"
2560+
dhcp6: false
25492561
dhcp6-overrides:
25502562
route-metric: 95
25512563
networkmanager:

0 commit comments

Comments
 (0)