Merge ~raharper/cloud-init:curtin-centos into cloud-init:master
- Git
- lp:~raharper/cloud-init
- curtin-centos
- Merge into master
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 7e41b2a773b81452f14a18ec8c4f3316a66d3f5e | ||||||||||||
Proposed branch: | ~raharper/cloud-init:curtin-centos | ||||||||||||
Merge into: | cloud-init:master | ||||||||||||
Diff against target: |
357 lines (+232/-3) 4 files modified
cloudinit/net/eni.py (+1/-1) cloudinit/net/sysconfig.py (+18/-0) cloudinit/sources/DataSourceAzure.py (+1/-1) tests/unittests/test_net.py (+212/-1) |
||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
cloud-init Commiters | Pending | ||
Review via email: mp+327648@code.launchpad.net |
Commit message
Description of the change
WIP branch with changes for el6/el7 networking rendering
Scott Moser (smoser) wrote : | # |
Ryan Harper (raharper) wrote : | # |
Not sure that's right (I Think it should be IPV6_GATEWAY0)
On Tue, Jul 18, 2017 at 4:09 PM, Scott Moser <email address hidden> wrote:
> I pulled:
>
> Your-commit trunk-comt summary
> 8da074f831c d1e8eb73ac sysconfig: include GATEWAY value if set in subnet
>
> changes:
> i shorted lines in commit messages and made tox tests pass (had to add the
> newly rendered GATEWAY values) to more than the one test you did it to.
>
> $ git diff 8da074f831c.
> http://
>
> --
> https:/
> cloud-init/
> You are the owner of ~raharper/
>
Scott Moser (smoser) wrote : | # |
i took your commit
Use prefix for ipv6 and set v4 and v6 gateway keys, use DEFROUTE
and put up
https:/
Scott Moser (smoser) wrote : | # |
your commit
Templatize systemd service files
is modified and up at
https:/
Scott Moser (smoser) wrote : | # |
merge for your
Fix sysconfig rendering of virtual interfaces with network configurations
is up at
https:/
i plan on adding a vlan and a simple bridge test.
Scott Moser (smoser) wrote : | # |
merge for
sysconfig: fix ipv6 gateway routes
at
https:/
Scott Moser (smoser) wrote : | # |
sysconfig: handle manual type subnets
is at
https:/
- 14f552e... by Ryan Harper
-
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_addressLP: #1701417
Scott Moser (smoser) wrote : | # |
https:/
has
sysconfig: enable mtu set per subnet, including ipv6 mtu
and then
net: eni route rendering missed ipv6 default route config
- 8bf9253... by Ryan Harper
-
sysconfig: enable mtu set per subnet, including ipv6 mtu
Render MTU values if present in subnet and route configurations
for v4 and v6.LP: #1702513
Scott Moser (smoser) wrote : | # |
marked as merged as we have these all now in trunk.
thanks Ryan
Preview Diff
1 | diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py |
2 | index b707146..bb80ec0 100644 |
3 | --- a/cloudinit/net/eni.py |
4 | +++ b/cloudinit/net/eni.py |
5 | @@ -355,7 +355,7 @@ class Renderer(renderer.Renderer): |
6 | default_gw = " default gw %s" % route['gateway'] |
7 | content.append(up + default_gw + or_true) |
8 | content.append(down + default_gw + or_true) |
9 | - elif route['network'] == '::' and route['netmask'] == 0: |
10 | + elif route['network'] == '::' and route['prefix'] == 0: |
11 | # ipv6! |
12 | default_gw = " -A inet6 default gw %s" % route['gateway'] |
13 | content.append(up + default_gw + or_true) |
14 | diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py |
15 | index b0f2ccf..e4490c4 100644 |
16 | --- a/cloudinit/net/sysconfig.py |
17 | +++ b/cloudinit/net/sysconfig.py |
18 | @@ -264,6 +264,9 @@ class Renderer(renderer.Renderer): |
19 | for (old_key, new_key) in [('mac_address', 'HWADDR'), ('mtu', 'MTU')]: |
20 | old_value = iface.get(old_key) |
21 | if old_value is not None: |
22 | + # only set HWADDR on physical interfaces |
23 | + if old_key == 'mac_address' and iface['type'] != 'physical': |
24 | + continue |
25 | iface_cfg[new_key] = old_value |
26 | |
27 | @classmethod |
28 | @@ -273,6 +276,7 @@ class Renderer(renderer.Renderer): |
29 | |
30 | # modifying base values according to subnets |
31 | for i, subnet in enumerate(subnets, start=len(iface_cfg.children)): |
32 | + mtu_key = 'MTU' |
33 | subnet_type = subnet.get('type') |
34 | if subnet_type == 'dhcp6': |
35 | iface_cfg['IPV6INIT'] = True |
36 | @@ -292,7 +296,13 @@ class Renderer(renderer.Renderer): |
37 | # if iface_cfg['BOOTPROTO'] == 'none': |
38 | # iface_cfg['BOOTPROTO'] = 'static' |
39 | if subnet_is_ipv6(subnet): |
40 | + mtu_key = 'IPV6_MTU' |
41 | iface_cfg['IPV6INIT'] = True |
42 | + if 'mtu' in subnet: |
43 | + iface_cfg[mtu_key] = subnet['mtu'] |
44 | + |
45 | + elif subnet_type == 'manual': |
46 | + iface_cfg['ONBOOT'] = False |
47 | else: |
48 | raise ValueError("Unknown subnet type '%s' found" |
49 | " for interface '%s'" % (subnet_type, |
50 | @@ -425,6 +435,9 @@ class Renderer(renderer.Renderer): |
51 | master_cfg['BONDING_MASTER'] = True |
52 | master_cfg.kind = 'bond' |
53 | |
54 | + if 'mac_address' in iface and iface.get('mac_address'): |
55 | + iface_cfg['MACADDR'] = iface.get('mac_address') |
56 | + |
57 | iface_subnets = iface.get("subnets", []) |
58 | route_cfg = iface_cfg.routes |
59 | cls._render_subnets(iface_cfg, iface_subnets) |
60 | @@ -436,6 +449,7 @@ class Renderer(renderer.Renderer): |
61 | [slave_iface['name'] for slave_iface in |
62 | network_state.iter_interfaces(slave_filter) |
63 | if slave_iface['bond-master'] == iface_name]) |
64 | + |
65 | for index, bond_slave in enumerate(bond_slaves): |
66 | slavestr = 'BONDING_SLAVE%s' % index |
67 | iface_cfg[slavestr] = bond_slave |
68 | @@ -494,6 +508,10 @@ class Renderer(renderer.Renderer): |
69 | for old_key, new_key in cls.bridge_opts_keys: |
70 | if old_key in iface: |
71 | iface_cfg[new_key] = iface[old_key] |
72 | + |
73 | + if 'mac_address' in iface and iface.get('mac_address'): |
74 | + iface_cfg['MACADDR'] = iface.get('mac_address') |
75 | + |
76 | # Is this the right key to get all the connected interfaces? |
77 | for bridged_iface_name in iface.get('bridge_ports', []): |
78 | # Ensure all bridged interfaces are correctly tagged |
79 | diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py |
80 | index b5a95a1..e02d7a7 100644 |
81 | --- a/cloudinit/sources/DataSourceAzure.py |
82 | +++ b/cloudinit/sources/DataSourceAzure.py |
83 | @@ -442,7 +442,7 @@ class DataSourceAzure(sources.DataSource): |
84 | self.ds_cfg['agent_command']) |
85 | try: |
86 | fabric_data = metadata_func() |
87 | - except Exception as exc: |
88 | + except Exception: |
89 | LOG.warning( |
90 | "Error communicating with Azure fabric; You may experience." |
91 | "connectivity issues.", exc_info=True) |
92 | diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py |
93 | index e625934..4e05a82 100644 |
94 | --- a/tests/unittests/test_net.py |
95 | +++ b/tests/unittests/test_net.py |
96 | @@ -422,6 +422,31 @@ NETWORK_CONFIGS = { |
97 | via: 65.61.151.37 |
98 | set-name: eth99 |
99 | """).rstrip(' '), |
100 | + 'expected_sysconfig': { |
101 | + 'ifcfg-eth1': textwrap.dedent("""\ |
102 | + # Created by cloud-init on instance boot automatically, do not edit. |
103 | + # |
104 | + BOOTPROTO=none |
105 | + DEVICE=eth1 |
106 | + HWADDR=cf:d6:af:48:e8:80 |
107 | + NM_CONTROLLED=no |
108 | + ONBOOT=yes |
109 | + TYPE=Ethernet |
110 | + USERCTL=no""").rstrip(' '), |
111 | + 'ifcfg-eth99': textwrap.dedent("""\ |
112 | + # Created by cloud-init on instance boot automatically, do not edit. |
113 | + # |
114 | + BOOTPROTO=dhcp |
115 | + DEFROUTE=yes |
116 | + DEVICE=eth99 |
117 | + GATEWAY=65.61.151.37 |
118 | + HWADDR=c0:d6:9f:2c:e8:80 |
119 | + IPADDR=192.168.21.3 |
120 | + NETMASK=255.255.255.0 |
121 | + NM_CONTROLLED=no |
122 | + ONBOOT=yes |
123 | + TYPE=Ethernet |
124 | + USERCTL=no """).rstrip(' ')}, |
125 | 'yaml': textwrap.dedent(""" |
126 | version: 1 |
127 | config: |
128 | @@ -541,6 +566,8 @@ iface br0 inet static |
129 | # control-alias br0 |
130 | iface br0 inet6 static |
131 | address 2001:1::1/64 |
132 | + post-up route add -A inet6 default gw 2001:4800:78ff:1b::1 || true |
133 | + pre-down route del -A inet6 default gw 2001:4800:78ff:1b::1 || true |
134 | |
135 | auto bond0.200 |
136 | iface bond0.200 inet dhcp |
137 | @@ -675,6 +702,9 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true |
138 | eth3: 50 |
139 | eth4: 75 |
140 | priority: 22 |
141 | + routes: |
142 | + - to: ::/0 |
143 | + via: 2001:4800:78ff:1b::1 |
144 | vlans: |
145 | bond0.200: |
146 | dhcp4: true |
147 | @@ -697,6 +727,146 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true |
148 | - sacchromyces.maas |
149 | - brettanomyces.maas |
150 | """).rstrip(' '), |
151 | + 'expected_sysconfig': { |
152 | + 'ifcfg-bond0': textwrap.dedent("""\ |
153 | + # Created by cloud-init on instance boot automatically, do not edit. |
154 | + # |
155 | + BONDING_MASTER=yes |
156 | + BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 miimon=100" |
157 | + BONDING_SLAVE0=eth1 |
158 | + BONDING_SLAVE1=eth2 |
159 | + BOOTPROTO=dhcp |
160 | + DEVICE=bond0 |
161 | + DHCPV6C=yes |
162 | + IPV6INIT=yes |
163 | + MACADDR=aa:bb:cc:dd:ee:ff |
164 | + NM_CONTROLLED=no |
165 | + ONBOOT=yes |
166 | + TYPE=Bond |
167 | + USERCTL=no |
168 | + """).rstrip(' '), |
169 | + 'ifcfg-bond0.200': textwrap.dedent("""\ |
170 | + # Created by cloud-init on instance boot automatically, do not edit. |
171 | + # |
172 | + BOOTPROTO=dhcp |
173 | + DEVICE=bond0.200 |
174 | + NM_CONTROLLED=no |
175 | + ONBOOT=yes |
176 | + PHYSDEV=bond0 |
177 | + TYPE=Ethernet |
178 | + USERCTL=no |
179 | + VLAN=yes |
180 | + """).rstrip(' '), |
181 | + 'ifcfg-br0': textwrap.dedent("""\ |
182 | + # Created by cloud-init on instance boot automatically, do not edit. |
183 | + # |
184 | + AGEING=250 |
185 | + BOOTPROTO=none |
186 | + DEFROUTE=yes |
187 | + DEVICE=br0 |
188 | + IPADDR=192.168.14.2 |
189 | + IPV6ADDR=2001:1::1/64 |
190 | + IPV6INIT=yes |
191 | + IPV6_DEFAULTGW=2001:4800:78ff:1b::1 |
192 | + NETMASK=255.255.255.0 |
193 | + NM_CONTROLLED=no |
194 | + ONBOOT=yes |
195 | + PRIO=22 |
196 | + STP=off |
197 | + TYPE=Bridge |
198 | + USERCTL=no |
199 | + """).rstrip(' '), |
200 | + 'ifcfg-eth0': textwrap.dedent("""\ |
201 | + # Created by cloud-init on instance boot automatically, do not edit. |
202 | + # |
203 | + BOOTPROTO=none |
204 | + DEVICE=eth0 |
205 | + HWADDR=c0:d6:9f:2c:e8:80 |
206 | + NM_CONTROLLED=no |
207 | + ONBOOT=yes |
208 | + TYPE=Ethernet |
209 | + USERCTL=no |
210 | + """).rstrip(' '), |
211 | + 'ifcfg-eth0.101': textwrap.dedent("""\ |
212 | + # Created by cloud-init on instance boot automatically, do not edit. |
213 | + # |
214 | + BOOTPROTO=none |
215 | + DEFROUTE=yes |
216 | + DEVICE=eth0.101 |
217 | + GATEWAY=192.168.0.1 |
218 | + IPADDR=192.168.0.2 |
219 | + IPADDR1=192.168.2.10 |
220 | + MTU=1500 |
221 | + NETMASK=255.255.255.0 |
222 | + NETMASK1=255.255.255.0 |
223 | + NM_CONTROLLED=no |
224 | + ONBOOT=yes |
225 | + PHYSDEV=eth0 |
226 | + TYPE=Ethernet |
227 | + USERCTL=no |
228 | + VLAN=yes |
229 | + """).rstrip(' '), |
230 | + 'ifcfg-eth1': textwrap.dedent("""\ |
231 | + # Created by cloud-init on instance boot automatically, do not edit. |
232 | + # |
233 | + BOOTPROTO=none |
234 | + DEVICE=eth1 |
235 | + HWADDR=aa:d6:9f:2c:e8:80 |
236 | + MASTER=bond0 |
237 | + NM_CONTROLLED=no |
238 | + ONBOOT=yes |
239 | + SLAVE=yes |
240 | + TYPE=Ethernet |
241 | + USERCTL=no |
242 | + """).rstrip(' '), |
243 | + 'ifcfg-eth2': textwrap.dedent("""\ |
244 | + # Created by cloud-init on instance boot automatically, do not edit. |
245 | + # |
246 | + BOOTPROTO=none |
247 | + DEVICE=eth2 |
248 | + HWADDR=c0:bb:9f:2c:e8:80 |
249 | + MASTER=bond0 |
250 | + NM_CONTROLLED=no |
251 | + ONBOOT=yes |
252 | + SLAVE=yes |
253 | + TYPE=Ethernet |
254 | + USERCTL=no |
255 | + """).rstrip(' '), |
256 | + 'ifcfg-eth3': textwrap.dedent("""\ |
257 | + # Created by cloud-init on instance boot automatically, do not edit. |
258 | + # |
259 | + BOOTPROTO=none |
260 | + BRIDGE=br0 |
261 | + DEVICE=eth3 |
262 | + HWADDR=66:bb:9f:2c:e8:80 |
263 | + NM_CONTROLLED=no |
264 | + ONBOOT=yes |
265 | + TYPE=Ethernet |
266 | + USERCTL=no |
267 | + """).rstrip(' '), |
268 | + 'ifcfg-eth4': textwrap.dedent("""\ |
269 | + # Created by cloud-init on instance boot automatically, do not edit. |
270 | + # |
271 | + BOOTPROTO=none |
272 | + BRIDGE=br0 |
273 | + DEVICE=eth4 |
274 | + HWADDR=98:bb:9f:2c:e8:80 |
275 | + NM_CONTROLLED=no |
276 | + ONBOOT=yes |
277 | + TYPE=Ethernet |
278 | + USERCTL=no |
279 | + """).rstrip(' '), |
280 | + 'ifcfg-eth5': textwrap.dedent("""\ |
281 | + # Created by cloud-init on instance boot automatically, do not edit. |
282 | + # |
283 | + BOOTPROTO=dhcp |
284 | + DEVICE=eth5 |
285 | + HWADDR=98:bb:9f:2c:e8:8a |
286 | + NM_CONTROLLED=no |
287 | + ONBOOT=no |
288 | + TYPE=Ethernet |
289 | + USERCTL=no |
290 | + """).rstrip(' ')}, |
291 | 'yaml': textwrap.dedent(""" |
292 | version: 1 |
293 | config: |
294 | @@ -807,6 +977,10 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true |
295 | address: 192.168.14.2/24 |
296 | - type: static |
297 | address: 2001:1::1/64 # default to /64 |
298 | + routes: |
299 | + - gateway: 2001:4800:78ff:1b::1 |
300 | + netmask: '::' |
301 | + network: '::' |
302 | # A global nameserver. |
303 | - type: nameserver |
304 | address: 8.8.8.8 |
305 | @@ -869,7 +1043,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true |
306 | DEFROUTE=yes |
307 | DEVICE=bond0 |
308 | GATEWAY=192.168.0.1 |
309 | - HWADDR=aa:bb:cc:dd:e8:ff |
310 | + MACADDR=aa:bb:cc:dd:e8:ff |
311 | IPADDR=192.168.0.2 |
312 | IPADDR1=192.168.1.2 |
313 | IPV6ADDR=2001:1::1/92 |
314 | @@ -2004,6 +2178,43 @@ class TestEniRoundTrip(CiTestCase): |
315 | expected, [line for line in found if line]) |
316 | |
317 | |
318 | +class TestSysconfigRoundTrip(CiTestCase): |
319 | + def _render_and_read(self, network_config=None, state=None, dir=None): |
320 | + if dir is None: |
321 | + dir = self.tmp_dir() |
322 | + |
323 | + if network_config: |
324 | + ns = network_state.parse_net_config_data(network_config) |
325 | + elif state: |
326 | + ns = state |
327 | + else: |
328 | + raise ValueError("Expected data or state, got neither") |
329 | + |
330 | + renderer = sysconfig.Renderer() |
331 | + renderer.render_network_state(ns, dir) |
332 | + return dir2dict(dir) |
333 | + |
334 | + def testsimple_render_small(self): |
335 | + entry = NETWORK_CONFIGS['small'] |
336 | + files = self._render_and_read(network_config=yaml.load(entry['yaml'])) |
337 | + expected_sysconfig = entry.get('expected_sysconfig') |
338 | + for ifcfg_name in expected_sysconfig: |
339 | + expected_ifcfg = expected_sysconfig.get(ifcfg_name) |
340 | + ifcfg_path = '/etc/sysconfig/network-scripts/' + ifcfg_name |
341 | + self.assertEqual(expected_ifcfg.splitlines(), |
342 | + files[ifcfg_path].splitlines()) |
343 | + |
344 | + def testsimple_render_all(self): |
345 | + entry = NETWORK_CONFIGS['all'] |
346 | + files = self._render_and_read(network_config=yaml.load(entry['yaml'])) |
347 | + expected_sysconfig = entry.get('expected_sysconfig') |
348 | + for ifcfg_name in expected_sysconfig: |
349 | + expected_ifcfg = expected_sysconfig.get(ifcfg_name) |
350 | + ifcfg_path = '/etc/sysconfig/network-scripts/' + ifcfg_name |
351 | + self.assertEqual(expected_ifcfg.splitlines(), |
352 | + files[ifcfg_path].splitlines()) |
353 | + |
354 | + |
355 | class TestNetRenderers(CiTestCase): |
356 | @mock.patch("cloudinit.net.renderers.sysconfig.available") |
357 | @mock.patch("cloudinit.net.renderers.eni.available") |
I pulled:
Your-commit trunk-comt summary
8da074f831c d1e8eb73ac sysconfig: include GATEWAY value if set in subnet
changes:
i shorted lines in commit messages and made tox tests pass (had to add the newly rendered GATEWAY values) to more than the one test you did it to.
$ git diff 8da074f831c. .d1e8eb73ac | pastebinit -f diff paste.ubuntu. com/25121124/
http://