Merge ~smoser/cloud-init:feature/curtin-centos8 into cloud-init:master

Proposed by Scott Moser
Status: Merged
Merged at revision: 7e41b2a773b81452f14a18ec8c4f3316a66d3f5e
Proposed branch: ~smoser/cloud-init:feature/curtin-centos8
Merge into: cloud-init:master
Diff against target: 224 lines (+159/-1)
2 files modified
cloudinit/net/sysconfig.py (+11/-0)
tests/unittests/test_net.py (+148/-1)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Ryan Harper Approve
Review via email: mp+327838@code.launchpad.net

Commit message

sysconfig: use MACADDR on bonds/bridges to configure mac_address

Previously, sysconfig rendered HWADDR for all interface types, but
that value is only used to identify physical devices. Instead use
MACADDR to configure the MAC on virtual devices, like bonds and
bridges.

- Sort bond slave list to ensure consistent ordering in sysconfig
  rendered files.
- Add unittests for sysconfig rendering of bonds/bridges with
  mac_address

LP: #1701417

To post a comment you must log in.
Revision history for this message
Ryan Harper (raharper) wrote :

Looks good.

review: Approve
Revision history for this message
Chad Smith (chad.smith) :
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:b440a27ec07b54d36acbcac637c240f0cee5c9a6
https://jenkins.ubuntu.com/server/job/cloud-init-ci/71/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/71/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/72/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: CentOS 6 & 7: Build & Test
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/72/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
2index c7df36c..9184bce 100644
3--- a/cloudinit/net/sysconfig.py
4+++ b/cloudinit/net/sysconfig.py
5@@ -264,6 +264,9 @@ class Renderer(renderer.Renderer):
6 for (old_key, new_key) in [('mac_address', 'HWADDR'), ('mtu', 'MTU')]:
7 old_value = iface.get(old_key)
8 if old_value is not None:
9+ # only set HWADDR on physical interfaces
10+ if old_key == 'mac_address' and iface['type'] != 'physical':
11+ continue
12 iface_cfg[new_key] = old_value
13
14 @classmethod
15@@ -430,6 +433,9 @@ class Renderer(renderer.Renderer):
16 master_cfg['BONDING_MASTER'] = True
17 master_cfg.kind = 'bond'
18
19+ if iface.get('mac_address'):
20+ iface_cfg['MACADDR'] = iface.get('mac_address')
21+
22 iface_subnets = iface.get("subnets", [])
23 route_cfg = iface_cfg.routes
24 cls._render_subnets(iface_cfg, iface_subnets)
25@@ -441,6 +447,7 @@ class Renderer(renderer.Renderer):
26 [slave_iface['name'] for slave_iface in
27 network_state.iter_interfaces(slave_filter)
28 if slave_iface['bond-master'] == iface_name])
29+
30 for index, bond_slave in enumerate(bond_slaves):
31 slavestr = 'BONDING_SLAVE%s' % index
32 iface_cfg[slavestr] = bond_slave
33@@ -499,6 +506,10 @@ class Renderer(renderer.Renderer):
34 for old_key, new_key in cls.bridge_opts_keys:
35 if old_key in iface:
36 iface_cfg[new_key] = iface[old_key]
37+
38+ if iface.get('mac_address'):
39+ iface_cfg['MACADDR'] = iface.get('mac_address')
40+
41 # Is this the right key to get all the connected interfaces?
42 for bridged_iface_name in iface.get('bridge_ports', []):
43 # Ensure all bridged interfaces are correctly tagged
44diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
45index d15cd1f..caf3134 100644
46--- a/tests/unittests/test_net.py
47+++ b/tests/unittests/test_net.py
48@@ -422,6 +422,28 @@ NETWORK_CONFIGS = {
49 via: 65.61.151.37
50 set-name: eth99
51 """).rstrip(' '),
52+ 'expected_sysconfig': {
53+ 'ifcfg-eth1': textwrap.dedent("""\
54+ BOOTPROTO=none
55+ DEVICE=eth1
56+ HWADDR=cf:d6:af:48:e8:80
57+ NM_CONTROLLED=no
58+ ONBOOT=yes
59+ TYPE=Ethernet
60+ USERCTL=no"""),
61+ 'ifcfg-eth99': textwrap.dedent("""\
62+ BOOTPROTO=dhcp
63+ DEFROUTE=yes
64+ DEVICE=eth99
65+ GATEWAY=65.61.151.37
66+ HWADDR=c0:d6:9f:2c:e8:80
67+ IPADDR=192.168.21.3
68+ NETMASK=255.255.255.0
69+ NM_CONTROLLED=no
70+ ONBOOT=yes
71+ TYPE=Ethernet
72+ USERCTL=no"""),
73+ },
74 'yaml': textwrap.dedent("""
75 version: 1
76 config:
77@@ -758,6 +780,119 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
78 - sacchromyces.maas
79 - brettanomyces.maas
80 """).rstrip(' '),
81+ 'expected_sysconfig': {
82+ 'ifcfg-bond0': textwrap.dedent("""\
83+ BONDING_MASTER=yes
84+ BONDING_OPTS="mode=active-backup """
85+ """xmit_hash_policy=layer3+4 """
86+ """miimon=100"
87+ BONDING_SLAVE0=eth1
88+ BONDING_SLAVE1=eth2
89+ BOOTPROTO=dhcp
90+ DEVICE=bond0
91+ DHCPV6C=yes
92+ IPV6INIT=yes
93+ MACADDR=aa:bb:cc:dd:ee:ff
94+ NM_CONTROLLED=no
95+ ONBOOT=yes
96+ TYPE=Bond
97+ USERCTL=no"""),
98+ 'ifcfg-bond0.200': textwrap.dedent("""\
99+ BOOTPROTO=dhcp
100+ DEVICE=bond0.200
101+ NM_CONTROLLED=no
102+ ONBOOT=yes
103+ PHYSDEV=bond0
104+ TYPE=Ethernet
105+ USERCTL=no
106+ VLAN=yes"""),
107+ 'ifcfg-br0': textwrap.dedent("""\
108+ AGEING=250
109+ BOOTPROTO=none
110+ DEFROUTE=yes
111+ DEVICE=br0
112+ IPADDR=192.168.14.2
113+ IPV6ADDR=2001:1::1/64
114+ IPV6INIT=yes
115+ IPV6_DEFAULTGW=2001:4800:78ff:1b::1
116+ NETMASK=255.255.255.0
117+ NM_CONTROLLED=no
118+ ONBOOT=yes
119+ PRIO=22
120+ STP=off
121+ TYPE=Bridge
122+ USERCTL=no"""),
123+ 'ifcfg-eth0': textwrap.dedent("""\
124+ BOOTPROTO=none
125+ DEVICE=eth0
126+ HWADDR=c0:d6:9f:2c:e8:80
127+ NM_CONTROLLED=no
128+ ONBOOT=yes
129+ TYPE=Ethernet
130+ USERCTL=no"""),
131+ 'ifcfg-eth0.101': textwrap.dedent("""\
132+ BOOTPROTO=none
133+ DEFROUTE=yes
134+ DEVICE=eth0.101
135+ GATEWAY=192.168.0.1
136+ IPADDR=192.168.0.2
137+ IPADDR1=192.168.2.10
138+ MTU=1500
139+ NETMASK=255.255.255.0
140+ NETMASK1=255.255.255.0
141+ NM_CONTROLLED=no
142+ ONBOOT=yes
143+ PHYSDEV=eth0
144+ TYPE=Ethernet
145+ USERCTL=no
146+ VLAN=yes"""),
147+ 'ifcfg-eth1': textwrap.dedent("""\
148+ BOOTPROTO=none
149+ DEVICE=eth1
150+ HWADDR=aa:d6:9f:2c:e8:80
151+ MASTER=bond0
152+ NM_CONTROLLED=no
153+ ONBOOT=yes
154+ SLAVE=yes
155+ TYPE=Ethernet
156+ USERCTL=no"""),
157+ 'ifcfg-eth2': textwrap.dedent("""\
158+ BOOTPROTO=none
159+ DEVICE=eth2
160+ HWADDR=c0:bb:9f:2c:e8:80
161+ MASTER=bond0
162+ NM_CONTROLLED=no
163+ ONBOOT=yes
164+ SLAVE=yes
165+ TYPE=Ethernet
166+ USERCTL=no"""),
167+ 'ifcfg-eth3': textwrap.dedent("""\
168+ BOOTPROTO=none
169+ BRIDGE=br0
170+ DEVICE=eth3
171+ HWADDR=66:bb:9f:2c:e8:80
172+ NM_CONTROLLED=no
173+ ONBOOT=yes
174+ TYPE=Ethernet
175+ USERCTL=no"""),
176+ 'ifcfg-eth4': textwrap.dedent("""\
177+ BOOTPROTO=none
178+ BRIDGE=br0
179+ DEVICE=eth4
180+ HWADDR=98:bb:9f:2c:e8:80
181+ NM_CONTROLLED=no
182+ ONBOOT=yes
183+ TYPE=Ethernet
184+ USERCTL=no"""),
185+ 'ifcfg-eth5': textwrap.dedent("""\
186+ BOOTPROTO=dhcp
187+ DEVICE=eth5
188+ HWADDR=98:bb:9f:2c:e8:8a
189+ NM_CONTROLLED=no
190+ ONBOOT=no
191+ TYPE=Ethernet
192+ USERCTL=no""")
193+ },
194 'yaml': textwrap.dedent("""
195 version: 1
196 config:
197@@ -934,7 +1069,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
198 DEFROUTE=yes
199 DEVICE=bond0
200 GATEWAY=192.168.0.1
201- HWADDR=aa:bb:cc:dd:e8:ff
202+ MACADDR=aa:bb:cc:dd:e8:ff
203 IPADDR=192.168.0.2
204 IPADDR1=192.168.1.2
205 IPV6ADDR=2001:1::1/92
206@@ -1564,6 +1699,18 @@ USERCTL=no
207 self._compare_files_to_expected(entry['expected_sysconfig'], found)
208 self._assert_headers(found)
209
210+ def test_all_config(self):
211+ entry = NETWORK_CONFIGS['all']
212+ found = self._render_and_read(network_config=yaml.load(entry['yaml']))
213+ self._compare_files_to_expected(entry['expected_sysconfig'], found)
214+ self._assert_headers(found)
215+
216+ def test_small_config(self):
217+ entry = NETWORK_CONFIGS['small']
218+ found = self._render_and_read(network_config=yaml.load(entry['yaml']))
219+ self._compare_files_to_expected(entry['expected_sysconfig'], found)
220+ self._assert_headers(found)
221+
222 def test_v4_and_v6_static_config(self):
223 entry = NETWORK_CONFIGS['v4_and_v6_static']
224 found = self._render_and_read(network_config=yaml.load(entry['yaml']))

Subscribers

People subscribed via source and target branches