diff --git a/Dockerfile.bordercontrol b/Dockerfile.bordercontrol
index c3eafea8..4105b836 100644
--- a/Dockerfile.bordercontrol
+++ b/Dockerfile.bordercontrol
@@ -1,4 +1,4 @@
-FROM golang:1.21.4-bookworm AS builder
+FROM golang:1.21.5-bookworm AS builder
COPY / /src/pw-bordercontrol
@@ -8,7 +8,7 @@ RUN go mod tidy && \
go build ./... && \
go install ./...
-FROM debian:bookworm-20231030-slim
+FROM debian:bookworm-20231120-slim
ARG S6_OVERLAY_VERSION=3.1.6.0
diff --git a/Dockerfile.feeder b/Dockerfile.feeder
index 0bf28f43..72b9f3c8 100644
--- a/Dockerfile.feeder
+++ b/Dockerfile.feeder
@@ -1,6 +1,6 @@
FROM ghcr.io/plane-watch/pw-pipeline:pw_ingest as pipeline
-FROM debian:bookworm-20231030-slim
+FROM debian:bookworm-20231120-slim
ARG S6_OVERLAY_VERSION=3.1.6.0
@@ -16,42 +16,11 @@ RUN set -x && \
KEPT_PACKAGES+=(procps) && \
KEPT_PACKAGES+=(iproute2) && \
KEPT_PACKAGES+=(xz-utils) && \
- # packages needed to build
- TEMP_PACKAGES+=(build-essential) && \
- TEMP_PACKAGES+=(cmake) && \
- TEMP_PACKAGES+=(pkg-config) && \
- # prerequisites for readsb-protobuf \
- KEPT_PACKAGES+=(protobuf-c-compiler) && \
- KEPT_PACKAGES+=(libprotobuf-c1) && \
- TEMP_PACKAGES+=(libprotobuf-c-dev) && \
- TEMP_PACKAGES+=(librrd-dev) && \
- KEPT_PACKAGES+=(libncurses6) && \
- TEMP_PACKAGES+=(libncurses5-dev) && \
- TEMP_PACKAGES+=(binutils) && \
apt-get update && \
apt-get install -y --no-install-recommends \
"${KEPT_PACKAGES[@]}" \
"${TEMP_PACKAGES[@]}" \
&& \
- # install mictronics readsb
- BRANCH_READSB="dev" && \
- # readsb: clone repo
- git clone \
- --branch "$BRANCH_READSB" \
- --depth 1 \
- --single-branch \
- 'https://github.com/Mictronics/readsb-protobuf.git' \
- /src/readsb-protobuf \
- && \
- # readsb: build & install (note, -j seems to have issues, so not using...)
- pushd /src/readsb-protobuf && \
- make BLADERF=no RTLSDR=no PLUTOSDR=no HAVE_BIASTEE=no && \
- find "/src/readsb-protobuf" -maxdepth 1 -executable -type f -exec cp -v {} /usr/local/bin/ \; && \
- popd && \
- ldconfig && \
- # readsb: simple tests
- readsb --version && \
- viewadsb --version && \
# deploy healthchecks framework
git clone \
--depth=1 \
@@ -81,7 +50,13 @@ RUN tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz
ENV S6_LOGGING=0 \
S6_VERBOSITY=1
+# Set defaults
+ENV PW_INGEST_INPUT_MODE=listen \
+ PW_INGEST_INPUT_PROTO=beast \
+ PW_INGEST_INPUT_ADDR=0.0.0.0 \
+ PW_INGEST_INPUT_PORT=12345
+
# Set s6 init as entrypoint
ENTRYPOINT [ "/init" ]
-HEALTHCHECK --interval=60s --timeout=10s --start-period=300s --retries=5 CMD /scripts/healthcheck.sh
+HEALTHCHECK --interval=300s --timeout=40s --start-period=600s --retries=5 CMD /scripts/healthcheck.sh
diff --git a/Dockerfile.mux b/Dockerfile.mux
index 3b0b5c5f..b657f975 100644
--- a/Dockerfile.mux
+++ b/Dockerfile.mux
@@ -1,4 +1,6 @@
-FROM debian:bookworm-20231030-slim
+FROM ghcr.io/plane-watch/pw-pipeline:pw_ingest as pipeline
+
+FROM debian:bookworm-20231120-slim
ARG S6_OVERLAY_VERSION=3.1.6.0
@@ -87,6 +89,7 @@ RUN set -x && \
apt-get autoremove -y && \
rm -rf /src/* /tmp/* /var/lib/apt/lists/*
+COPY --from=pipeline /app/pw_ingest /usr/local/bin/pw_ingest
COPY pw-mux/rootfs/ /
# Deploy s6 overlay
diff --git a/docker-compose.yml b/docker-compose.yml
index 6def4410..138d49b6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -15,12 +15,7 @@ x-mux-common: &mux-common
networks:
- bordercontrol_feeder
environment:
- - READSB_NET_BEAST_OUTPUT_PORT=30005
- - READSB_NET_BEAST_REDUCE_OUT_PORT=30015
- - READSB_NET_BEAST_REDUCE_INTERVAL=0.5
- - READSB_NET_BEAST_INPUT_PORT=12345
- - READSB_NET_ENABLE=true
- - READSB_NET_ONLY=true
+ - PW_INGEST_SINK=${PW_INGEST_SINK}
tmpfs:
- /run:exec,size=64M
- /var/log
@@ -55,6 +50,7 @@ services:
- 12345:12345 # BEAST
- 12346:12346 # MLAT
+ # feed-in image builder
feed-in-builder:
container_name: feed-in-builder
build:
@@ -63,98 +59,74 @@ services:
image: feed-in
entrypoint: /bin/true
- # Multiplexer: Australia ACT
+ # MLAT: Australia ACT
mux-act:
container_name: mux-act
hostname: mux-act
<<: *mux-common
- ports:
- - 12601:30015
- # Multiplexer: Australia NSW
+ # MLAT: Australia NSW
mux-nsw:
container_name: mux-nsw
hostname: mux-nsw
<<: *mux-common
- ports:
- - 12001:30015
- # Multiplexer: Australia NT
+ # MLAT: Australia NT
mux-nt:
container_name: mux-nt
hostname: mux-nt
<<: *mux-common
- ports:
- - 10801:30015
- # Multiplexer: QLD
+ # MLAT: QLD
mux-qld:
container_name: mux-qld
hostname: mux-qld
<<: *mux-common
- ports:
- - 14001:30015
- # Multiplexer: SA
+ # MLAT: SA
mux-sa:
container_name: mux-sa
hostname: mux-sa
<<: *mux-common
- ports:
- - 15001:30015
- # Multiplexer: TAS
+ # MLAT: TAS
mux-tas:
container_name: mux-tas
hostname: mux-tas
<<: *mux-common
- ports:
- - 17001:30015
- # Multiplexer: VIC
+ # MLAT: VIC
mux-vic:
container_name: mux-vic
hostname: mux-vic
<<: *mux-common
- ports:
- - 13001:30015
- # Multiplexer: WA
+ # MLAT: WA
mux-wa:
container_name: mux-wa
hostname: mux-wa
<<: *mux-common
- ports:
- - 16001:30015
- # Multiplexer: NZ
+ # MLAT: NZ
mux-nz:
container_name: mux-nz
hostname: mux-nz
<<: *mux-common
- ports:
- - 19001:30015
- # Multiplexer: EU
+ # MLAT: EU
mux-eu:
container_name: mux-eu
hostname: mux-eu
<<: *mux-common
- ports:
- - 22001:30015
- # Multiplexer: USA
+ # MLAT: USA
mux-us:
container_name: mux-us
hostname: mux-us
<<: *mux-common
- ports:
- - 23001:30015
- # Multiplexer: ASIA
+ # MLAT: ASIA
mux-asia:
container_name: mux-asia
hostname: mux-asia
<<: *mux-common
- ports:
- - 24001:30015
diff --git a/pw-bordercontrol/cmd/bordercontrol/containers.go b/pw-bordercontrol/cmd/bordercontrol/containers.go
index b2329b24..d767992a 100644
--- a/pw-bordercontrol/cmd/bordercontrol/containers.go
+++ b/pw-bordercontrol/cmd/bordercontrol/containers.go
@@ -184,6 +184,7 @@ func startFeederContainers(
Str("label", string(containerToStart.clientDetails.label)).
Str("uuid", string(containerToStart.clientDetails.clientApiKey.String())).
Str("src", string(containerToStart.srcIP.String())).
+ Str("code", string(containerToStart.clientDetails.feederCode)).
Logger()
// determine if container is already running
@@ -222,13 +223,12 @@ func startFeederContainers(
fmt.Sprintf("FEEDER_LAT=%f", containerToStart.clientDetails.refLat),
fmt.Sprintf("FEEDER_LON=%f", containerToStart.clientDetails.refLon),
fmt.Sprintf("FEEDER_UUID=%s", containerToStart.clientDetails.clientApiKey.String()),
- // "READSB_STATS_EVERY=300",
- "READSB_NET_ENABLE=true",
- "READSB_NET_BEAST_INPUT_PORT=12345",
- "READSB_NET_BEAST_OUTPUT_PORT=30005",
- "READSB_NET_ONLY=true",
- fmt.Sprintf("READSB_NET_CONNECTOR=%s,12345,beast_out", containerToStart.clientDetails.mux),
+ fmt.Sprintf("FEEDER_TAG=%s", containerToStart.clientDetails.feederCode),
"PW_INGEST_PUBLISH=location-updates",
+ "PW_INGEST_INPUT_MODE=listen",
+ "PW_INGEST_INPUT_PROTO=beast",
+ "PW_INGEST_INPUT_ADDR=0.0.0.0",
+ "PW_INGEST_INPUT_PORT=12345",
fmt.Sprintf("PW_INGEST_SINK=%s", pwIngestPublish),
}
diff --git a/pw-bordercontrol/cmd/bordercontrol/containers_test.go b/pw-bordercontrol/cmd/bordercontrol/containers_test.go
index 4cefdfd0..da193dd4 100644
--- a/pw-bordercontrol/cmd/bordercontrol/containers_test.go
+++ b/pw-bordercontrol/cmd/bordercontrol/containers_test.go
@@ -32,6 +32,7 @@ const (
TestFeederLatitude = 123.456789
TestFeederLongitude = 98.765432
TestFeederMux = "test-mux"
+ TestFeederCode = "ABCD-1234"
TestPWIngestSink = "nats://pw-ingest-sink:12345"
)
@@ -39,12 +40,6 @@ const (
func TestContainersWithKill(t *testing.T) {
var (
- ContainerEnvVarFeederLatOK bool
- ContainerEnvVarFeederLonOK bool
- ContainerEnvVarFeederUUIDOK bool
- ContainerEnvVarFeederReadsbNetConnectorOK bool
- ContainerEnvVarFeederPWIngestSinkOK bool
-
ContainerNetworkOK bool
)
@@ -124,7 +119,8 @@ func TestContainersWithKill(t *testing.T) {
refLat: TestFeederLatitude,
refLon: TestFeederLongitude,
mux: TestFeederMux,
- label: TestFeederMux,
+ label: TestFeederLabel,
+ feederCode: TestFeederCode,
},
srcIP: net.IPv4(127, 0, 0, 1),
}
@@ -143,25 +139,21 @@ func TestContainersWithKill(t *testing.T) {
// check environment variables
t.Log("checking container environment variables")
+ envVars := make(map[string]string)
for _, e := range ct.Config.Env {
- switch e {
- case fmt.Sprintf("FEEDER_LAT=%f", TestFeederLatitude):
- ContainerEnvVarFeederLatOK = true
- case fmt.Sprintf("FEEDER_LON=%f", TestFeederLongitude):
- ContainerEnvVarFeederLonOK = true
- case fmt.Sprintf("FEEDER_UUID=%s", strings.ToLower(TestFeederAPIKey)):
- ContainerEnvVarFeederUUIDOK = true
- case fmt.Sprintf("READSB_NET_CONNECTOR=%s,12345,beast_out", TestFeederMux):
- ContainerEnvVarFeederReadsbNetConnectorOK = true
- case fmt.Sprintf("PW_INGEST_SINK=%s", TestPWIngestSink):
- ContainerEnvVarFeederPWIngestSinkOK = true
- }
+ envVars[strings.Split(e, "=")[0]] = strings.Split(e, "=")[1]
}
- assert.True(t, ContainerEnvVarFeederLatOK)
- assert.True(t, ContainerEnvVarFeederLonOK)
- assert.True(t, ContainerEnvVarFeederUUIDOK)
- assert.True(t, ContainerEnvVarFeederReadsbNetConnectorOK)
- assert.True(t, ContainerEnvVarFeederPWIngestSinkOK)
+
+ assert.Equal(t, fmt.Sprintf("%f", TestFeederLatitude), envVars["FEEDER_LAT"])
+ assert.Equal(t, fmt.Sprintf("%f", TestFeederLongitude), envVars["FEEDER_LON"])
+ assert.Equal(t, strings.ToLower(fmt.Sprintf("%s", TestFeederAPIKey)), envVars["FEEDER_UUID"])
+ assert.Equal(t, TestFeederCode, envVars["FEEDER_TAG"])
+ assert.Equal(t, TestPWIngestSink, envVars["PW_INGEST_SINK"])
+ assert.Equal(t, "location-updates", envVars["PW_INGEST_PUBLISH"])
+ assert.Equal(t, "listen", envVars["PW_INGEST_INPUT_MODE"])
+ assert.Equal(t, "beast", envVars["PW_INGEST_INPUT_PROTO"])
+ assert.Equal(t, "0.0.0.0", envVars["PW_INGEST_INPUT_ADDR"])
+ assert.Equal(t, "12345", envVars["PW_INGEST_INPUT_PORT"])
// check container autoremove set to true
t.Log("check container autoremove set to true")
diff --git a/pw-bordercontrol/cmd/bordercontrol/feeder_conn.go b/pw-bordercontrol/cmd/bordercontrol/feeder_conn.go
index 887e6e16..594f3e02 100644
--- a/pw-bordercontrol/cmd/bordercontrol/feeder_conn.go
+++ b/pw-bordercontrol/cmd/bordercontrol/feeder_conn.go
@@ -32,9 +32,9 @@ type (
// struct to hold feeder client information
feederClient struct {
- clientApiKey uuid.UUID
- refLat, refLon float64
- mux, label string
+ clientApiKey uuid.UUID
+ refLat, refLon float64
+ mux, label, feederCode string
}
// struct for proxy goroutines
@@ -298,7 +298,10 @@ func authenticateFeeder(connIn net.Conn) (clientDetails *feederClient, err error
if err != nil {
return clientDetails, err
}
- log = log.With().Str("uuid", clientDetails.clientApiKey.String()).Logger()
+ log = log.With().
+ Str("uuid", clientDetails.clientApiKey.String()).
+ Str("code", clientDetails.feederCode).
+ Logger()
// log.Trace().Msg("feeder API key received from SNI")
// check valid api key against atc
@@ -500,6 +503,7 @@ func proxyClientConnection(connIn net.Conn, connProto string, connNum uint, cont
Str("uuid", clientDetails.clientApiKey.String()).
Str("mux", clientDetails.mux).
Str("label", clientDetails.label).
+ Str("code", clientDetails.feederCode).
Logger()
// check number of connections, and drop connection if limit exceeded
@@ -519,12 +523,20 @@ func proxyClientConnection(connIn net.Conn, connProto string, connNum uint, cont
switch connProto {
case protoBeast:
- log = log.With().Str("dst", fmt.Sprintf("%s%s", feedInContainerPrefix, clientDetails.clientApiKey.String())).Logger()
+ log = log.With().
+ Str("dst", fmt.Sprintf("%s%s", feedInContainerPrefix, clientDetails.clientApiKey.String())).
+ Logger()
- // start the container
- containersToStartRequests <- startContainerRequest{
+ // request start of the feed-in container with submission timeout
+ select {
+ case containersToStartRequests <- startContainerRequest{
clientDetails: clientDetails,
srcIP: remoteIP,
+ }:
+ case <-time.After(5 * time.Second):
+ err := errors.New("5s timeout waiting to submit container start request")
+ log.Err(err).Msg("could not start feed-in container")
+ return err
}
// wait for request to be actioned
@@ -597,7 +609,7 @@ func proxyClientConnection(connIn net.Conn, connProto string, connNum uint, cont
}
// update stats
- stats.addConnection(clientDetails.clientApiKey, connIn.RemoteAddr(), connOut.RemoteAddr(), connProto, connNum)
+ stats.addConnection(clientDetails.clientApiKey, connIn.RemoteAddr(), connOut.RemoteAddr(), connProto, clientDetails.feederCode, connNum)
defer stats.delConnection(clientDetails.clientApiKey, connProto, connNum)
// method to signal goroutines to exit
diff --git a/pw-bordercontrol/cmd/bordercontrol/feeder_meta.go b/pw-bordercontrol/cmd/bordercontrol/feeder_meta.go
index ccf4c977..0e628c43 100644
--- a/pw-bordercontrol/cmd/bordercontrol/feeder_meta.go
+++ b/pw-bordercontrol/cmd/bordercontrol/feeder_meta.go
@@ -47,6 +47,7 @@ func getFeederInfo(f *feederClient) error {
f.refLon = v.Longitude
f.mux = v.Mux
f.label = v.Label
+ f.feederCode = v.FeederCode
found = true
break
}
diff --git a/pw-bordercontrol/cmd/bordercontrol/stats.go b/pw-bordercontrol/cmd/bordercontrol/stats.go
index 8d6c8926..c633b46a 100644
--- a/pw-bordercontrol/cmd/bordercontrol/stats.go
+++ b/pw-bordercontrol/cmd/bordercontrol/stats.go
@@ -29,6 +29,7 @@ type FeederStats struct {
Label string // feeder label
Lat float64 // feeder lat
Lon float64 // feeder lon
+ Code string // feeder_code
// Connection details
// string key = protocol (BEAST/MLAT, and in future ACARS/VDLM2 etc)
@@ -192,6 +193,7 @@ func (stats *Statistics) setFeederDetails(f *feederClient) {
y.Label = f.label
y.Lat = f.refLat
y.Lon = f.refLon
+ y.Code = f.feederCode
y.TimeUpdated = time.Now()
// write stats entry
@@ -270,7 +272,7 @@ func (stats *Statistics) delConnection(uuid uuid.UUID, proto string, connNum uin
// log.Debug().Msg("finished")
}
-func (stats *Statistics) addConnection(uuid uuid.UUID, src net.Addr, dst net.Addr, proto string, connNum uint) {
+func (stats *Statistics) addConnection(uuid uuid.UUID, src net.Addr, dst net.Addr, proto, code string, connNum uint) {
// updates the connected status of a feeder
log := log.With().
@@ -279,6 +281,7 @@ func (stats *Statistics) addConnection(uuid uuid.UUID, src net.Addr, dst net.Add
Str("src", src.String()).
Str("dst", dst.String()).
Str("proto", proto).
+ Str("code", code).
Uint("connNum", connNum).
Logger()
@@ -303,10 +306,11 @@ func (stats *Statistics) addConnection(uuid uuid.UUID, src net.Addr, dst net.Add
Name: "feeder_data_in_bytes_total",
Help: "Per-feeder bytes received (in)",
ConstLabels: prometheus.Labels{
- "protocol": strings.ToLower(proto),
- "uuid": uuid.String(),
- "label": stats.Feeders[uuid].Label,
- "connnum": fmt.Sprintf("%d", connNum),
+ "protocol": strings.ToLower(proto),
+ "uuid": uuid.String(),
+ "label": stats.Feeders[uuid].Label,
+ "connnum": fmt.Sprintf("%d", connNum),
+ "feeder_code": code,
}})
c.promMetricBytesOut = prometheus.NewCounter(prometheus.CounterOpts{
Namespace: promNamespace,
@@ -314,10 +318,11 @@ func (stats *Statistics) addConnection(uuid uuid.UUID, src net.Addr, dst net.Add
Name: "feeder_data_out_bytes_total",
Help: "Per-feeder bytes sent (out)",
ConstLabels: prometheus.Labels{
- "protocol": strings.ToLower(proto),
- "uuid": uuid.String(),
- "label": stats.Feeders[uuid].Label,
- "connnum": fmt.Sprintf("%d", connNum),
+ "protocol": strings.ToLower(proto),
+ "uuid": uuid.String(),
+ "label": stats.Feeders[uuid].Label,
+ "connnum": fmt.Sprintf("%d", connNum),
+ "feeder_code": code,
}})
err := prometheus.Register(c.promMetricBytesIn)
if err != nil {
diff --git a/pw-bordercontrol/cmd/bordercontrol/stats.tmpl b/pw-bordercontrol/cmd/bordercontrol/stats.tmpl
index e8c6bed2..b265e592 100644
--- a/pw-bordercontrol/cmd/bordercontrol/stats.tmpl
+++ b/pw-bordercontrol/cmd/bordercontrol/stats.tmpl
@@ -17,6 +17,7 @@
Feeder |
UUID |
+ Code |
Proto |
Conn # |
Src |
@@ -30,6 +31,7 @@
{{ $felement.Label }} |
{{ $index }} |
+ {{ $felement.Code }} |
{{ $pindex }} |
{{ $cindex }} |
{{ $celement.Src }} |
diff --git a/pw-bordercontrol/cmd/bordercontrol/stats_test.go b/pw-bordercontrol/cmd/bordercontrol/stats_test.go
index fbf6889d..411d5cdc 100644
--- a/pw-bordercontrol/cmd/bordercontrol/stats_test.go
+++ b/pw-bordercontrol/cmd/bordercontrol/stats_test.go
@@ -139,8 +139,8 @@ func TestStats(t *testing.T) {
// add some fake feeder connections
stats.setFeederDetails(&fc)
- stats.addConnection(u, &ip, &ip, protoBeast, 1)
- stats.addConnection(u, &ip, &ip, protoMLAT, 2)
+ stats.addConnection(u, &ip, &ip, protoBeast, "ABCD-1234", 1)
+ stats.addConnection(u, &ip, &ip, protoMLAT, "ABCD-1234", 2)
// check num conns
assert.Equal(t, 1, stats.getNumConnections(u, protoBeast))
@@ -165,10 +165,10 @@ func TestStats(t *testing.T) {
`pw_bordercontrol_feeders 1`,
`pw_bordercontrol_feeders_active{protocol="beast"} 1`,
`pw_bordercontrol_feeders_active{protocol="mlat"} 1`,
- fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="1",label="%s",protocol="beast",uuid="%s"} 100`, fc.label, fc.clientApiKey),
- fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="2",label="%s",protocol="mlat",uuid="%s"} 300`, fc.label, fc.clientApiKey),
- fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="1",label="%s",protocol="beast",uuid="%s"} 200`, fc.label, fc.clientApiKey),
- fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="2",label="%s",protocol="mlat",uuid="%s"} 400`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="1",feeder_code="ABCD-1234",label="%s",protocol="beast",uuid="%s"} 100`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="2",feeder_code="ABCD-1234",label="%s",protocol="mlat",uuid="%s"} 300`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="1",feeder_code="ABCD-1234",label="%s",protocol="beast",uuid="%s"} 200`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="2",feeder_code="ABCD-1234",label="%s",protocol="mlat",uuid="%s"} 400`, fc.label, fc.clientApiKey),
}
// tests
@@ -185,7 +185,7 @@ func TestStats(t *testing.T) {
_ = getMetricsFromTestServer(t, fmt.Sprintf("%s", statsBaseURL))
// add another beast connection
- stats.addConnection(u, &ip, &ip, protoBeast, 3)
+ stats.addConnection(u, &ip, &ip, protoBeast, "ABCD-1234", 3)
// remove connections (working)
stats.delConnection(u, protoBeast, 1)
@@ -225,10 +225,10 @@ func TestStats(t *testing.T) {
`pw_bordercontrol_feeders_active{protocol="mlat"} 0`,
}
notExpectedMetrics := []string{
- fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="1",label="%s",protocol="beast",uuid="%s"}`, fc.label, fc.clientApiKey),
- fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="2",label="%s",protocol="mlat",uuid="%s"}`, fc.label, fc.clientApiKey),
- fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="1",label="%s",protocol="beast",uuid="%s"}`, fc.label, fc.clientApiKey),
- fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="2",label="%s",protocol="mlat",uuid="%s"}`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="1",feeder_code="ABCD-1234",label="%s",protocol="beast",uuid="%s"}`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_in_bytes_total{connnum="2",feeder_code="ABCD-1234",label="%s",protocol="mlat",uuid="%s"}`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="1",feeder_code="ABCD-1234",label="%s",protocol="beast",uuid="%s"}`, fc.label, fc.clientApiKey),
+ fmt.Sprintf(`pw_bordercontrol_feeder_data_out_bytes_total{connnum="2",feeder_code="ABCD-1234",label="%s",protocol="mlat",uuid="%s"}`, fc.label, fc.clientApiKey),
}
checkPromMetricsExist(t, body, expectedMetrics)
diff --git a/pw-bordercontrol/go.mod b/pw-bordercontrol/go.mod
index 9104e119..00102544 100644
--- a/pw-bordercontrol/go.mod
+++ b/pw-bordercontrol/go.mod
@@ -8,7 +8,7 @@ require (
github.com/prometheus/client_golang v1.17.0
github.com/rs/zerolog v1.31.0
github.com/stretchr/testify v1.8.4
- github.com/urfave/cli/v2 v2.25.7
+ github.com/urfave/cli/v2 v2.26.0
)
require (
diff --git a/pw-bordercontrol/lib/atc/api.go b/pw-bordercontrol/lib/atc/api.go
index a689fc4f..87a506f2 100644
--- a/pw-bordercontrol/lib/atc/api.go
+++ b/pw-bordercontrol/lib/atc/api.go
@@ -27,6 +27,7 @@ type (
Feeder struct { // part of schema for /api/v1/feeders.json atc endpoint
Altitude float64 `json:",string"`
ApiKey uuid.UUID
+ FeederCode string
FeedDirection string
FeedProtocol string
ID int
@@ -38,19 +39,6 @@ type (
User string
}
- FeederB struct { // schema for /api/v1/feeders/{uuid}.json atc endpoint
- Feeder struct {
- ApiKey uuid.UUID `json:"api_key"`
- Label string `json:"label"`
- MlatEnabled bool `json:"mlat_enabled"`
- Latitude float64 `json:"latitude,string"`
- Longitude float64 `json:"longitude,string"`
- Protocol string `json:"protocol"`
- Elevation float64 `json:"elevation,string"`
- Mux string `json:"mux"`
- } `json:"feeder"`
- }
-
atcCredentials struct { // schema for atc credentials
Email string `json:"email"`
Password string `json:"password"`
@@ -105,62 +93,6 @@ func authenticate(server *Server) (authToken string, err error) {
return authToken, nil
}
-func GetFeederInfo(server *Server, feederApiKey uuid.UUID) (refLat float64, refLon float64, mux string, label string, err error) {
-
- authToken, err := authenticate(server)
- if err != nil {
- return refLat, refLon, mux, label, err
- }
-
- atcUrl := server.Url.JoinPath(fmt.Sprintf("/api/v1/feeders/%s.json", feederApiKey.String()))
-
- req, err := http.NewRequest("GET", atcUrl.String(), nil)
- if err != nil {
- return refLat, refLon, mux, label, err
- }
- req.Header.Set("Content-Type", "application/json")
- req.Header.Set("Authorization", authToken)
-
- client := &http.Client{}
- response, err := client.Do(req)
- if err != nil {
- return refLat, refLon, mux, label, err
- }
- defer response.Body.Close()
-
- // fmt.Println("response Status:", response.Status)
- // fmt.Println("response Headers:", response.Header)
- // body, _ := ioutil.ReadAll(response.Body)
- // fmt.Println("response Body:", string(body))
-
- body, err := io.ReadAll(response.Body)
- if err != nil {
- return refLat, refLon, mux, label, err
- }
-
- var feeder FeederB
-
- if response.StatusCode == 200 {
-
- err := json.Unmarshal(body, &feeder)
- if err != nil {
- return refLat, refLon, mux, label, err
- }
-
- refLat = feeder.Feeder.Latitude
- refLon = feeder.Feeder.Longitude
- mux = feeder.Feeder.Mux
- label = feeder.Feeder.Label
-
- } else {
- errStr := fmt.Sprintf("ATC API response status: %s", response.Status)
- return refLat, refLon, mux, label, errors.New(errStr)
- }
-
- return refLat, refLon, mux, label, err
-
-}
-
func GetFeeders(server *Server) (feeders Feeders, err error) {
authToken, err := authenticate(server)
diff --git a/pw-bordercontrol/lib/atc/api_test.go b/pw-bordercontrol/lib/atc/api_test.go
index cac84ddf..e5d0b6f4 100644
--- a/pw-bordercontrol/lib/atc/api_test.go
+++ b/pw-bordercontrol/lib/atc/api_test.go
@@ -120,12 +120,13 @@ func prepMockATCServer(t *testing.T, testScenario int) *httptest.Server {
// mock response
resp := fmt.Sprintf(
- `{"Feeders":[{"ApiKey":"%s","Label":"%s","Latitude":"%f","Longitude":"%f","Mux":"%s"}]}`,
+ `{"Feeders":[{"ApiKey":"%s","Label":"%s","Latitude":"%f","Longitude":"%f","Mux":"%s", "FeederCode":"%s"}]}`,
TestFeederAPIKeyWorking,
TestFeederLabel,
TestFeederLatitude,
TestFeederLongitude,
TestFeederMux,
+ TestFeederCode,
)
// response code
@@ -269,74 +270,6 @@ func TestAuthenticate_NoResponse(t *testing.T) {
assert.Error(t, err)
}
-func TestGetFeederInfo_Working(t *testing.T) {
-
- server := prepMockATCServer(t, MockServerTestScenarioWorking)
- defer server.Close()
-
- // prep url
- u, err := url.Parse(server.URL)
- assert.NoError(t, err)
-
- // function argument
- s := Server{
- Url: (*u),
- Username: TestUser,
- Password: TestPassword,
- }
-
- refLat, refLon, mux, label, err := GetFeederInfo(&s, uuid.MustParse(TestFeederAPIKeyWorking))
- assert.NoError(t, err)
- assert.Equal(t, TestFeederLatitude, refLat)
- assert.Equal(t, TestFeederLongitude, refLon)
- assert.Equal(t, TestFeederMux, mux)
- assert.Equal(t, TestFeederLabel, label)
-
-}
-
-func TestGetFeederInfo_BadResponse(t *testing.T) {
-
- // prep test server
- server := prepMockATCServer(t, MockServerTestScenarioBadResponseCodeFeeder)
- defer server.Close()
-
- // prep url
- u, err := url.Parse(server.URL)
- assert.NoError(t, err)
-
- // function argument
- s := Server{
- Url: (*u),
- Username: TestUser,
- Password: TestPassword,
- }
-
- _, _, _, _, err = GetFeederInfo(&s, uuid.MustParse(TestFeederAPIKeyWorking))
- assert.Error(t, err)
-
-}
-
-func TestGetFeederInfo_NoResponse(t *testing.T) {
-
- // prep test server
- server := prepMockATCServer(t, MockServerTestScenarioNoResponse)
-
- // prep url
- u, err := url.Parse(server.URL)
- assert.NoError(t, err)
-
- // function argument
- s := Server{
- Url: (*u),
- Username: TestUser,
- Password: TestPassword,
- }
-
- _, _, _, _, err = GetFeederInfo(&s, uuid.MustParse(TestFeederAPIKeyWorking))
- assert.Error(t, err)
-
-}
-
func TestGetFeeders_Working(t *testing.T) {
server := prepMockATCServer(t, MockServerTestScenarioWorking)
@@ -358,11 +291,12 @@ func TestGetFeeders_Working(t *testing.T) {
expectedFeeders := Feeders{
[]Feeder{{
- ApiKey: uuid.MustParse(TestFeederAPIKeyWorking),
- Label: TestFeederLabel,
- Latitude: TestFeederLatitude,
- Longitude: TestFeederLongitude,
- Mux: TestFeederMux,
+ ApiKey: uuid.MustParse(TestFeederAPIKeyWorking),
+ Label: TestFeederLabel,
+ Latitude: TestFeederLatitude,
+ Longitude: TestFeederLongitude,
+ Mux: TestFeederMux,
+ FeederCode: TestFeederCode,
}},
}
diff --git a/pw-feed-in/README.MD b/pw-feed-in/README.MD
new file mode 100644
index 00000000..d5f96bba
--- /dev/null
+++ b/pw-feed-in/README.MD
@@ -0,0 +1,19 @@
+# pw-feed-in #
+
+a.k.a "feed-in" containers.
+
+Spawns an instance of `pw_ingest` configured as-per below.
+
+## Environment Variables ##
+
+| Variable | Detail | Default |
+| -------- | ------ | ------- |
+| `FEEDER_LAT` | (Optional) Feeder latitude | *unset* |
+| `FEEDER_LON` | (Optional) Feeder longitude | *unset* |
+| `FEEDER_TAG` | (Required) Feeder tag | *unset* |
+| `PW_INGEST_INPUT_MODE` | Must be set to either `listen` or `fetch` | `listen` |
+| `PW_INGEST_INPUT_PROTO` | Must be either `avr`, `beast` or `sbs1` | `beast` |
+| `PW_INGEST_INPUT_ADDR` | The IP address to listen on / fetch from | `0.0.0.0` |
+| `PW_INGEST_INPUT_PORT` | The TCP port to listen on / fetch from | `12345` |
+| `PW_INGEST_SINK` | (Required) The place to send decoded JSON in URL Form, eg `nats://user:pass@host:port/vhost?ttl=60` | *unset* |
+| `PW_INGEST_ENABLE_ADSC` | (Optional) Set to `true` to enable ADS-C | `false` |
diff --git a/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/run b/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/run
index 7d832c26..945fd0d9 100755
--- a/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/run
+++ b/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/run
@@ -4,11 +4,16 @@
# Set pw_ingest binary
PW_INGEST_BIN="/usr/local/bin/pw_ingest"
+# Set ADS-C mode
+if [[ "${PW_INGEST_ENABLE_ADSC,,}" == "true" ]]; then
+ PW_INGEST_CMD+=("--ads-c")
+fi
+
# Set feeder tag/uuid
-PW_INGEST_CMD=("--tag" "${FEEDER_UUID}")
+PW_INGEST_CMD=("--tag" "${FEEDER_TAG}")
# Set input
-PW_INGEST_CMD+=("--fetch" "beast://127.0.0.1:30005")
+PW_INGEST_CMD+=("--${PW_INGEST_INPUT_MODE}" "${PW_INGEST_INPUT_PROTO}://${PW_INGEST_INPUT_ADDR}:${PW_INGEST_INPUT_PORT}")
# Set output
PW_INGEST_CMD+=("--sink" "${PW_INGEST_SINK}")
@@ -27,6 +32,12 @@ fi
# simple Gather ADSB data and sends it to the configured output.
PW_INGEST_CMD+=("simple")
+# show version
+fdmove -c 2 1 \
+ "${PW_INGEST_BIN}" \
+ --version |
+ awk -W Interactive '{print "[pw_ingest] " $0}'
+
# shellcheck disable=SC2016
fdmove -c 2 1 \
"${PW_INGEST_BIN}" \
diff --git a/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/readsb/run b/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/readsb/run
deleted file mode 100755
index 6d34fa7d..00000000
--- a/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/readsb/run
+++ /dev/null
@@ -1,341 +0,0 @@
-#!/command/with-contenv bash
-#shellcheck shell=bash
-
-mkdir -p /run/readsb
-chmod -R 755 /run/readsb
-
-# Set readsb binary
-READSB_BIN="/usr/local/bin/readsb"
-
-##### DEFAULT OPTIONS #####
-
-# Listen on 0.0.0.0
-READSB_CMD=("--net-bind-address=0.0.0.0")
-
-# Set quiet mode (TODO: unless verbose?)
-READSB_CMD+=("--quiet")
-
-# TODO: Only do this if webserver is enabled
-# Set path for protobuf output files
-READSB_CMD+=("--write-output=/run/readsb")
-
-##### GENERAL OPTIONS #####
-
-# Handle "--aggressive"
-if [[ -n "$READSB_AGGRESSIVE" ]]; then
- READSB_CMD+=("--aggressive")
-fi
-
-# Handle "--dcfilter"
-if [[ -n "$READSB_DCFILTER" ]]; then
- READSB_CMD+=("--dcfilter")
-fi
-
-# Handle "--device-type"
-if [[ -n "$READSB_DEVICE_TYPE" ]]; then
- READSB_CMD+=("--device-type=$READSB_DEVICE_TYPE")
-fi
-
-# Handle "--enable-biastee"
-if [[ -n "$READSB_ENABLE_BIASTEE" ]]; then
- READSB_CMD+=("--enable-biastee")
-fi
-
-# Handle "--fix"
-#shellcheck disable=SC2153
-if [[ -n "$READSB_FIX" ]]; then
- READSB_CMD+=("--fix")
-fi
-
-# Handle "--forward-mlat"
-if [[ -n "$READSB_FORWARD_MLAT" ]]; then
- READSB_CMD+=("--forward-mlat")
-fi
-
-# Handle "--freq="
-if [[ -n "$READSB_FREQ" ]]; then
- READSB_CMD+=("--freq=$READSB_FREQ")
-fi
-
-# Handle "--gain="
-# TODO - write specified gain to a file in a cont-init.d script,
-# so we can change gain using an auto-gain script and tell s6 to restart this service.
-# We can then read the gain from the file here.
-# If file doesn't exist then go with max gain.
-# if [[ -n "$READSB_GAIN" ]]; then
-# READSB_CMD+=("--gain=$READSB_GAIN")
-# fi
-if [[ -e "$GAIN_VALUE_FILE" ]]; then
- READSB_CMD+=("--gain=$(cat "$GAIN_VALUE_FILE")")
-fi
-
-# Handle "--gnss"
-if [[ -n "$READSB_GNSS" ]]; then
- READSB_CMD+=("--gnss")
-fi
-
-# Handle "--lat="
-if [[ -n "$FEEDER_LAT" ]]; then
- READSB_CMD+=("--lat=$FEEDER_LAT")
-fi
-
-# Handle "--lon="
-#shellcheck disable=SC2153
-if [[ -n "$FEEDER_LON" ]]; then
- READSB_CMD+=("--lon=$FEEDER_LON")
-fi
-
-# Handle "--max-range="
-if [[ -n "$READSB_MAX_RANGE" ]]; then
- READSB_CMD+=("--max-range=$READSB_MAX_RANGE")
-fi
-
-# Handle "--metric"
-if [[ -n "$READSB_METRIC" ]]; then
- READSB_CMD+=("--metric")
-fi
-
-# Handle "--mlat"
-if [[ -n "$READSB_MLAT" ]]; then
- READSB_CMD+=("--mlat")
-fi
-
-# Handle "--modeac"
-if [[ -n "$READSB_MODEAC" ]]; then
- READSB_CMD+=("--modeac")
-fi
-
-# Handle "--no-crc-check"
-if [[ -n "$READSB_NO_CRC_CHECK" ]]; then
- READSB_CMD+=("--no-crc-check")
-fi
-
-# Handle "--no-fix"
-if [[ -n "$READSB_NO_FIX" ]]; then
- READSB_CMD+=("--no-fix")
-fi
-
-# Handle "--no-modeac-auto"
-if [[ -n "$READSB_NO_MODEAC_AUTO" ]]; then
- READSB_CMD+=("--no-modeac-auto")
-fi
-
-# Handle "--preamble-threshold="
-if [[ -n "$READSB_PREAMBLE_THRESHOLD" ]]; then
- READSB_CMD+=("--preamble-threshold=$READSB_PREAMBLE_THRESHOLD")
-fi
-
-# Handle "--rx-location-accuracy="
-if [[ -n "$READSB_RX_LOCATION_ACCURACY" ]]; then
- READSB_CMD+=("--rx-location-accuracy=$READSB_RX_LOCATION_ACCURACY")
-fi
-
-# Handle "--stats-every="
-if [[ -n "$READSB_STATS_EVERY" ]]; then
- READSB_CMD+=("--stats-every=$READSB_STATS_EVERY")
-fi
-
-# Handle "--stats-range"
-if [[ -n "$READSB_STATS_RANGE" ]]; then
- READSB_CMD+=("--stats-range")
-fi
-
-##### NETWORK OPTIONS #####
-
-# Handle "--net"
-if [[ -n "$READSB_NET_ENABLE" ]]; then
- READSB_CMD+=("--net")
-fi
-
-# Handle "--net-beast-reduce-interval="
-if [[ -n "$READSB_NET_BEAST_REDUCE_INTERVAL" ]]; then
- READSB_CMD+=("--net-beast-reduce-interval=$READSB_NET_BEAST_REDUCE_INTERVAL")
-fi
-
-# Handle "--net-beast-reduce-out-port="
-if [[ -n "$READSB_NET_BEAST_REDUCE_OUT_PORT" ]]; then
- READSB_CMD+=("--net-beast-reduce-out-port=$READSB_NET_BEAST_REDUCE_OUT_PORT")
-fi
-
-# Handle "--net-bi-port="
-if [[ -n "$READSB_NET_BEAST_INPUT_PORT" ]]; then
- READSB_CMD+=("--net-bi-port=$READSB_NET_BEAST_INPUT_PORT")
-fi
-
-# Handle "--net-bo-port="
-if [[ -n "$READSB_NET_BEAST_OUTPUT_PORT" ]]; then
- READSB_CMD+=("--net-bo-port=$READSB_NET_BEAST_OUTPUT_PORT")
-fi
-
-# Handle "--net-buffer="
-if [[ -n "$READSB_NET_BUFFER" ]]; then
- READSB_CMD+=("--net-buffer=$READSB_NET_BUFFER")
-fi
-
-# Handle "--net-connector="
-if [[ -n "$READSB_NET_CONNECTOR" ]]; then
- IFS=';' read -r -a READSB_NET_CONNECTOR_ARRAY <<< "$READSB_NET_CONNECTOR"
- for NET_CONNECTOR_ELEMENT in "${READSB_NET_CONNECTOR_ARRAY[@]}"
- do
- READSB_CMD+=("--net-connector=$NET_CONNECTOR_ELEMENT")
- done
-fi
-
-# Handle "--net-connector-delay="
-if [[ -n "$READSB_NET_CONNECTOR_DELAY" ]]; then
- READSB_CMD+=("--net-connector-delay=$READSB_NET_CONNECTOR_DELAY")
-fi
-
-# Handle "--net-heartbeat="
-if [[ -n "$READSB_NET_HEARTBEAT" ]]; then
- READSB_CMD+=("--net-heartbeat=$READSB_NET_HEARTBEAT")
-fi
-
-# Handle "--net-only"
-if [[ -n "$READSB_NET_ONLY" ]]; then
- READSB_CMD+=("--net-only")
-fi
-
-# Handle "--net-ri-port="
-if [[ -n "$READSB_NET_RAW_INPUT_PORT" ]]; then
- READSB_CMD+=("--net-ri-port=$READSB_NET_RAW_INPUT_PORT")
-fi
-
-# Handle "--net-ro-interval="
-if [[ -n "$READSB_NET_RAW_OUTPUT_INTERVAL" ]]; then
- READSB_CMD+=("--net-ro-interval=$READSB_NET_RAW_OUTPUT_INTERVAL")
-fi
-
-# Handle "--net-ri-port="
-if [[ -n "$READSB_NET_RAW_OUTPUT_PORT" ]]; then
- READSB_CMD+=("--net-ro-port=$READSB_NET_RAW_OUTPUT_PORT")
-fi
-
-# Handle "--net-ro-size="
-if [[ -n "$READSB_NET_RAW_OUTPUT_SIZE" ]]; then
- READSB_CMD+=("--net-ro-size=$READSB_NET_RAW_OUTPUT_SIZE")
-fi
-
-# Handle "--net-sbs-in-port="
-if [[ -n "$READSB_NET_SBS_INPUT_PORT" ]]; then
- READSB_CMD+=("--net-sbs-in-port=$READSB_NET_SBS_INPUT_PORT")
-fi
-
-# Handle "--net-sbs-port="
-if [[ -n "$READSB_NET_SBS_OUTPUT_PORT" ]]; then
- READSB_CMD+=("--net-sbs-port=$READSB_NET_SBS_OUTPUT_PORT")
-fi
-
-# Handle "--net-verbatim"
-if [[ -n "$REASSB_NET_VERBATIM" ]]; then
- READSB_CMD+=("--net-verbatim")
-fi
-
-# Handle "--net-vrs-port="
-if [[ -n "$READSB_NET_VRS_PORT" ]]; then
- READSB_CMD+=("--net-vrs-port=$READSB_NET_VRS_PORT")
-
-# Telegraf needs the JSON output from readsb, so if this hasn't been enabled by the user, enable it
-elif [ -z "$INFLUXDB_SKIP_AIRCRAFT" ] && { [ -n "$INFLUXDBURL" ] || [ -n "$ENABLE_PROMETHEUS" ]; } then
- READSB_NET_VRS_PORT="33333"
- READSB_CMD+=("--net-vrs-port=$READSB_NET_VRS_PORT")
-fi
-
-##### RTL-SDR OPTIONS #####
-
-# Handle "--device="
-if [[ -n "$READSB_RTLSDR_DEVICE" ]]; then
- READSB_CMD+=("--device=$READSB_RTLSDR_DEVICE")
-fi
-
-# Handle "--enable-agc"
-if [[ -n "$READSB_RTLSDR_ENABLE_AGC" ]]; then
- READSB_CMD+=("--enable-agc")
-fi
-
-# Handle "--ppm="
-if [[ -n "$READSB_RTLSDR_PPM" ]]; then
- READSB_CMD+=("--ppm=$READSB_RTLSDR_PPM")
-fi
-
-##### BLADERF OPTIONS #####
-
-# Handle "--device="
-if [[ -n "$READSB_BLADERF_DEVICE" ]]; then
- READSB_CMD+=("--device=$READSB_BLADERF_DEVICE")
-fi
-
-# Handle "--bladerf-bandwidth="
-if [[ -n "$READSB_BLADERF_BANDWIDTH" ]]; then
- READSB_CMD+=("--bladerf-bandwidth=$READSB_BLADERF_BANDWIDTH")
-fi
-
-# Handle "--bladerf-decimation="
-if [[ -n "$READSB_BLADERF_DECIMATION" ]]; then
- READSB_CMD+=("--bladerf-decimation=$READSB_BLADERF_DECIMATION")
-fi
-
-# Handle "--bladerf-fpga="
-if [[ -n "$READSB_BLADERF_FPGA" ]]; then
- READSB_CMD+=("--bladerf-fpga=\"$READSB_BLADERF_FPGA\"")
-fi
-
-##### MODE-S BEAST OPTIONS #####
-
-# Handle "--beast-crc-off"
-if [[ -n "$READSB_BEAST_CRC_OFF" ]]; then
- READSB_CMD+=("--beast-crc-off")
-fi
-
-# Handle "--beast-df045-on"
-if [[ -n "$READSB_BEAST_DF045_ON" ]]; then
- READSB_CMD+=("--beast-df045-on")
-fi
-
-# Handle "--beast-df1117-on"
-if [[ -n "$READSB_BEAST_DF1117_ON" ]]; then
- READSB_CMD+=("--beast-df1117-on")
-fi
-
-# Handle "--beast-fec-off"
-if [[ -n "$READSB_BEAST_FEC_OFF" ]]; then
- READSB_CMD+=("--beast-fec-off")
-fi
-
-# Handle "--beast-mlat-off"
-if [[ -n "$READSB_BEAST_MLAT_OFF" ]]; then
- READSB_CMD+=("--beast-mlat-off")
-fi
-
-# Handle "--beast-modeac"
-if [[ -n "$READSB_BEAST_MODEAC" ]]; then
- READSB_CMD+=("--beast-modeac")
-fi
-
-# Handle "--beast-serial="
-if [[ -n "$READSB_BEAST_SERIAL" ]]; then
- READSB_CMD+=("--beast-serial=$READSB_BEAST_SERIAL")
-fi
-
-##### ADALM-Pluto SDR OPTIONS #####
-
-# Handle "--pluto-network="
-if [[ -n "$READSB_PLUTO_NETWORK" ]]; then
- READSB_CMD+=("--pluto-network=$READSB_PLUTO_NETWORK")
-fi
-
-# Handle "--pluto-uri="
-if [[ -n "$READSB_PLUTO_URI" ]]; then
- READSB_CMD+=("--pluto-uri=$READSB_PLUTO_URI")
-fi
-
-##### LAUNCH READSB #####
-
-set -eo pipefail
-
-# shellcheck disable=SC2016
-fdmove -c 2 1 \
- "${READSB_BIN}" \
- "${READSB_CMD[@]}" |
- sed --unbuffered '/^$/d' |
- awk -W Interactive '{print "[readsb] " strftime("%Y/%m/%d %H:%M:%S", systime()) " " $0}'
\ No newline at end of file
diff --git a/pw-feed-in/rootfs/scripts/healthcheck.sh b/pw-feed-in/rootfs/scripts/healthcheck.sh
index 58b5e150..7bfb9cde 100755
--- a/pw-feed-in/rootfs/scripts/healthcheck.sh
+++ b/pw-feed-in/rootfs/scripts/healthcheck.sh
@@ -1,11 +1,14 @@
#!/usr/bin/env bash
# shellcheck shell=bash
+# Sleep for random seconds between 1 and 30
+sleep "$((1 + $RANDOM % 30))"
+
EXITCODE=0
# check beast connection inbound from bordercontrol
CONNECTED_BEAST_IN=false
-if ss -ntH state established | tr -s " " | cut -d " " -f 3 | grep ":12345" > /dev/null 2>&1; then
+if ss -ntH state established | tr -s " " | cut -d " " -f 3 | grep ":${PW_INGEST_INPUT_PORT}" > /dev/null 2>&1; then
CONNECTED_BEAST_IN=true
echo "CONNECTED_BEAST_IN=true"
else
@@ -13,16 +16,6 @@ else
EXITCODE=1
fi
-# check beast connection outbound to mux
-CONNECTED_BEAST_OUT=false
-if ss -ntH state established | tr -s " " | cut -d " " -f 4 | grep ":12345" > /dev/null 2>&1; then
- CONNECTED_BEAST_OUT=true
- echo "CONNECTED_BEAST_OUT=true"
-else
- echo "CONNECTED_BEAST_OUT=false"
- EXITCODE=1
-fi
-
# check nats connection outbound
CONNECTED_NATS_OUT=false
if ss -ntH state established | tr -s " " | cut -d " " -f 4 | grep ":4222" > /dev/null 2>&1; then
@@ -33,6 +26,14 @@ else
EXITCODE=1
fi
+# check FEEDER_TAG exists
+if /command/s6-env bash -c '[[ -n "$FEEDER_TAG" ]]'; then
+ echo "FEEDER_TAG_VALID=true"
+else
+ echo "FEEDER_TAG_VALID=false"
+ EXITCODE=1
+fi
+
# update /run/healthcheck
if [ "$(cat /run/healthcheck)" != "$EXITCODE" ]; then
echo "$EXITCODE" > /run/healthcheck
@@ -41,7 +42,9 @@ fi
# if container has been unhealthy for 10mins+ then stop container
if [ "$(cat /run/healthcheck)" != "0" ]; then
if test "$(find /run/healthcheck -mmin +10)"; then
- s6-svscanctl -t /var/run/s6/services
+ # kill container init, which will stop container
+ # as container should be started with autoremove, it should be deleted
+ kill 1
fi
fi
diff --git a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/mlat-server/run b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/mlat-server/run
index b457ac2a..3146f77b 100755
--- a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/mlat-server/run
+++ b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/mlat-server/run
@@ -19,6 +19,7 @@ mkdir -p /run/mlat-server/workdir
fdmove -c 2 1 \
/opt/mlat-server/mlat-server \
--client-listen 0.0.0.0:12346 \
+ --basestation-listen 0.0.0.0:30003 \
--motd "plane.watch:${HOSTNAME}" \
--work-dir /run/mlat-server/workdir \
--status-interval 3600 |
diff --git a/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/readsb/dependencies.d/base b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/dependencies.d/base
similarity index 100%
rename from pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/readsb/dependencies.d/base
rename to pw-mux/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/dependencies.d/base
diff --git a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/run b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/run
new file mode 100755
index 00000000..14365645
--- /dev/null
+++ b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/run
@@ -0,0 +1,43 @@
+#!/command/with-contenv bash
+# shellcheck shell=bash
+
+# Set pw_ingest binary
+PW_INGEST_BIN="/usr/local/bin/pw_ingest"
+
+# Set feeder tag/uuid
+PW_INGEST_CMD=("--tag" "mlat-$(hostname)")
+
+# Set input
+PW_INGEST_CMD+=("--fetch" "sbs1://127.0.0.1:30003")
+
+# Set output
+PW_INGEST_CMD+=("--sink" "${PW_INGEST_SINK}")
+
+# # Set LAT if given
+# if [[ -n "${FEEDER_LAT}" ]]; then
+# PW_INGEST_CMD+=("--ref-lat" "${FEEDER_LAT}")
+# fi
+
+# # Set LON if given
+# if [[ -n "${FEEDER_LON}" ]]; then
+# PW_INGEST_CMD+=("--ref-lon" "${FEEDER_LON}")
+# fi
+
+# "simple" mode
+# simple Gather ADSB data and sends it to the configured output.
+PW_INGEST_CMD+=("simple")
+
+# show version
+fdmove -c 2 1 \
+ "${PW_INGEST_BIN}" \
+ --version |
+ awk -W Interactive '{print "[pw_ingest] " $0}'
+
+# shellcheck disable=SC2016
+fdmove -c 2 1 \
+ "${PW_INGEST_BIN}" \
+ "${PW_INGEST_CMD[@]}" |
+ awk -W Interactive '{print "[pw_ingest] " $0}'
+
+# prevent re-launching too fast
+sleep 5
diff --git a/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/readsb/type b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/type
similarity index 100%
rename from pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/readsb/type
rename to pw-mux/rootfs/etc/s6-overlay/s6-rc.d/pw-ingest/type
diff --git a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/dependencies.d/base b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/dependencies.d/base
deleted file mode 100644
index e69de29b..00000000
diff --git a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/run b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/run
deleted file mode 100755
index 78a89a02..00000000
--- a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/run
+++ /dev/null
@@ -1,342 +0,0 @@
-#!/command/with-contenv bash
-#shellcheck shell=bash
-
-mkdir -p /run/readsb
-chmod -R 755 /run/readsb
-
-# Set readsb binary
-READSB_BIN="/usr/local/bin/readsb"
-
-##### DEFAULT OPTIONS #####
-
-# Listen on 0.0.0.0
-READSB_CMD=("--net-bind-address=0.0.0.0")
-
-# Set quiet mode (TODO: unless verbose?)
-READSB_CMD+=("--quiet")
-
-# TODO: Only do this if webserver is enabled
-# Set path for protobuf output files
-READSB_CMD+=("--write-output=/run/readsb")
-
-##### GENERAL OPTIONS #####
-
-# Handle "--aggressive"
-if [[ -n "$READSB_AGGRESSIVE" ]]; then
- READSB_CMD+=("--aggressive")
-fi
-
-# Handle "--dcfilter"
-if [[ -n "$READSB_DCFILTER" ]]; then
- READSB_CMD+=("--dcfilter")
-fi
-
-# Handle "--device-type"
-if [[ -n "$READSB_DEVICE_TYPE" ]]; then
- READSB_CMD+=("--device-type=$READSB_DEVICE_TYPE")
-fi
-
-# Handle "--enable-biastee"
-if [[ -n "$READSB_ENABLE_BIASTEE" ]]; then
- READSB_CMD+=("--enable-biastee")
-fi
-
-# Handle "--fix"
-#shellcheck disable=SC2153
-if [[ -n "$READSB_FIX" ]]; then
- READSB_CMD+=("--fix")
-fi
-
-# Handle "--forward-mlat"
-if [[ -n "$READSB_FORWARD_MLAT" ]]; then
- READSB_CMD+=("--forward-mlat")
-fi
-
-# Handle "--freq="
-if [[ -n "$READSB_FREQ" ]]; then
- READSB_CMD+=("--freq=$READSB_FREQ")
-fi
-
-# Handle "--gain="
-# TODO - write specified gain to a file in a cont-init.d script,
-# so we can change gain using an auto-gain script and tell s6 to restart this service.
-# We can then read the gain from the file here.
-# If file doesn't exist then go with max gain.
-# if [[ -n "$READSB_GAIN" ]]; then
-# READSB_CMD+=("--gain=$READSB_GAIN")
-# fi
-if [[ -e "$GAIN_VALUE_FILE" ]]; then
- READSB_CMD+=("--gain=$(cat "$GAIN_VALUE_FILE")")
-fi
-
-# Handle "--gnss"
-if [[ -n "$READSB_GNSS" ]]; then
- READSB_CMD+=("--gnss")
-fi
-
-# Handle "--lat="
-if [[ -n "$FEEDER_LAT" ]]; then
- READSB_CMD+=("--lat=$FEEDER_LAT")
-fi
-
-# Handle "--lon="
-#shellcheck disable=SC2153
-if [[ -n "$FEEDER_LON" ]]; then
- READSB_CMD+=("--lon=$FEEDER_LON")
-fi
-
-# Handle "--max-range="
-if [[ -n "$READSB_MAX_RANGE" ]]; then
- READSB_CMD+=("--max-range=$READSB_MAX_RANGE")
-fi
-
-# Handle "--metric"
-if [[ -n "$READSB_METRIC" ]]; then
- READSB_CMD+=("--metric")
-fi
-
-# Handle "--mlat"
-if [[ -n "$READSB_MLAT" ]]; then
- READSB_CMD+=("--mlat")
-fi
-
-# Handle "--modeac"
-if [[ -n "$READSB_MODEAC" ]]; then
- READSB_CMD+=("--modeac")
-fi
-
-# Handle "--no-crc-check"
-if [[ -n "$READSB_NO_CRC_CHECK" ]]; then
- READSB_CMD+=("--no-crc-check")
-fi
-
-# Handle "--no-fix"
-if [[ -n "$READSB_NO_FIX" ]]; then
- READSB_CMD+=("--no-fix")
-fi
-
-# Handle "--no-modeac-auto"
-if [[ -n "$READSB_NO_MODEAC_AUTO" ]]; then
- READSB_CMD+=("--no-modeac-auto")
-fi
-
-# Handle "--preamble-threshold="
-if [[ -n "$READSB_PREAMBLE_THRESHOLD" ]]; then
- READSB_CMD+=("--preamble-threshold=$READSB_PREAMBLE_THRESHOLD")
-fi
-
-# Handle "--rx-location-accuracy="
-if [[ -n "$READSB_RX_LOCATION_ACCURACY" ]]; then
- READSB_CMD+=("--rx-location-accuracy=$READSB_RX_LOCATION_ACCURACY")
-fi
-
-# Handle "--stats-every="
-if [[ -n "$READSB_STATS_EVERY" ]]; then
- READSB_CMD+=("--stats-every=$READSB_STATS_EVERY")
-fi
-
-# Handle "--stats-range"
-if [[ -n "$READSB_STATS_RANGE" ]]; then
- READSB_CMD+=("--stats-range")
-fi
-
-##### NETWORK OPTIONS #####
-
-# Handle "--net"
-if [[ -n "$READSB_NET_ENABLE" ]]; then
- READSB_CMD+=("--net")
-fi
-
-# Handle "--net-beast-reduce-interval="
-if [[ -n "$READSB_NET_BEAST_REDUCE_INTERVAL" ]]; then
- READSB_CMD+=("--net-beast-reduce-interval=$READSB_NET_BEAST_REDUCE_INTERVAL")
-fi
-
-# Handle "--net-beast-reduce-out-port="
-if [[ -n "$READSB_NET_BEAST_REDUCE_OUT_PORT" ]]; then
- READSB_CMD+=("--net-beast-reduce-out-port=$READSB_NET_BEAST_REDUCE_OUT_PORT")
-fi
-
-# Handle "--net-bi-port="
-if [[ -n "$READSB_NET_BEAST_INPUT_PORT" ]]; then
- READSB_CMD+=("--net-bi-port=$READSB_NET_BEAST_INPUT_PORT")
-fi
-
-# Handle "--net-bo-port="
-if [[ -n "$READSB_NET_BEAST_OUTPUT_PORT" ]]; then
- READSB_CMD+=("--net-bo-port=$READSB_NET_BEAST_OUTPUT_PORT")
-fi
-
-# Handle "--net-buffer="
-if [[ -n "$READSB_NET_BUFFER" ]]; then
- READSB_CMD+=("--net-buffer=$READSB_NET_BUFFER")
-fi
-
-# Handle "--net-connector="
-if [[ -n "$READSB_NET_CONNECTOR" ]]; then
- IFS=';' read -r -a READSB_NET_CONNECTOR_ARRAY <<< "$READSB_NET_CONNECTOR"
- for NET_CONNECTOR_ELEMENT in "${READSB_NET_CONNECTOR_ARRAY[@]}"
- do
- READSB_CMD+=("--net-connector=$NET_CONNECTOR_ELEMENT")
- done
-fi
-
-# Handle "--net-connector-delay="
-if [[ -n "$READSB_NET_CONNECTOR_DELAY" ]]; then
- READSB_CMD+=("--net-connector-delay=$READSB_NET_CONNECTOR_DELAY")
-fi
-
-# Handle "--net-heartbeat="
-if [[ -n "$READSB_NET_HEARTBEAT" ]]; then
- READSB_CMD+=("--net-heartbeat=$READSB_NET_HEARTBEAT")
-fi
-
-# Handle "--net-only"
-if [[ -n "$READSB_NET_ONLY" ]]; then
- READSB_CMD+=("--net-only")
-fi
-
-# Handle "--net-ri-port="
-if [[ -n "$READSB_NET_RAW_INPUT_PORT" ]]; then
- READSB_CMD+=("--net-ri-port=$READSB_NET_RAW_INPUT_PORT")
-fi
-
-# Handle "--net-ro-interval="
-if [[ -n "$READSB_NET_RAW_OUTPUT_INTERVAL" ]]; then
- READSB_CMD+=("--net-ro-interval=$READSB_NET_RAW_OUTPUT_INTERVAL")
-fi
-
-# Handle "--net-ri-port="
-if [[ -n "$READSB_NET_RAW_OUTPUT_PORT" ]]; then
- READSB_CMD+=("--net-ro-port=$READSB_NET_RAW_OUTPUT_PORT")
-fi
-
-# Handle "--net-ro-size="
-if [[ -n "$READSB_NET_RAW_OUTPUT_SIZE" ]]; then
- READSB_CMD+=("--net-ro-size=$READSB_NET_RAW_OUTPUT_SIZE")
-fi
-
-# Handle "--net-sbs-in-port="
-if [[ -n "$READSB_NET_SBS_INPUT_PORT" ]]; then
- READSB_CMD+=("--net-sbs-in-port=$READSB_NET_SBS_INPUT_PORT")
-fi
-
-# Handle "--net-sbs-port="
-if [[ -n "$READSB_NET_SBS_OUTPUT_PORT" ]]; then
- READSB_CMD+=("--net-sbs-port=$READSB_NET_SBS_OUTPUT_PORT")
-fi
-
-# Handle "--net-verbatim"
-if [[ -n "$REASSB_NET_VERBATIM" ]]; then
- READSB_CMD+=("--net-verbatim")
-fi
-
-# Handle "--net-vrs-port="
-if [[ -n "$READSB_NET_VRS_PORT" ]]; then
- READSB_CMD+=("--net-vrs-port=$READSB_NET_VRS_PORT")
-
-# Telegraf needs the JSON output from readsb, so if this hasn't been enabled by the user, enable it
-elif [ -z "$INFLUXDB_SKIP_AIRCRAFT" ] && { [ -n "$INFLUXDBURL" ] || [ -n "$ENABLE_PROMETHEUS" ]; } then
- READSB_NET_VRS_PORT="33333"
- READSB_CMD+=("--net-vrs-port=$READSB_NET_VRS_PORT")
-fi
-
-##### RTL-SDR OPTIONS #####
-
-# Handle "--device="
-if [[ -n "$READSB_RTLSDR_DEVICE" ]]; then
- READSB_CMD+=("--device=$READSB_RTLSDR_DEVICE")
-fi
-
-# Handle "--enable-agc"
-if [[ -n "$READSB_RTLSDR_ENABLE_AGC" ]]; then
- READSB_CMD+=("--enable-agc")
-fi
-
-# Handle "--ppm="
-if [[ -n "$READSB_RTLSDR_PPM" ]]; then
- READSB_CMD+=("--ppm=$READSB_RTLSDR_PPM")
-fi
-
-##### BLADERF OPTIONS #####
-
-# Handle "--device="
-if [[ -n "$READSB_BLADERF_DEVICE" ]]; then
- READSB_CMD+=("--device=$READSB_BLADERF_DEVICE")
-fi
-
-# Handle "--bladerf-bandwidth="
-if [[ -n "$READSB_BLADERF_BANDWIDTH" ]]; then
- READSB_CMD+=("--bladerf-bandwidth=$READSB_BLADERF_BANDWIDTH")
-fi
-
-# Handle "--bladerf-decimation="
-if [[ -n "$READSB_BLADERF_DECIMATION" ]]; then
- READSB_CMD+=("--bladerf-decimation=$READSB_BLADERF_DECIMATION")
-fi
-
-# Handle "--bladerf-fpga="
-if [[ -n "$READSB_BLADERF_FPGA" ]]; then
- READSB_CMD+=("--bladerf-fpga=\"$READSB_BLADERF_FPGA\"")
-fi
-
-##### MODE-S BEAST OPTIONS #####
-
-# Handle "--beast-crc-off"
-if [[ -n "$READSB_BEAST_CRC_OFF" ]]; then
- READSB_CMD+=("--beast-crc-off")
-fi
-
-# Handle "--beast-df045-on"
-if [[ -n "$READSB_BEAST_DF045_ON" ]]; then
- READSB_CMD+=("--beast-df045-on")
-fi
-
-# Handle "--beast-df1117-on"
-if [[ -n "$READSB_BEAST_DF1117_ON" ]]; then
- READSB_CMD+=("--beast-df1117-on")
-fi
-
-# Handle "--beast-fec-off"
-if [[ -n "$READSB_BEAST_FEC_OFF" ]]; then
- READSB_CMD+=("--beast-fec-off")
-fi
-
-# Handle "--beast-mlat-off"
-if [[ -n "$READSB_BEAST_MLAT_OFF" ]]; then
- READSB_CMD+=("--beast-mlat-off")
-fi
-
-# Handle "--beast-modeac"
-if [[ -n "$READSB_BEAST_MODEAC" ]]; then
- READSB_CMD+=("--beast-modeac")
-fi
-
-# Handle "--beast-serial="
-if [[ -n "$READSB_BEAST_SERIAL" ]]; then
- READSB_CMD+=("--beast-serial=$READSB_BEAST_SERIAL")
-fi
-
-##### ADALM-Pluto SDR OPTIONS #####
-
-# Handle "--pluto-network="
-if [[ -n "$READSB_PLUTO_NETWORK" ]]; then
- READSB_CMD+=("--pluto-network=$READSB_PLUTO_NETWORK")
-fi
-
-# Handle "--pluto-uri="
-if [[ -n "$READSB_PLUTO_URI" ]]; then
- READSB_CMD+=("--pluto-uri=$READSB_PLUTO_URI")
-fi
-
-##### LAUNCH READSB #####
-
-set -eo pipefail
-
-fdmove -c 2 1 \
- "${READSB_BIN}" \
- "${READSB_CMD[@]}" |
- sed --unbuffered '/^$/d' |
- awk -W Interactive '{print "[readsb] " strftime("%Y/%m/%d %H:%M:%S", systime()) " " $0}'
-
-sleep 5
diff --git a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/type b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/type
deleted file mode 100644
index 1780f9f4..00000000
--- a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/readsb/type
+++ /dev/null
@@ -1 +0,0 @@
-longrun
\ No newline at end of file
diff --git a/pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/readsb b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/pw-ingest
similarity index 100%
rename from pw-feed-in/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/readsb
rename to pw-mux/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/pw-ingest
diff --git a/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/readsb b/pw-mux/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/readsb
deleted file mode 100644
index e69de29b..00000000