File cloud-init-write-routes.patch of Package cloud-init
xxxxxxxxxx
1
--- cloudinit/distros/__init__.py.orig
2
+++ cloudinit/distros/__init__.py
3
4
5
network_state = parse_net_config_data(netconfig, renderer=renderer)
6
self._write_network_state(network_state, renderer)
7
+ # The sysconfig renderer has no route writing implementation
8
+ # for SUSE yet use the old code for now that depends on the
9
+ # raw config.
10
+ try:
11
+ # Only exists for SUSE distro via this patch all other
12
+ # implementations throw which breaks testing
13
+ self._write_routes(netconfig)
14
+ except AttributeError:
15
+ pass
16
17
# Now try to bring them up
18
if bring_up:
19
--- cloudinit/distros/opensuse.py.orig
20
+++ cloudinit/distros/opensuse.py
21
22
23
import os
24
25
-from cloudinit import distros, helpers
26
+from cloudinit import distros, helpers, net
27
from cloudinit import log as logging
28
from cloudinit import subp, util
29
from cloudinit.distros import rhel_util as rhutil
30
31
conf.set_hostname(hostname)
32
util.write_file(filename, str(conf), 0o644)
33
34
+ def _write_routes_v1(self, netconfig):
35
+ """Write route files, not part of the standard distro interface"""
36
+ # Due to the implementation of the sysconfig renderer default routes
37
+ # are setup in ifcfg-* files. But this does not work on SLES or
38
+ # openSUSE https://bugs.launchpad.net/cloud-init/+bug/1812117
39
+ # this is a very hacky way to get around the problem until a real
40
+ # solution is found in the sysconfig renderer
41
+ device_configs = netconfig.get('config', [])
42
+ default_nets = ('::', '0.0.0.0')
43
+ for config in device_configs:
44
+ if_name = config.get('name')
45
+ subnets = config.get('subnets', [])
46
+ config_routes = ''
47
+ has_default_route = False
48
+ seen_default_gateway = None
49
+ for subnet in subnets:
50
+ # Render the default gateway if it is present
51
+ gateway = subnet.get('gateway')
52
+ if gateway:
53
+ config_routes += ' '.join(
54
+ ['default', gateway, '-', '-\n']
55
+ )
56
+ has_default_route = True
57
+ if not seen_default_gateway:
58
+ seen_default_gateway = gateway
59
+ # Render subnet routes
60
+ routes = subnet.get('routes', [])
61
+ for route in routes:
62
+ dest = route.get('destination') or route.get('network')
63
+ if not dest or dest in default_nets:
64
+ dest = 'default'
65
+ if not has_default_route:
66
+ has_default_route = True
67
+ if dest != 'default':
68
+ netmask = route.get('netmask')
69
+ if netmask:
70
+ if net.is_ipv4_network(netmask):
71
+ prefix = net.ipv4_mask_to_net_prefix(netmask)
72
+ if net.is_ipv6_network(netmask):
73
+ prefix = net.ipv6_mask_to_net_prefix(netmask)
74
+ dest += '/' + str(prefix)
75
+ if '/' not in dest:
76
+ LOG.warning(
77
+ 'Skipping route; has no prefix "%s"', dest
78
+ )
79
+ continue
80
+ gateway = route.get('gateway')
81
+ if not gateway:
82
+ LOG.warning(
83
+ 'Missing gateway for "%s", skipping', dest
84
+ )
85
+ continue
86
+ if (
87
+ dest == 'default'
88
+ and has_default_route
89
+ and gateway == seen_default_gateway
90
+ ):
91
+ dest_info = dest
92
+ if gateway:
93
+ dest_info = ' '.join([dest, gateway, '-', '-'])
94
+ LOG.warning(
95
+ '%s already has default route, skipping "%s"',
96
+ if_name, dest_info
97
+ )
98
+ continue
99
+ config_routes += ' '.join(
100
+ [dest, gateway, '-', '-\n']
101
+ )
102
+ if config_routes:
103
+ route_file = '/etc/sysconfig/network/ifroute-%s' % if_name
104
+ util.write_file(route_file, config_routes)
105
+
106
+ def _render_route_string(self, netconfig_route):
107
+ route_to = netconfig_route.get('to', None)
108
+ route_via = netconfig_route.get('via', None)
109
+ route_metric = netconfig_route.get('metric', None)
110
+ route_string = ''
111
+
112
+ if route_to and route_via:
113
+ route_string = ' '.join([route_to, route_via, '-', '-'])
114
+ if route_metric:
115
+ route_string += ' metric {}\n'.format(route_metric)
116
+ else:
117
+ route_string += '\n'
118
+ else:
119
+ LOG.warning('invalid route definition, skipping route')
120
+
121
+ return route_string
122
+
123
+ def _write_routes_v2(self, netconfig):
124
+ for device_type in netconfig:
125
+ if device_type == 'version':
126
+ continue
127
+
128
+ if device_type == 'routes':
129
+ # global static routes
130
+ config_routes = ''
131
+ for route in netconfig['routes']:
132
+ config_routes += self._render_route_string(route)
133
+ if config_routes:
134
+ route_file = '/etc/sysconfig/network/routes'
135
+ util.write_file(route_file, config_routes)
136
+ else:
137
+ devices = netconfig[device_type]
138
+ for device_name in devices:
139
+ config_routes = ''
140
+ device_config = devices[device_name]
141
+ try:
142
+ gateways = [
143
+ v for k, v in device_config.items()
144
+ if 'gateway' in k
145
+ ]
146
+ for gateway in gateways:
147
+ config_routes += ' '.join(
148
+ ['default', gateway, '-', '-\n']
149
+ )
150
+ for route in device_config.get('routes', []):
151
+ config_routes += self._render_route_string(route)
152
+ if config_routes:
153
+ route_file = \
154
+ '/etc/sysconfig/network/ifroute-{}'.format(
155
+ device_name
156
+ )
157
+ util.write_file(route_file, config_routes)
158
+ except Exception:
159
+ # the parser above epxects another level of nesting
160
+ # which should be there in case it's properly
161
+ # formatted; if not we may get an exception on items()
162
+ pass
163
+
164
+ def _write_routes(self, netconfig):
165
+ netconfig_ver = netconfig.get('version')
166
+ if netconfig_ver == 1:
167
+ self._write_routes_v1(netconfig)
168
+ elif netconfig_ver == 2:
169
+ self._write_routes_v2(netconfig)
170
+ else:
171
+ LOG.warning(
172
+ 'unsupported or missing netconfig version, not writing routes'
173
+ )
174
+
175
@property
176
def preferred_ntp_clients(self):
177
"""The preferred ntp client is dependent on the version."""
178