Skip to content

Testing with podman as non root

mdavidsaver edited this page Nov 20, 2022 · 12 revisions

Testing CF with podman as a non-root user

This page describes using podman only to test development builds of channelfinder.

See also the docker-compose.yml file.

Tested with podman 3.0.1 and ChannelFinderService circa November 2022.

Privileged Setup

sudo apt-get install podman rootlesskit

Build scripts

Several script files will be referenced below.

cat <<EOF > build-in-container.sh
#!/bin/sh
set -e -x
mvn --version
git clone --depth 1 https://github.com/ChannelFinder/ChannelFinderService /tmp/cf
(cd /tmp/cf && mvn install && ls target)
cp /tmp/cf/target/ChannelFinder*.jar .
EOF
chmod +x build-in-container.sh
cat <<EOF > Containerfile.recsync 
FROM docker.io/library/python:3.9
MAINTAINER \$USER

RUN pip install --no-cache-dir \
 Twisted~=20.3 \
 git+https://github.com/ChannelFinder/pyCFClient.git \
 git+https://github.com/ChannelFinder/recsync#subdirectory=server

RUN python -c 'from twisted.plugin import IPlugin, getPlugins; list(getPlugins(IPlugin))'

USER nobody:nogroup

ENTRYPOINT exec /usr/local/bin/twistd -n --reactor=poll --pidfile=/tmp/twistd.pid recceiver -f recceiver.conf
EOF

Building

Build ChannelFinder*.jar from current source.

podman run --rm \
 -v $PWD:/io \
 docker.io/library/maven:3-eclipse-temurin-11 \
 /io/build-in-container.sh
ls ChannelFinder*.jar

Create an image with the latest recsync server.

podman build -f Containerfile.recsync  -t recsync:latest

If successful, a file with a name like ChannelFinder-4.7.1-SNAPSHOT.jar will be listed.

Runtime Container Setup

Networking

Create an isolated "pod" which will contain both the channelfinder and elasticsearch daemons, but only allow access to the channelfinder daemon.

podman pod create --name cf --network slirp4netns -p 8080:8080 -p 8443:8443

Alternately, use --net host to allow access to all ports of both daemons.

podman pod create --name cf --network host

ElasticSearch

Create the directory which will hold the elasticsearch database files.

podman unshare install -d -o 1000 -g 1000 $PWD/esdata

Note that this directory could later be removed with podman unshare rm -rf $PWD/esdata.

Now create a container for the elasticsearch daemon.

podman create --name elasticsearch --pod cf \
 -e ES_JAVA_OPTS="-Xms1g -Xmx1g" \
 -e "discovery.type=single-node" \
 -e "xpack.security.enabled=false" \
 -e "network.host=127.0.0.1" \
 -e "bootstrap.memory_lock=true" \
 -v $PWD/esdata:/usr/share/elasticsearch/data \
 --health-cmd "curl http://localhost:9200/" \
 --health-start-period 10s \
 docker.elastic.co/elasticsearch/elasticsearch:8.2.3

See the elasticsearch documentation for details.

ChannelFinder

podman create --name channelfinder --pod cf \
 -v $PWD:/io:ro -w /io \
 --health-cmd "curl http://localhost:8080/ChannelFinder" \
 --health-start-period 10s \
 docker.io/library/eclipse-temurin:11-jre \
 java -Xms1g -Xmx1g -jar ChannelFinder*.jar

This uses the default application.properties file with demo_auth.enabled = true.

Append --spring.config.location=file:/io/application.properties to read a customized application.properties from the current directory.

Recsync

Place two configuration files in the current directory, where the can be edited.

cat <<EOF > recceiver.conf
[recceiver]
loglevel = DEBUG
procs = cf
EOF
cat <<EOF > channelfinderapi.conf 
[DEFAULT]
BaseURL=http://localhost:8080/ChannelFinder
username=admin
password=adminPass
EOF

Create a container for the recsync server (recceiver). This container uses --net host to allow UDP announcement broadcasts to reach any local IOCs.

podman create --name recceiver --net host \
 -v $PWD:/io -w /io \
 localhost/recsync:latest

Startup

podman start elasticsearch
until podman healthcheck run elasticsearch; do sleep 1; done
podman start channelfinder
until podman healthcheck run channelfinder; do sleep 1; done
podman start recceiver

Shutdown

podman stop recceiver
podman stop channelfinder
podman stop -t 100 elasticsearch
podman pod stop cf

Testing

Check to see that the CF server is accessible. (redundant to healthcheck above)

curl http://localhost:8080/ChannelFinder
{
  "name" : "ChannelFinder Service",
  "version" : "4.7.0",
  "elastic" : {
    "status" : "Connected",
    "clusterName" : "docker-cluster",
    "clusterUuid" : "9vRVCVnlTKmA7Kgih-gVPg",
    "version" : "co.elastic.clients.elasticsearch._types.ElasticsearchVersionInfo@3487af93"
  }
}

See that recceiver has created the cfstore properties.

curl http://localhost:8080/ChannelFinder/resources/properties
[{"name":"hostName","owner":"cfstore","value":null,"channels":[]},
 {"name":"iocName","owner":"cfstore","value":null,"channels":[]},
 {"name":"iocid","owner":"cfstore","value":null,"channels":[]},
 {"name":"pvStatus","owner":"cfstore","value":null,"channels":[]},
 {"name":"time","owner":"cfstore","value":null,"channels":[]}]

Cleanup

Complete removal of containers and locally created images.

podman rm recceiver
podman rm channelfinder
podman rm elasticsearch
podman rmi localhost/recsync
podman pod rm cf

Remove elasticsearch database fiels.

podman unshare rm -rf $PWD/esdata