From b0c9ccd16f4a852c32cc650504276ec0efa42cf5 Mon Sep 17 00:00:00 2001 From: Luca Miccini Date: Fri, 7 Aug 2026 10:23:10 +0200 Subject: [PATCH] Add infra container images for memcached, redis, rabbitmq and mariadb Port container definitions from tcib for infrastructure services that don't require Python source builds. These are RPM-only containers built on top of openstack-base. - memcached: simple memcached service - redis: uses valkey (Redis-compatible fork) with procps-ng - rabbitmq: installs from CentOS Messaging SIG repo directly (the centos-release-rabbitmq-4 package requires centos-release which is unavailable on UBI), includes kolla extend_start bootstrap script - mariadb: full Galera cluster support with mariadb-server-galera, includes kolla extend_start and security_reset.expect scripts Also updates build.sh to handle infrastructure containers (projects without sources.txt) by skipping source cloning and constraints. Co-Authored-By: Claude Opus 4.6 --- build.sh | 16 +++++ containers/base/rpms.repo | 6 ++ containers/mariadb/mariadb/Containerfile | 24 +++++++ containers/mariadb/mariadb/bindeps.txt | 12 ++++ .../mariadb/mariadb/scripts/extend_start.sh | 35 ++++++++++ .../mariadb/scripts/security_reset.expect | 67 +++++++++++++++++++ containers/memcached/memcached/Containerfile | 14 ++++ containers/memcached/memcached/bindeps.txt | 1 + containers/rabbitmq/rabbitmq/Containerfile | 18 +++++ containers/rabbitmq/rabbitmq/bindeps.txt | 2 + .../rabbitmq/rabbitmq/scripts/extend_start.sh | 16 +++++ containers/redis/redis/Containerfile | 14 ++++ containers/redis/redis/bindeps.txt | 2 + 13 files changed, 227 insertions(+) create mode 100644 containers/mariadb/mariadb/Containerfile create mode 100644 containers/mariadb/mariadb/bindeps.txt create mode 100644 containers/mariadb/mariadb/scripts/extend_start.sh create mode 100644 containers/mariadb/mariadb/scripts/security_reset.expect create mode 100644 containers/memcached/memcached/Containerfile create mode 100644 containers/memcached/memcached/bindeps.txt create mode 100644 containers/rabbitmq/rabbitmq/Containerfile create mode 100644 containers/rabbitmq/rabbitmq/bindeps.txt create mode 100644 containers/rabbitmq/rabbitmq/scripts/extend_start.sh create mode 100644 containers/redis/redis/Containerfile create mode 100644 containers/redis/redis/bindeps.txt diff --git a/build.sh b/build.sh index 8df932b..1153329 100755 --- a/build.sh +++ b/build.sh @@ -303,6 +303,17 @@ build_image() { return fi + # Infrastructure containers: no sources.txt means RPM-only (no Python source builds) + local project_sources="${CONTAINERS_DIR}/${project}/sources.txt" + if [[ ! -f "${project_sources}" ]]; then + buildah bud \ + $(image_tag_args "${dir_name}") \ + --build-arg "BASE_IMAGE=${BASE_IMAGE}" \ + -f "${CONTAINERS_DIR}/${dir_name}/Containerfile" \ + "${CONTAINERS_DIR}/${dir_name}/" + return + fi + # Ensure stream is set for service images if [[ -z "${STREAM}" ]]; then echo "ERROR: STREAM is required for building service images." >&2 @@ -887,6 +898,11 @@ ensure_sources_for_targets() { continue fi + # Skip rpm-only projects (no sources.txt) + if [[ ! -f "${CONTAINERS_DIR}/${project}/sources.txt" ]]; then + continue + fi + ensure_sources_for_stream "${img}" "${stream}" if [[ -z "${_ensure_projects_seen[$project]:-}" ]]; then diff --git a/containers/base/rpms.repo b/containers/base/rpms.repo index 70213d9..accc884 100644 --- a/containers/base/rpms.repo +++ b/containers/base/rpms.repo @@ -63,3 +63,9 @@ baseurl=http://mirror.stream.centos.org/10-stream/AppStream/$basearch/os/ enabled=1 gpgcheck=0 excludepkgs=openssl* + +[centos10-messaging-sig-rabbitmq4] +name=CentOS Stream 10 - Messaging SIG - RabbitMQ 4 +baseurl=http://mirror.stream.centos.org/SIGs/10-stream/messaging/$basearch/rabbitmq-4/ +enabled=1 +gpgcheck=0 diff --git a/containers/mariadb/mariadb/Containerfile b/containers/mariadb/mariadb/Containerfile new file mode 100644 index 0000000..f569792 --- /dev/null +++ b/containers/mariadb/mariadb/Containerfile @@ -0,0 +1,24 @@ +ARG BASE_IMAGE=localhost/openstack/openstack-base:latest +FROM ${BASE_IMAGE} + +LABEL summary="OpenStack MariaDB" \ + io.k8s.description="MariaDB database service with Galera clustering for OpenStack" + +RUN uid_gid_manage mysql + +# UBI AppStream disabled to avoid mariadb version conflicts with CentOS packages +COPY bindeps.txt /tmp/bindeps.txt +RUN pkgs=$(cat /tmp/bindeps.txt | grep -v '^#' | grep -v '^$' | tr '\n' ' ') && \ + if [ -n "${pkgs}" ]; then microdnf -y --disablerepo=ubi-10-appstream-rpms install ${pkgs} && microdnf clean all && rm -rf /var/cache/dnf; fi && \ + rm /tmp/bindeps.txt + +COPY scripts/extend_start.sh /usr/local/bin/kolla_extend_start +COPY scripts/security_reset.expect /usr/local/bin/kolla_security_reset +RUN chmod 755 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_security_reset + +RUN rm -rf /var/lib/mysql/* /etc/my.cnf.d/mariadb-server.cnf /etc/my.cnf.d/auth_gssapi.cnf + +USER mysql + +ENTRYPOINT ["dumb-init", "--"] +CMD ["kolla_start"] diff --git a/containers/mariadb/mariadb/bindeps.txt b/containers/mariadb/mariadb/bindeps.txt new file mode 100644 index 0000000..5a33bfa --- /dev/null +++ b/containers/mariadb/mariadb/bindeps.txt @@ -0,0 +1,12 @@ +expect +galera +hostname +jq +mariadb +mariadb-backup +mariadb-server-galera +mariadb-server-utils +rsync +socat +stunnel +tar diff --git a/containers/mariadb/mariadb/scripts/extend_start.sh b/containers/mariadb/mariadb/scripts/extend_start.sh new file mode 100644 index 0000000..24356ee --- /dev/null +++ b/containers/mariadb/mariadb/scripts/extend_start.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +function bootstrap_db { + mysqld_safe --wsrep-new-cluster --skip-networking --wsrep-on=OFF --pid-file=/var/lib/mysql/mariadb.pid & + # Wait for the mariadb server to be "Ready" before starting the security reset with a max timeout + # NOTE(huikang): the location of mysql's socket file varies depending on the OS distributions. + # Querying the cluster status has to be executed after the existence of mysql.sock and mariadb.pid. + TIMEOUT=${DB_MAX_TIMEOUT:-60} + while [[ ! -S /var/lib/mysql/mysql.sock ]] && \ + [[ ! -S /var/run/mysqld/mysqld.sock ]] || \ + [[ ! -f /var/lib/mysql/mariadb.pid ]]; do + if [[ ${TIMEOUT} -gt 0 ]]; then + let TIMEOUT-=1 + sleep 1 + else + exit 1 + fi + done + + sudo -E kolla_security_reset + mysql -u root --password="${DB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '${DB_ROOT_PASSWORD}' WITH GRANT OPTION;" + mysql -u root --password="${DB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${DB_ROOT_PASSWORD}' WITH GRANT OPTION;" + mysqladmin -uroot -p"${DB_ROOT_PASSWORD}" shutdown +} + +# This catches all cases of the BOOTSTRAP variable being set, including empty +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + mysql_install_db + bootstrap_db + exit 0 +fi + +if [[ "${!BOOTSTRAP_ARGS[@]}" ]]; then + ARGS="${BOOTSTRAP_ARGS}" +fi diff --git a/containers/mariadb/mariadb/scripts/security_reset.expect b/containers/mariadb/mariadb/scripts/security_reset.expect new file mode 100644 index 0000000..ec40eaf --- /dev/null +++ b/containers/mariadb/mariadb/scripts/security_reset.expect @@ -0,0 +1,67 @@ +#!/usr/bin/expect -f + +if [catch {set timeout $env(DB_MAX_TIMEOUT)}] {set timeout 10} +spawn mysql_secure_installation +expect { + timeout { send_user "\nFailed to get 'Enter current password for root (enter for none):' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Enter current password for root (enter for none):' prompt\n"; exit 1 } + "Enter current password for root (enter for none):" +} +send "\r" + +expect { + timeout { send_user "\nFailed to get 'Switch to unix_socket authentication [Y/n] ' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Switch to unix_socket authentication' prompt\n"; exit 1 } + "Switch to unix_socket authentication \\\[Y/n\\\] " +} +send "n\r" + +expect { + timeout { send_user "\nFailed to get 'Change the root password? [Y/n]' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Change the root password?' prompt\n"; exit 1 } + "Change the root password? \\\[Y/n\\\] " +} +send "y\r" + +expect { + timeout { send_user "\nFailed to get 'New password:' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'New password:' prompt\n"; exit 1 } + "New password:" +} +send "$env(DB_ROOT_PASSWORD)\r" + +expect { + timeout { send_user "\nFailed to get 'Re-enter new password:' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Re-enter new password:' prompt\n"; exit 1 } + "Re-enter new password:" +} +send "$env(DB_ROOT_PASSWORD)\r" + +expect { + timeout { send_user "\nFailed to get 'Remove anonymous users?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Remove anonymous users?' prompt\n"; exit 1 } + "Remove anonymous users?" +} +send "y\r" + +expect { + timeout { send_user "\nFailed to get 'Disallow root login remotely?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Disallow root login remotely?' prompt\n"; exit 1 } + "Disallow root login remotely?" +} +send "n\r" + +expect { + timeout { send_user "\nFailed to get 'Remove test database and access to it?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Remove test database and access to it?' prompt\n"; exit 1 } + "Remove test database and access to it?" +} +send "y\r" + +expect { + timeout { send_user "\nFailed to get 'Reload privilege tables now?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Reload privilege tables now?' prompt\n"; exit 1 } + "Reload privilege tables now?" +} +send "y\r" +expect eof diff --git a/containers/memcached/memcached/Containerfile b/containers/memcached/memcached/Containerfile new file mode 100644 index 0000000..a3f57df --- /dev/null +++ b/containers/memcached/memcached/Containerfile @@ -0,0 +1,14 @@ +ARG BASE_IMAGE=localhost/openstack/openstack-base:latest +FROM ${BASE_IMAGE} + +LABEL summary="OpenStack Memcached" \ + io.k8s.description="Memcached caching service for OpenStack" + +RUN uid_gid_manage memcached + +COPY bindeps.txt /tmp/bindeps.txt +RUN pkgs=$(cat /tmp/bindeps.txt | grep -v '^#' | grep -v '^$' | tr '\n' ' ') && \ + if [ -n "${pkgs}" ]; then microdnf -y install ${pkgs} && microdnf clean all && rm -rf /var/cache/dnf; fi && \ + rm /tmp/bindeps.txt + +USER memcached diff --git a/containers/memcached/memcached/bindeps.txt b/containers/memcached/memcached/bindeps.txt new file mode 100644 index 0000000..51b7e42 --- /dev/null +++ b/containers/memcached/memcached/bindeps.txt @@ -0,0 +1 @@ +memcached diff --git a/containers/rabbitmq/rabbitmq/Containerfile b/containers/rabbitmq/rabbitmq/Containerfile new file mode 100644 index 0000000..6163783 --- /dev/null +++ b/containers/rabbitmq/rabbitmq/Containerfile @@ -0,0 +1,18 @@ +ARG BASE_IMAGE=localhost/openstack/openstack-base:latest +FROM ${BASE_IMAGE} + +LABEL summary="OpenStack RabbitMQ" \ + io.k8s.description="RabbitMQ messaging service for OpenStack" + +RUN uid_gid_manage rabbitmq + +COPY bindeps.txt /tmp/bindeps.txt +RUN pkgs=$(cat /tmp/bindeps.txt | grep -v '^#' | grep -v '^$' | tr '\n' ' ') && \ + if [ -n "${pkgs}" ]; then microdnf -y install ${pkgs} && microdnf clean all && rm -rf /var/cache/dnf; fi && \ + rm /tmp/bindeps.txt && \ + rm -f /etc/rabbitmq/rabbitmq.conf + +COPY scripts/extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 755 /usr/local/bin/kolla_extend_start + +USER rabbitmq diff --git a/containers/rabbitmq/rabbitmq/bindeps.txt b/containers/rabbitmq/rabbitmq/bindeps.txt new file mode 100644 index 0000000..e692859 --- /dev/null +++ b/containers/rabbitmq/rabbitmq/bindeps.txt @@ -0,0 +1,2 @@ +hostname +rabbitmq-server diff --git a/containers/rabbitmq/rabbitmq/scripts/extend_start.sh b/containers/rabbitmq/rabbitmq/scripts/extend_start.sh new file mode 100644 index 0000000..858d3aa --- /dev/null +++ b/containers/rabbitmq/rabbitmq/scripts/extend_start.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + +# NOTE(sbezverk): In kubernetes environment, if this file exists from previous +# bootstrap, the system does not allow to overwrite it (it bootstrap files with +# permission denied error) but it allows to delete it and then recreate it. + if [[ -e "/var/lib/rabbitmq/.erlang.cookie" ]]; then + rm -f /var/lib/rabbitmq/.erlang.cookie + fi + echo "${RABBITMQ_CLUSTER_COOKIE}" > /var/lib/rabbitmq/.erlang.cookie + chmod 400 /var/lib/rabbitmq/.erlang.cookie + exit 0 +fi diff --git a/containers/redis/redis/Containerfile b/containers/redis/redis/Containerfile new file mode 100644 index 0000000..18bdd59 --- /dev/null +++ b/containers/redis/redis/Containerfile @@ -0,0 +1,14 @@ +ARG BASE_IMAGE=localhost/openstack/openstack-base:latest +FROM ${BASE_IMAGE} + +LABEL summary="OpenStack Redis (Valkey)" \ + io.k8s.description="Valkey (Redis-compatible) caching and messaging service for OpenStack" + +RUN uid_gid_manage valkey + +COPY bindeps.txt /tmp/bindeps.txt +RUN pkgs=$(cat /tmp/bindeps.txt | grep -v '^#' | grep -v '^$' | tr '\n' ' ') && \ + if [ -n "${pkgs}" ]; then microdnf -y install ${pkgs} && microdnf clean all && rm -rf /var/cache/dnf; fi && \ + rm /tmp/bindeps.txt + +USER valkey diff --git a/containers/redis/redis/bindeps.txt b/containers/redis/redis/bindeps.txt new file mode 100644 index 0000000..d1e1057 --- /dev/null +++ b/containers/redis/redis/bindeps.txt @@ -0,0 +1,2 @@ +procps-ng +valkey