From c979843b1a12ca9689bf2038c13bb93637b2f873 Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Fri, 25 Oct 2024 14:18:57 -0300
Subject: [PATCH] upstream CI: Allow podman options when creating containers

When using containers to test ansible-freeipa there's a need to deal
with 'podman' the development environment and the Azure environment. In
the Azure environment, with Ubuntu hosts, using 'cap-add' does not allow
FreeIPA to be installed on the containers, and they need to be executed
with privileged mode. On the other hand, on development environments,
such as recent Fedora hosts, there's no need to run the container with
extra privileges.

This patch modifies the utility function 'container_create' to allow the
usage of key-value argumes such as "cpus=4" and "privileged", that will
be used in the container creation.

The currently available options are "privileged", "cpus", "memory" and
"hostname". By default "cpus=2" and "hostname=ipaserver.test.local".

Also, too make the image build script more self-contained, if the
required Ansible collections are not installed, they will be temporarily
installed so that the image can be built.
---
 infra/image/build.sh    | 29 ++++++++++++++++++++++++-----
 infra/image/shcontainer | 27 +++++++++++++++++++--------
 infra/image/start.sh    | 16 ++++++++++++----
 3 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/infra/image/build.sh b/infra/image/build.sh
index 6da8179..3220ecc 100755
--- a/infra/image/build.sh
+++ b/infra/image/build.sh
@@ -15,7 +15,7 @@ valid_distro() {
 usage() {
     local prog="${0##*/}"
     cat << EOF
-usage: ${prog} [-h] [-s] distro
+usage: ${prog} [-h] [-p] [-c HOSTNAME] [-s] distro
     ${prog} build a container image to test ansible-freeipa.
 EOF
 }
@@ -29,8 +29,9 @@ positional arguments:
 
 optional arguments:
 
-    -s  Deploy IPA server
-
+    -c HOSTNAME   Container hostname
+    -p            Give extended privileges to the container
+    -s            Deploy IPA server
 EOF
 }
 
@@ -41,11 +42,14 @@ hostname="ipaserver.test.local"
 memory="3g"
 quayname="quay.io/ansible-freeipa/upstream-tests"
 deploy_server="N"
+privileged=""
 
-while getopts ":hs" option
+while getopts ":hc:ps" option
 do
     case "${option}" in
         h) help && exit 0 ;;
+        c) hostname="${OPTARG}" ;;
+        p) privileged="privileged" ;;
         s) deploy_server="Y" ;;
         *) die -u "Invalid option: ${option}" ;;
     esac
@@ -82,13 +86,28 @@ container_remove_image_if_exists "${tag}"
     container_remove_image_if_exists "${server_tag}"
 
 container_build "${tag}" "${BASEDIR}/dockerfile/${distro}" "${BASEDIR}"
-container_create "${name}" "${tag}" "${hostname}" "${memory}"
+container_create "${name}" "${tag}" \
+    "hostname=${hostname}" \
+    "memory=${memory}" \
+    "cpus=${cpus}" \
+    "${privileged}"
 container_commit "${name}" "${quayname}:${tag}"
 
 if [ "${deploy_server}" == "Y" ]
 then
     deployed=false
 
+    # Set path to ansible-freeipa roles
+    [ -z "${ANSIBLE_ROLES_PATH:-""}" ] && export ANSIBLE_ROLES_PATH="${TOPDIR}/roles"
+
+    # Install collection containers.podman if not available
+    if [ -z "$(ansible-galaxy collection list containers.podman)" ]
+    then
+        tmpdir="$(mktemp -d)"
+        export ANSIBLE_COLLECTIONS_PATH="${tmpdir}"
+        ansible-galaxy collection install -p "${tmpdir}" containers.podman
+    fi
+
     [ "${container_state}" != "running" ] && container_start "${name}"
 
     container_wait_for_journald "${name}"
diff --git a/infra/image/shcontainer b/infra/image/shcontainer
index 6f4e8a8..0bc3326 100644
--- a/infra/image/shcontainer
+++ b/infra/image/shcontainer
@@ -9,24 +9,35 @@ TOPDIR="$(readlink -f "${SCRIPTDIR}/../..")"
 container_create() {
     local name=${1}
     local image=${2}
-    local hostname=${3}
-    local memory=${4:-"3g"}
-    local cpus=${5:-"2"}
+    shift 2
+    declare -a extra_opts=()
+    for opt in "$@"
+    do
+        [ -z "${opt}" ] && continue
+        case "${opt}" in
+            hostname=*) extra_opts+=("--${opt}") ;;
+            cpus=*) extra_opts+=("--${opt}") ;;
+            memory=*) extra_opts+=("--${opt}") ;;
+            privileged) extra_opts+=("--${opt}") ;;
+            *) log error "container_create: Invalid option: ${opt}" ;;
+        esac
+    done
 
-    [ -n "${hostname}" ] || die "No hostname given"
+    # ensure default values are set
+    [[ " ${extra_opts[*]} " =~ " --cpus=" ]] || extra_opts+=("--cpus=2")
+    [[ " ${extra_opts[*]} " =~ " --hostname=" ]] \
+        || extra_opts+=("--hostname=ipaserver.test.local")
 
     log info "= Creating ${name} ="
     podman create \
            --security-opt label=disable \
-           --name "${name}" \
-           --hostname "${hostname}" \
            --network bridge:interface_name=eth0 \
            --systemd true \
-           --cpus "${cpus}" \
-           --memory "${memory}" \
+           --name "${name}" \
            --memory-swap -1 \
            --no-hosts \
            --replace \
+           "${extra_opts[@]}" \
            "${image}"
     echo
 }
diff --git a/infra/image/start.sh b/infra/image/start.sh
index c5a7a34..0f17189 100755
--- a/infra/image/start.sh
+++ b/infra/image/start.sh
@@ -11,7 +11,7 @@ TOPDIR="$(readlink -f "${BASEDIR}/../..")"
 usage() {
     local prog="${0##*/}"
     cat << EOF
-usage: ${prog} [-h] [-l] image
+usage: ${prog} [-h] [-l] [-n HOSTNAME ] image
     ${prog} start a prebuilt ansible-freeipa test container image.
 EOF
 }
@@ -24,7 +24,14 @@ positional arguments:
 
 optional arguments:
 
-    -l    Try to use local image first, if not found download.
+    -h            Show this message
+    -l            Try to use local image first, if not found download.
+    -n HOSTNAME   Set container hostname
+
+NOTE:
+    - The hostname must be the same as the hostname of the container
+      when FreeIPA was deployed. Use only if you built the image and
+      defined its hostname.
 
 EOF
 }
@@ -45,11 +52,12 @@ name="ansible-freeipa-tests"
 hostname="ipaserver.test.local"
 try_local_first="N"
 
-while getopts ":hl" option
+while getopts ":hln:" option
 do
     case "${option}" in
         h) help && exit 0 ;;
         l) try_local_first="Y" ;;
+        n) hostname="${OPTARG}" ;;
         *) die -u "Invalid option: ${option}" ;;
     esac
 done
@@ -79,7 +87,7 @@ fi
 
 [ -z "${local_image}" ] && die "Image '${image}' is not valid"
 
-container_create "${name}" "${local_image}" "${hostname}"
+container_create "${name}" "${local_image}" "hostname=${hostname}"
 container_start "${name}"
 container_wait_for_journald "${name}"
 container_wait_up "${name}"
-- 
GitLab