-
Notifications
You must be signed in to change notification settings - Fork 413
/
Copy pathNetworkManager-clean-initrd-state.yaml
139 lines (115 loc) · 6.13 KB
/
NetworkManager-clean-initrd-state.yaml
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
mode: 0755
path: "/usr/local/bin/nm-clean-initrd-state.sh"
contents:
inline: |
#!/bin/bash
set -ex -o pipefail
NM_DEVICES_DIR=/run/NetworkManager/devices
NM_RUN_CONN_DIR=/run/NetworkManager/system-connections
NM_ETC_CONN_DIR=/etc/NetworkManager/system-connections
logger -t nm-clean-initrd-state "Cleaning network activation state generated by dracut..."
logger -t nm-clean-initrd-state "To disable, remove /var/lib/mco/nm-clean-initrd-state"
if [ ! -e "$NM_DEVICES_DIR" ] || [ ! -e "$NM_RUN_CONN_DIR" ] || [ ! -e "$NM_ETC_CONN_DIR" ]; then
logger -t nm-clean-initrd-state "There is no network activation state to clean"
exit
fi
# Some deployments require an active network early in the boot process. To
# achieve this, dracut runs specific NetworkManager modules. This results in
# NetworkManager keyfiles being generated (either default or from ip kernel
# arguments) and activated. This activation generates state that makes those
# profiles to be re-activated by the NetworkManager service later in the
# boot process. And this has the effect that other profiles deployed by the
# user for the same set of devices are ignored.
# Most of the time this is the desired behavior. The exception to this rule
# is when the user wants to run the boot process with a different network
# setup than the real root which is usually related to the fact that
# generating images with customized kernel arguments is a complication in
# the deployment pipeline.
# This need has been exacerbated by past NetworkManager bugs that activated
# the network on boot when it was not really needed. Most notably when ip
# kernel argument is present, something that the baremetal installer adds by
# default.
# The intention here is to remove the state that was generated with the
# activation of those profiles during dracut execution. Then when
# NetworkManager service runs, the profiles generated by dracut, along with
# other profiles configured by the user, are evaluated towards finding the
# most appropriate profile to connect a device with. As a precaution, clean
# state only for devices that:
# - have been activated with a default profile (assume that a non-default
# configuration expresses intention by user to run with it permanently)
# - have a specific configured profile set to auto-connect (if there is no
# alternate configured profile for a device it makes no sense to
# de-activate anything)
#
# Although this can theoretically happen on any deployment type, need has
# mostly come from IPI bare metal deployments. For the time being, this
# should be opt-in in any other deploment type.
#
# There is an RFE filed against NM that once implemented would make this
# script unnecessary: https://bugzilla.redhat.com/show_bug.cgi?id=2089707
for device in "${NM_DEVICES_DIR}"/*; do
if [ ! -e "$device" ]; then
continue
fi
# the device file name is the ifindex
ifindex=$(basename "$device")
# get the interface name by ifindex
ifname=$(ip -j link show | jq -r ".[] | select(.ifindex == ${ifindex}) | .ifname // empty")
# no interface name found, ignore
if [ -z "$ifname" ]; then
continue
fi
# get the uuid of the profile the device has been activated with
active_profile_uuid=$(sed -nr '/^\[device\]/,/^\[/{/^connection-uuid\s*=/{s/[^=]+\s*=\s*//;P}}' "$device")
# the device was not activated with any profile, ignore
if [ -z "$active_profile_uuid" ]; then
continue
fi
# find the generated profile by uuid
for profile in "${NM_RUN_CONN_DIR}"/*; do
generated_profile_uuid=$(sed -nr '/^\[connection\]/,/^\[/{/^uuid\s*=/{s/[^=]+\s*=\s*//;P}}' "$profile")
if [ "$active_profile_uuid" = "$generated_profile_uuid" ]; then
break
fi
done
# generated profile not found, ignore
if [ "$active_profile_uuid" != "$generated_profile_uuid" ]; then
continue
fi
# check that it is not specific for the device, otherwise ignore
profile_ifname=$(sed -nr '/^\[connection\]/,/^\[/{/^interface-name\s*=/{s/[^=]+\s*=\s*//;P}}' "$profile")
if [ -n "$profile_ifname" ]; then
continue
fi
# profile not generated by nm-initrd-generator, ignore
# only check it if the key is set (from NM 1.32.4)
origin=$(sed -nr '/^\[user\]/,/^\[/{/^org.freedesktop.NetworkManager.origin\s*=/{s/[^=]+\s*=\s*//;P}}' "$profile")
if [ -n "$origin" ] && [ "$origin" != "nm-initrd-generator" ]; then
continue
fi
# find the configured profile by name with auto-connect set
for profile in "${NM_ETC_CONN_DIR}"/*; do
profile_ifname=$(sed -nr '/^\[connection\]/,/^\[/{/^interface-name\s*=/{s/[^=]+\s*=\s*//;P}}' "$profile")
autoconnect=$(sed -nr '/^\[connection\]/,/^\[/{/^autoconnect\s*=/{s/[^=]+\s*=\s*//;P}}' "$profile")
if [ "$profile_ifname" = "$ifname" ] && [ "$autoconnect" != "false" ]; then
break
fi
done
# configured profile not found, ignore
if [ "$profile_ifname" != "$ifname" ] || [ "$autoconnect" = "false" ]; then
continue
fi
configured_profile_uuid=$(sed -nr '/^\[connection\]/,/^\[/{/^uuid\s*=/{s/[^=]+\s*=\s*//;P}}' "$profile")
logger -t nm-clean-initrd-state "$ifname activated with default generated profile $generated_profile_uuid"
logger -t nm-clean-initrd-state "$ifname has different configured specific profile $configured_profile_uuid"
logger -t nm-clean-initrd-state "$ifname: removing state..."
# NM can still generate internal profiles from the IP address
# configuration of devices, so flush addresses
logger -t nm-clean-initrd-state "Flushing IP addresses from $ifname"
ip addr flush "$ifname"
ip -6 addr flush "$ifname"
# remove device state file to prevent NM to unilaterally connect with the
# latest activated profile without evaluating other profiles
logger -t nm-clean-initrd-state "Removing $device"
rm -f -- "$device"
done