Running OpenNMS Minion on Raspberry Pi with ARM architecture

Hello together,

tried to run the dockerized minion on a pi as described https://www.opennms.com/en/blog/2018-05-20-minion-docker/ but in vain. Unfortunatelly there is no output at all … no error logs, no warnings. The only error indicator is the exit code of the docker container: “Exited (132)”.

Does anyone has got it running on a pi3 or pi4?

Regards, Guenther

With Horizon 26.0.0 we improved in NMS-12483 our opennms/minion container image to support amd64 and arm64 architecture. If you want to give it a spin on a Raspberry Pi 3+ make sure you have a 64bit OS running, e.g. Ubuntu Core 18 would be one option. The 1 GB RAM of a Pi 3+ might be very limited.

For myself, I have the Minion Docker image running on a Raspberry Pi 4 and picked the 4 GB version. The OpenNMS Minion instructions in our docs Run with Docker should point you in the right directions.

TL;DR
We ran in an issue when you have a 32-bit operating system. Thankfully @mattixtech investigated this issue and ran in a problem with Java Native Access (JNA) which we use for ICMP. He was able to send them a patch as a PR in their repository which is merged and released in Java JNA 5.5.0. We run right now with JNA 4.4.0 and the dependency isn’t updated yet on our side.

I guess the question from Minion on pi / arm-architecture? is the same topic. I’ve closed it and we can use this topic here. Let me know if there is anything missing.

1 Like

I’ve got a Pi4 running a minion, except I have to reboot it every 2-3 days as it goes to 100% CPU and memory usage and becomes unrecoverable.

I’ve tried setting the ulimits in the docker-compose but it’s not made much of an effect.

