diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..bde490f
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,22 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "docker" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ target-branch: "main"
+ schedule:
+ interval: "daily"
+ assignees:
+ - "fredclausen"
+
+ # Maintain dependencies for GitHub Actions
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ assignees:
+ - "fredclausen"
diff --git a/.github/workflows/cancel_dupes.yml b/.github/workflows/cancel_dupes.yml
new file mode 100644
index 0000000..daa8c3e
--- /dev/null
+++ b/.github/workflows/cancel_dupes.yml
@@ -0,0 +1,20 @@
+name: Cancelling Duplicates
+on:
+ workflow_run:
+ workflows:
+ - "Deploy to Docker Hub"
+ - "Check Linting"
+ - "Tests"
+ types: ["requested"]
+
+jobs:
+ cancel-duplicate-workflow-runs:
+ name: "Cancel duplicate workflow runs"
+ runs-on: ubuntu-18.04
+ steps:
+ - uses: potiuk/cancel-workflow-runs@master
+ name: "Cancel duplicate workflow runs"
+ with:
+ cancelMode: allDuplicates
+ token: ${{ secrets.GITHUB_TOKEN }}
+ sourceRunId: ${{ github.event.workflow_run.id }}
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 0000000..f0321fc
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,113 @@
+---
+name: Deploy
+
+on:
+ workflow_dispatch:
+ inputs:
+ reason:
+ required: false
+ description: "Reason for running this workflow"
+ use_test_image:
+ required: false
+ type: boolean
+ description: "Use base image testpr"
+ default: false
+
+ push:
+ branches:
+ - main
+ # Don't trigger if it's just a documentation update
+ paths-ignore:
+ - "**.md"
+ - "**.MD"
+ - "**.yml"
+ - "LICENSE"
+ - ".gitattributes"
+ - ".gitignore"
+ - ".dockerignore"
+
+# Set workflow-wide environment variables
+# - REPO: repo name on dockerhub
+# - IMAGE: image name on dockerhub
+env:
+ # DOCKERHUB_REPO: sdr-enthusiasts
+ # DOCKERHUB_IMAGE: vrs
+ GHCR_IMAGE: sdr-enthusiasts/docker-radar1090
+ GHCR_REGISTRY: ghcr.io
+ GH_LABEL: main
+ GHCR_TAG: latest
+
+jobs:
+ workflow-dispatch:
+ name: Triggered via Workflow Dispatch?
+ # only run this step if workflow dispatch triggered
+ # log the reason the workflow dispatch was triggered
+ if: |
+ github.event_name == 'workflow_dispatch' &&
+ github.event.inputs.reason != ''
+ runs-on: ubuntu-latest
+ steps:
+ - name: Log dispatch reason
+ env:
+ INPUTS_REASON: ${{ github.event.inputs.reason }}
+ INPUTS_USE_TEST_IMAGE: ${{ github.event.inputs.use_test_image }}
+ run: |
+ echo "Workflow dispatch reason: $INPUTS_REASON"
+ echo "Use test image: $INPUTS_USE_TEST_IMAGE"
+
+ hadolint:
+ name: Run hadolint against docker files
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Pull hadolint/hadolint:latest Image
+ run: docker pull hadolint/hadolint:latest
+ - name: Run hadolint against Dockerfiles
+ run: docker run --rm -i -v "$PWD":/workdir --workdir /workdir --entrypoint hadolint hadolint/hadolint --ignore DL3015 --ignore DL3003 --ignore DL3006 --ignore DL3010 --ignore DL4001 --ignore DL3007 --ignore DL3008 --ignore SC2068 --ignore DL3007 --ignore SC1091 --ignore DL3013 --ignore DL3010 $(find . -type f -iname "Dockerfile*")
+
+ deploy:
+ name: Deploy without telegraf
+ uses: sdr-enthusiasts/common-github-workflows/.github/workflows/build_and_push_image.yml@main
+ with:
+ push_enabled: true
+ push_destinations: ghcr.io
+ ghcr_repo_owner: ${{ github.repository_owner }}
+ ghcr_repo: ${{ github.repository }}
+ get_version_method: file_in_container:file=/CONTAINER_VERSION
+ # set build_latest to true if github.event.inputs.use_test_image is false
+ build_latest: ${{ github.event.inputs.use_test_image == 'false' || github.event.inputs.use_test_image == '' }}
+ build_baseimage_test: ${{ github.event.inputs.use_test_image == 'true' }}
+ # only build the entire stack if we are not using the test image
+ build_version_specific: false
+ build_platform_specific: false
+ build_nohealthcheck: false
+ build_baseimage_url: docker-tar1090:latest/docker-tar1090:baseimage-test
+ secrets:
+ ghcr_token: ${{ secrets.GITHUB_TOKEN }}
+
+ # unfortunately we can't use build_and_push_image.yml to build the telegraf label because
+ # that GH Action doesn't have the capability to build specific custom-named labels
+
+ deploy_with_telegraf:
+ name: Deploy with telegraf and healthcheck
+ uses: sdr-enthusiasts/common-github-workflows/.github/workflows/build_and_push_image.yml@main
+ with:
+ push_enabled: true
+ push_destinations: ghcr.io
+ ghcr_repo_owner: ${{ github.repository_owner }}
+ ghcr_repo: ${{ github.repository }}
+ get_version_method: file_in_container:file=/CONTAINER_VERSION
+ # set build_latest to true if github.event.inputs.use_test_image is false
+ build_latest: ${{ github.event.inputs.use_test_image == 'false' || github.event.inputs.use_test_image == '' }}
+ build_baseimage_test: ${{ github.event.inputs.use_test_image == 'true' }}
+ build_baseimage_url: docker-tar1090:telegraf/docker-tar1090:telegraf-baseimage-test
+ # only build the entire stack if we are not using the test image
+ build_version_specific: false
+ build_platform_specific: false
+ build_nohealthcheck: false
+ docker_latest_tag: telegraf
+ dockerfile_changes: |
+ docker-tar1090:latest/docker-tar1090:telegraf
+
+ secrets:
+ ghcr_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/pre-commit-updates.yaml b/.github/workflows/pre-commit-updates.yaml
new file mode 100644
index 0000000..f075972
--- /dev/null
+++ b/.github/workflows/pre-commit-updates.yaml
@@ -0,0 +1,23 @@
+name: Update pre-commit hooks
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: 0 0 * * *
+
+jobs:
+ update:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4.1.0
+ with:
+ fetch-depth: 0
+ - uses: vrslev/pre-commit-autoupdate@v1.0.0
+ - uses: peter-evans/create-pull-request@v5
+ with:
+ branch: pre-commit-autoupdate
+ title: "chore(deps): Update pre-commit hooks"
+ commit-message: "chore(deps): Update pre-commit hooks"
+ body: Update pre-commit hooks
+ labels: dependencies
+ delete-branch: True
diff --git a/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/watchdog b/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/watchdog
new file mode 100644
index 0000000..e69de29
diff --git a/rootfs/etc/s6-overlay/s6-rc.d/watchdog/dependencies.d/radar1090 b/rootfs/etc/s6-overlay/s6-rc.d/watchdog/dependencies.d/radar1090
new file mode 100644
index 0000000..e69de29
diff --git a/rootfs/etc/s6-overlay/s6-rc.d/watchdog/run b/rootfs/etc/s6-overlay/s6-rc.d/watchdog/run
new file mode 100755
index 0000000..64a10d7
--- /dev/null
+++ b/rootfs/etc/s6-overlay/s6-rc.d/watchdog/run
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /etc/s6-overlay/scripts/watchdog
diff --git a/rootfs/etc/s6-overlay/s6-rc.d/watchdog/type b/rootfs/etc/s6-overlay/s6-rc.d/watchdog/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/rootfs/etc/s6-overlay/s6-rc.d/watchdog/type
@@ -0,0 +1 @@
+longrun
diff --git a/rootfs/etc/s6-overlay/scripts/watchdog b/rootfs/etc/s6-overlay/scripts/watchdog
new file mode 100755
index 0000000..f23308c
--- /dev/null
+++ b/rootfs/etc/s6-overlay/scripts/watchdog
@@ -0,0 +1,105 @@
+#!/command/with-contenv bash
+# shellcheck shell=bash disable=SC1091,SC2015,SC2164,SC2068,SC2145,SC2120
+
+source /scripts/common
+s6wrap=(s6wrap --quiet --timestamps --prepend="$(basename "$0")")
+
+#---------------------------------------------------------------------------------------------
+# This repository, docker container, and accompanying scripts and documentation is
+# Copyright (C) 2022-2023, Ramon F. Kolb (kx1t)
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program.
+# If not, see .
+#
+# Radar1090 is an ADS-B RADAR Feed Service
+# Copyright (C) 2023 by Michael J. Tubby B.Sc. MIET G8TIC mik@tubby.org All Rights Reserved.
+# No license to the "radar" binary and its source code is implied; contact the author for information.
+#---------------------------------------------------------------------------------------------
+
+# Watchdog to ensure there's traffic flowing for radar1090
+# Uses TCPDUMP to ensure there are packets sent to the destination port
+
+"${s6wrap[@]}" echo "Started as an s6 service"
+
+MEASURE_TIME="${MEASURE_TIME:-15}" # how long we take samples to check data is flowing
+MEASURE_INTERVAL="${MEASURE_INTERVAL:-300}" # wait time between check runs
+TRANSPORT_PROTOCOL="${TRANSPORT_PROTOCOL:-udp}" # [udp|tcp] the protocol used to transport data to the remote aggregator
+TRANSPORT_PROTOCOL="${TRANSPORT_PROTOCOL,,}"
+
+HEALTHFILE=/run/watchdog-log/health_failures_since_last_success
+
+# make sure the log files exists:
+mkdir -p "$(dirname "$HEALTHFILE")"
+echo "0" > "$HEALTHFILE"
+
+monitor_feeder () {
+ # see if data is flowing from this container to the remote aggregator
+ # usage: monitor_feeder [measure_time]
+ # where measure_time is optional; if omitted, $MEASURE_TIME or 10 secs will be used
+ # $RADARSERVER and $RADARPORT are used to indicate the aggregator's name and port, defaulting to adsb-in.1090mhz.uk and 2227
+ # Function returns 0 (true) if successful and 1 (false) if the host cannot be reached
+ local measure_time
+ local result
+ local resultcode
+
+ chk_enabled "$VERBOSE" && "${s6wrap[@]}" --args echo monitoring "${RADARSERVER:-adsb-in.1090mhz.uk}:${RADARPORT:-2227}/${TRANSPORT_PROTOCOL:-udp} for ${measure_time:-10} secs" || true
+
+ measure_time="${1:-${MEASURE_TIME:-10}}"
+ result="$(grep captured <<< "$(timeout --preserve-status "${measure_time}" tcpdump -p dst "${RADARSERVER:-adsb-in.1090mhz.uk}" and "${TRANSPORT_PROTOCOL:-udp}" port "${RADARPORT:-2227}" 2>/dev/stdout 1>/dev/null)" | awk '{print $1}')"
+ resultcode="$?"
+
+ if (( resultcode != 0 )); then
+ return $resultcode
+ elif [[ "$result" == "0" ]]; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+fix_feeder () { # bring down the feeder Python app:
+ pkill -SIGTERM -f "/usr/sbin/radar"
+ sleep 10
+
+ # check if data is flowing again:
+ monitor_feeder
+ return $?
+}
+
+while :
+do
+ # first sleep a bit
+ sleep "$MEASURE_INTERVAL" & wait !
+
+ # then check if data is flowing
+ if ! monitor_feeder; then
+ "${s6wrap[@]}" --args echo "WARNING: DataFlow Failure: No data is flowing to ${RADARSERVER:-adsb-in.1090mhz.uk}:${RADARPORT:-2227}/${TRANSPORT_PROTOCOL:-udp} after checking for ${measure_time:-10} secs. Feeder will be restarted"
+ if ! fix_feeder
+ then
+ "${s6wrap[@]}" --args echo "FATAL: DataFlow Failure: Restarting feeder module didn't restart the data flow. Please check your system! We will try again in $MEASURE_INTERVAL secs"
+ read -r healthfailures < "$HEALTHFILE"
+ (( healthfailures++ )) || true
+ echo "$healthfailures" > "$HEALTHFILE"
+ else
+ "${s6wrap[@]}" --args echo "SUCCESS: Feeder restart made data flow again!"
+ echo "0" > "$HEALTHFILE"
+ fi
+
+ else
+ if chk_enabled "$VERBOSE"; then
+ "${s6wrap[@]}" --args echo "SUCCESS: Data is flowing to ${RADARSERVER:-adsb-in.1090mhz.uk}:${RADARPORT:-2227}/${TRANSPORT_PROTOCOL:-udp} after checking for ${measure_time:-10} secs"
+ fi
+ echo "0" > "$HEALTHFILE"
+
+ fi
+
+done
diff --git a/rootfs/scripts/healthcheck.sh b/rootfs/scripts/healthcheck.sh
new file mode 100644
index 0000000..59a2430
--- /dev/null
+++ b/rootfs/scripts/healthcheck.sh
@@ -0,0 +1,51 @@
+#!/command/with-contenv bash
+# shellcheck shell=bash disable=SC1091
+# SC2015,SC2164,SC2068,SC2145,SC2120
+
+source /scripts/common
+s6wrap=(s6wrap --quiet --timestamps --prepend="$(basename "$0")")
+
+#---------------------------------------------------------------------------------------------
+# This repository, docker container, and accompanying scripts and documentation is
+# Copyright (C) 2022-2023, Ramon F. Kolb (kx1t)
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program.
+# If not, see .
+#
+# Radar1090 is an ADS-B RADAR Feed Service
+# Copyright (C) 2023 by Michael J. Tubby B.Sc. MIET G8TIC mik@tubby.org All Rights Reserved.
+# No license to the "radar" binary and its source code is implied; contact the author for information.
+#---------------------------------------------------------------------------------------------
+
+# Healthcheck for autoheal. Returns 1 if $HEALTHFILE contains a number greater than 0
+# This number is written by the watchdog service to ensure there's traffic flowing for radar1090
+
+HEALTHFILE=/run/watchdog-log/health_failures_since_last_success
+MEASURE_TIME="${MEASURE_TIME:-15}" # how long we take samples to check data is flowing
+MEASURE_INTERVAL="${MEASURE_INTERVAL:-300}" # wait time between check runs
+TRANSPORT_PROTOCOL="${TRANSPORT_PROTOCOL:-udp}" # [udp|tcp] the protocol used to transport data to the remote aggregator
+TRANSPORT_PROTOCOL="${TRANSPORT_PROTOCOL,,}"
+
+FAILURES_TO_GO_UNHEALTHY=3 # after this number of failures, the container will go unhealthy
+
+# make sure the log files exists:
+mkdir -p "$(dirname "$HEALTHFILE")"
+touch "$HEALTHFILE"
+
+read -r healthfailures < "$HEALTHFILE"
+
+if [[ -n "$healthfailures" ]] && (( healthfailures > FAILURES_TO_GO_UNHEALTHY )); then
+ "${s6wrap[@]}" --args echo "UNHEALTHY: No data is flowing to ${RADARSERVER:-adsb-in.1090mhz.uk}:${RADARPORT:-2227}/${TRANSPORT_PROTOCOL:-udp} - failure count since last successful measurement is $healthfailures"
+ exit 1
+else
+ exit 0
+fi
\ No newline at end of file