Share: bash scripts to solve boot events

scenario:
after a blackout, a massive number of CPE go online and come to knock our ACS door.

objective:
While most of the time each CPE is correctly configured and the customer should have no problem accessing the net, we want to make sure each one of them has the proper configuration.

solution:
TLDR: give a tag to each CPE and call it later (Hollywood principle: “Don’t call us, we will call you”).

  1. sample preset:

arguments columns are passed to the argv variable. We use that to test if we are really under a boot event and not just a factory reset.

  1. sample provision code (in this preset case, “default”):
var provision = args[0];
const cual_preset = args[1];

    if( provision === "boot" && ( cual_preset === "realboot" ) ) {
        declare( "Tags.ProcesarBoot", null, { value: true } );
        return;
    }

// rest of configuration goes here 
  1. so far so good. here comes the part where we want to call each CPE.
    now we need a process which ask our ASC for all the CPE having this particular tag: ProcesarBoot

replace ACS.com with your ACS. localhost should be fine

root@acs3:~/bin/acs/faults# cat procesar_boot.sh
#!/bin/bash

lista=$(curl -s 'http://ACS.com:7557/devices/?query=%7B%22_tags%22%3A%22ProcesarBoot%22%7D&projection=_id'  -X GET )

nada="[

]"

# no CPE? good
[[ "$lista" == "$nada" ]] && exit 0


logger INICIO ProcesarBoot

# I know this is kinda messy but I rather have multiple simple and clear commands than one that does too much 
lista2=$(echo $lista| python -m json.tool |egrep "_id" |egrep -o '(":\s)(.*)' |egrep -o '\s(.*)' | egrep -o '[^" ]*')

while IFS= read -r devid
do
  
    parte1='http://ACS.com:7557/devices/?query=%7B%22_id%22%3A%22'
    parte2='%22%7D&projection=InternetGatewayDevice.ManagementServer.ConnectionRequestURL'
    completo=$parte1$devid$parte2

    respuesta=$(curl -s  $completo )
    crurl=$(echo $respuesta  | python -m json.tool  | grep value | egrep 'http[^\"]*' -o)

# curl = connection request url

    # procesar IP y ver si el equipo responde
    ip=$(echo $crurl |egrep "[0-9\.]+:" -o |egrep ".*[^:]+" -o)

# wait 1 second. send 1 packet only. discard output.
    ping -w 1 -c 1 $ip >/dev/null 
    if [ "$?" -ne 0 ];     then
        # no direct access to CPE, then remove the tag to prevent futher processing
        logger removing tag from $devid
        curl -s 'http://ACS.com:7557/devices/'$devid'/tags/ProcesarBoot' -X DELETE
    else 
        # equipo responde
        logger BOOT $crurl
        # adapt if you dont use user/password
        curl -s $crurl --digest -u user:password
        # if curl gave an error, try w/o user/password
        [[ "$?" -ne 0 ]] && ( logger forcing ... ;  curl -s $crurl )
        sleep 2 # adapt
    fi


done < <(echo "$lista2")

logger FIN processing boots

how this get executed? using cron is tempting but I think we should avoid at all cost running multiple processes at the same time. Instead I propose, under Debian, we use a “service” /etc/rc.local to fire the script responsible to execute it. Slackware uses /etc/rc.d/rc.local

root@acs3:~/bin/acs/faults# cat  /etc/rc.local 

#!/bin/bash
cd /root/bin/acs/faults
/root/bin/acs/faults/daemon_tr069.sh &
root@acs3:~/bin/acs/faults# cat daemon_tr069.sh 

#!/bin/bash
while true ; do
    sleep 60
    ./procesar_lista.sh
done
root@acs3:~/bin/acs/faults# cat procesar_lista.sh 

#!/bin/bash
cd /root/bin/acs/faults
./procesar_boot.sh

sry about the Spanish mix. hope it helps.

1 Like