Revert "Revert "oran-shell-release: release image for F""
[pti/rtp.git] / meta-starlingx / meta-stx-cloud / recipes-support / puppet / files / stx-puppet / apply_network_config_poky.sh
1 #!/bin/bash
2
3 ################################################################################
4 # Copyright (c) 2016 Wind River Systems, Inc.
5 #
6 # SPDX-License-Identifier: Apache-2.0
7 #
8 ################################################################################
9
10 #
11 #  Purpose of this script is to copy the puppet-built
12 #  network config file from the puppet dir to the /etc/network/interfaces  
13 #  Only copied when difference detected 
14 #
15 #  Please note:  function is_eq_ifcfg() is used to determine if
16 #                cfg files are different
17 #
18
19 ACQUIRE_LOCK=1
20 RELEASE_LOCK=0
21
22 if [ ! -f /var/run/interfaces.puppet ] ; then
23     # No puppet file? Nothing to do!
24     exit 1
25 fi
26
27 function log_it {
28     logger "${0} ${1}"
29 }
30
31 function do_if_up {
32     local iface=$1
33     log_it "Bringing $iface up"
34     /sbin/ifup $iface
35 }
36
37 function do_if_down {
38     local iface=$1
39     log_it "Bringing $iface down"
40     /sbin/ifdown $iface
41 }
42
43 function do_rm {
44     local theFile=$1
45     log_it "Removing $theFile"
46     /bin/rm  $theFile
47 }
48
49 function do_cp {
50     local srcFile=$1
51     local dstFile=$2
52     log_it "copying network cfg $srcFile to $dstFile"
53     cp  $srcFile $dstFile
54 }
55
56 function do_mv {
57     local srcFile=$1
58     local dstFile=$2
59     log_it "Moving network cfg $srcFile to $dstFile"
60     mv  $srcFile $dstFile
61 }
62
63 # Return items in list1 that are not in list2
64 array_diff () {
65     list1=${!1}
66     list2=${!2}
67
68     result=()
69     l2=" ${list2[*]} "
70     for item in ${list1[@]}; do
71         if [[ ! $l2 =~ " $item " ]] ; then
72             result+=($item)
73         fi
74     done
75
76     echo  ${result[@]}
77 }
78
79 function normalized_cfg_attr_value {
80     local cfg=$1
81     local attr_name=$2
82     local attr_value
83     attr_value=$(cat $cfg | grep $attr_name= | awk -F "=" {'print $2'})
84
85
86     #
87     # Special case BONDING_OPTS attribute.
88     #
89     # The BONDING_OPTS attribute contains '=' characters, so is not correctly
90     # parsed by splitting on '=' as done above.  This results in changes to
91     # BONDING_OPTS not causing the interface to be restarted, so the old
92     # BONDING_OPTS still be used.  Because this is only checking for changes,
93     # rather than actually using the returned value, we can return the whole
94     # line.
95     #
96     if [[ "${attr_name}" == "BONDING_OPTS" ]]; then
97         echo "$(cat $cfg | grep $attr_name=)"
98         return $(true)
99     fi
100
101     if [[ "${attr_name}" != "BOOTPROTO" ]]; then
102         echo "${attr_value}"
103         return $(true)
104     fi
105     #
106     # Special case BOOTPROTO attribute.
107     #
108     # The BOOTPROTO attribute is not populated consistently by various aspects
109     # of the system.  Different values are used to indicate a manually
110     # configured interfaces (i.e., one that does not expect to have an IP
111     # address) and so to avoid reconfiguring an interface that has different
112     # values with the same meaning we normalize them here before making any
113     # decisions.
114     #
115     # From a user perspective the values "manual", "none", and "" all have the
116     # same meaning - an interface without an IP address while "dhcp" and
117     # "static" are distinct values with a separate meaning.  In practice
118     # however, the only value that matters from a ifup/ifdown script point of
119     # view is "dhcp".  All other values are ignored.
120     #
121     # In our system we set BOOTPROTO to "static" to indicate that IP address
122     # attributes exist and to "manual"/"none" to indicate that no IP address
123     # attributes exist.  These are not needed by ifup/ifdown as it looks for
124     # the "IPADDR" attribute whenever BOOTPROTO is set to anything other than
125     # "dhcp".
126     #
127     if [[ "${attr_value}" == "none" ]]; then
128         attr_value="none"
129     fi
130     if [[ "${attr_value}" == "manual" ]]; then
131         attr_value="none"
132     fi
133     if [[ "${attr_value}" == "" ]]; then
134         attr_value="none"
135     fi
136     echo "${attr_value}"
137     return $(true)
138 }
139
140 #
141 # returns $(true) if cfg file ( $1 ) has property propName ( $2 ) with a value of propValue ( $3 )
142 #
143 function cfg_has_property_with_value {
144     local cfg=$1
145     local propname=$2
146     local propvalue=$3
147     if [ -f $cfg ]; then
148         if [[ "$(normalized_cfg_attr_value $cfg $propname)" == "${propvalue}" ]]; then
149             return $(true)
150         fi
151     fi
152     return $(false)
153 }
154
155 #
156 # returns $(true) if cfg file is configured as a slave
157 #
158 function is_slave {
159     cfg_has_property_with_value $1 "SLAVE" "yes"
160     return $?
161 }
162
163 #
164 # returns $(true) if cfg file is configured for DHCP
165 #
166 function is_dhcp {
167     cfg_has_property_with_value $1 "BOOTPROTO" "dhcp"
168 }
169
170 #
171 # returns $(true) if cfg file is configured as a VLAN interface
172 #
173 function is_vlan {
174     cfg_has_property_with_value $1 "VLAN" "yes"
175     return $?
176 }
177
178 #
179 # returns $(true) if cfg file is configured as an ethernet interface.  For the
180 # purposes of this script "ethernet" is considered as any interface that is not
181 # a vlan or a slave.  This includes both regular ethernet interfaces and bonded
182 # interfaces.
183 #
184 function is_ethernet {
185     if ! is_vlan $1; then
186         if ! is_slave $1; then
187             return $(true)
188         fi
189     fi
190     return $(false)
191 }
192
193 #
194 # returns $(true) if cfg file represents an interface of the specified type.
195 #
196 function iftype_filter {
197     local iftype=$1
198
199     return $(is_$iftype $2)
200 }
201
202 #
203 # returns $(true) if ifcfg files have the same number of VFs
204 #
205 #
206 function is_eq_sriov_numvfs {
207     local cfg_1=$1
208     local cfg_2=$2
209     local sriov_numvfs_1
210     sriov_numvfs_1=$(grep -o 'echo *[1-9].*sriov_numvfs' $cfg_1 | awk {'print $2'})
211     local sriov_numvfs_2
212     sriov_numvfs_2=$(grep -o 'echo *[1-9].*sriov_numvfs' $cfg_2 | awk {'print $2'})
213
214     sriov_numvfs_1=${sriov_numvfs_1:-0}
215     sriov_numvfs_2=${sriov_numvfs_2:-0}
216
217     if [[ "${sriov_numvfs_1}" != "${sriov_numvfs_2}" ]]; then
218         log_it "$cfg_1 and $cfg_2 differ on attribute sriov_numvfs [${sriov_numvfs_1}:${sriov_numvfs_2}]"
219         return $(false)
220     fi
221
222     return $(true)
223 }
224
225 #
226 # returns $(true) if ifcfg files are equal
227 #
228 # Warning:  Only compares against cfg file attributes:
229 #            BOOTPROTO DEVICE IPADDR NETMASK GATEWAY MTU BONDING_OPTS SRIOV_NUMVFS
230 #
231 function is_eq_ifcfg {
232     local cfg_1=$1
233     local cfg_2=$2
234
235     for attr in BOOTPROTO DEVICE IPADDR NETMASK GATEWAY MTU BONDING_OPTS; do
236         local attr_value1
237         attr_value1=$(normalized_cfg_attr_value $cfg_1 $attr)
238         local attr_value2
239         attr_value2=$(normalized_cfg_attr_value $cfg_2 $attr)
240         if [[ "${attr_value1}" != "${attr_value2}"  ]]; then
241             log_it "$cfg_1 and $cfg_2 differ on attribute $attr"
242             return $(false)
243         fi
244     done
245
246     is_eq_sriov_numvfs $1 $2
247     return $?
248 }
249
250 # Synchronize with sysinv-agent audit (ifup/down to query link speed).
251 function sysinv_agent_lock {
252     case $1 in
253     $ACQUIRE_LOCK)
254         local lock_file="/var/run/apply_network_config.lock"
255         # Lock file should be the same as defined in sysinv agent code
256         local lock_timeout=5
257         local max=15
258         local n=1
259         LOCK_FD=0
260         exec {LOCK_FD}>$lock_file
261         while [[ $n -le $max ]]; do
262
263             flock -w $lock_timeout $LOCK_FD && break
264             log_it "Failed to get lock($LOCK_FD) after $lock_timeout seconds ($n/$max), will retry"
265             sleep 1
266             n=$(($n+1))
267         done
268         if [[ $n -gt $max ]]; then
269             log_it "Failed to acquire lock($LOCK_FD) even after $max retries"
270             exit 1
271         fi
272         ;;
273     $RELEASE_LOCK)
274         [[ $LOCK_FD -gt 0 ]] && flock -u $LOCK_FD
275         ;;
276     esac
277 }
278
279
280 # synchronize with sysinv-agent audit
281 sysinv_agent_lock $ACQUIRE_LOCK
282
283 # check if this is a duplicated configuration
284 if ! diff -I '^#' "/var/run/interfaces.puppet" "/etc/network/interfaces" > /dev/null; then
285     # now copy the puppet changed interfaces to /etc/network/interfaces
286     do_mv /var/run/interfaces.puppet /etc/network/interfaces
287
288     # now restart networking service 
289     /etc/init.d/networking restart
290
291     sleep 5
292 else
293     # need to remove this file also
294     do_rm /var/run/interfaces.puppet
295 fi
296
297
298 # workaround the loopback label addresses cannot be configured as scope of host
299 ip addr show lo | egrep "inet.*global.*lo:" > /tmp/loop$$
300
301 while read addr_info; do 
302         echo $addr_info
303         log_it "replace $addr_info with scope host"
304         addr=`echo $addr_info | cut -d' ' -f 2`
305         ifname=`echo $addr_info | cut -d' ' -f 5`
306         ip addr del $addr dev lo label $ifname
307         ip addr add $addr dev lo scope host label $ifname
308 done < /tmp/loop$$
309
310
311 # unlock: synchronize with sysinv-agent audit
312 sysinv_agent_lock $RELEASE_LOCK