/
preflight_checks_network_linux.go
334 lines (286 loc) · 11.2 KB
/
preflight_checks_network_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
//go:build linux
// +build linux
package preflight
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/crc-org/crc/v2/pkg/crc/logging"
"github.com/crc-org/crc/v2/pkg/crc/systemd"
"github.com/crc-org/crc/v2/pkg/crc/systemd/states"
crcos "github.com/crc-org/crc/v2/pkg/os"
)
var nmPreflightChecks = []Check{
{
configKeySuffix: "check-systemd-networkd-running",
checkDescription: "Checking if systemd-networkd is running",
check: checkSystemdNetworkdIsNotRunning,
fixDescription: "Network configuration with systemd-networkd is not supported. Perhaps you can try this new network mode: https://github.com/crc-org/crc/wiki/VPN-support--with-an--userland-network-stack",
flags: NoFix,
labels: labels{Os: Linux, NetworkMode: System},
},
{
configKeySuffix: "check-network-manager-installed",
checkDescription: "Checking if NetworkManager is installed",
check: checkNetworkManagerInstalled,
fixDescription: "NetworkManager is required and must be installed manually",
flags: NoFix,
labels: labels{Os: Linux, NetworkMode: System},
},
{
configKeySuffix: "check-network-manager-running",
checkDescription: "Checking if NetworkManager service is running",
check: checkNetworkManagerIsRunning,
fixDescription: "NetworkManager is required. Please make sure it is installed and running manually",
flags: NoFix,
labels: labels{Os: Linux, NetworkMode: System},
},
}
var dnsmasqPreflightChecks = []Check{
{
configKeySuffix: "check-network-manager-config",
checkDescription: "Checking if /etc/NetworkManager/conf.d/crc-nm-dnsmasq.conf exists",
check: checkCrcNetworkManagerConfig,
fixDescription: "Writing Network Manager config for crc",
fix: fixCrcNetworkManagerConfig,
cleanupDescription: "Removing /etc/NetworkManager/conf.d/crc-nm-dnsmasq.conf file",
cleanup: removeCrcNetworkManagerConfig,
labels: labels{Os: Linux, NetworkMode: System, DNS: Dnsmasq},
},
{
configKeySuffix: "check-crc-dnsmasq-file",
checkDescription: "Checking if /etc/NetworkManager/dnsmasq.d/crc.conf exists",
check: checkCrcDnsmasqConfigFile,
fixDescription: "Writing dnsmasq config for crc",
fix: fixCrcDnsmasqConfigFile,
cleanupDescription: "Removing /etc/NetworkManager/dnsmasq.d/crc.conf file",
cleanup: removeCrcDnsmasqConfigFile,
labels: labels{Os: Linux, NetworkMode: System, DNS: Dnsmasq},
},
}
var (
crcNetworkManagerRootPath = filepath.Join(string(filepath.Separator), "etc", "NetworkManager")
crcDnsmasqConfigPath = filepath.Join(crcNetworkManagerRootPath, "dnsmasq.d", "crc.conf")
crcDnsmasqConfig = `server=/apps-crc.testing/192.168.130.11
server=/crc.testing/192.168.130.11
`
crcNetworkManagerConfigPath = filepath.Join(crcNetworkManagerRootPath, "conf.d", "crc-nm-dnsmasq.conf")
crcNetworkManagerConfig = `[main]
dns=dnsmasq
`
crcNetworkManagerOldDispatcherPath = filepath.Join(crcNetworkManagerRootPath, "dispatcher.d", "pre-up.d", "99-crc.sh")
crcNetworkManagerDispatcherPath = filepath.Join(crcNetworkManagerRootPath, "dispatcher.d", "99-crc.sh")
crcNetworkManagerDispatcherConfig = `#!/bin/sh
# This is a NetworkManager dispatcher script to configure split DNS for
# the 'crc' libvirt network.
#
# The corresponding crc bridge is not created through NetworkManager, so
# it cannot be configured permanently through NetworkManager. We make the
# change directly using systemd-resolve instead.
#
# systemd-resolve is used instead of resolvectl due to distributions shipping
# systemd releases older than 239 not having the newer renamed tool. resolvectl
# supports being called as systemd-resolve, correctly handling the old CLI.
#
# NetworkManager will overwrite this systemd-resolve configuration every time a
# network connection goes up/down, so we run this script on each of these events
# to restore our settings. This is a NetworkManager bug which is fixed in
# version 1.26.6 by this commit:
# https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=ee4e679bc7479de42780ebd8e3a4d74afa2b2ebe
export LC_ALL=C
systemd-resolve --interface crc --set-dns 192.168.130.11 --set-domain ~testing
exit 0
`
)
var systemdResolvedPreflightChecks = []Check{
{
configKeySuffix: "check-dnsmasq-network-manager-config",
checkDescription: "Checking if dnsmasq configurations file exist for NetworkManager",
check: checkCrcDnsmasqAndNetworkManagerConfigFile,
fixDescription: "Removing dnsmasq configuration file for NetworkManager",
fix: fixCrcDnsmasqAndNetworkManagerConfigFile,
labels: labels{Os: Linux, NetworkMode: System, DNS: SystemdResolved},
},
{
configKeySuffix: "check-systemd-resolved-running",
checkDescription: "Checking if the systemd-resolved service is running",
check: checkSystemdResolvedIsRunning,
fixDescription: "systemd-resolved is required on this distribution. Please make sure it is installed and running manually",
flags: NoFix,
labels: labels{Os: Linux, NetworkMode: System, DNS: SystemdResolved},
},
{
configKeySuffix: "check-network-manager-dispatcher-file",
checkDescription: fmt.Sprintf("Checking if %s exists", crcNetworkManagerDispatcherPath),
check: checkCrcNetworkManagerDispatcherFile,
fixDescription: "Writing NetworkManager dispatcher file for crc",
fix: fixCrcNetworkManagerDispatcherFile,
cleanupDescription: fmt.Sprintf("Removing %s file", crcNetworkManagerDispatcherPath),
cleanup: removeCrcNetworkManagerDispatcherFile,
labels: labels{Os: Linux, NetworkMode: System, DNS: SystemdResolved},
},
}
func fixNetworkManagerConfigFile(path string, content string, perms os.FileMode) error {
err := crcos.WriteToFileAsRoot(
fmt.Sprintf("Writing NetworkManager configuration to %s", path),
content,
path,
perms,
)
if err != nil {
return fmt.Errorf("Failed to write config file: %s: %v", path, err)
}
logging.Debug("Reloading NetworkManager")
sd := systemd.NewHostSystemdCommander()
if err := sd.Reload("NetworkManager"); err != nil {
return fmt.Errorf("Failed to restart NetworkManager: %v", err)
}
return nil
}
func removeNetworkManagerConfigFile(path string) error {
if err := checkNetworkManagerInstalled(); err != nil {
// When NetworkManager is not installed, its config files won't exist
return nil
}
if _, err := os.Stat(path); !os.IsNotExist(err) {
logging.Debugf("Removing NetworkManager configuration file: %s", path)
err := crcos.RemoveFileAsRoot(
fmt.Sprintf("Removing NetworkManager configuration file in %s", path),
path,
)
if err != nil {
return fmt.Errorf("Failed to remove NetworkManager configuration file: %s: %v", path, err)
}
logging.Debug("Reloading NetworkManager")
sd := systemd.NewHostSystemdCommander()
if err := sd.Reload("NetworkManager"); err != nil {
return fmt.Errorf("Failed to restart NetworkManager: %v", err)
}
}
return nil
}
func checkCrcDnsmasqConfigFile() error {
logging.Debug("Checking dnsmasq configuration")
err := crcos.FileContentMatches(crcDnsmasqConfigPath, []byte(crcDnsmasqConfig))
if err != nil {
return err
}
logging.Debug("dnsmasq configuration is good")
return nil
}
func fixCrcDnsmasqConfigFile() error {
logging.Debug("Fixing dnsmasq configuration")
err := fixNetworkManagerConfigFile(crcDnsmasqConfigPath, crcDnsmasqConfig, 0644)
if err != nil {
return err
}
logging.Debug("dnsmasq configuration fixed")
return nil
}
func removeCrcDnsmasqConfigFile() error {
return removeNetworkManagerConfigFile(crcDnsmasqConfigPath)
}
func checkCrcNetworkManagerConfig() error {
logging.Debug("Checking NetworkManager configuration")
err := crcos.FileContentMatches(crcNetworkManagerConfigPath, []byte(crcNetworkManagerConfig))
if err != nil {
return err
}
logging.Debug("NetworkManager configuration is good")
return nil
}
func fixCrcNetworkManagerConfig() error {
logging.Debug("Fixing NetworkManager configuration")
err := fixNetworkManagerConfigFile(crcNetworkManagerConfigPath, crcNetworkManagerConfig, 0644)
if err != nil {
return err
}
logging.Debug("NetworkManager configuration fixed")
return nil
}
func removeCrcNetworkManagerConfig() error {
return removeNetworkManagerConfigFile(crcNetworkManagerConfigPath)
}
func checkSystemdNetworkdIsNotRunning() error {
err := checkSystemdServiceRunning("systemd-networkd.service")
if err == nil {
return fmt.Errorf("systemd-networkd.service is running")
}
logging.Debugf("systemd-networkd.service is not running")
return nil
}
func checkNetworkManagerInstalled() error {
logging.Debug("Checking if 'nmcli' is available")
path, err := exec.LookPath("nmcli")
if err != nil {
return fmt.Errorf("NetworkManager cli nmcli was not found in path")
}
logging.Debug("'nmcli' was found in ", path)
return nil
}
func checkSystemdServiceRunning(service string) error {
logging.Debugf("Checking if %s is running", service)
sd := systemd.NewHostSystemdCommander()
status, err := sd.Status(service)
if err != nil {
return err
}
if status != states.Running {
return fmt.Errorf("%s is not running", service)
}
logging.Debugf("%s is already running", service)
return nil
}
func checkNetworkManagerIsRunning() error {
return checkSystemdServiceRunning("NetworkManager.service")
}
func checkSystemdResolvedIsRunning() error {
return checkSystemdServiceRunning("systemd-resolved.service")
}
func checkCrcNetworkManagerDispatcherFile() error {
logging.Debug("Checking NetworkManager dispatcher file for crc network")
err := crcos.FileContentMatches(crcNetworkManagerDispatcherPath, []byte(crcNetworkManagerDispatcherConfig))
if err != nil {
return err
}
logging.Debug("Dispatcher file has the expected content")
return nil
}
func fixCrcNetworkManagerDispatcherFile() error {
logging.Debug("Fixing NetworkManager dispatcher configuration")
// Remove dispatcher script which was used in crc 1.20 - it's been moved to a new location
_ = removeNetworkManagerConfigFile(crcNetworkManagerOldDispatcherPath)
err := fixNetworkManagerConfigFile(crcNetworkManagerDispatcherPath, crcNetworkManagerDispatcherConfig, 0755)
if err != nil {
return err
}
logging.Debug("NetworkManager dispatcher configuration fixed")
return nil
}
func removeCrcNetworkManagerDispatcherFile() error {
// Remove dispatcher script which was used in crc 1.20 - it's been moved to a new location
_ = removeNetworkManagerConfigFile(crcNetworkManagerOldDispatcherPath)
return removeNetworkManagerConfigFile(crcNetworkManagerDispatcherPath)
}
func checkCrcDnsmasqAndNetworkManagerConfigFile() error {
// IF check return nil, which means file
if _, err := os.Stat(crcDnsmasqConfigPath); !os.IsNotExist(err) {
return fmt.Errorf("%s file exists", crcDnsmasqConfigPath)
}
if _, err := os.Stat(crcNetworkManagerConfigPath); !os.IsNotExist(err) {
return fmt.Errorf("%s file exists", crcNetworkManagerConfigPath)
}
return nil
}
func fixCrcDnsmasqAndNetworkManagerConfigFile() error {
// In case user upgrades from f-32 to f-33 the dnsmasq config for NM still
// exists and needs to be removed.
if err := removeCrcNetworkManagerConfig(); err != nil {
logging.Debugf("%s: not present.", crcNetworkManagerConfigPath)
}
if err := removeCrcDnsmasqConfigFile(); err != nil {
logging.Debugf("%s: not present.", crcDnsmasqConfigPath)
}
return nil
}