It’s using the opennms/pi-minion image currently as the opennms/minion:26.1.0 image for arm comes up with this error when running:

    onms-sec-minion-01 | org.apache.felix.resolver.reason.ReasonException: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=minion-provisiond-detectors; type=karaf.feature; version="[26.1.0,26.1.0]"; filter:="(&(osgi.identity=minion-provisiond-detectors)(type=karaf.feature)(version>=26.1.0)(version<=26.1.0))" [caused by: Unable to resolve minion-provisiond-detectors/26.1.0: missing requirement [minion-provisiond-detectors/26.1.0] osgi.identity; osgi.identity=opennms-icmp-best; type=karaf.feature [caused by: Unable to resolve opennms-icmp-best/26.1.0: missing requirement [opennms-icmp-best/26.1.0] osgi.identity; osgi.identity=opennms-icmp-jna; type=karaf.feature [caused by: Unable to resolve opennms-icmp-jna/26.1.0: missing requirement [opennms-icmp-jna/26.1.0] osgi.identity; osgi.identity=org.opennms.opennms-icmp-jna; type=osgi.bundle; version="[26.1.0,26.1.0]"; resolution:=mandatory [caused by: Unable to resolve org.opennms.opennms-icmp-jna/26.1.0: missing requirement [org.opennms.opennms-icmp-jna/26.1.0] osgi.wiring.package; filter:="(osgi.wiring.package=com.sun.jna)" [caused by: Unable to resolve com.sun.jna [13](R 13.0): missing requirement [com.sun.jna [13](R 13.0)] osgi.native; (|(&(osgi.native.osname~=win32)(osgi.native.processor~=x86))(&(osgi.native.osname~=win32)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=win)(osgi.native.processor~=x86))(&(osgi.native.osname~=win)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=wince)(osgi.native.processor~=arm))(&(osgi.native.osname~=sunos)(osgi.native.processor~=x86))(&(osgi.native.osname~=sunos)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=sunos)(osgi.native.processor~=sparc))(&(osgi.native.osname~=sunos)(osgi.native.processor~=sparcv9))(&(osgi.native.osname~=aix)(osgi.native.processor~=ppc))(&(osgi.native.osname~=aix)(osgi.native.processor~=ppc64))(&(osgi.native.osname~=linux)(osgi.native.processor~=ppc))(&(osgi.native.osname~=linux)(osgi.native.processor~=ppc64))(&(osgi.native.osname~=linux)(osgi.native.processor~=ppc64le))(&(osgi.native.osname~=linux)(osgi.native.processor~=x86))(&(osgi.native.osname~=linux)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=linux)(osgi.native.processor~=arm))(&(osgi.native.osname~=linux)(osgi.native.processor~=armel))(&(osgi.native.osname~=linux)(osgi.native.processor~=aarch64))(&(osgi.native.osname~=linux)(osgi.native.processor~=ia64))(&(osgi.native.osname~=linux)(osgi.native.processor~=sparcv9))(&(osgi.native.osname~=freebsd)(osgi.native.processor~=x86))(&(osgi.native.osname~=freebsd)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=openbsd)(osgi.native.processor~=x86))(&(osgi.native.osname~=openbsd)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=macosx)(|(osgi.native.processor~=x86)(osgi.native.processor~=x86-64)(osgi.native.processor~=ppc))))]]]]]
    onms-sec-minion-01 |    at org.apache.felix.resolver.Candidates$MissingRequirementError.toException(Candidates.java:1343)
    onms-sec-minion-01 |    at org.apache.felix.resolver.ResolverImpl.doResolve(ResolverImpl.java:392)
    onms-sec-minion-01 |    at org.apache.felix.resolver.ResolverImpl.resolve(ResolverImpl.java:378)
    onms-sec-minion-01 |    at org.apache.felix.resolver.ResolverImpl.resolve(ResolverImpl.java:332)
    onms-sec-minion-01 |    at org.apache.karaf.features.internal.region.SubsystemResolver.resolve(SubsystemResolver.java:257)
    onms-sec-minion-01 |    at org.apache.karaf.features.internal.service.Deployer.deploy(Deployer.java:393)
    onms-sec-minion-01 |    at org.apache.karaf.features.internal.service.FeaturesServiceImpl.doProvision(FeaturesServiceImpl.java:1062)
    onms-sec-minion-01 |    at org.apache.karaf.features.internal.service.FeaturesServiceImpl.lambda$doProvisionInThread$13(FeaturesServiceImpl.java:998)
    onms-sec-minion-01 |    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    onms-sec-minion-01 |    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    onms-sec-minion-01 |    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    onms-sec-minion-01 |    at java.base/java.lang.Thread.run(Thread.java:834)
    onms-sec-minion-01 | Caused by: org.apache.felix.resolver.reason.ReasonException: Unable to resolve minion-provisiond-detectors/26.1.0: missing requirement [minion-provisiond-detectors/26.1.0] osgi.identity; osgi.identity=opennms-icmp-best; type=karaf.feature [caused by: Unable to resolve opennms-icmp-best/26.1.0: missing requirement [opennms-icmp-best/26.1.0] osgi.identity; osgi.identity=opennms-icmp-jna; type=karaf.feature [caused by: Unable to resolve opennms-icmp-jna/26.1.0: missing requirement [opennms-icmp-jna/26.1.0] osgi.identity; osgi.identity=org.opennms.opennms-icmp-jna; type=osgi.bundle; version="[26.1.0,26.1.0]"; resolution:=mandatory [caused by: Unable to resolve org.opennms.opennms-icmp-jna/26.1.0: missing requirement [org.opennms.opennms-icmp-jna/26.1.0] osgi.wiring.package; filter:="(osgi.wiring.package=com.sun.jna)" [caused by: Unable to resolve com.sun.jna [13](R 13.0): missing requirement [com.sun.jna [13](R 13.0)] osgi.native; (|(&(osgi.native.osname~=win32)(osgi.native.processor~=x86))(&(osgi.native.osname~=win32)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=win)(osgi.native.processor~=x86))(&(osgi.native.osname~=win)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=wince)(osgi.native.processor~=arm))(&(osgi.native.osname~=sunos)(osgi.native.processor~=x86))(&(osgi.native.osname~=sunos)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=sunos)(osgi.native.processor~=sparc))(&(osgi.native.osname~=sunos)(osgi.native.processor~=sparcv9))(&(osgi.native.osname~=aix)(osgi.native.processor~=ppc))(&(osgi.native.osname~=aix)(osgi.native.processor~=ppc64))(&(osgi.native.osname~=linux)(osgi.native.processor~=ppc))(&(osgi.native.osname~=linux)(osgi.native.processor~=ppc64))(&(osgi.native.osname~=linux)(osgi.native.processor~=ppc64le))(&(osgi.native.osname~=linux)(osgi.native.processor~=x86))(&(osgi.native.osname~=linux)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=linux)(osgi.native.processor~=arm))(&(osgi.native.osname~=linux)(osgi.native.processor~=armel))(&(osgi.native.osname~=linux)(osgi.native.processor~=aarch64))(&(osgi.native.osname~=linux)(osgi.native.processor~=ia64))(&(osgi.native.osname~=linux)(osgi.native.processor~=sparcv9))(&(osgi.native.osname~=freebsd)(osgi.native.processor~=x86))(&(osgi.native.osname~=freebsd)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=openbsd)(osgi.native.processor~=x86))(&(osgi.native.osname~=openbsd)(osgi.native.processor~=x86-64))(&(osgi.native.osname~=macosx)(|(osgi.native.processor~=x86)(osgi.native.processor~=x86-64)(osgi.native.processor~=ppc))))]]]]
    onms-sec-minion-01 |    at org.apache.felix.resolver.Candidates$MissingRequirementError.toException(Candidates.java:1343)
    onms-sec-minion-01 |    ... 12 more

This is my docker-compose:
version: ‘3.4’

