diff --git a/.github/workflows/build_qa_framework_docker_image.yml b/.github/workflows/build_qa_framework_docker_image.yml new file mode 100644 index 000000000..a10fca59d --- /dev/null +++ b/.github/workflows/build_qa_framework_docker_image.yml @@ -0,0 +1,148 @@ +name: Build and Push Docker Image for PMM QA Framework + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + paths: + - '.github/workflows/build_qa_framework_docker_image.yml' + - 'qa_framework/docker_images/**' + workflow_dispatch: + inputs: + image: + description: 'Which image to build' + required: true + type: choice + options: + - percona-server-mysql + - mysql-community + - percona-distribution-postgresql + - postgresql-community + - percona-server-mongodb + - mongodb + - valkey + db_version: + description: 'Database version to build/tag (e.g. 8.0, 8.4, 5.7). Applies to any image.' + required: false + default: '' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: percona/pmm-qa + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Resolve image config + id: cfg + run: | + BASE="qa_framework/docker_images" + # inputs are absent on push / pull_request events -> default the image + IMAGE="${{ github.event.inputs.image }}" + IMAGE="${IMAGE:-percona-server-mysql}" + case "$IMAGE" in + percona-server-mysql) + NAME="percona-server-mysql" + DIR="$BASE/percona_server_for_mysql" + ;; + mysql-community) + NAME="mysql-community" + DIR="$BASE/mysql-community" + ;; + percona-distribution-postgresql) + NAME="percona-distribution-postgresql" + DIR="$BASE/percona-distribution-postgresql" + ;; + postgresql-community) + NAME="postgresql-community" + DIR="$BASE/postgresql-community" + ;; + percona-server-mongodb) + NAME="percona-server-mongodb" + DIR="$BASE/percona-server-mongodb" + ;; + mongodb) + NAME="mongodb" + DIR="$BASE/mongodb" + ;; + valkey) + NAME="valkey" + DIR="$BASE/valkey" + ;; + *) + echo "Unknown image: $IMAGE" + exit 1 + ;; + esac + FILE="$DIR/Dockerfile" + CONTEXT="$DIR" + echo "name=$NAME" >> "$GITHUB_OUTPUT" + echo "file=$FILE" >> "$GITHUB_OUTPUT" + echo "context=$CONTEXT" >> "$GITHUB_OUTPUT" + + # Version handling: db_version is free-text and usable by any image. + # Every image receives DB_VERSION as a build arg (Dockerfiles may ignore it); + # percona-server-mysql additionally derives its repo/base/package args. + DBV="${{ github.event.inputs.db_version }}" + FLAVOR="$DBV" + { + echo "build_args<> "$GITHUB_OUTPUT" + echo "flavor=$FLAVOR" >> "$GITHUB_OUTPUT" + echo "Resolved: image=$NAME file=$FILE context=$CONTEXT flavor=${FLAVOR:-none}" + + - name: Assemble tags + id: tags + run: | + IMG="${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ steps.cfg.outputs.name }}" + FLAVOR="${{ steps.cfg.outputs.flavor }}" + # Two tags only: latest, plus the db_version (flavor) when set. + { + echo "tags<> "$GITHUB_OUTPUT" + + - name: Set up Docker Build + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + # Pull requests only validate the build; no push, so no login needed. + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build (and push on non-PR events) + uses: docker/build-push-action@v6 + with: + context: ${{ steps.cfg.outputs.context }} + file: ${{ steps.cfg.outputs.file }} + push: ${{ github.event_name != 'pull_request' }} + build-args: ${{ steps.cfg.outputs.build_args }} + tags: ${{ steps.tags.outputs.tags }} diff --git a/qa_framework/docker_images/percona_server_for_mysql/Dockerfile b/qa_framework/docker_images/percona_server_for_mysql/Dockerfile new file mode 100644 index 000000000..cb70afb44 --- /dev/null +++ b/qa_framework/docker_images/percona_server_for_mysql/Dockerfile @@ -0,0 +1,56 @@ +# Percona Server for MySQL — QA image (systemd), based on qa-integration/pmm_qa +# qa-integration/pmm_qa/percona_server_for_mysql +# +# Reproduces the same container the pmm-qa Ansible framework builds, WITHOUT the +# PMM client. A single image acts as any node in three topologies, selected at +# runtime via the SETUP_TYPE env var: +# - single : standalone instance (my.cnf.j2) +# - replication : async replication (my-async-replication.cnf.j2) +# - gr : group replication (my-group-replication.cnf.j2) +# +# The entrypoint (ps-node-setup.sh, run by a systemd oneshot unit) renders the +# matching my.cnf from env vars, initializes the datadir, sets the root password, +# and wires up replication for the node's role. +# +# ---- Version selection (build args) ---- +# 8.0 (default): docker build -t ps-qa:8.0 . +# 8.4: docker build -t ps-qa:8.4 --build-arg PS_REPO=ps-84-lts . +# 5.7: docker build -t ps-qa:5.7 \ +# --build-arg BASE_IMAGE=antmelekhin/docker-systemd:ubuntu-22.04 \ +# --build-arg PS_REPO=ps-57 \ +# --build-arg PS_PKG_SUFFIX=-5.7 . +ARG BASE_IMAGE=antmelekhin/docker-systemd:ubuntu-24.04 +FROM ${BASE_IMAGE} + +# ps-80 | ps-84-lts | ps-57 (percona-release channel) +ARG PS_REPO=ps-80 +# "" for 8.x, "-5.7" for 5.7 package names +ARG PS_PKG_SUFFIX= + +ENV DEBIAN_FRONTEND=noninteractive + +# Dependencies + Percona repo + Percona Server + RocksDB + sysbench +# (mirrors prepare_install_ps.yml and the sysbench step in percona-server-setup.yml) +RUN apt-get update \ + && apt-get install -y wget gnupg2 lsb-release curl \ + && wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb \ + && dpkg -i percona-release_latest.generic_all.deb \ + && rm -f percona-release_latest.generic_all.deb \ + && percona-release enable ${PS_REPO} release \ + && apt-get update \ + && apt-get install -y \ + percona-server-server${PS_PKG_SUFFIX} \ + percona-server-rocksdb${PS_PKG_SUFFIX} \ + sysbench \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +COPY ps-node-setup.sh /usr/local/bin/ps-node-setup.sh +COPY ps-node-setup.service /etc/systemd/system/ps-node-setup.service + +# Don't let mysql auto-start before the config is rendered; the setup unit starts it. +RUN chmod +x /usr/local/bin/ps-node-setup.sh \ + && systemctl disable mysql 2>/dev/null || true \ + && systemctl enable ps-node-setup.service + +# 3306 = MySQL, 34061 = group replication communication (XCOM) +EXPOSE 3306 34061