Skip to content

Commit

Permalink
Add ZoneTables feature to auto-distribute load over different servers…
Browse files Browse the repository at this point in the history
… and ports (#73)

* auto dns/port selection based on zone

* add zone map

* Update README.md

* make use of zonetable persistent across all functions

* make logging more consistent

* cleanup

* cleanup

* made ImAlive more robust

* add EU zones

* improve zonetable to auto-extract zone names; add EU zones

* Update README.md
  • Loading branch information
kx1t authored Aug 1, 2024
1 parent 246b66f commit 1637957
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ghcr.io/sdr-enthusiasts/docker-baseimage:mlatclient as downloader
FROM ghcr.io/sdr-enthusiasts/docker-baseimage:mlatclient AS downloader

FROM ghcr.io/sdr-enthusiasts/docker-baseimage:base

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ To add `RadarVirtuel` to an existing Docker Stack, simply copy and paste the rel
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `FEEDER_KEY` | This key is provided by RadarVirtuel and is your PRIVATE KEY. Do no share this with anyone else. | `[icao]:[private_key]` |
| `SOURCE_HOST` | host and port number of your ADSB receiver. When running stand-alone on your local machine, this should be `${HOSTNAME}`. The value after the `:` is the port number to the RAW or AVR service on the target machine, most probably `30002`. | `${HOSTNAME}:30002` |
| `RV_SERVER` | The hostname and the port of the RadarVirtuel server. You should NOT change this unless specifically instructed. | `mg2.adsbnetwork.com:50050` |
| `RV_SERVER` | The hostname and the port of the RadarVirtuel server. You should NOT change this unless specifically instructed. Note - this value may be overwritten/automatically updated if you are in a [predefined zone in North America](https://github.com/user-attachments/assets/c59b6026-3cc0-44ef-92b7-eec886555564) or [Europe](https://github.com/user-attachments/assets/1d76b061-cdfa-45f5-b531-b6030402e29a) | `mg2.adsbnetwork.com:50050` |
| `VERBOSE` | Write verbose messages to the log | `OFF` (default) / `ON` |
| `MLAT_SERVER` | RV MLAT server address and port - do not change unless instructed to | mlat.adsbnetwork.com:50000 |
| `MLAT_HOST` | This is the same hostname as for SOURCE_HOST, but now using port 30005 | `${HOSTNAME}:30005` |
Expand Down
23 changes: 17 additions & 6 deletions rootfs/etc/s6-overlay/scripts/50-radarvirtuel
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@
# shellcheck shell=bash disable=SC1091,SC2015,SC2145,SC2154

source /scripts/common
"${s6wrap[@]}" echo "Initializing RadarVirtuel..."

RV_SERVER="${RV_SERVER:-mg22.adsbnetwork.com:50050}"
# check if we are in one of the defined zones, and update the server address accordingly:
source /home/zonetable
if [[ -n "$zone_id" ]]; then
RV_SERVER="${zone_dns}:${zone_port}"
"${s6wrap[@]}" cat <<EOF
Server and port have been updated automatically based on the LAT/LON of the receiver:
Zone: $zone_id
Name: $zone_name
DNS: $zone_dns
Port: $zone_port
------------------
EOF
fi

[[ "$RV_SERVER" == "" ]] && RV_SERVER="mg22.adsbnetwork.com:50050" || true
if [[ "${RV_SERVER%%:*}" == "mg2.adsbnetwork.com" ]]; then
RV_SERVER="mg22.adsbnetwork.com:${RV_SERVER##*:}"
"${s6wrap[@]}" cat <<EOF
+------------------------------------------------------------------------+
| ATTENTION! RV_SERVER mg2.adsbnetwork.com will be retired. |
| Please update the RV_SERVER parameter in docker-compose.yml |
| to: "mg22.adsbnetwork.com:${RV_SERVER##*:}". |
| Please remove the RV_SERVER parameter in docker-compose.yml |
| We will use mg22.adsbnetwork.com for this session. |
+------------------------------------------------------------------------+
EOF
fi

[[ "$RV_SERVER" == "" ]] && RV_SERVER="mg2.adsbnetwork.com:50050"

"${s6wrap[@]}" echo "Initializing RadarVirtuel..."
if chk_enabled "${VERBOSE}"; then
"${s6wrap[@]}" cat <<EOF
Feeder key: ${FEEDER_KEY}
Expand Down
15 changes: 13 additions & 2 deletions rootfs/etc/s6-overlay/scripts/imalive
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ touch /run/imalive/errors

RV_SERVER="${RV_SERVER:-mg22.adsbnetwork.com:50050}"
[[ "${RV_SERVER%%:*}" == "mg2.adsbnetwork.com" ]] && RV_SERVER="mg22.adsbnetwork.com:${RV_SERVER##*:}" || true
source /home/zonetable
if [[ -n "$zone_id" ]]; then
RV_SERVER="${zone_dns}:${zone_port}"
fi

# Source in the scripts from @Mikenye's healthchecks-framework so we can use them here
source /opt/healthchecks-framework/healthchecks.sh
Expand Down Expand Up @@ -41,8 +45,15 @@ do
st=${FEEDER_KEY%%:*}
timestamp=$(date "+%s")
#echo " $st Current Time : $ts"
STATUS="$(curl -sSL "${RV_SERVER%%:*}"/rtools/pyalive.php?stid="${st,,}" 2>&1)" || true
if ! STATUS="$(curl -sSL "${RV_SERVER%%:*}"/rtools/pyalive.php?stid="${st,,}" 2>&1)"; then
if STATUS="$(curl -sSL http://mg22.adsbnetwork.com/rtools/pyalive.php?stid="${st,,}" 2>&1)"; then
"${s6wrap[@]}" echo "ImAlive status on ${RV_SERVER%%:*} wasn't available, fell back to mg22.adsbnetwork.com"
else
STATUS=""
fi
fi
# STATUS now contains either "ok-12345678" or "ko-12345678"
# If STATUS is empty then there was a connection error
# where ok/ko means OK or not OK and 12345678 is the secs since epoch
# STATUS can also contain the error page if the server returns an error

Expand All @@ -54,7 +65,7 @@ do
"${s6wrap[@]}" echo "ImAlive Server returned 404-Not Found. Restarting ANFeeder \"just in case\"..."
killall /home/py/ANfeeder >/dev/null 2>&1
ALIVE="404 failure for ${RV_SERVER%%:*}/rtools/pyalive.php?stid=$st"
elif [[ -z $STATUS ]]; then
elif [[ -z "$STATUS" ]]; then
"${s6wrap[@]}" echo "ImAlive Server cannot be reached: network failure. Restarting ANFeeder \"just in case\"..."
killall /home/py/ANfeeder >/dev/null 2>&1
ALIVE="no network failure"
Expand Down
8 changes: 8 additions & 0 deletions rootfs/etc/s6-overlay/scripts/radarvirtuel
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@ RV_SERVER="${RV_SERVER:-mg22.adsbnetwork.com:50050}"
[[ "${RV_SERVER%%:*}" == "mg2.adsbnetwork.com" ]] && RV_SERVER="mg22.adsbnetwork.com:${RV_SERVER##*:}" || true
"${s6wrap[@]}" echo "started as an s6 service"

# check if we are in one of the defined zones, and update the server address accordingly:
source /home/zonetable
if [[ -n "$zone_id" ]]; then
RV_SERVER="${zone_dns}:${zone_port}"
fi

sleep ${START_DELAY}
if chk_enabled "$VERBOSE"; then
"${s6wrap[@]}" echo "Starting /home/py/ANfeeder -v -i \"${FEEDER_KEY}\" -d \"${RV_SERVER}\" -s \"${SOURCE_HOST}\""
exec "${s6wrap[@]}" /home/py/ANfeeder -v -i "${FEEDER_KEY}" -d "${RV_SERVER}" -s "${SOURCE_HOST}"
else
"${s6wrap[@]}" echo "Starting /home/py/ANfeeder -i \"${FEEDER_KEY}\" -d \"${RV_SERVER}\" -s \"${SOURCE_HOST}\""
exec "${s6wrap[@]}" /home/py/ANfeeder -i "${FEEDER_KEY}" -d "${RV_SERVER}" -s "${SOURCE_HOST}"
fi
260 changes: 260 additions & 0 deletions rootfs/home/zonetable
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
#shellcheck shell=bash disable=SC2154

# associative array with the DNS, port, and boundary data for each zone.

declare -A ZoneTable=(
[EU001:name]="West-Portugal West-Spain"
[EU001:dns]="mg22.adsbnetwork.com"
[EU001:port]="50050"
[EU001:max_lat]="43.5"
[EU001:max_lon]="-7.5"
[EU001:min_lat]="34.0"
[EU001:min_lon]="-25.0"
[EU002:name]="East-Portugal Spain South-France"
[EU002:dns]="mg22.adsbnetwork.com"
[EU002:port]="50050"
[EU002:max_lat]="43.5"
[EU002:max_lon]="10.0"
[EU002:min_lat]="34.0"
[EU002:min_lon]="-7.5"
[EU003:name]="East-Mediterranean"
[EU003:dns]="mg22.adsbnetwork.com"
[EU003:port]="50050"
[EU003:max_lat]="43.5"
[EU003:max_lon]="27.5"
[EU003:min_lat]="34.0"
[EU003:min_lon]="10.0"
[EU004:name]="Turkey Middle-East"
[EU004:dns]="mg22.adsbnetwork.com"
[EU004:port]="50050"
[EU004:max_lat]="43.5"
[EU004:max_lon]="45.0"
[EU004:min_lat]="34.0"
[EU004:min_lon]="27.5"
[EU005:name]="Southwest-Ireland"
[EU005:dns]="mg22.adsbnetwork.com"
[EU005:port]="50050"
[EU005:max_lat]="53.0"
[EU005:max_lon]="-7.5"
[EU005:min_lat]="43.5"
[EU005:min_lon]="-25.0"
[EU006:name]="Southwest Ireland France Benelux Western-Germany"
[EU006:dns]="mg22.adsbnetwork.com"
[EU006:port]="50050"
[EU006:max_lat]="53.0"
[EU006:max_lon]="10.0"
[EU006:min_lat]="43.5"
[EU006:min_lon]="-7.5"
[EU007:name]="Eastern-Germany Mid-Eastern-Europe"
[EU007:dns]="mg22.adsbnetwork.com"
[EU007:port]="50050"
[EU007:max_lat]="53.0"
[EU007:max_lon]="27.5"
[EU007:min_lat]="43.5"
[EU007:min_lon]="10.0"
[EU008:name]="Southeastern-Europe"
[EU008:dns]="mg22.adsbnetwork.com"
[EU008:port]="50050"
[EU008:max_lat]="53.0"
[EU008:max_lon]="45.0"
[EU008:min_lat]="43.5"
[EU008:min_lon]="27.5"
[EU009:name]="Northwestern-Ireland"
[EU009:dns]="mg22.adsbnetwork.com"
[EU009:port]="50050"
[EU009:max_lat]="62.5"
[EU009:max_lon]="-7.5"
[EU009:min_lat]="53.0"
[EU009:min_lon]="-25.0"
[EU010:name]="Great-Britain Northeastern-Ireland NorthSea-Countries"
[EU010:dns]="mg22.adsbnetwork.com"
[EU010:port]="50050"
[EU010:max_lat]="62.5"
[EU010:max_lon]="10.0"
[EU010:min_lat]="53.0"
[EU010:min_lon]="-7.5"
[EU011:name]="BalticSea-Countries"
[EU011:dns]="mg22.adsbnetwork.com"
[EU011:port]="50050"
[EU011:max_lat]="62.5"
[EU011:max_lon]="27.5"
[EU011:min_lat]="53.0"
[EU011:min_lon]="10.0"
[EU012:name]="Belarus Russia Eastern-Finland Eastern-Latvia"
[EU012:dns]="mg22.adsbnetwork.com"
[EU012:port]="50050"
[EU012:max_lat]="62.5"
[EU012:max_lon]="45.0"
[EU012:min_lat]="53.0"
[EU012:min_lon]="27.5"
[EU013:name]="Iceland"
[EU013:dns]="mg22.adsbnetwork.com"
[EU013:port]="50050"
[EU013:max_lat]="72.0"
[EU013:max_lon]="-7.5"
[EU013:min_lat]="62.5"
[EU013:min_lon]="-25.0"
[EU014:name]="Mid-Western-Norway"
[EU014:dns]="mg22.adsbnetwork.com"
[EU014:port]="50050"
[EU014:max_lat]="72.0"
[EU014:max_lon]="10.0"
[EU014:min_lat]="62.5"
[EU014:min_lon]="-7.5"
[EU015:name]="Northern-Scandinavia Northern-Finland"
[EU015:dns]="mg22.adsbnetwork.com"
[EU015:port]="50050"
[EU015:max_lat]="72.0"
[EU015:max_lon]="27.5"
[EU015:min_lat]="62.5"
[EU015:min_lon]="10.0"
[EU016:name]="Eastern-Finland Northwestern-Russia"
[EU016:dns]="mg22.adsbnetwork.com"
[EU016:port]="50050"
[EU016:max_lat]="72.0"
[EU016:max_lon]="45.0"
[EU016:min_lat]="62.5"
[EU016:min_lon]="27.5"
[NA001:name]="SoCal"
[NA001:dns]="mg21.adsbnetwork.com"
[NA001:port]="50021"
[NA001:max_lat]="34.3534155"
[NA001:max_lon]="-117.1984944"
[NA001:min_lat]="25.34440649"
[NA001:min_lon]="-128.7677266"
[NA002:dns]="mg21.adsbnetwork.com"
[NA002:name]="AZ NM Baja nw-Mex"
[NA002:port]="50031"
[NA002:max_lat]="34.3534155"
[NA002:max_lon]="-105.6292621"
[NA002:min_lat]="25.34440649"
[NA002:min_lon]="-117.1984944"
[NA003:name]="se-NM TX se-OK sw-AR"
[NA003:dns]="mg21.adsbnetwork.com"
[NA003:port]="50033"
[NA003:max_lat]="34.3534155"
[NA003:max_lon]="-94.06002987"
[NA003:min_lat]="25.34440649"
[NA003:min_lon]="-105.6292621"
[NA004:name]="so-AR LA MS AL FL GA"
[NA004:dns]="mg21.adsbnetwork.com"
[NA004:port]="50037"
[NA004:max_lat]="34.3534155"
[NA004:max_lon]="-85.13"
[NA004:min_lat]="25.34440649"
[NA004:min_lon]="-94.06002987"
[NA005:name]="GA FL"
[NA005:dns]="mg21.adsbnetwork.com"
[NA005:port]="50039"
[NA005:max_lat]="34.3534155"
[NA005:max_lon]="-70.92156537"
[NA005:min_lat]="24.5"
[NA005:min_lon]="-85.13"
[NA006:name]="CA NV OR"
[NA006:dns]="mg21.adsbnetwork.com"
[NA006:port]="50040"
[NA006:max_lat]="43.3624245"
[NA006:max_lon]="-117.1984944"
[NA006:min_lat]="34.3534155"
[NA006:min_lon]="-128.7677266"
[NA007:name]="NV sw-CA UT CO AZ NM ID WY"
[NA007:dns]="mg21.adsbnetwork.com"
[NA007:port]="50041"
[NA007:max_lat]="43.3624245"
[NA007:max_lon]="-105.6292621"
[NA007:min_lat]="34.3534155"
[NA007:min_lon]="-117.1984944"
[NA008:name]="WY SD IA CO KS MS NM no_TX OK we-AR"
[NA008:dns]="mg21.adsbnetwork.com"
[NA008:port]="50042"
[NA008:max_lat]="43.3624245"
[NA008:max_lon]="-94.06002987"
[NA008:min_lat]="34.3534155"
[NA008:min_lon]="-105.6292621"
[NA009:name]="IA WI MI IL IN OH MS KY AR TN no-MS no-AL no-GA"
[NA009:dns]="mg21.adsbnetwork.com"
[NA009:port]="50043"
[NA009:max_lat]="43.3624245"
[NA009:max_lon]="-82.49079762"
[NA009:min_lat]="34.3534155"
[NA009:min_lon]="-94.06002987"
[NA010:name]="mid-Atlantic south-NewEngland"
[NA010:dns]="mg21.adsbnetwork.com"
[NA010:port]="50044"
[NA010:max_lat]="43.3624245"
[NA010:max_lon]="-69.9"
[NA010:min_lat]="34.3534155"
[NA010:min_lon]="-82.49079762"
[NA011:name]="Pac NW"
[NA011:dns]="mg21.adsbnetwork.com"
[NA011:port]="50045"
[NA011:max_lat]="52.37143351"
[NA011:max_lon]="-117.1984944"
[NA011:min_lat]="43.3624245"
[NA011:min_lon]="-128.7677266"
[NA012:name]="ID MT WY east-BC AB SK"
[NA012:dns]="mg21.adsbnetwork.com"
[NA012:port]="50046"
[NA012:max_lat]="52.37143351"
[NA012:max_lon]="-105.6292621"
[NA012:min_lat]="43.3624245"
[NA012:min_lon]="-117.1984944"
[NA013:name]="WY MT ND SD MN SK MB ON"
[NA013:dns]="mg21.adsbnetwork.com"
[NA013:port]="50048"
[NA013:max_lat]="52.37143351"
[NA013:max_lon]="-94.06002987"
[NA013:min_lat]="43.3624245"
[NA013:min_lon]="-105.6292621"
[NA014:name]="MN WI MI ON"
[NA014:dns]="mg21.adsbnetwork.com"
[NA014:port]="50049"
[NA014:max_lat]="52.37143351"
[NA014:max_lon]="-82.49079762"
[NA014:min_lat]="43.3624245"
[NA014:min_lon]="-94.06002987"
[NA015:name]="No-NewEngland East-Canada StPierreMiquelon"
[NA015:dns]="mg21.adsbnetwork.com"
[NA015:port]="50051"
[NA015:max_lat]="52.37143351"
[NA015:max_lon]="-52.432265"
[NA015:min_lat]="43.3624245"
[NA015:min_lon]="-82.49079762"
[NA016:name]="Hawaii"
[NA016:dns]="mg21.adsbnetwork.com"
[NA016:port]="50039"
[NA016:max_lat]="22.356682"
[NA016:max_lon]="-154.539553"
[NA016:min_lat]="18.809780"
[NA016:min_lon]="-160.453822"
[NA017:name]="Alaska"
[NA017:dns]="mg21.adsbnetwork.com"
[NA017:port]="50039"
[NA017:max_lat]="71.5388"
[NA017:max_lon]="-130"
[NA017:min_lat]="51.2097"
[NA017:min_lon]="-172"
)

declare -a ZoneNames=()
for name in "${!ZoneTable[@]}"; do
if [[ ! " ${ZoneNames[*]} " =~ " ${name:0:5} " ]]; then
ZoneNames+=("${name:0:5}")
fi
done

if [[ -n "$LON" ]] && [[ -n "$LAT" ]]; then
for zone in "${ZoneNames[@]}"; do
math_string="$LAT > ${ZoneTable[$zone:min_lat]} && "
math_string+="$LAT <= ${ZoneTable[$zone:max_lat]} && "
math_string+="$LON > ${ZoneTable[$zone:min_lon]} && "
math_string+="$LON <= ${ZoneTable[$zone:max_lon]}"
if [[ "$(bc -l <<< "$math_string")" == "1" ]]; then
zone_name="${ZoneTable[$zone:name]}"
zone_id="$zone"
zone_dns="${ZoneTable[$zone:dns]}"
zone_port="${ZoneTable[$zone:port]}"
break
fi
done
fi

0 comments on commit 1637957

Please sign in to comment.