services:
  minion:
    #image: opennms/minion:26.1.0
    image: opennms/pi-minion
    container_name: onms-minion-01
    environment:
      - TZ=Australia/Perth
      - MINION_ID=<id>
      - MINION_LOCATION=Default
      - OPENNMS_BROKER_URL=tcp://opennms:61616
      - OPENNMS_HTTP_URL=http://opennms:8980/opennms
    command: ["-f"]
    ulimits:
      nofile:
        soft: 1024
        hard: 65536
    sysctls:
      - net.ipv4.ping_group_range=0 429496729
    healthcheck:
      test: ["CMD", "/opt/minion/bin/client", "ping", "|", "grep", "-Pzo", "\"(?s).*Success.*.Success.*\"", "||", "exit", "1"]
      interval: 10s
      timeout: 3s
      retries: 3
    ports:
      - "8201:8201/tcp"
      - "1162:1162/udp"
      - "1514:1514/udp"
    restart: unless-stopped

This error message is exactly the one you will seen when you try to run on 32-bit ARM architecture. See NMS-10447. You have to switch to a 64-bit operating system run the Minion Docker image.

Ok, I’ll take that onboard and give it a go.

I will say this, though. The Pi has only been running since March and the earliest version it had on it was 25 (currently 26.1.0) and it’s only been seen since changing from the docker pi-minion image to using opennms/minion:26.1.0 image.

The incident you’ve cited was resolved back in October last year, I’d have thought this would have been immediately seen when we tried to deploy the minions initially, not several months (and releases) later.

This here should explain it :slight_smile:

I did a very ‘dirty’ workaround, but it works.

JNA 4.4.0 has an issue with an ARM -32 bit system. This has been resolved with JNA 5.5.0

Files required are jna-5.5.0.jar and jna-platform-5.5.0.jar

I did the following:

  1. /usr/share/minion/system/net/java/dev/jna/jna-platform/4.4.0, copied jna-platform-5.5.0.jar into that directory and renamed it to jna-platform-4.4.0.jar
  2. /usr/share/minion/system/net/java/dev/jna/jna/4.4.0, copied jna-5.5.0.jar into that directory and renamed it to jna-4.4.0.jar

All bundles which were initiall yin ‘Installed’ state turned into ‘Active’ state afterwards.

I’ve put your proposed changes together into a docker composition and a on-the-fly-replacement script:

#
# Description:
#      Docker composition for OpenNMS Minion on Raspberry PI.
#
version: '3.4'
#
services:
  minion:
    image:              opennms/minion:27.0.2
    container_name:     minion
    network_mode:       host
    environment:
      - TZ=Europe/Berlin
      - MINION_ID=AnUniqueUUID
      - MINION_LOCATION=MyLocation
      - OPENNMS_BROKER_URL=failover:tcp://FQDN:61616
      - OPENNMS_BROKER_USER=MyUsername
      - OPENNMS_BROKER_PASS=MyPassword
      - OPENNMS_HTTP_URL=http://FQDN:8980/opennms
      - OPENNMS_HTTP_USER=AnotherUsername
      - OPENNMS_HTTP_PASS=AnotherPassword
    command: ["-c"]
    sysctls:
      - net.ipv4.ping_group_range=0 429496729
    volumes:
      - .:/mnt
    healthcheck:
      test: "/mnt/replace-jna-and-health.sh"
      interval: 15s
      timeout: 6s
      retries: 1
#
# end-of-docker-compose.yml
#

with the script named replace-jna-and-health.sh in the same directory

#!/bin/bash
SRCDIR=/mnt
DSTDIR=/opt/minion
MARKERFILE=/tmp/jna-replacement-is-done
#
# Check whether we still have to replace the jna files
#
if [ ! -f ${MARKERFILE} ]; then
   echo "Part I"
   echo "removing checksums"
   find ${DSTDIR} -name jna-platform-4.4.0.jar.sha1 -print -exec rm {} \;
   echo "replacing files"
   find ${DSTDIR} -name jna-platform-4.4.0.jar -print -exec cp ${SRCDIR}/jna-platform-5.6.0.jar {} \;
   echo "Part II"
   echo "removing checksums"
   find ${DSTDIR} -name jna-4.4.0.jar.sha1 -print -exec rm {} \;
   echo "replacing files"
   find ${DSTDIR} -name jna-4.4.0.jar -print -exec cp ${SRCDIR}/jna-5.6.0.jar {} \;
   echo "done"
   echo "done" >${MARKERFILE}
fi
#
# Do the health test
#
exec /health.sh
#
# end-of-replace-jna-and-health.sh
#

and, of course, the two appropriate jar files jna-5.6.0.jar and jna-platform-5.6.0.jar.

After initiating the docker composition with docker up -d it takes ten seconds and a well-running OpenNMS Minion is running on a pi4.