Browse Source

Two stage build to reduce image size and build improvements provided by @imrehg.

Add (optional) metering support for use with Prometheus.
master
Jac Kersing 5 years ago
parent
commit
2922f63a85
  1. 37
      Dockerfile.template
  2. 58
      Dockerfile.template.metering
  3. 21
      README.md
  4. 20
      dev/build.sh
  5. BIN
      gwexporter.tgz
  6. 7
      run.py
  7. 3
      start.sh
  8. 15
      start.sh.metering

37
Dockerfile.template

@ -1,18 +1,29 @@
FROM resin/%%RESIN_MACHINE_NAME%%-buildpack-deps
FROM resin/%%RESIN_MACHINE_NAME%%-debian:latest AS buildstep
# Enable systemd, as Resin requires this
ENV INITSYSTEM on
WORKDIR /opt/ttn-gateway/
# Make the hardware type available as a runtime env var
ENV RESIN_ARCH %%RESIN_ARCH%%
ENV RESIN_MACHINE_NAME %%RESIN_MACHINE_NAME%%
# downloading utils
RUN apt-get update && \
apt-get install wget build-essential libc6-dev git pkg-config protobuf-compiler libprotobuf-dev libprotoc-dev automake libtool autoconf python-dev python-rpi.gpio
# Copy the build and run environment
COPY . /opt/ttn-gateway/
WORKDIR /opt/ttn-gateway/
COPY dev dev
RUN ./dev/build.sh
FROM resin/%%RESIN_MACHINE_NAME%%-debian:latest
WORKDIR /opt/ttn-gateway
RUN apt-get update && \
apt-get install python-rpi.gpio && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY --from=buildstep /opt/ttn-gateway/mp_pkt_fwd .
COPY --from=buildstep /usr/local/lib/libpaho-embed-* /usr/lib/
COPY --from=buildstep /usr/lib/libttn* /usr/lib/
# Build the gateway (or comment this out if debugging on-device)
RUN ./dev/build.sh && rm -rf ./dev
COPY run.py ./
COPY start.sh ./
# Start it up
CMD ["sh", "-c", "./run.py"]
# run when container lands on device
CMD ["bash", "start.sh"]

58
Dockerfile.template.metering

