From 8153239ef7eae7e0fc2dea49f13e32d243905264 Mon Sep 17 00:00:00 2001
From: Thomas Woerner <twoerner@redhat.com>
Date: Fri, 19 Jul 2024 18:44:20 +0200
Subject: [PATCH] New image builder without molecule using podman

The new image builder is not using molecule and uses podman directly for
the generation of the ansible-test images.

Two additional services are installed to simplify the use of the
container in the test:

- fixnet.service uses /root/fixnet.sh to fix IP address of the server in
  /etc/hosts and to set localhost as the nameserver.
  This service is executed before IPA is started. This eliminates the
  need to restart the IPA server after the container has been started
  and the IPs have been fixed.
- fixipaip.service uses /root/fixipaip.sh to fix the IP address of the
  IPA dnsrecords of server and ipa-ca.

With these services it is now only needed to wait till all services in
the container are started. There is no need to restart the IPA server
anymore. Simply use something like this before starting the tests:

    while [ -n "$(podman exec ansible-test systemctl list-jobs | grep -vi 'no jobs running')" ]; do echo "waiting.."; sleep 5; done

New files
- infra/image/build.sh
- infra/image/dockerfile/c8s
- infra/image/dockerfile/c9s
- infra/image/dockerfile/c10s
- infra/image/dockerfile/fedora-latest
- infra/image/dockerfile/fedora-rawhide
- infra/image/inventory
- infra/image/system-service/fixipaip.service
- infra/image/system-service/fixipaip.sh
- infra/image/system-service/fixnet.service
- infra/image/system-service/fixnet.sh
---
 infra/image/build.sh                        | 66 +++++++++++++++++++++
 infra/image/dockerfile/c10s                 | 26 ++++++++
 infra/image/dockerfile/c8s                  | 32 ++++++++++
 infra/image/dockerfile/c9s                  | 26 ++++++++
 infra/image/dockerfile/fedora-latest        | 28 +++++++++
 infra/image/dockerfile/fedora-rawhide       | 29 +++++++++
 infra/image/inventory                       | 15 +++++
 infra/image/system-service/fixipaip.service | 10 ++++
 infra/image/system-service/fixipaip.sh      | 26 ++++++++
 infra/image/system-service/fixnet.service   | 12 ++++
 infra/image/system-service/fixnet.sh        | 24 ++++++++
 11 files changed, 294 insertions(+)
 create mode 100755 infra/image/build.sh
 create mode 100644 infra/image/dockerfile/c10s
 create mode 100644 infra/image/dockerfile/c8s
 create mode 100644 infra/image/dockerfile/c9s
 create mode 100644 infra/image/dockerfile/fedora-latest
 create mode 100644 infra/image/dockerfile/fedora-rawhide
 create mode 100644 infra/image/inventory
 create mode 100644 infra/image/system-service/fixipaip.service
 create mode 100755 infra/image/system-service/fixipaip.sh
 create mode 100644 infra/image/system-service/fixnet.service
 create mode 100755 infra/image/system-service/fixnet.sh

