Initial commit
[ta/start-menu.git] / src / start_menu.sh
1 #!/bin/bash
2
3 # Copyright 2019 Nokia
4
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 DEFAULT_WIDTH=120
18 DEFAULT_HEIGHT=40
19
20 USER_CONFIG_FILE=/etc/userconfig/user_config.yaml
21 LOG_DIR=/var/log/start-menu
22 RC_FILE=/tmp/start_menu.rc
23 DEBUG_FLAG=/opt/start-menu/config/__debug
24
25 function ask_for_device()
26 {
27   device=$1
28   shift 1
29
30   declare -a devices
31   devices=($(ls /sys/class/net))
32   radiolist=""
33   if [ -z "$device" ]; then
34     device=${devices[0]}
35   fi
36   for dev in ${devices[*]}; do
37     if [ "$dev" != "lo" ]; then
38       mac=$(cat /sys/class/net/$dev/address)
39       if [ "$dev" == "$device" ]; then
40         status="on"
41       else
42         status="off"
43       fi
44       radiolist="${radiolist}$dev $mac $status "
45     fi
46   done
47   device=$(dialog --clear --stdout --no-cancel --radiolist "Select network device:" 0 $DEFAULT_WIDTH 10 $radiolist)
48   RC=$?
49   if [ "$RC" -eq 0 ]; then
50     echo $device
51   fi
52
53   return $RC
54 }
55
56 function ask_for_ip()
57 {
58   device=$1
59   address=$2
60
61   rc=1
62   while [ "$rc" -ne 0 ]; do
63     address=$(dialog --clear --stdout --inputbox "Enter IP address for $device (CIDR format):" 0 $DEFAULT_WIDTH $address)
64     if [ "$?" -ne 0 ]; then
65       return 1
66     fi
67
68     if [ -z "$address" ]; then
69       dialog --clear --stdout --msgbox "No address entered" 0 0
70     else
71       # check if valid address
72       err=$(ipcalc -c $address 2>&1)
73       rc=$?
74       if [ "$rc" -ne 0 ]; then
75         dialog --clear --stdout --msgbox "$err" 0 0
76       else
77         # check if network address (prefix given)
78         if [[ $address != */* ]]; then
79           dialog --clear --stdout --msgbox "No CIDR prefix given" 0 0
80         fi
81       fi
82     fi
83   done
84
85   echo $address
86
87   return 0
88 }
89
90 function ask_for_gateway()
91 {
92   device=$1
93   gateway=$2
94
95   rc=1
96   while [ "$rc" -ne 0 ]; do
97     gateway=$(dialog --clear --stdout --inputbox "Enter gateway address for $device:" 0 $DEFAULT_WIDTH $gateway)
98     if [ "$?" -ne 0 ]; then
99       return 1
100     fi
101
102     if [ -z "$gateway" ]; then
103       dialog --clear --stdout --msgbox "No address entered" 0 0
104     else
105       err=$(ipcalc -c $gateway 2>&1)
106       rc=$?
107       if [ "$rc" -ne 0 ]; then
108         dialog --clear --stdout --msgbox "$err" 0 0
109       fi
110     fi
111   done
112
113   echo $gateway
114
115   return 0
116 }
117
118 function ask_for_vlan()
119 {
120   device=$1
121   vlanid=$2
122
123   rc=255
124   while [ "$rc" -eq 255 ]; do
125     dialog --clear --stdout --yesno "Set VLAN for $device?" 0 0
126     rc=$?
127     if [ "$rc" -eq 0 ]; then
128       id_rc=1
129       while [ "$id_rc" -ne 0 ]; do
130         vlanid=$(dialog --clear --stdout --inputbox "Enter VLAN ID:" 0 $DEFAULT_WIDTH $vlanid)
131         id_rc=$?
132         if [ "$id_rc" -eq 255 ]; then
133           return 1
134         fi
135       done
136     fi
137   done
138
139   echo $vlanid
140 }
141
142 function wait_for_gateway()
143 {
144   GATEWAY=$1
145   for i in {1..180}; do
146     echo "$(date)"
147     if [[ $GATEWAY = *:* ]]; then
148         ping -6 -w 1 -c 1 $GATEWAY
149     else
150         ping -w 1 -c 1 $GATEWAY
151     fi
152     if [ "$?" -eq 0 ]; then
153       echo -e "\nping to network gateway OK.\n"
154       return 0
155     else
156       sleep 1
157     fi
158   done
159
160   echo -e "\nping to network gateway failed."
161
162   if [ "$vlanid" != "" ] ; then
163     ip link delete vlan$vlanid
164     rm -f /etc/sysconfig/network-scripts/*vlan$vlanid*
165   else
166     ip a delete $address dev $device
167     rm -f /etc/sysconfig/network-scripts/*$device*
168   fi
169   ip link set $device down
170   dialog --colors --stdout --clear --cr-wrap --title "ERROR" \
171          --msgbox '\n\Z1 Can not ping gateway! \n Shut down link!' 8 29
172 }
173
174 function run_external_network_create_command()
175 {
176   local if_status
177   local max_retries
178   local i
179
180   echo -e "Creating external network."
181   echo -e " Device : $device"
182   echo -e "Address : $address"
183   echo -e "Gateway : $gateway"
184   [ -z "$vlanid" ] || echo -e " VlanId : $vlanid"
185
186   mkdir -p /etc/os-net-config/
187   if [[ $gateway = *:* ]]; then
188     defaultroute=::/0
189   else
190     defaultroute=0.0.0.0/0
191   fi
192   if [ "$vlanid" != "" ]; then
193     sed  "s|PHYDEV|${device}|g;s|VLANID|${vlanid}|g;s|IPADDR|${address}|g;s|DEFAULTROUTE|${defaultroute}|g;s|GATEWAY|${gateway}|g" os_net_config_vlan_template.yml > /etc/os-net-config/config.yaml
194   else
195     sed  "s|PHYDEV|${device}|g;s|IPADDR|${address}|g;s|DEFAULTROUTE|${defaultroute}|g;s|GATEWAY|${gateway}|g" os_net_config_template.yml > /etc/os-net-config/config.yaml
196   fi
197
198   /bin/os-net-config
199   rm -rf /etc/os-net-config/config.yaml
200
201   max_retries=180
202   i=0
203   while [ $i -lt $max_retries ]; do
204     echo "Waiting for interface ${device} to come up..."
205     if_status="$(cat /sys/class/net/${device}/operstate)"
206     [ "$if_status" = "up" ] && break
207     sleep 1;
208     i=$((i+1))
209   done
210   echo "Link status of interface $device : $if_status"
211   [ "$if_status" != "up" ] && \
212     dialog --colors --stdout --clear --cr-wrap --title "ERROR" --msgbox '\n\Z1 Link does not come up!' 8 29
213 }
214
215 function set_external_network()
216 {
217   device=$1
218   address=$2
219   gateway=$3
220   vlanid=$4
221   shift 4
222
223   device=$(ask_for_device "$device")
224   if [ "$?" -ne 0 ]; then
225     return 1
226   fi
227
228   address=$(ask_for_ip "$device" "$address")
229   if [ "$?" -ne 0 ]; then
230     return 1
231   fi
232
233   addr_no_mask=$(awk -F\/ '{print $1}' <<< "$address")
234
235   gateway=$(ask_for_gateway "$device" "$gateway")
236   if [ "$?" -ne 0 ]; then
237     return 1
238   fi
239
240   vlanid=$(ask_for_vlan "$device" "$vlanid")
241   if [ "$?" -ne 0 ]; then
242     return 1
243   fi
244
245   # echo is an ugly hack to workaround dialog bug (ok button loses two first lines of output)
246   (echo -e -n "\n\n"; run_external_network_create_command 2>&1) | tee $LOG_DIR/external_net_create.log | dialog --clear --stdout --progressbox "Setting up external network:" $DEFAULT_HEIGHT $DEFAULT_WIDTH
247
248   # echo is an ugly hack to workaround dialog bug (ok button loses two first lines of output)
249   
250   (echo -e -n "\n\n"; wait_for_gateway $gateway 2>&1) | tee $LOG_DIR/wait_for_gateway.log | sed -ru "s/.{$[DEFAULT_WIDTH-4]}/&\n   /g" | dialog --clear --stdout --programbox "Verify ping to gateway:" $DEFAULT_HEIGHT $DEFAULT_WIDTH
251
252 }
253
254
255 function installation_start()
256 {
257   local config_file
258   config_file=${1}
259   local mode
260   mode=${2}
261   if validate_user_config ${config_file}; then
262     pushd /opt/cmframework/scripts/
263     if ./bootstrap.sh ${config_file} ${mode}; then
264       echo -e "################################################################################"
265       echo -e "#########################  All Done!!  ########################################"
266       echo -e "################################################################################"
267       return 0
268     else
269       echo -e "Installation failed!!!"
270     fi
271   else
272     echo -e "Validation failed!!!"
273     return 1
274   fi
275 }
276
277 function start_install()
278 {
279   local config_file
280   config_file=${1}
281
282   (echo -e -n "\n\n";installation_start ${config_file} --install 2>&1) | tee $LOG_DIR/start_install.log
283 }
284
285 function validate_user_config()
286 {
287   local config_file
288   config_file=${1}
289   if [ -e ${config_file} ]; then
290     return 0
291   else
292     return 1
293   fi
294 }
295
296 function main_menu()
297 {
298   echo -e "Starting main menu"
299   selection="0"
300   while [ "$selection" != "X" ]; do
301     rc=255
302     while [ "$rc" -ne 0 ]; do
303       rm -f /tmp/dialog.out
304       selection=$(dialog --clear --stdout --no-cancel --menu "Installation" 0 0 10 \
305                                         0 "Set external network" \
306                                         1 "Start installation")
307       rc=$?
308     done
309     case $selection in
310       0)
311         set_external_network
312         ;;
313       1)
314         if start_install ${USER_CONFIG_FILE}; then
315           echo "0" > $RC_FILE
316           exit 0
317         else
318           /usr/bin/bash
319         fi
320         ;;
321       *)
322         ;;
323     esac
324   done
325 }
326
327 function create_config_user()
328 {
329   mkdir -p /etc/userconfig/
330   userconfig_passwd=$(python -c "import crypt, getpass, pwd; print crypt.crypt('userconfig')")
331   useradd --home-dir=/etc/userconfig/ --password=$userconfig_passwd userconfig
332   chown userconfig:userconfig /etc/userconfig
333 }
334
335 function delete_config_user()
336 {
337   pkill -u userconfig
338   userdel userconfig
339 }
340
341 while [[ "$(systemctl is-system-running)" == "starting" ]]; do
342   echo "start-menu waiting for systemctl to finish startup..."
343   sleep 10
344 done
345
346 clear
347
348 # disable kernel logs to console
349 echo 3 > /proc/sysrq-trigger
350  
351 mkdir -p $LOG_DIR
352
353 if [ -e $DEBUG_FLAG ]; then
354   logger "start-menu in debug mode"
355   /usr/bin/bash
356 fi
357
358 if [ -e ${USER_CONFIG_FILE} ]; then
359   if start_install ${USER_CONFIG_FILE}; then
360     echo "Install succeeded"
361     echo "0" > $RC_FILE
362     exit 0
363   else
364     echo "Install failed, check logs ($LOG_DIR)"
365     echo "1" > $RC_FILE
366     /usr/bin/bash
367     exit 1
368   fi
369 else
370   main_menu
371 fi