@ -0,0 +1,58 @@
FROM resin/%%RESIN_MACHINE_NAME%%-debian:latest AS buildstep
# downloading utils
RUN apt-get update && \
apt-get install wget build-essential libc6-dev git pkg-config protobuf-compiler libprotobuf-dev libprotoc-dev automake libtool autoconf python-dev python-rpi.gpio
WORKDIR /etc
# versions
ENV NODE_EXPORTER_VERSION 0.12.0
ENV DIST_ARCH linux-armv7
RUN wget https://github.com/prometheus/node_exporter/releases/download/${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.${DIST_ARCH}.tar.gz \
&& tar xvfz node_exporter-${NODE_EXPORTER_VERSION}.${DIST_ARCH}.tar.gz \
&& rm node_exporter-${NODE_EXPORTER_VERSION}.${DIST_ARCH}.tar.gz
COPY gwexporter.tgz /opt/ttn-gateway/gwexporter.tgz
WORKDIR /opt/gwexporter
RUN tar xvzf /opt/ttn-gateway/gwexporter.tgz
RUN wget https://nodejs.org/dist/v8.8.1/node-v8.8.1-linux-armv6l.tar.gz \
&& tar xvzf node-v8.8.1-linux-armv6l.tar.gz \
&& mv node-v8.8.1-linux-armv6l/* . \
&& rm -rf node-v8.8.1-linux-armv6l
WORKDIR /opt/ttn-gateway/
COPY dev dev
RUN ./dev/build.sh
FROM resin/%%RESIN_MACHINE_NAME%%-debian:latest
RUN apt-get update && \
apt-get install python-rpi.gpio && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Enable systemd
ENV INITSYSTEM on
# versions
ENV NODE_EXPORTER_VERSION 0.12.0
ENV DIST_ARCH linux-armv7
WORKDIR /etc
COPY --from=buildstep /etc/node_exporter-${NODE_EXPORTER_VERSION}.${DIST_ARCH} .
WORKDIR /opt/gwexporter
COPY --from=buildstep /opt/gwexporter .
WORKDIR /opt/ttn-gateway
COPY --from=buildstep /opt/ttn-gateway/mp_pkt_fwd .
COPY --from=buildstep /usr/local/lib/libpaho-embed-* /usr/lib/
COPY --from=buildstep /usr/lib/libttn* /usr/lib/
COPY run.py run.py
WORKDIR /
COPY start.sh.metering start.sh
# run when container lands on device
CMD ["bash", "start.sh"]

21
README.md

@ -14,6 +14,7 @@ Currently any Raspberry Pi with one of the following gateway boards, communicati
* [IMST iC880A-SPI](http://webshop.imst.de/ic880a-spi-lorawan-concentrator-868mhz.html). Preferable configured as described [by TTN-ZH](https://github.com/ttn-zh/ic880a-gateway/wiki). You **do not** need to follow the **Setting up the software** step, as the setup scripts in this repository does it for you.
* [LinkLabs Raspberry Pi "Hat"](http://link-labs.myshopify.com/products/lorawan-raspberry-pi-board)
* [RisingHF IoT Dicovery](http://www.risinghf.com/product/risinghf-iot-dicovery/?lang=en)
* [RAK831](http://www.rakwireless.com/en/WisKeyOSH/RAK831)
## Prerequisites
@ -37,7 +38,7 @@ For a more complete list of possible environment variables, see [CONFIGURATION](
### Device environment variables - no GPS
For example, for an IMST iC880A with no GPS, the MINIMUM environment variables that you should configure at this screen should look something like this:
For example, for an IMST iC880A or RAK831 with no GPS, the MINIMUM environment variables that you should configure at this screen should look something like this:
Name | Value
------------------|--------------------------
@ -47,7 +48,7 @@ GW_ID | The gateway ID from the TTN console
GW_KEY | The gateway KEY from the TTN console
GW_RESET_PIN | 22 (optional)
GW_RESET_PIN can be left out if you are using Gonzalo Casas' backplane board, or any other setup using pin 22 as reset pin. This is because pin 22 is the default reset pin used by this resin.io setup.
GW_RESET_PIN can be left out if you are using Gonzalo Casas' backplane board, the RAK backplane for the RAK831, or any other setup using pin 22 as reset pin. This is because pin 22 is the default reset pin used by this resin.io setup.
### Device environment variables - with GPS
@ -77,6 +78,7 @@ Linklabs Rasberry Pi Hat<br />https://www.amazon.co.uk/868-MHz-LoRaWAN-RPi-Shiel
Rising HF Board<br />http://www.risinghf.com/product/risinghf-iot-dicovery/?lang=en | 26
IMST backplane or Lite gateway<br />https://wireless-solutions.de/products/long-range-radio/lora_lite_gateway.html | 29 (untested)
Coredump backplane<br />https://github.com/dbrgn/ic880a-backplane/<br />https://shop.coredump.ch/product/ic880a-lorawan-gateway-backplane/ | 22
RAK backplane<br /> | 11
If you get the message
@ -84,7 +86,7 @@ If you get the message
after resin.io is finished downloading the application, or when restarting the gateway, it most likely means the `GW_RESET_PIN` you defined is incorrect. Alternatively the problem can be caused by the hardware, typically for the `IMST iC880A-SPI` board with insufficient voltage, try another power supply or slightly increase the voltage.
## Special note for using the LinkLabs gateway on a Raspberry Pi 3
## Special note for using a Raspberry Pi 3
There is a backward incomatibility between the Raspberry Pi 1 and 2 hardware, and Raspberry Pi 3. For Raspberry Pi 3, it is necessary to make a small additional configuration change.
@ -156,11 +158,22 @@ If you get the error below please check if your ssh public key has been added to
```
git add .
git commit -m "Updated gateway version"
git push -f resin master"
git push -f resin master
```
- For devices without a GPS, the location that is configured on the TTN console is used. This location is only read at startup of the gateway. Therefore, after you set or changed the location, restart the application from the resin.io console.
# Device statistics
If you want to show nice looking statistics for your gateway(s) there are a couple of additional steps to take. First,
copy Dockerfile.template.metering to Dockerfile.template . Next copy start.sh.metering to start.sh . Now use the instructions above to
update the resin image.
Once the new image is deployed, go to the resin.io dashboard for your devices and select 'Enable Public device URL' in the drop down menu
(the one to the right of the light bulb). That is all that is required to provide metrics. Now you will need to install a metrics collector
on a seperate system as outlined in [Fleet-wide Machine Metrics Monitoring in 20mins](https://resin.io/blog/prometheusv2/)
(To show packet forwarder graphs you need to add your own graphs to the provided templates)
# Credits
* [Gonzalo Casas](https://github.com/gonzalocasas) on the [iC880a-based gateway](https://github.com/ttn-zh/ic880a-gateway/tree/spi)

20
dev/build.sh

@ -5,17 +5,6 @@ INSTALL_DIR="/opt/ttn-gateway"
mkdir -p $INSTALL_DIR/dev
cd $INSTALL_DIR/dev
if [ ! -d wiringPi ]; then
git clone git://git.drogon.net/wiringPi || { echo 'Cloning wiringPi failed.' ; exit 1; }
cd wiringPi
else
cd wiringPi
git reset --hard
git pull
fi
./build
cd ..
if [ ! -d lora_gateway ]; then
git clone https://github.com/kersing/lora_gateway.git || { echo 'Cloning lora_gateway failed.' ; exit 1; }
else
@ -70,13 +59,10 @@ else
cd ..
fi
apt-get update
apt-get -y install protobuf-compiler libprotobuf-dev libprotoc-dev automake libtool autoconf python-dev python-rpi.gpio
cd $INSTALL_DIR/dev/lora_gateway/libloragw
sed -i -e 's/PLATFORM= .*$/PLATFORM= imst_rpi/g' library.cfg
sed -i -e 's/CFG_SPI= .*$/CFG_SPI= native/g' library.cfg
make
make -j$(nproc)
cd $INSTALL_DIR/dev/protobuf-c
./autogen.sh
@ -92,11 +78,11 @@ make install
cd $INSTALL_DIR/dev/ttn-gateway-connector
cp config.mk.in config.mk
make
make -j$(nproc)
cp bin/libttn-gateway-connector.so /usr/lib/
cd $INSTALL_DIR/dev/packet_forwarder/mp_pkt_fwd/
make
make -j$(nproc)
# Copy things needed at runtime to where they'll be expected
cp $INSTALL_DIR/dev/packet_forwarder/mp_pkt_fwd/mp_pkt_fwd $INSTALL_DIR/mp_pkt_fwd

BIN
gwexporter.tgz

Binary file not shown.

7
run.py

@ -23,7 +23,7 @@ except RuntimeError:
GWID_PREFIX="FFFE"
if not os.path.exists("mp_pkt_fwd"):
if not os.path.exists("/opt/ttn-gateway/mp_pkt_fwd"):
print ("ERROR: gateway executable not found. Is it built yet?")
sys.exit(0)
@ -172,6 +172,7 @@ gateway_conf = {}
gateway_conf['gateway_ID'] = my_eui
gateway_conf['contact_email'] = os.getenv('GW_CONTACT_EMAIL', "")
gateway_conf['description'] = description
gateway_conf['stat_file'] = 'loragwstat.json'
if(os.getenv('GW_FWD_CRC_ERR', "false")=="true"):
#default is False
@ -291,7 +292,7 @@ if(os.getenv('SERVER_3_ENABLED', "false")=="true"):
# We merge the json objects from the global_conf and local_conf and save it to the global_conf.
# Therefore there will not be a local_conf.json file.
local_conf = {'SX1301_conf': sx1301_conf, 'gateway_conf': gateway_conf}
with open('global_conf.json', 'w') as the_file:
with open('/opt/ttn-gateway/global_conf.json', 'w') as the_file:
the_file.write(json.dumps(local_conf, indent=4))
@ -332,5 +333,5 @@ while True:
GPIO.cleanup(22)
# Start forwarder
subprocess.call(["./mp_pkt_fwd"])
subprocess.call("/opt/ttn-gateway/mp_pkt_fwd -c /opt/ttn-gateway", shell=True)
time.sleep(15)

3
start.sh

@ -0,0 +1,3 @@
#!/bin/bash
python /opt/ttn-gateway/run.py

15
start.sh.metering

@ -0,0 +1,15 @@
#!/bin/bash
# Start the node exporter
mkdir /mnt/ramdisk
mount -t tmpfs -o size=8m tmpfs /mnt/ramdisk
cd /mnt/ramdisk
/opt/ttn-gateway/run.py &
# WORKAROUND: Add symlink, as gwexporter otherwise currently don't seem to find this file
ln -s /mnt/ramdisk/loragwstat.json /opt/gwexporter/loragwstat.json
export PATH=$PATH:/opt/gwexporter/bin
node /opt/gwexporter/gwexporter.js &
cd /etc && ./node_exporter -web.listen-address ":81"
Loading…
Cancel
Save