avail/avail.sh

263 lines
7.0 KiB
Bash
Raw Normal View History

2022-08-29 10:48:29 +10:00
#!/bin/bash
[[ -e ${HOME}/.bashtools/bashtools.sh ]] && . ${HOME}/.bashtools/bashtools.sh
if [[ -n $HAVE_BASHTOOLS ]]; then
print1="csecho"
print2="inform"
else
print1="echo"
print2="echo"
fi
function usage() {
echo "usage: $0 [-n] mode v1 [v2] ... [v3]"
echo
echo " -n: plaintext mode, no ansi colours"
echo
echo "Valid modes:"
echo " s = systems in series"
echo " v1 = system1 availability%"
echo " v2 = system1 availability%"
echo " ..."
echo " p = systems in parallel"
echo " v1 = one system's availability%"
echo " v2 = number of systems"
echo " i = individual system"
echo " v1 = mtbr (mean time between failures)"
echo " v2 = mttr (mean time to repair)"
echo ""
}
function line() {
local len fmt out
len=$1
cmd="printf %0.s- {1..${len}}"
out=$(bash -c "$cmd")
echo "$out"
}
if [[ $1 == "-n" ]]; then
HAVE_BASHTOOLS=""
shift
fi
mode=$1
shift
if [[ $mode == "s" ]]; then
if [[ $# -lt 1 ]]; then
error "usage: $0 s sys1uptime sys2uptime ... sysXuptime"
exit 1
fi
diagram="[client]\n"
diagram="${diagram} |\n"
diagram="${diagram}[^b${1}%^p uptime]\n"
eq="(${1}/100)"
shift
while [[ $# -ge 1 ]]; do
diagram="${diagram} |\n"
diagram="${diagram}[^b${1}%^p uptime]\n"
eq="${eq} * (${1}/100)"
shift
done
diagram="${diagram} |\n"
diagram="${diagram}[server]\n"
eq="${eq} * 100"
answer=$(echo "scale=9; $eq" | bc)
2022-08-29 11:33:09 +10:00
answershort=$(echo "$answer" | sed '/\./ s/\.\{0,1\}0\{1,\}$//')
2022-08-29 11:01:10 +10:00
if [[ $answershort == 99.* ]]; then
nines=$(echo $answershort | tr -d -C 9 | wc -c | tr -d ' ')
[[ $nines -eq 1 ]] && ess="" || ess="s"
if [[ -n $HAVE_BASHTOOLS ]]; then
ninestext=" (^b\"${nines} nine${ess}\"^p)"
else
ninestext=" (\"${nines} nine${ess}\")"
fi
else
ninestext=""
fi
2022-08-29 10:48:29 +10:00
if [[ -n $HAVE_BASHTOOLS ]]; then
csecho -e "$WHITE" "^b${UNDERLINE}Architecture^p\n"
csecho "$GREEN" "${diagram}"
echo
csecho -e "$WHITE" "^b${UNDERLINE}Availability^p\n"
inform "^bEquation:^p ${eq}"
2022-08-29 11:01:10 +10:00
inform "^bAvailability:^p ${answershort}% $ninestext"
2022-08-29 10:48:29 +10:00
echo
else
echo "Architecture"
echo "------------"
diagram=$(echo "$diagram" | sed 's/\^.//g')
echo -e "${diagram}"
echo
echo "Availability"
echo "------------"
echo "* Equation: ${eq}"
2022-08-29 11:01:10 +10:00
echo "* Availability: ${answershort}% $ninestext"
2022-08-29 10:48:29 +10:00
echo
fi
elif [[ $mode == "p" ]]; then
if [[ $# -ne 2 ]]; then
error "usage: $0 s sysuptime nsystems"
exit 1
fi
sysuptime=${1}
shift
nsites=${1}
shift
text="[${sysuptime}% uptime]"
textansi="[^b${sysuptime}%^p uptime]"
len=${#text}
biglen=$(( $len * $nsites ))
biglen=$(echo "$biglen + ($nsites * 3)" | bc)
len=$((len + 3))
if [[ $((len % 2)) -eq 0 ]]; then
s1=$(( $len / 2 ))
s2=$(( $s1 - 1 ))
linktext=$(printf "%${s1}s|%${s2}s" " " " ")
else
s1=$(( $len / 2 ))
linktext=$(printf "%${s1}s|%${s1}s" " " " ")
fi
diagram="$(line $biglen)"
diagram="${diagram}\n"
if [[ $((biglen % 2)) -eq 0 ]]; then
s1=$(( $biglen / 2 ))
s2=$(( $s1 - 1 ))
upd=$(printf "[%${s1}s%${s2}s]" "client")
else
s1=$(( $biglen / 2 ))
upd=$(printf "[%${s1}s%${s1}s]" "client")
fi
diagram="${diagram}${upd}"
diagram="${diagram}\n"
diagram="${diagram}$(line $biglen)"
diagram="${diagram}\n"
# intentially skip element 0
for ((i=0;i<nsites;i++)); do
diagram="${diagram}${linktext}"
done
diagram="${diagram}\n"
sysline="$(line ${#text})"
syslines="${sysline}"
for ((i=1;i<nsites;i++)); do
syslines="${syslines} ${sysline}"
done
diagram="${diagram}${syslines}\n"
diagram="${diagram}${textansi}"
# intentially skip element 0
for ((i=1;i<nsites;i++)); do
diagram="${diagram} ${textansi}"
done
diagram="${diagram}\n"
diagram="${diagram}${syslines}\n"
# intentially skip element 0
for ((i=0;i<nsites;i++)); do
diagram="${diagram}${linktext}"
done
diagram="${diagram}\n"
if [[ $((biglen % 2)) -eq 0 ]]; then
s1=$(( $biglen / 2 ))
s2=$(( $s1 - 1 ))
upd=$(printf "[%${s1}s%${s2}s]" "server")
else
s1=$(( $biglen / 2 ))
upd=$(printf "[%${s1}s%${s1}s]" "server")
fi
diagram="${diagram}$(line $biglen)"
diagram="${diagram}\n"
diagram="${diagram}${upd}\n"
diagram="${diagram}$(line $biglen)"
diagram="${diagram}\n"
eq="(1 - (1 - (${sysuptime}/100))^${nsites})*100"
answer=$(echo "scale=15; $eq" | bc)
2022-08-29 11:33:09 +10:00
answershort=$(echo "$answer" | sed '/\./ s/\.\{0,1\}0\{1,\}$//')
2022-08-29 11:01:10 +10:00
if [[ $answershort == 99.* ]]; then
nines=$(echo $answershort | tr -d -C 9 | wc -c | tr -d ' ')
[[ $nines -eq 1 ]] && ess="" || ess="s"
if [[ -n $HAVE_BASHTOOLS ]]; then
ninestext=" (^b\"${nines} nine${ess}\"^p)"
else
ninestext=" (\"${nines} nine${ess}\")"
fi
else
ninestext=""
fi
2022-08-29 10:48:29 +10:00
if [[ -n $HAVE_BASHTOOLS ]]; then
csecho -e "$WHITE" "^b${UNDERLINE}Architecture^p\n"
csecho "$GREEN" "${diagram}"
echo
csecho -e "$WHITE" "^b${UNDERLINE}Availability^p\n"
inform "^bEquation:^p ${eq}"
inform "^bAvailability:^p ${answershort}% $ninestext"
2022-08-29 10:48:29 +10:00
else
echo "Architecture"
echo "------------"
diagram=$(echo "$diagram" | sed 's/\^.//g')
echo -e "${diagram}"
echo
echo "Availability"
echo "------------"
echo "Equation: ${eq}"
2022-08-29 11:01:10 +10:00
echo "Availability: ${answershort}% $ninestext"
2022-08-29 10:48:29 +10:00
fi
echo
elif [[ $mode == "i" ]]; then
if [[ $# -ne 2 ]]; then
error "usage: $0 i mtbf mttr"
exit 1
fi
mtbf=${1}
shift
mttr=${1}
shift
eq="${mtbf} / (${mtbf} + ${mttr}) * 100"
answer=$(echo "scale=15; $eq" | bc)
answershort=$(echo "$answer" | sed 's/0\+$//')
if [[ -n $HAVE_BASHTOOLS ]]; then
csecho -e "$WHITE" "^b${UNDERLINE}Availability^p\n"
inform "^bMean Time Between Failures:^p ${mtbf} hours"
inform "^bMean Time to Repair:^p ${mttr} hours"
inform "^bEquation:^p ${eq}"
inform "^bAvailability:^p $GREEN$BOLD${answershort}%^p"
else
echo "Availability"
echo "------------"
echo "Mean Time Between Failures: ${mtbf} hours"
echo "Mean Time to Repair: ${mttr} hours"
echo "Equation: ${eq}"
echo "Availability: ${answershort}%"
fi
echo
else
if [[ -n $HAVE_BASHTOOLS ]]; then
error "invalid mode."
else
echo "ERROR: invalid mode."
fi
usage
exit 1
fi