github.com/openshift/installer@v1.4.17/pkg/asset/agent/manifests/network-scripts.go (about) 1 package manifests 2 3 // This file is copied from https://github.com/openshift/assisted-service/blob/master/internal/constants/scripts.go 4 // as its in the internal directory so can't be imported 5 6 // PreNetworkConfigScript script runs on hosts before network manager service starts in order to apply 7 // user's provided network configuration on the host. 8 // If the user provides static network configuration, the network config files will be stored in directory 9 // /etc/assisted/network in the following structure: 10 // 11 // +-- host1 12 // | +--- *.nmconnection 13 // | +--- mac_interface.ini 14 // +-- host2 15 // +--- *.nmconnection 16 // +--- mac_interface.ini 17 // 1. *.nmconnections - files generated by nmstate based on yaml files provided by the user 18 // 2. mac_interface.ini - the file contains mapping of mac-address to logical interface name. 19 // There are two usages for the file: 20 // 1. Map logical interface name to MAC Address of the host. The logical interface name is a 21 // name provided by the user for the interface. It will be replaced by the script with the 22 // actual network interface name. 23 // 2. Identify if a host directory belongs to the current host by matching a MAC Address 24 // from the mapping file with host network interfaces. 25 // 26 // Applying the network configuration of each host will be done by: 27 // 1. Associate the current host with its matching hostX directories. The association will be done by 28 // matching host's mac addresses with those in mac_interface.ini. 29 // 2. Replace logical interface name in nmconnection files with the interface name as set on the host 30 // 3. Rename nmconnection files to start with the interface name (instead of the logical interface name) 31 // 4. Copy the nmconnection files to the target directory. That will be 32 // '/etc/NetworkManager/system-connections' when the script is part of the full ISO and 33 // '/etc/coreos-firstboot-network' when the script is part of the minimal ISO. 34 const PreNetworkConfigScript = `#!/bin/bash 35 36 PATH_PREFIX=${PATH_PREFIX:=''} 37 38 # The directory that contains nmconnection files of all nodes 39 NMCONNECTIONS_DIR=${PATH_PREFIX}/etc/assisted/network 40 MAC_NIC_MAPPING_FILE=mac_interface.ini 41 42 if [[ ! -d "$NMCONNECTIONS_DIR" ]] 43 then 44 echo "Error (exiting): Expected to find the directory $NMCONNECTIONS_DIR on the host but this was not present." 45 exit 0 46 fi 47 48 # A map of host mac addresses to interface names 49 declare -A host_macs_to_hw_iface 50 51 # A mac-to-nic map created from the mapping file associated with the host 52 declare -A logical_mac_nic_map 53 54 # A map from old vlan interface names to new ones 55 declare -A vlan_replacements 56 57 # Working directory used for storage of processed files before installation in the target directory 58 work_dir=$(mktemp -d) 59 60 # Find destination directory based on ISO mode 61 if [[ -f ${PATH_PREFIX}/etc/initrd-release ]]; then 62 ETC_NETWORK_MANAGER="${PATH_PREFIX}/etc/coreos-firstboot-network" 63 else 64 ETC_NETWORK_MANAGER="${PATH_PREFIX}/etc/NetworkManager/system-connections" 65 fi 66 echo "Info: ETC_NETWORK_MANAGER was set to $ETC_NETWORK_MANAGER" 67 68 # Create a map of host mac addresses to their network interfaces 69 function map_host_macs_to_interfaces() { 70 SYS_CLASS_NET_DIR="${PATH_PREFIX}/sys/class/net" 71 for nic in $( ls $SYS_CLASS_NET_DIR ) 72 do 73 mac=$(cat $SYS_CLASS_NET_DIR/$nic/address | tr '[:lower:]' '[:upper:]') 74 [[ -n "$mac" ]] && host_macs_to_hw_iface[$mac]=$nic 75 done 76 } 77 78 # Copy all nmstate files representing a host nic. All these files have the host nic as filename prefix. 79 function copy_physical_nics_files() { 80 host_src_dir=$1 81 mapping_file=$2 82 host_work_dir=$3 83 for mac_address in $(cat $mapping_file | cut -d= -f1 | tr '[:lower:]' '[:upper:]'); do 84 host_nic="${host_macs_to_hw_iface[${mac_address}]:-}" 85 if [[ -n "$host_nic" ]]; then 86 logical_nic="${logical_mac_nic_map[${mac_address}]:-}" 87 if [[ -n "$(ls -A $host_src_dir/*.nmconnection )" ]] ; then 88 for nmfile in $host_src_dir/*.nmconnection ; do 89 filename=$(basename $nmfile) 90 prefix="${filename%%.*}" 91 extension="${filename#*.}" 92 93 if [[ -n "$prefix" ]] && [[ "$prefix" == "$logical_nic" ]] ; then 94 95 # Check to see if adding the vlan id will push the interface name over 15 characters and trim the host interface if so 96 # NetworkManager has a 15 character limit on interface names 97 this_host_nic=${host_nic} 98 vlan_id="$(echo ${extension} | cut -s -d'.' -f1)" 99 if [[ -n "${vlan_id}" ]] ; then 100 len=$(echo -n "${host_nic}.${vlan_id}" | wc -m) 101 if [ "$len" -gt "15" ] ; then 102 extra=$(($len - 15)) 103 nic_len=$(echo -n "${host_nic}" | wc -m) 104 this_host_nic=$(echo ${host_nic} | cut -c -$(($nic_len-$extra))) 105 # record this substitution to be used later 106 vlan_replacements[${host_nic}.${vlan_id}]=${this_host_nic}.${vlan_id} 107 fi 108 fi 109 110 target_file=$host_work_dir/${this_host_nic}.${extension} 111 mv -f $nmfile $target_file 112 echo "Info: Copied $nmfile to $target_file" 113 fi 114 done 115 fi 116 fi 117 done 118 } 119 120 # Copy all files that were not copied already by the function copy_physical_nics_files. These files represent nics 121 # that do not have prefix of physical nic (example: eth0). In this case the file is either copied as is 122 # having the same name as the source file, or if such a name already exists an error is generated 123 function copy_other_files() { 124 host_src_dir=$1 125 host_work_dir=$2 126 if [[ -n "$(ls -A ${host_src_dir}/*.nmconnection)" ]] ; then 127 for nmfile in ${host_src_dir}/*.nmconnection ; do 128 filename=$(basename $nmfile) 129 target_file=$host_work_dir/$filename 130 131 # Copy the file only if the file name was not used already 132 if ! [[ -f $work_dir/$filename ]] ; then 133 mv -f $nmfile $target_file 134 echo "Info: Copied $nmfile to $target_file" 135 else 136 echo "Error: connection file name ${filename} is already in use. Please rename" 137 fi 138 done 139 fi 140 } 141 142 # Update references to host nics in the nmstate files 143 function update_physical_nics_references() { 144 mapping_file=$1 145 host_work_dir=$2 146 if [ "$(ls -A $host_work_dir )" ] ; then 147 for mac_address in $(cat $mapping_file | cut -d= -f1 | tr '[:lower:]' '[:upper:]'); do 148 host_nic="${host_macs_to_hw_iface[${mac_address}]:-}" 149 if [[ -n "$host_nic" ]]; then 150 logical_nic="${logical_mac_nic_map[${mac_address}]:-}" 151 for nmfile in $host_work_dir/*.nmconnection ; do 152 sed -i -e "s/=$logical_nic$/=$host_nic/g" -e "s/=$logical_nic\./=$host_nic\./g" $nmfile 153 echo "Info: Using logical interface name '$logical_nic' for interface with Mac address '$mac_address', updated $nmfile" 154 155 for vlan in "${!vlan_replacements[@]}"; do 156 sed -i "s/=${vlan}/=${vlan_replacements[${vlan}]}/g" $nmfile 157 echo "Info: Replacing instances of logical vlan name ${vlan} with ${vlan_replacements[${vlan}]} in $nmfile" 158 done 159 done 160 fi 161 done 162 fi 163 } 164 165 # Iterate over the host directories and process any of them that having matching interfaces with any of the local nics. 166 # A host directory matches a host if the MAC address of one of the nics of the local host appears in the file 167 # mac_mapping.ini in the directory. 168 function process_host_directories_by_mac_address() { 169 pattern="$(echo -n ${!host_macs_to_hw_iface[@]} | sed 's/ */|/g')" 170 if [[ -z "$pattern" ]] ; then 171 return 172 fi 173 src_dir=$(mktemp -d) 174 cp -r ${NMCONNECTIONS_DIR}/host* $src_dir || /bin/true 175 for host_src_dir in $(ls -1 -d $src_dir/host* || echo) 176 do 177 mapping_file="${host_src_dir}/${MAC_NIC_MAPPING_FILE}" 178 if [[ ! -f "$mapping_file" ]] 179 then 180 echo "Warning: Mapping file $mapping_file is missing. Skipping on directory $host_src_dir" 181 continue 182 fi 183 184 if [[ -z "$(ls -A $host_src_dir/*.nmconnection)" ]] 185 then 186 echo "Warning: Host directory does not contain any nmconnection files, skipping" 187 continue 188 fi 189 190 if grep -q -i -E "$pattern" $mapping_file; then 191 echo "Info: Found host directory: $(basename $host_src_dir) , copying configuration" 192 host_work_dir=$(mktemp -d) 193 194 echo "Info: Copying physical interface files for host $(basename $host_src_dir)" 195 # Copy all physical nics files that match logical nics in the mapping file 196 copy_physical_nics_files $host_src_dir $mapping_file $host_work_dir 197 198 echo "Info: Copying other interface files for host $(basename $host_src_dir)" 199 # Copy the rest of the files from the host directory 200 copy_other_files $host_src_dir $host_work_dir 201 202 echo "Info: Updating references for host $(basename $host_src_dir)" 203 # Update references in the nmstate files to host nics 204 update_physical_nics_references $mapping_file $host_work_dir 205 206 cp $host_work_dir/* $work_dir || /bin/true 207 rm -rf $host_work_dir 208 fi 209 done 210 rm -rf $src_dir 211 } 212 213 function map_mac_logical_nic_mapping() { 214 echo "Info: Checking all '${MAC_NIC_MAPPING_FILE}' for mac to logical nic mappings" 215 # initialize logical_mac_nic_map with mapping file entries 216 for f in $(echo ${NMCONNECTIONS_DIR}/host*/${MAC_NIC_MAPPING_FILE} || echo) ; do 217 readarray -t lines < "${f}" 218 for line in "${lines[@]}" 219 do 220 mac=${line%%=*} 221 nic=${line#*=} 222 logical_mac_nic_map[${mac^^}]=$nic 223 done 224 done 225 } 226 227 228 echo "PreNetworkConfig Start" 229 230 # Get the mac to host nic mapping from local machine 231 map_host_macs_to_interfaces 232 233 # Get mac to local nic mapping from all mac_mapping.ini files in host directories 234 map_mac_logical_nic_mapping 235 236 # Process all relevant files and put them in work_dir 237 process_host_directories_by_mac_address 238 239 # Make sure we do not run any of the following functions if there was no matching config. 240 if [ "$(ls -A $work_dir )" ]; then 241 # Remove default connection file create by NM(nm-initrd-generator). This is a WA until 242 # NM is back to supporting priority between nmconnections. 243 # 244 # Note that when this is intended mostly for the full ISO scenario. In the minimal ISO scenario 245 # this script runs before the 'coreos-coreos-copy-firstboot-network' service, and that script 246 # already removes the connection files, but it doesn't hurt to do it again. 247 mkdir -p ${ETC_NETWORK_MANAGER} 248 echo "Info: Removing default connection files in '$ETC_NETWORK_MANAGER'" 249 rm -f ${ETC_NETWORK_MANAGER}/* 250 echo "Info: Copying files from working directory to '$ETC_NETWORK_MANAGER'" 251 cp -v $work_dir/* ${ETC_NETWORK_MANAGER} 252 else 253 echo "Info: No matching host directories found" 254 fi 255 rm -rf $work_dir 256 echo "PreNetworkConfig End" 257 `