small-package/floatip/files/floatip.sh

135 lines
3.3 KiB
Bash
Executable File

#!/bin/sh
# random number 0-255
random() {
local num=$(dd if=/dev/urandom bs=1 count=1 2>/dev/null | hexdump -ve '1/1 "%u"')
if [[ -z "$num" ]]; then
num=$(($(grep -om1 '[0-9][0-9]$' /proc/uptime) * 255 / 100))
fi
echo ${num:-1}
}
host_alive() {
ping -4 -c 2 -A -t 1 -W 1 -q "$1" >/dev/null
}
set_up() {
local ipaddr="$1"
echo "set my floatip to $ipaddr" >&2
if ! uci -q get network.floatip.ipaddr | grep -Fwq $ipaddr; then
if [[ "x$(uci -q get network.floatip)" = xinterface ]]; then
uci -q batch <<-EOF >/dev/null
delete network.floatip.ipaddr
add_list network.floatip.ipaddr=$ipaddr
EOF
else
uci -q batch <<-EOF >/dev/null
set network.floatip=interface
set network.floatip.proto=static
add_list network.floatip.ipaddr=$ipaddr
set network.floatip.device=br-lan
set network.floatip.auto=0
EOF
fi
uci commit network
fi
ifup floatip
}
. /lib/functions.sh
fallback_loop() {
local set_ip check_ip set_net set_prefix
config_get set_ip "main" set_ip
config_get check_ip "main" check_ip
eval "$(ipcalc.sh "$set_ip" )";set_net=$NETWORK;set_prefix=$PREFIX;set_ip=$IP
[[ "$set_net" = 0.0.0.0 ]] && set_net=192.168.100.0
[[ "$set_prefix" = 0 ]] && set_prefix=24
[[ "$set_ip" = 0.0.0.0 ]] && set_ip=192.168.100.2
local ipaddr="$set_ip/$set_prefix"
local valid_check_ip cip
for cip in $check_ip; do
eval "$(ipcalc.sh $cip $set_prefix )"
[[ "$NETWORK" = "$set_net" ]] && valid_check_ip="$valid_check_ip $cip"
done
valid_check_ip="$valid_check_ip "
local order_check_ip="$valid_check_ip"
local found_alive consume_time
local dead_counter=0 floatip_up=0
while :; do
found_alive=0
consume_time=0
echo "checking host(s) $order_check_ip alive"
for cip in $order_check_ip; do
if host_alive $cip; then
echo "host $cip alive"
found_alive=1
# reorder to reduce check time
order_check_ip=" ${cip}${valid_check_ip// $cip / }"
break
fi
consume_time=$(($consume_time + 2))
done
if [[ $found_alive = 1 ]]; then
if [[ $floatip_up = 1 ]]; then
echo "set down floatip" >&2
ifdown floatip
floatip_up=0
else
dead_counter=0
fi
[[ $consume_time -lt 10 ]] && sleep $((10 - $consume_time))
continue
fi
if [[ $floatip_up = 1 ]]; then
[[ $consume_time -lt 5 ]] && sleep $((5 - $consume_time))
continue
fi
dead_counter=$(($dead_counter + 1))
if [[ $dead_counter -lt 3 ]]; then
[[ $consume_time -lt 10 ]] && sleep $((10 - $consume_time))
continue
fi
echo "no host alive, set up floatip $ipaddr"
set_up "$ipaddr"
floatip_up=1
sleep 5
done
}
main_loop() {
local set_ip set_net set_prefix
config_get set_ip "main" set_ip
eval "$(ipcalc.sh "$set_ip" )";set_net=$NETWORK;set_prefix=$PREFIX;set_ip=$IP
[[ "$set_net" = 0.0.0.0 ]] && set_net=192.168.100.0
[[ "$set_prefix" = 0 ]] && set_prefix=24
[[ "$set_ip" = 0.0.0.0 ]] && set_ip=192.168.100.2
local ipaddr="$set_ip/$set_prefix"
while :; do
# sleep 2-6s
sleep $(( random / 60 + 2))
echo "checking host $set_ip alive"
if host_alive $set_ip; then
echo "host $set_ip alive"
continue
fi
echo "no host alive, set up floatip $ipaddr"
set_up "$ipaddr"
break
done
}
main() {
local role
config_load floatip
config_get role "main" role
if [[ "$role" = "main" ]]; then
main_loop
elif [[ "$role" = "fallback" ]]; then
fallback_loop
fi
}
main