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/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} && \