Initial commit
[ta/config-manager.git] / cmframework / scripts / common.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
18 #
19 # Collection of variables and functions for the bootstrap.sh
20
21 set -o nounset
22
23 #
24 # Variables
25 #
26
27 CM_IP=127.0.0.1
28 CM_PORT=61100
29 CMCLI="/usr/local/bin/cmcli --ip $CM_IP --port $CM_PORT --client-lib cmframework.lib.cmclientimpl.CMClientImpl"
30 CM_ACTIVATORS=/opt/cmframework/activators
31 CM_PID=
32 CM_VALIDATORS=/opt/cmframework/validators
33 CM_INVENTORY_HANDLERS=/opt/cmframework/inventoryhandlers
34 DB_IP=127.0.0.1
35 DB_CHECK_CMD="/bin/redis-cli -h $DB_IP --scan --pattern '*'"
36 DB_PORT=6379
37 DB_STARTUP_CMD="/bin/redis-server ./redis.conf"
38 INVENTORY_FILE=/opt/cmframework/inventory.data
39 STATE_FILE=/etc/installation_state
40 USER_CONFIG_HANDLERS=/opt/cmframework/userconfighandlers
41
42 #
43 # Source log variables and functions
44 #
45 source $(dirname "${BASH_SOURCE[0]}")/log.sh
46
47 #
48 # Functions
49 #
50
51 function run_cmd()
52 {
53     local result
54     local ret
55     log_info "Running $*"
56     result=$(eval "$*" 2>&1)
57     ret=$?
58     if [ $ret -ne 0 ]; then
59         log_error "Failed with error $result"
60     else
61         log_info "Command succeeded: $result"
62     fi
63
64     return $ret
65 }
66
67 function stop_process()
68 {
69     local pid=$1
70     log_info "Stopping process $pid"
71     if ! [ -z $pid ]; then
72         if [ -d /proc/$pid ]; then
73             log_info "Shutting down process $pid gracefully"
74             run_cmd "pkill -TERM -g $pid"
75             log_info "Waiting for process $pid to exit"
76             for ((i=0; i<10; i++)); do
77                 if ! [ -d /proc/$pid ]; then
78                     log_info "Process $pid exited"
79                     break
80                 fi
81                 log_info "Process $pid is still running"
82                 sleep 2
83             done
84
85             if [ -d /proc/$pid ]; then
86                 log_error "Process $pid is still running, forcefully shutting it down"
87                 run_cmd "pkill -KILL -g $pid"
88             fi
89         fi
90     fi
91 }
92
93 function cleanup()
94 {
95     log_info "Cleaning up"
96     systemctl stop redis
97     stop_process $CM_PID
98     rm -f $INVENTORY_FILE
99 }
100
101 function start_db()
102 {
103     log_info "Starting redis db using $DB_STARTUP_CMD"
104     systemctl start redis
105     log_info "Wait till DB is serving"
106     local dbok
107     dbok=0
108     for ((i=0; i<10; i++)); do
109         run_cmd "$DB_CHECK_CMD"
110         dbok=$?
111         if [ $dbok -eq 0 ]; then
112             break
113         fi
114         log_info "DB still not running"
115         sleep 2
116     done
117
118     return $dbok
119 }
120
121 function start_cm()
122 {
123     rm -f "${STATE_FILE}"
124     log_info "Starting CM server"
125     setsid /usr/local/bin/cmserver --ip $CM_IP --port $CM_PORT \
126         --backend-api cmframework.redisbackend.cmredisdb.CMRedisDB \
127         --backend-uri redis://:@$DB_IP:$DB_PORT \
128         --log-level debug \
129         --validators $CM_VALIDATORS \
130         --activators $CM_ACTIVATORS \
131         --disable-remote-activation \
132         --log-dest console \
133         --log-level debug \
134         --inventory-handlers $CM_INVENTORY_HANDLERS \
135         --inventory-data $INVENTORY_FILE \
136         --activationstate-handler-api cmframework.utils.cmdsshandler.CMDSSHandler \
137         --activationstate-handler-uri /run/.dss-server \
138         --alarmhandler-api cmframework.lib.cmalarmhandler_dummy.AlarmHandler_Dummy \
139         --install-phase \
140         --snapshot-handler-api cmframework.utils.cmdsshandler.CMDSSHandler \
141         --snapshot-handler-uri /run/.dss-server \
142         --verbose 2> "$CM_LOG" 1>&2 &
143     export CM_PID=$!
144     log_info "cmserver pid is $CM_PID"
145     if ! [ -d /proc/$CM_PID ]; then
146         log_error "CM server is not running!"
147         log_info "Check redis.log and $BOOTSTRAP_LOG for details"
148         return 1
149     fi
150
151     log_info "Wait till cmserver is ready to serve"
152     local out
153     while true; do
154         out=$($CMCLI get-properties --matching-filter '.*' 2>&1)
155         if [ $? -eq 0 ]; then
156             break
157         fi
158         echo $out | grep "Not found" 2> /dev/null 1>&2
159         if [ $? -eq 0 ]; then
160             break
161         fi
162         log_info "cmserver not ready yet, got error $out"
163         sleep 1
164     done
165     return 0
166 }
167
168 function handle_user_config()
169 {
170     log_info "Handling user configuration from file $CONFIG_FILE"
171     run_cmd "$CMCLI bootstrap --config $CONFIG_FILE --plugin_path $USER_CONFIG_HANDLERS"
172     return $?
173 }
174
175 function start_installation()
176 {
177     log_info "Start installation"
178     handle_user_config
179     return $?
180 }
181
182 function wait_installation_complete()
183 {
184     log_info "Waiting for installation to complete"
185     while true; do
186         if [ -f $STATE_FILE ]; then
187             log_info "installation completed"
188             break
189         fi
190         sleep 5
191     done
192     local result
193     result=$(cat $STATE_FILE)
194
195     if [ "$result" == "success" ]; then
196         log_info "exiting with success :)"
197         return 0
198     else
199         log_error "exiting with failure :("
200         return 1
201     fi
202 }
203
204 function execute_post_install()
205 {
206     log_info "Start post installation"
207     return 0
208 }
209
210 function parameter_exists_in_list()
211 {
212     local EXPECTED_PARAM=$1
213     shift
214     local PARAM_LIST=$*
215     local PARAM
216     for PARAM in ${PARAM_LIST}
217     do
218         if [ "${PARAM}" == "${EXPECTED_PARAM}" ]
219         then
220             return 0
221         fi
222     done
223     return 1
224 }
225
226 function get_next_boot_args()
227 (
228     GRUB_CMDLINE_LINUX=""
229     GRUB_CMDLINE_LINUX_DEFAULT=""
230
231     if source /etc/default/grub > /dev/null
232     then
233         echo "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
234     fi
235 )
236
237 function get_current_boot_args()
238 {
239     local CURRENT_BOOT_ARGS
240     local CMDLINE_PATTERN='BOOT_IMAGE='
241     CURRENT_BOOT_ARGS=$(grep ${CMDLINE_PATTERN} /proc/cmdline)
242     CURRENT_BOOT_ARGS=${CURRENT_BOOT_ARGS#${CMDLINE_PATTERN}}
243     CURRENT_BOOT_ARGS=${CURRENT_BOOT_ARGS#\"}
244     CURRENT_BOOT_ARGS=${CURRENT_BOOT_ARGS%\"}
245     echo "${CURRENT_BOOT_ARGS}"
246 }
247
248 function has_kernel_parameters_changed()
249 {
250     local CURRENT_BOOT_ARGS
251     CURRENT_BOOT_ARGS=$(get_current_boot_args)
252     local NEXT_BOOT_ARG
253     for NEXT_BOOT_ARG in $(get_next_boot_args)
254     do
255         if ! parameter_exists_in_list "${NEXT_BOOT_ARG}" "${CURRENT_BOOT_ARGS}"
256         then
257             log_info "kernel parameter <${NEXT_BOOT_ARG}> does not exist in [${CURRENT_BOOT_ARGS}]"
258             return 0
259         fi
260     done
261     return 1
262 }
263
264 function reboot_host()
265 {
266     local DELAY=5
267     log_info "Reboot the host in ${DELAY} seconds to apply the kernel parameter changes"
268     sleep ${DELAY}
269     systemctl reboot
270 }