packaging: add debian build and args for script

Added debian 10, 11, 12 and Ubuntu 20.04 Dockerfiles.
Added arguments selector in build_packages.sh to choose what to build.
Make build parallels and wait for all to finish at end.

Change-Id: I307fcac3e9b02eb821841309779f9268549aaeb0
diff --git a/README.md b/README.md
index 70c9f0c..da379a2 100644
--- a/README.md
+++ b/README.md
@@ -97,6 +97,16 @@
 - **[Argon2](https://github.com/P-H-C/phc-winner-argon2)**, a dependency for key stretching.
 - **Readline**, an optional dependency for the DHT tools.
 
+## Packaging and release
+
+In `extras/packaging`, you will find a `build_packages.sh` script which will build packages for supported plateform. You must provide as argument the OS for which you want to build. You can't specify the plateform (arm64, x86, ...) as you can compile only for the same plateform as the one you are running on.
+
+**Usage:**
+```bash
+extras/packaging/build_packages.sh -a  # -a or --all will build all plateform which are known to be supported
+extras/packaging/build_packages.sh -u  # -u or --ubuntu will build for all supported versions of Ubuntu
+extras/packaging/build_packages.sh -u22 -d11  # -u22 will build for ubuntu 22.04 and -d11 will build for Debian 11
+```
 
 ## See also
 
diff --git a/build_tar_gz.sh b/build_tar_gz.sh
deleted file mode 100755
index dacbc04..0000000
--- a/build_tar_gz.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-PKG_NAME=dhtnet
-PKG_VERSION=0.2.0
-
-FOLDER_NAME="${PKG_NAME}-${PKG_VERSION}"
-
-rm -Rf "${FOLDER_NAME}"
-rm -f "${PKG_NAME}-${PKG_VERSION}.tar.gz"
-mkdir -p "${FOLDER_NAME}"
-
-git submodule update --init --recursive
-
-# copy source code
-cp -Rf dependencies "${FOLDER_NAME}/dependencies"
-cp -Rf include "${FOLDER_NAME}/include"
-cp -Rf src "${FOLDER_NAME}/src"
-cp -Rf tools "${FOLDER_NAME}/tools"
-cp -Rf CMakeLists.txt "${FOLDER_NAME}/CMakeLists.txt"
-cp -Rf COPYING "${FOLDER_NAME}/COPYING"
-cp -Rf dhtnet.pc.in "${FOLDER_NAME}/dhtnet.pc.in"
-cp -Rf README.md "${FOLDER_NAME}/README.md"
-
-# copy debian conf
-cp -Rf "extras/packaging/gnu-linux/debian" "${FOLDER_NAME}/debian"
-
-tar -czf "${PKG_NAME}-${PKG_VERSION}.tar.gz" "${FOLDER_NAME}"
-
-echo "Archive ${PKG_NAME}-${PKG_VERSION}.tar.gz is ready"
-echo "Use   tar -xzf ${PKG_NAME}-${PKG_VERSION}.tar.gz   to unzip this file and package it with debuild"
diff --git a/extras/packaging/.gitignore b/extras/packaging/.gitignore
index 84a45e1..043509b 100644
--- a/extras/packaging/.gitignore
+++ b/extras/packaging/.gitignore
@@ -3,4 +3,7 @@
 
 ubuntu-*/*.deb
 ubuntu-*/build-at-*
-dhtnet-*.tar.gz
+**/build.log
+debian-*/*.deb
+debian-*/build-at-*
+*dhtnet-*.tar.gz
diff --git a/extras/packaging/build_packages.sh b/extras/packaging/build_packages.sh
index 8fdbeb0..9b44393 100755
--- a/extras/packaging/build_packages.sh
+++ b/extras/packaging/build_packages.sh
@@ -2,7 +2,7 @@
 set -e
 
 PKG_NAME=dhtnet
-PKG_VERSION=0.2.0
+PKG_VERSION=0.3.0
 
 FOLDER_NAME="${PKG_NAME}-${PKG_VERSION}"
 
@@ -10,7 +10,7 @@
 cd "$(dirname "$0")" || exit 1
 
 rm -Rf "${FOLDER_NAME}"
-rm -f "${PKG_NAME}-${PKG_VERSION}.tar.gz"
+rm -f -- *${PKG_NAME}-${PKG_VERSION}.tar.gz
 mkdir -p "${FOLDER_NAME}"
 
 rm -Rf "../../dependencies/msgpack"
@@ -19,6 +19,65 @@
 rm -Rf "../../dependencies/restinio"
 (cd ../.. && git submodule update --init --recursive)
 
+build_ubuntu=false
+build_ubuntu20=false
+build_ubuntu22=false
+build_ubuntu24=false
+build_debian=false
+build_debian10=false
+build_debian11=false
+build_debian12=false
+
+parse_args() {
+    while [ "$1" != "" ]; do
+        case $1 in
+            -u | --ubuntu )         build_ubuntu=true
+                                    build_ubuntu20=true
+                                    build_ubuntu22=true
+                                    build_ubuntu24=true
+                                    ;;
+            -u20 | --ubuntu20 )     build_ubuntu20=true
+                                    build_ubuntu=true
+                                    ;;
+            -u22 | --ubuntu22 )     build_ubuntu22=true
+                                    build_ubuntu=true
+                                    ;;
+            -u24 | --ubuntu24 )     build_ubuntu24=true
+                                    build_ubuntu=true
+                                    ;;
+            -d | --debian )         build_debian=true
+                                    build_debian10=true
+                                    build_debian11=true
+                                    build_debian12=true
+                                    ;;
+            -d10 | --debian10 )     build_debian10=true
+                                    build_debian=true
+                                    ;;
+            -d11 | --debian11 )     build_debian11=true
+                                    build_debian=true
+                                    ;;
+            -d12 | --debian12 )     build_debian12=true
+                                    build_debian=true
+                                    ;;
+            -a | --all )            build_ubuntu=true
+                                    # not working: build_ubuntu20=true
+                                    build_ubuntu22=true
+                                    build_ubuntu24=true
+                                    build_debian=true
+                                    # not working: build_debian10=true
+                                    # not working: build_debian11=true
+                                    build_debian12=true
+                                    ;;
+            * )                     echo "Argument '$1' is not recognized"
+                                    ;;
+        esac
+        shift
+    done
+}
+
+parse_args "$@"
+
+
 # copy source code
 cp -Rf ../../dependencies "${FOLDER_NAME}/dependencies"
 cp -Rf ../../include "${FOLDER_NAME}/include"
