Simple functionality checks

Add script to verify basic functionality (port connectivity) for all
services and slightly more advanced functionality for pdns and pdnsmysql
This commit is contained in:
Bernhard "bero" Rosenkränzer (Boggins) 2025-02-17 20:03:27 +01:00
parent b8fb6d55be
commit a38d625025
8 changed files with 189 additions and 55 deletions

82
bin/check Executable file
View File

@ -0,0 +1,82 @@
#!/bin/bash
SERVICE="$1"
. /federated/lib/functions.sh
if [ -e /federated/services/$SERVICE/service ]; then
. /federated/services/$SERVICE/service
elif [ -d /federated/apps/$SERVICE ]; then
INTERNAL_IP="$(cat /federated/apps/$SERVICE/docker-compose.yml |grep 'ipv4_address:' |cut -d: -f2 |xargs echo)"
RELEVANT=false
while read r; do
[ -z "$r" ] && continue
if [ "$r" = "ports:" ]; then
RELEVANT=true
continue
fi
$RELEVANT || continue
if [ "$(echo $r |cut -b1)" != "-" ]; then
break
fi
P="$(echo $r |cut -b2- |xargs echo |sed -e 's,",,g')"
if echo $P |grep -q :; then
P="$(echo $P |cut -d: -f2-)"
fi
PUBLICPORTS="${PUBLICPORTS} ${P}"
done < <(cat /federated/apps/$SERVICE/docker-compose.yml)
unset RELEVANT
else
echo "Invalid service $SERVICE" >&2
exit 1
fi
if [ -n "${INTERNAL_IP}" ]; then
# Make sure the container is responding
for IP in ${INTERNAL_IP} ${EXTRA_IPS}; do
if ! ping -c3 ${IP}; then
echo "$1 container not responding on ${IP}" >&2
exit 1
fi
done
fi
if [ -n "${PORTS}" ]; then
# Make sure we can connect to the provided ports
for PORT in ${PORTS}; do
TRIES=5
while ! nc -z ${INTERNAL_IP} ${PORT}; do
sleep 5s
TRIES=$((TRIES-1))
if [ "$TRIES" = "0" ]; then
echo "$1 container fails to respond on port ${PORT}" >&2
exit 2
fi
done
done
fi
if [ -n "${PUBLICPORTS}" ]; then
# Make sure we can connect to the external ports on the public IP
IP="$(get_externalip)"
for PORT in ${PUBLICPORTS}; do
TRIES=5
if echo $PORT |grep -q '/udp$'; then
NC_OPTS="--udp"
PORT="$(echo $PORT |sed -e 's,/udp$,,')"
else
NC_OPTS=""
fi
while ! nc -z ${NC_OPTS} ${IP} ${PORT}; do
sleep 5s
TRIES=$((TRIES-1))
if [ "$TRIES" = "0" ]; then
echo "${SERVICE} container fails to respond on public port ${PORT}" >&2
exit 3
fi
done
done
fi
[ -e /federated/services/${SERVICE}/check ] && . /federated/services/${SERVICE}/check
exit 0

View File