diff --git a/infra/image/build.sh b/infra/image/build.sh
new file mode 100755
index 0000000..1e31cbb
--- /dev/null
+++ b/infra/image/build.sh
@@ -0,0 +1,66 @@
+#!/bin/bash -eu
+
+BASEDIR="$(readlink -f "$(dirname "$0")")"
+TOPDIR="$(readlink -f "${BASEDIR}/../..")"
+
+scenario=${1:-}
+name="ansible-test"
+hostname="ipaserver.test.local"
+cpus="2"
+memory="4g"
+quayname="quay.io/ansible-freeipa/upstream-tests"
+
+if [ -z "${scenario}" ]; then
+    echo "ERROR: Image needs to be given"
+    exit 1
+fi
+if [ ! -f "${BASEDIR}/dockerfile/${scenario}" ]; then
+    echo "ERROR: ${scenario} is not a valid image"
+    exit 1
+fi
+
+echo "= Cleanup existing ${scenario} ="
+podman image rm "${scenario}" --force
+echo
+
+echo "= Building ${scenario} ="
+podman build -t "${scenario}" -f "${BASEDIR}/dockerfile/${scenario}" \
+       "${BASEDIR}"
+echo
+
+echo "= Creating ${name} ="
+podman create --privileged --name "${name}" --hostname "${hostname}" \
+       --network bridge:interface_name=eth0 --systemd true \
+       --cpus "${cpus}" --memory "${memory}" --memory-swap -1 --no-hosts \
+       --replace "${scenario}"
+echo
+
+echo "= Starting ${name} ="
+podman start "${name}"
+echo
+
+echo "= Installing IPA ="
+ansible-playbook -i "${BASEDIR}/inventory" \
+       "${TOPDIR}/playbooks/install-server.yml"
+echo
+
+echo "= Enabling additional services ="
+podman exec "${name}" systemctl enable fixnet
+podman exec "${name}" systemctl enable fixipaip
+echo
+
+echo "= Stopping ${name} ="
+podman stop "${name}"
+echo
+
+echo "= Committing \"${quayname}:${scenario}\" ="
+podman commit "${name}" "${quayname}:${scenario}"
+echo
+
+echo "= DONE ="
+
+# For tests:
+# podman start "${name}"
+# while [ -n "$(podman exec ansible-test systemctl list-jobs | grep -vi "no jobs running")" ]; do echo "waiting.."; sleep 5; done
+# # Run tests
+# podman stop "${name}"
diff --git a/infra/image/dockerfile/c10s b/infra/image/dockerfile/c10s
new file mode 100644
index 0000000..622098f
--- /dev/null
+++ b/infra/image/dockerfile/c10s
@@ -0,0 +1,26 @@
+FROM quay.io/centos/centos:stream10-development
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/dockerfile/c8s b/infra/image/dockerfile/c8s
new file mode 100644
index 0000000..87a5b82
--- /dev/null
+++ b/infra/image/dockerfile/c8s
@@ -0,0 +1,32 @@
+FROM quay.io/centos/centos:stream8
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo; \
+sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo; \
+sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/python3-config \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+dnf clean all; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
+
diff --git a/infra/image/dockerfile/c9s b/infra/image/dockerfile/c9s
new file mode 100644
index 0000000..5fe77d9
--- /dev/null
+++ b/infra/image/dockerfile/c9s
@@ -0,0 +1,26 @@
+FROM quay.io/centos/centos:stream9
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/dockerfile/fedora-latest b/infra/image/dockerfile/fedora-latest
new file mode 100644
index 0000000..aadcffb
--- /dev/null
+++ b/infra/image/dockerfile/fedora-latest
@@ -0,0 +1,28 @@
+FROM fedora:latest
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/python3-config \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+dnf clean all; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/dockerfile/fedora-rawhide b/infra/image/dockerfile/fedora-rawhide
new file mode 100644
index 0000000..5a1aa00
--- /dev/null
+++ b/infra/image/dockerfile/fedora-rawhide
@@ -0,0 +1,29 @@
+FROM fedora:rawhide
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/python3-config \
+    /usr/bin/dnf-3 \
+    python3-libdnf5 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+dnf clean all; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/inventory b/infra/image/inventory
new file mode 100644
index 0000000..7ee5e70
--- /dev/null
+++ b/infra/image/inventory
@@ -0,0 +1,15 @@
+[ipaserver]
+ansible-test ansible_connection=podman ansible_python_interpreter=/usr/bin/python3
+
+[ipaserver:vars]
+ipaadmin_password=SomeADMINpassword
+ipadm_password=SomeDMpassword
+ipaserver_domain=test.local
+ipaserver_realm=TEST.LOCAL
+ipaserver_setup_dns=true
+ipaserver_auto_forwarders=true
+ipaserver_no_dnssec_validation=true
+ipaserver_auto_reverse=true
+ipaserver_setup_kra=true
+ipaserver_setup_firewalld=false
+ipaclient_no_ntp=true
diff --git a/infra/image/system-service/fixipaip.service b/infra/image/system-service/fixipaip.service
new file mode 100644
index 0000000..6dde6ae
--- /dev/null
+++ b/infra/image/system-service/fixipaip.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Fix IPA server IP in IPA Server
+After=multi-user.target
+
+[Service]
+Type=oneshot
+ExecStart=/root/fixipaip.sh
+
+[Install]
+WantedBy=default.target
diff --git a/infra/image/system-service/fixipaip.sh b/infra/image/system-service/fixipaip.sh
new file mode 100755
index 0000000..dd638fa
--- /dev/null
+++ b/infra/image/system-service/fixipaip.sh
@@ -0,0 +1,26 @@
+#!/bin/bash -eu
+
+HOSTNAME=$(hostname)
+IP=$(hostname -I | cut -d " " -f 1)
+
+if [ -z "${HOSTNAME}" ]; then
+    echo "ERROR: Failed to retrieve hostname."
+    exit 1
+fi
+if [ -z "${IP}" ]; then
+    echo "ERROR: Failed to retrieve IP address."
+    exit 1
+fi
+
+if ! echo "SomeADMINpassword" | kinit -c ansible_freeipa_cache admin
+then
+    echo "ERROR: Failed to obtain Kerberos ticket"
+    exit 1
+fi
+KRB5CCNAME=ansible_freeipa_cache \
+    ipa dnsrecord-mod test.local "${HOSTNAME%%.*}" --a-rec="$IP"
+KRB5CCNAME=ansible_freeipa_cache \
+    ipa dnsrecord-mod test.local ipa-ca --a-rec="$IP"
+kdestroy -c ansible_freeipa_cache -A
+
+exit 0
diff --git a/infra/image/system-service/fixnet.service b/infra/image/system-service/fixnet.service
new file mode 100644
index 0000000..c481b19
--- /dev/null
+++ b/infra/image/system-service/fixnet.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Fix server IP in IPA Server
+Wants=network.target
+After=network.target
+Before=ipa.service
+
+[Service]
+Type=oneshot
+ExecStart=/root/fixnet.sh
+
+[Install]
+WantedBy=ipa.service
diff --git a/infra/image/system-service/fixnet.sh b/infra/image/system-service/fixnet.sh
new file mode 100755
index 0000000..3fc05b5
--- /dev/null
+++ b/infra/image/system-service/fixnet.sh
@@ -0,0 +1,24 @@
+#!/bin/bash -eu
+
+HOSTNAME=$(hostname)
+IP=$(hostname -I | cut -d " " -f 1)
+
+if [ -z "${HOSTNAME}" ]; then
+    echo "ERROR: Failed to retrieve hostname."
+    exit 1
+fi
+if [ -z "${IP}" ]; then
+    echo "ERROR: Failed to retrieve IP address."
+    exit 1
+fi
+
+# shellcheck disable=SC2143
+if [ -n "$(grep -P "[[:space:]]${HOSTNAME}" /etc/hosts)" ]; then
+    sed -ie "s/.*${HOSTNAME}/${IP}\t${HOSTNAME}/" /etc/hosts
+else
+    echo -e "$IP\t${HOSTNAME}" >> /etc/hosts
+fi
+
+echo "nameserver 127.0.0.1" > /etc/resolv.conf
+
+exit 0
-- 
GitLab