@@ -29,24 +88,90 @@
 cp -Rf ../../dhtnet.pc.in "${FOLDER_NAME}/dhtnet.pc.in"
 cp -Rf ../../README.md "${FOLDER_NAME}/README.md"
 
-# copy debian conf
-cp -Rf "./gnu-linux/debian" "${FOLDER_NAME}/debian"
+if [ "$build_ubuntu" == true ] || [ "$build_debian" == true ]; then
+    # copy debian conf
+    cp -Rf "./gnu-linux/debian" "${FOLDER_NAME}/debian"
 
-tar -czf "${PKG_NAME}-${PKG_VERSION}.tar.gz" "${FOLDER_NAME}"
+    tar -czf "deb-${PKG_NAME}-${PKG_VERSION}.tar.gz" "${FOLDER_NAME}"
+    rm -Rf "${FOLDER_NAME}/debian"
+fi
+
 rm -Rf "${FOLDER_NAME}"
-
-echo "Archive ${PKG_NAME}-${PKG_VERSION}.tar.gz is ready, starting builds... (will take few minutes)"
+echo "Archives <os>-${PKG_NAME}-${PKG_VERSION}.tar.gz are ready, starting builds... (will take few minutes)"
 
 #######################
 
-# build deb package
+started_builds=()
+started_pid=()
+remainning_builds=0
 
-docker build -t dhtnet-builder:ubuntu24 -f gnu-linux/ubuntu-24.Dockerfile --build-arg PKG_NAME="$FOLDER_NAME" .
-docker run --rm -v "$(pwd)/ubuntu-24/":/build/debs -e PKG_NAME="$FOLDER_NAME" dhtnet-builder:ubuntu24
-rm -f ubuntu-24/build-at-*
-echo "Ubuntu 24.04 package built at $(date)" > "ubuntu-24/build-at-$(date +%F-%R)"
+build_target() {
+    target="$1"
+    mkdir -p "$target"
+    docker build -t "dhtnet-builder:$target" -f "gnu-linux/$target.Dockerfile" --build-arg PKG_NAME="$FOLDER_NAME" .
+    remainning_builds=$((remainning_builds+1))
+    (
+        docker run --rm \
+            -v "$(pwd)/$target/":/build/debs \
+            -e PKG_NAME="$FOLDER_NAME" "dhtnet-builder:$target" > "$target/build.log" 2>&1;
+        if [ $? -eq 0 ]; then
+            rm -f -- $target/build-at-*
+            echo "$target package built at $(date)" > "$target/build-at-$(date +%F-%R)"
+            echo "Successfully built $target package"
+        else
+            echo "Failed to build $target package, check log for more details"
+        fi
+    ) &
+    started_pid+=("$!")
+    started_builds+=("$target")
+}
 