@ -201,8 +201,13 @@ create_password() {
echo "$SECRET";
}
get_externalip() {
EXTERNALIP=`dig @resolver4.opendns.com myip.opendns.com +short 2> /dev/null`
echo "$EXTERNALIP";
EXTERNALIP="$(dig @resolver4.opendns.com myip.opendns.com +short 2> /dev/null)"
if [ -n "$EXTERNALIP" ]; then
echo "$EXTERNALIP"
else
# Try to get a reasonable response even if opendns is down
ip route list default |sed -e 's,.*src ,,;s, .*,,'
fi
}
start_service_convert() {
SERVICE="$1"

View File

@ -5,22 +5,24 @@
PATH=$HOME/.docker/cli-plugins:/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
config_pdns() {
echo -ne "\n* Configuring /federated/apps/pdns container.."
echo -ne "\n* Configuring /federated/apps/pdns container.."
if [ ! -d "/federated/apps/pdns" ]; then
mkdir -p /federated/apps/pdns/data/root
fi
if [ ! -d "/federated/apps/pdns" ]; then
mkdir -p /federated/apps/pdns/data/root
fi
cat > /federated/apps/pdns/docker-compose.yml <<EOF
. /federated/services/pdns/service
cat > /federated/apps/pdns/docker-compose.yml <<EOF
services:
pdns:
image: pschiffe/pdns-mysql:\${IMAGE_VERSION}
image: ${CONTAINER}:\${IMAGE_VERSION}
container_name: pdns
hostname: pdns.$DOMAIN
restart: always
networks:
core:
ipv4_address: 192.168.0.11
ipv4_address: ${INTERNAL_IP}
ports:
- "53:53"
- "53:53/udp"
@ -34,12 +36,12 @@ networks:
external: true
EOF
EXTERNALIP=$(get_externalip);
MYSQL_PASSWORD=`grep MYSQL_PASSWORD /federated/apps/pdnsmysql/.env | awk -F= '{ print $2 }'`
PDNS_APIKEY=$(create_password);
PDNS_WEBSERVER_PASSWORD=$(create_password);
EXTERNALIP=$(get_externalip)
MYSQL_PASSWORD=`grep MYSQL_PASSWORD /federated/apps/pdnsmysql/.env | awk -F= '{ print $2 }'`
PDNS_APIKEY=$(create_password)
PDNS_WEBSERVER_PASSWORD=$(create_password)
cat > /federated/apps/pdns/.env <<EOF
cat > /federated/apps/pdns/.env <<EOF
IMAGE_VERSION="4.9"
PDNS_gmysql_host=pdnsmysql.$DOMAIN
PDNS_gmysql_port=3306
@ -64,9 +66,9 @@ PDNS_default_soa_content=ns1.@ hostmaster.@ 0 10800 3600 604800 3600
PDNS_allow_dnsupdate_from=127.0.0.0/8,::1,192.168.0.0/16
PDNS_dnsupdate=yes
EOF
chmod 600 /federated/apps/pdns/.env
chmod 600 /federated/apps/pdns/.env
cat > /federated/apps/pdns/data/root/createrecords.sh <<EOF
cat > /federated/apps/pdns/data/root/createrecords.sh <<EOF
#!/bin/bash -x
# Create the default domain DNS zone
@ -96,36 +98,36 @@ pdnsutil add-record $DOMAIN @ A 86400 $EXTERNALIP
pdnsutil import-tsig-key fedcomdns hmac-sha512 2BJrbNNmy5Hl+uFO1QcvQBpXx+Kbv9IdbyrHpwK7lYWDKmgTOmJu7eR0srfRNSVpTOnK6bQWOm4BxkrrQxd6Gw==
pdnsutil activate-tsig-key $DOMAIN fedcomdns primary
EOF
chmod +x /federated/apps/pdns/data/root/createrecords.sh
chmod +x /federated/apps/pdns/data/root/createrecords.sh
echo -ne "done."
echo -ne "done."
}
start_pdns() {
# Start service with command to make sure it's up before proceeding
start_service "pdns" "nc -z 192.168.0.11 8081 &> /dev/null" "7"
# Start service with command to make sure it's up before proceeding
start_service "pdns" "nc -z 192.168.0.11 8081 &> /dev/null" "7"
# Create DNS records for newdomain
# docker exec pdns pdnsutil create-zone $DOMAIN
# docker exec pdns pdnsutil set-kind $DOMAIN native
# docker exec pdns pdnsutil set-meta $DOMAIN SOA-EDIT-API DEFAULT
# Create DNS records for newdomain
# docker exec pdns pdnsutil create-zone $DOMAIN
# docker exec pdns pdnsutil set-kind $DOMAIN native
# docker exec pdns pdnsutil set-meta $DOMAIN SOA-EDIT-API DEFAULT
# for i in ns1 ns2 powerdns traefik mail www computer panel nextcloud collabora jitsi matrix element listmonk vaultwarden vpn wireguard baserow gitea blog documentation calcom plane; do
# docker exec pdns pdnsutil add-record $DOMAIN $i A 86400 $EXTERNALIP
# done
# for i in ns1 ns2 powerdns traefik mail www computer panel nextcloud collabora jitsi matrix element listmonk vaultwarden vpn wireguard baserow gitea blog documentation calcom plane; do
# docker exec pdns pdnsutil add-record $DOMAIN $i A 86400 $EXTERNALIP
# done
# docker exec pdns pdnsutil add-record $DOMAIN @ NS ns1.$DOMAIN_NEW
# docker exec pdns pdnsutil add-record $DOMAIN @ NS ns2.$DOMAIN_NEW
# docker exec pdns pdnsutil add-record $DOMAIN @ MX 86400 "10 mail.$DOMAIN"
# docker exec pdns pdnsutil add-record $DOMAIN @ TXT 86400 "\"v=spf1 mx a:$DOMAIN ~all\""
# docker exec pdns pdnsutil add-record $DOMAIN \* CNAME 86400 www.$DOMAIN
# docker exec pdns pdnsutil add-record $DOMAIN @ A 86400 $EXTERNALIP
# docker exec pdns pdnsutil add-record $DOMAIN @ NS ns1.$DOMAIN_NEW
# docker exec pdns pdnsutil add-record $DOMAIN @ NS ns2.$DOMAIN_NEW
# docker exec pdns pdnsutil add-record $DOMAIN @ MX 86400 "10 mail.$DOMAIN"
# docker exec pdns pdnsutil add-record $DOMAIN @ TXT 86400 "\"v=spf1 mx a:$DOMAIN ~all\""
# docker exec pdns pdnsutil add-record $DOMAIN \* CNAME 86400 www.$DOMAIN
# docker exec pdns pdnsutil add-record $DOMAIN @ A 86400 $EXTERNALIP
# Run createrecords.sh inside pdns container
docker exec pdns /root/createrecords.sh &> /dev/null
[ $? -ne 0 ] && fail "Couldn't run createrecords.sh in /federated/apps/pdns container"
# Run createrecords.sh inside pdns container
docker exec pdns /root/createrecords.sh &> /dev/null
[ $? -ne 0 ] && fail "Couldn't run createrecords.sh in /federated/apps/pdns container"
# Remove createrecords
rm /federated/apps/pdns/data/root/createrecords.sh
# Remove createrecords
rm /federated/apps/pdns/data/root/createrecords.sh
echo -ne "done."
echo -ne "done."
}

View File

@ -5,22 +5,24 @@
PATH=$HOME/.docker/cli-plugins:/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
config_pdnsmysql() {
echo -ne "* Configuring pdnsmysql container.."
echo -ne "* Configuring pdnsmysql container.."
if [ ! -d "/federated/apps/pdnsmysql" ]; then
mkdir -p /federated/apps/pdnsmysql/data/var/lib/mysql
fi
. /federated/services/pdnsmysql/service
cat > /federated/apps/pdnsmysql/docker-compose.yml <<EOF
if [ ! -d "/federated/apps/pdnsmysql" ]; then
mkdir -p /federated/apps/pdnsmysql/data/var/lib/mysql
fi
cat > /federated/apps/pdnsmysql/docker-compose.yml <<EOF
services:
mysql:
image: mariadb:\${IMAGE_VERSION}
image: ${CONTAINER}:${VERSION}
container_name: pdnsmysql
hostname: pdnsmysql.$DOMAIN
restart: always
networks:
core:
ipv4_address: 192.168.0.10
ipv4_address: ${INTERNAL_IP}
env_file:
- ./.env
volumes:
@ -31,23 +33,23 @@ networks:
external: true
EOF
MYSQL_ROOTPASSWORD=$(create_password);
MYSQL_PASSWORD=$(create_password);
MYSQL_ROOTPASSWORD=$(create_password)
MYSQL_PASSWORD=$(create_password)
cat > /federated/apps/pdnsmysql/.env <<EOF
IMAGE_VERSION="10.7.8"
cat > /federated/apps/pdnsmysql/.env <<EOF
IMAGE_VERSION="${VERSION}"
MYSQL_ROOT_PASSWORD=$MYSQL_ROOTPASSWORD
MYSQL_PASSWORD=$MYSQL_PASSWORD
MYSQL_DATABASE=pdns
MYSQL_USER=pdns
EOF
chmod 600 /federated/apps/pdnsmysql/.env
chmod 600 /federated/apps/pdnsmysql/.env
echo -ne "done.\n"
echo -ne "done.\n"
}
start_pdnsmysql() {
# Start service with command to make sure it's up before proceeding
start_service "pdnsmysql" "nc -z 192.168.0.10 3306 &> /dev/null" "8"
# Start service with command to make sure it's up before proceeding
start_service "pdnsmysql" "nc -z 192.168.0.10 3306 &> /dev/null" "8"
echo -ne "done.\n"
echo -ne "done.\n"
}

19
services/pdns/check Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
. /federated/lib/functions.sh
. /federated/services/pdns/service
. /federated/apps/pdns/.env
. /etc/federated
EXTERNAL_IP=$(get_externalip)
# Check it is up and running and produces reasonable output
if [ "$(dig @${EXTERNAL_IP} ${DOMAIN} +short)" != "${EXTERNAL_IP}" ]; then
echo "PDNS returns invalid result for ${DOMAIN}"
fi
if [ "$(dig @${EXTERNAL_IP} pdns.${DOMAIN} +short |tail -n1)" != "${EXTERNAL_IP}" ]; then
echo "PDNS returns invalid result for federated.computer"
fi
if [ "$(dig @${EXTERNAL_IP} federated.computer +short)" != "5.161.88.87" ]; then
echo "PDNS returns invalid result for federated.computer"
fi
exit 0

6
services/pdns/service Normal file
View File

@ -0,0 +1,6 @@
CONTAINER=pschiffe/pdns-mysql
VERSION=4.9
DEPENDS=pdnsmysql
INTERNAL_IP=192.168.0.11
PORTS=8081
PUBLICPORTS="53 53/udp"

14
services/pdnsmysql/check Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
. /federated/services/pdnsmysql/service
. /federated/apps/pdnsmysql/.env
# Check it is up and running and produces reasonable output
TRIES=5
while ! docker exec -ti pdnsmysql mysql -p${MYSQL_ROOT_PASSWORD} mysql -e 'SELECT User FROM user WHERE User="root";'; do
TRIES=$((TRIES-1))
if [ "$TRIES" = 0 ]; then
echo "pdnsmysql not responding to SQL queries" >&2
exit 2
fi
done
exit 0

View File

@ -0,0 +1,4 @@
CONTAINER=mariadb
VERSION=10.7.8
INTERNAL_IP=192.168.0.10
PORTS=3306