-docker build -t dhtnet-builder:ubuntu22 -f gnu-linux/ubuntu-22.Dockerfile --build-arg PKG_NAME="$FOLDER_NAME" .
-docker run --rm -v "$(pwd)/ubuntu-22/":/build/debs -e PKG_NAME="$FOLDER_NAME" dhtnet-builder:ubuntu22
-rm -f ubuntu-22/build-at-*
-echo "Ubuntu 22.04 package built at $(date)" > "ubuntu-22/build-at-$(date +%F-%R)"
+# build Ubuntu package (deb-*)
+if [ "$build_ubuntu24" == true ]; then
+    build_target "ubuntu-24"
+fi
+
+if [ "$build_ubuntu22" == true ]; then
+    build_target "ubuntu-22"
+fi
+
+if [ "$build_ubuntu20" == true ]; then
+    build_target "ubuntu-20"
+fi
+
+# build Debian package (deb-*)
+if [ "$build_debian12" == true ]; then
+    build_target "debian-12"
+fi
+
+if [ "$build_debian11" == true ]; then
+    build_target "debian-11"
+fi
+
+if [ "$build_debian10" == true ]; then
+    build_target "debian-10"
+fi
+
+
+while [ $remainning_builds -gt 0 ]; do
+    time="$(date +%T)"
+    for index in "${!started_builds[@]}"; do
+        if [ "${started_pid[$index]}" != "" ]; then
+            if ps -p "${started_pid[$index]}" > /dev/null; then
+                echo "[$time] Still building ${started_builds[$index]}... (pid: ${started_pid[$index]})"
+            else
+                echo "[$time] Build ${started_builds[$index]} finished"
+                remainning_builds=$((remainning_builds-1))
+                started_pid[index]=""
+            fi
+        fi
+    done
+    if [ $remainning_builds -gt 0 ]; then
+        sleep 30
+    fi
+done
+
+echo "[$(date +%T)] All builds finished:"
+for target in "${started_builds[@]}"; do
+    echo "  - $target"
+done
diff --git a/extras/packaging/gnu-linux/debian-10.Dockerfile b/extras/packaging/gnu-linux/debian-10.Dockerfile
new file mode 100644
index 0000000..8cd1d16
--- /dev/null
+++ b/extras/packaging/gnu-linux/debian-10.Dockerfile
@@ -0,0 +1,34 @@
+FROM debian:10
+
+WORKDIR /build
+
+ENV EMAIL="contact@savoirfairelinux.com"
+ENV DEBFULLNAME="Savoir-faire Linux"
+
+RUN apt-get update && \
+    echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+    apt-get install -y \
+        dialog apt-utils make devscripts build-essential debmake lintian \
+    && apt-get clean && \
+    mkdir -p /build/debs
+
+RUN apt-get update && apt-get install -y \
+        build-essential pkg-config cmake dpkg-dev gcc g++ git wget \
+        libtool autotools-dev autoconf automake sbuild autopkgtest debhelper debhelper-compat \
+        cython3 python3-dev python3-setuptools python3-build python3-virtualenv \
+        libncurses5-dev libreadline-dev nettle-dev libcppunit-dev \
+        libgnutls28-dev libuv1-dev libjsoncpp-dev libargon2-dev libunistring-dev \
+        libssl-dev libfmt-dev libasio-dev libmsgpack-dev libyaml-cpp-dev \
+        systemd \
+    && apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
+
+ARG PKG_NAME
+COPY deb-${PKG_NAME}.tar.gz /build/${PKG_NAME}.tar.gz
+
+CMD tar -xzf ${PKG_NAME}.tar.gz && \
+    cd ${PKG_NAME} && \
+    debmake -b "dhtnet:bin" -y && \
+    debuild && \
+    cd .. && \
+    rm -Rf ${PKG_NAME} ${PKG_NAME}.tar.gz && \
+    cp /build/*.deb /build/debs/
diff --git a/extras/packaging/gnu-linux/debian-11.Dockerfile b/extras/packaging/gnu-linux/debian-11.Dockerfile
new file mode 100644
index 0000000..e803016
--- /dev/null
+++ b/extras/packaging/gnu-linux/debian-11.Dockerfile
@@ -0,0 +1,34 @@
+FROM debian:11
+
+WORKDIR /build
+
+ENV EMAIL="contact@savoirfairelinux.com"
+ENV DEBFULLNAME="Savoir-faire Linux"
+
+RUN apt-get update && \
+    echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+    apt-get install -y \
+        dialog apt-utils make devscripts build-essential debmake lintian \
+    && apt-get clean && \
+    mkdir -p /build/debs
+
+RUN apt-get update && apt-get install -y \
+        build-essential pkg-config cmake dpkg-dev gcc g++ git wget \
+        libtool autotools-dev autoconf automake sbuild autopkgtest debhelper debhelper-compat \
+        cython3 python3-dev python3-setuptools python3-build python3-virtualenv \
+        libncurses5-dev libreadline-dev nettle-dev libcppunit-dev \
+        libgnutls28-dev libuv1-dev libjsoncpp-dev libargon2-dev libunistring-dev \
+        libssl-dev libfmt-dev libasio-dev libmsgpack-dev libyaml-cpp-dev \
+        systemd \
+    && apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
+
+ARG PKG_NAME
+COPY deb-${PKG_NAME}.tar.gz /build/${PKG_NAME}.tar.gz
+
+CMD tar -xzf ${PKG_NAME}.tar.gz && \
+    cd ${PKG_NAME} && \
+    debmake -b "dhtnet:bin" -y && \
+    debuild && \
+    cd .. && \
+    rm -Rf ${PKG_NAME} ${PKG_NAME}.tar.gz && \
+    cp /build/*.deb /build/debs/
diff --git a/extras/packaging/gnu-linux/debian-12.Dockerfile b/extras/packaging/gnu-linux/debian-12.Dockerfile
new file mode 100644
index 0000000..8c74655
--- /dev/null
+++ b/extras/packaging/gnu-linux/debian-12.Dockerfile
@@ -0,0 +1,34 @@
+FROM debian:12
+
+WORKDIR /build
+
+ENV EMAIL="contact@savoirfairelinux.com"
+ENV DEBFULLNAME="Savoir-faire Linux"
+
+RUN apt-get update && \
+    echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+    apt-get install -y \
+        dialog apt-utils make devscripts build-essential debmake lintian \
+    && apt-get clean && \
+    mkdir -p /build/debs
+
+RUN apt-get update && apt-get install -y \
+        build-essential pkg-config cmake dpkg-dev gcc g++ git wget \
+        libtool autotools-dev autoconf automake sbuild autopkgtest debhelper debhelper-compat \
+        cython3 python3-dev python3-setuptools python3-build python3-virtualenv \
+        libncurses5-dev libreadline-dev nettle-dev libcppunit-dev \
+        libgnutls28-dev libuv1-dev libjsoncpp-dev libargon2-dev libunistring-dev \
+        libssl-dev libfmt-dev libasio-dev libmsgpack-dev libyaml-cpp-dev \
+        systemd \
+    && apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
+
+ARG PKG_NAME
+COPY deb-${PKG_NAME}.tar.gz /build/${PKG_NAME}.tar.gz
+
+CMD tar -xzf ${PKG_NAME}.tar.gz && \
+    cd ${PKG_NAME} && \
+    debmake -b "dhtnet:bin" -y && \
+    debuild && \
+    cd .. && \
+    rm -Rf ${PKG_NAME} ${PKG_NAME}.tar.gz && \
+    cp /build/*.deb /build/debs/
diff --git a/extras/packaging/gnu-linux/debian/changelog b/extras/packaging/gnu-linux/debian/changelog
index 8d0dee0..e9cf0c5 100644
--- a/extras/packaging/gnu-linux/debian/changelog
+++ b/extras/packaging/gnu-linux/debian/changelog
@@ -1,5 +1,14 @@
-dhtnet (0.2.0-1) UNRELEASED; urgency=low
+dhtnet (0.3.0-1) UNRELEASED; urgency=low
+
+  * Include UPnP support
+
+ -- Louis Maillard <louis.maillard@savoirfairelinux.com>  Mon, 29 Jul 2024 09:30:00 -0400
+
+dhtnet (0.2.0) unstable; urgency=low
 
   * Initial release.
+  * Add binaries dnc, dhtnet-crmgr, dsh, dvpn
+  * Include documentation as man pages
+  * Dynamic library available as libdhtnet.so
 
  -- Louis Maillard <louis.maillard@savoirfairelinux.com>  Wed, 17 Jul 2024 09:27:39 -0400
diff --git a/extras/packaging/gnu-linux/ubuntu-20.Dockerfile b/extras/packaging/gnu-linux/ubuntu-20.Dockerfile
new file mode 100644
index 0000000..4ef2496
--- /dev/null
+++ b/extras/packaging/gnu-linux/ubuntu-20.Dockerfile
@@ -0,0 +1,37 @@
+FROM ubuntu:20.04
+
+WORKDIR /build
+
+ENV EMAIL="contact@savoirfairelinux.com"
+ENV DEBFULLNAME="Savoir-faire Linux"
+
+RUN apt-get update && \
+    echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+    apt-get install -y \
+        dialog apt-utils make devscripts build-essential debmake lintian \
+    && apt-get clean && \
+    mkdir -p /build/debs
+
+RUN apt-get update && apt-get install -y \
+        build-essential pkg-config cmake dpkg-dev gcc g++ git wget \
+        libtool autotools-dev autoconf automake sbuild autopkgtest debhelper debhelper-compat \
+        cython3 python3-dev python3-setuptools python3-virtualenv \
+        # replacement for python3-build:
+        python3 python3-pip python-is-python3 python3-distutils python3-distutils-extra \
+        libncurses5-dev libreadline-dev nettle-dev libcppunit-dev \
+        libgnutls28-dev libuv1-dev libjsoncpp-dev libargon2-dev libunistring-dev \
+        libssl-dev libfmt-dev libasio-dev libmsgpack-dev libyaml-cpp-dev \
+        systemd \
+    && apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/* && \
+    pip install build
+
+ARG PKG_NAME
+COPY deb-${PKG_NAME}.tar.gz /build/${PKG_NAME}.tar.gz
+
+CMD tar -xzf ${PKG_NAME}.tar.gz && \
+    cd ${PKG_NAME} && \
+    debmake -b "dhtnet:bin" -y && \
+    debuild && \
+    cd .. && \
+    rm -Rf ${PKG_NAME} ${PKG_NAME}.tar.gz && \
+    cp /build/*.deb /build/debs/
diff --git a/extras/packaging/gnu-linux/ubuntu-22.Dockerfile b/extras/packaging/gnu-linux/ubuntu-22.Dockerfile
index 4bbbaf3..8552aac 100644
--- a/extras/packaging/gnu-linux/ubuntu-22.Dockerfile
+++ b/extras/packaging/gnu-linux/ubuntu-22.Dockerfile
@@ -1,7 +1,6 @@
 FROM ubuntu:22.04
 
 WORKDIR /build
-ARG PKG_NAME
 
 ENV EMAIL="contact@savoirfairelinux.com"
 ENV DEBFULLNAME="Savoir-faire Linux"
@@ -23,7 +22,8 @@
         systemd \
     && apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
 
-COPY ${PKG_NAME}.tar.gz /build/
+ARG PKG_NAME
+COPY deb-${PKG_NAME}.tar.gz /build/${PKG_NAME}.tar.gz
 
 CMD tar -xzf ${PKG_NAME}.tar.gz && \
     cd ${PKG_NAME} && \
diff --git a/extras/packaging/gnu-linux/ubuntu-24.Dockerfile b/extras/packaging/gnu-linux/ubuntu-24.Dockerfile
index b79a327..e876b43 100644
--- a/extras/packaging/gnu-linux/ubuntu-24.Dockerfile
+++ b/extras/packaging/gnu-linux/ubuntu-24.Dockerfile
@@ -1,7 +1,6 @@
 FROM ubuntu:24.04
 
 WORKDIR /build
-ARG PKG_NAME
 
 ENV EMAIL="contact@savoirfairelinux.com"
 ENV DEBFULLNAME="Savoir-faire Linux"
@@ -23,7 +22,8 @@
         systemd \
     && apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
 
-COPY ${PKG_NAME}.tar.gz /build/
+ARG PKG_NAME
+COPY deb-${PKG_NAME}.tar.gz /build/${PKG_NAME}.tar.gz
 
 CMD tar -xzf ${PKG_NAME}.tar.gz && \
     cd ${PKG_NAME} && \