diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 515a2263..8d75fbca 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -229,18 +229,27 @@ jobs: fail-fast: false matrix: include: - - mysql-tag: 'mysql-8.4.8' + # A component works only on the exact release it was built against (a build for + # 8.4.8 crashed 8.4.11 in askdba/myvector#244), so each image is based on + # mysql:, the release of mysql-tag, and also tagged with it. + - mysql-tag: 'mysql-8.4.13' + mysql-release: '8.4.13' mysql-version: '8.4' build-script: scripts/build-component-8.4-docker.sh image-tag: 'mysql8.4-component' - - mysql-tag: 'mysql-9.7.0' + release-image-tag: 'mysql8.4.13-component' + - mysql-tag: 'mysql-9.7.4' + mysql-release: '9.7.4' mysql-version: '9.7' build-script: scripts/build-component-9.7-docker.sh image-tag: 'mysql9.7-component' + release-image-tag: 'mysql9.7.4-component' - mysql-tag: 'mysql-26.10.0' + mysql-release: '26.10.0' mysql-version: '26.10' build-script: scripts/build-component-26.10-docker.sh image-tag: 'mysql26.10' + release-image-tag: 'mysql26.10.0' steps: - name: Checkout MyVector Code uses: actions/checkout@v4 @@ -276,7 +285,7 @@ jobs: - name: Smoke test component artifact run: | chmod +x scripts/smoke-component.sh - COMPONENT_DIR=build/component-amd64 ./scripts/smoke-component.sh "${{ matrix.mysql-version }}" + COMPONENT_DIR=build/component-amd64 ./scripts/smoke-component.sh "${{ matrix.mysql-release }}" - name: Smoke test image contents run: | @@ -284,7 +293,7 @@ jobs: docker buildx build \ --platform "linux/${arch}" \ --file Dockerfile.component \ - --build-arg MYSQL_VERSION=${{ matrix.mysql-version }} \ + --build-arg MYSQL_VERSION=${{ matrix.mysql-release }} \ -t "myvector-component-smoke:${{ matrix.mysql-version }}-${arch}" \ --load \ . @@ -315,17 +324,18 @@ jobs: platforms: linux/amd64,linux/arm64 # Never push on a dry_run dispatch — build only, to prove the pipeline. push: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }} - tags: ghcr.io/${{ github.repository }}:${{ matrix.image-tag }} + tags: | + ghcr.io/${{ github.repository }}:${{ matrix.image-tag }} + ghcr.io/${{ github.repository }}:${{ matrix.release-image-tag }} build-args: | - MYSQL_VERSION=${{ matrix.mysql-version }} + MYSQL_VERSION=${{ matrix.mysql-release }} - # A component works only on the patch release it was built against (the 8.4.8 guard - # crashes 8.4.11), so the mysql-mcp image is based on that exact release. + # Like the component image, the mysql-mcp image is based on the exact release the + # guard was built against (mysql-release). - name: Test mysql-mcp image env: - MYSQL_TAG: ${{ matrix.mysql-tag }} + MYSQL_VERSION: ${{ matrix.mysql-release }} run: | - MYSQL_VERSION=${MYSQL_TAG#mysql-} for arch in amd64 arm64; do docker buildx build \ --platform "linux/${arch}" \ @@ -341,12 +351,6 @@ jobs: docker run --rm --platform linux/arm64 --entrypoint /bin/sh "mysql-mcp-smoke:${MYSQL_VERSION}-arm64" -c \ "test -f /usr/lib64/mysql/plugin/component_mcp_guard.so && test -f /usr/share/mysql-mcp/mysql_mcp.sql && test -f /docker-entrypoint-initdb.d/50-mysql-mcp.sh" - - name: mysql-mcp base release - id: mcp-version - env: - MYSQL_TAG: ${{ matrix.mysql-tag }} - run: echo "version=${MYSQL_TAG#mysql-}" >> "$GITHUB_OUTPUT" - - name: Build and push mysql-mcp image uses: docker/build-push-action@v5 with: @@ -357,6 +361,6 @@ jobs: push: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }} tags: | ghcr.io/${{ github.repository_owner }}/mysql-mcp:${{ matrix.mysql-version }} - ghcr.io/${{ github.repository_owner }}/mysql-mcp:${{ steps.mcp-version.outputs.version }} + ghcr.io/${{ github.repository_owner }}/mysql-mcp:${{ matrix.mysql-release }} build-args: | - MYSQL_VERSION=${{ steps.mcp-version.outputs.version }} + MYSQL_VERSION=${{ matrix.mysql-release }} diff --git a/CHANGELOG.md b/CHANGELOG.md index a826305a..2245939c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -130,6 +130,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 and rebuild the index. See [Declaring a Vector Column](docs/usage.md#declaring-a-vector-column). ### Fixed +- **Component images pinned to their build release.** A component works only on the exact MySQL release it was built against: in a dry run, a `component_mcp_guard` built for 8.4.8 crashed `mysql:8.4` (8.4.11). The images were built for 8.4.8 and 9.7.0 but ran on the floating `mysql:8.4`/`mysql:9.7`. `docker-publish.yml` now builds the component images for **8.4.13, 9.7.4 and 26.10.0** (the releases the floating tags now point to) and bases each one on `mysql:`. It also tags each image with its release (`mysql8.4.13-component`, `mysql9.7.4-component`, `mysql26.10.0`), and the artifact smoke test runs on the same release. `Dockerfile.component` now requires `MYSQL_VERSION` (no default). - **Component build scripts reconfigure the server tree after a failed configure.** A `.configure-ok` marker is written only after `cmake` succeeds; before, the scripts trusted `CMakeCache.txt`, which appears before configuration finishes, so a failed configure was skipped on the next run. - **Component build scripts no longer re-clone the MySQL source on every run.** Inside the build container, git refused the host-owned tree ("dubious ownership"), so the tag check always failed and the tree was deleted and cloned again, which also defeated the CI cache of the source tree. The scripts now mark the tree as a git safe directory. - **Component: `myvector_construct()` with a constant argument is built once, not per row** diff --git a/Dockerfile.component b/Dockerfile.component index ea26434d..f6c2e0d5 100644 --- a/Dockerfile.component +++ b/Dockerfile.component @@ -1,4 +1,7 @@ -ARG MYSQL_VERSION=8.4 +# MYSQL_VERSION (required, no default) is the exact release the component was built +# against, for example 8.4.13: a component built for another patch release can crash +# the server. +ARG MYSQL_VERSION FROM mysql:${MYSQL_VERSION} ARG TARGETARCH diff --git a/docker/mysql-mcp/Dockerfile b/docker/mysql-mcp/Dockerfile index 90907fb7..e2584177 100644 --- a/docker/mysql-mcp/Dockerfile +++ b/docker/mysql-mcp/Dockerfile @@ -3,7 +3,7 @@ # Published as ghcr.io/askdba/mysql-mcp:<8.4|9.7|26.10> by docker-publish.yml. # Build context: the repository root, with component_mcp_guard-.so staged there. # MYSQL_VERSION (required, no default) must be the exact release the component was built -# against, for example 8.4.8: a component built for another patch release can crash the +# against, for example 8.4.13: a component built for another patch release can crash the # server. ARG MYSQL_VERSION diff --git a/docs/DOCKER_IMAGES.md b/docs/DOCKER_IMAGES.md index 473495b4..2b387336 100644 --- a/docs/DOCKER_IMAGES.md +++ b/docs/DOCKER_IMAGES.md @@ -221,6 +221,12 @@ instructions in the main README: | `ghcr.io/askdba/myvector:mysql26.10` | 26.10.x (Innovation) | Component only (`INSTALL COMPONENT`) | | `ghcr.io/askdba/myvector:latest` | 8.0.x | Plugin (`INSTALL PLUGIN`) | +Each component image is based on the exact MySQL release its component was built +against: a component built for one patch release can crash another (an 8.4.8 build +crashed 8.4.11). The image is also tagged with that release, e.g. +`mysql8.4.13-component`, `mysql9.7.4-component`, `mysql26.10.0`; the version tags +above move to the new release when the build is updated. + Component images (`INSTALL COMPONENT`) contain `/usr/lib/mysql/plugin/myvector.so` + `myvector.json` and `/docker-entrypoint-initdb.d/myvector_install_component.sql`, rather than the plugin's `myvectorplugin.sql`. diff --git a/docs/MCP_COMPONENTS.md b/docs/MCP_COMPONENTS.md index 5f625852..443b74c1 100644 --- a/docs/MCP_COMPONENTS.md +++ b/docs/MCP_COMPONENTS.md @@ -26,7 +26,7 @@ GRANT EXECUTE ON mysql_mcp.* TO 'mcp'@'%'; -- if the SQL tool pack is install ### Docker images (mysql-mcp) -`ghcr.io/askdba/mysql-mcp:<8.4|9.7|26.10>` (amd64, arm64; also tagged with the exact release, such as `8.4.8`) is the official `mysql` image of the release the component was built for, with `component_mcp_guard` and the `mysql_mcp` SQL tool pack. It is separate from the MyVector images. On first start, with an empty data directory, it installs both, grants `MCP_ADMIN` to the root accounts, and reads these settings: +`ghcr.io/askdba/mysql-mcp:<8.4|9.7|26.10>` (amd64, arm64; also tagged with the exact release, such as `8.4.13`) is the official `mysql` image of the release the component was built for, with `component_mcp_guard` and the `mysql_mcp` SQL tool pack. It is separate from the MyVector images. On first start, with an empty data directory, it installs both, grants `MCP_ADMIN` to the root accounts, and reads these settings: | Variable | Effect | |---|---| diff --git a/examples/movie-finder/README.md b/examples/movie-finder/README.md index 717ddc17..2f52415e 100644 --- a/examples/movie-finder/README.md +++ b/examples/movie-finder/README.md @@ -91,10 +91,11 @@ a restart. Until a release includes them, build a local image from `main`: ```bash # from the repository root; ARCH is arm64 or amd64, matching your machine ARCH=arm64 -./scripts/build-component-9.7-docker.sh mysql-9.7.0 build/component-local +./scripts/build-component-9.7-docker.sh mysql-9.7.4 build/component-local cp build/component-local/libmyvector_component.so myvector-component-$ARCH.so cp build/component-local/myvector.json sql/myvector_install_component.sql sql/myvector_uninstall_component.sql . -docker build -f Dockerfile.component --build-arg MYSQL_VERSION=9.7 \ +# MYSQL_VERSION must be the release the component was built for (mysql-9.7.4 above) +docker build -f Dockerfile.component --build-arg MYSQL_VERSION=9.7.4 \ --build-arg TARGETARCH=$ARCH -t myvector-local:mysql9.7-component . cd examples/movie-finder diff --git a/scripts/build-component-9.7-docker.sh b/scripts/build-component-9.7-docker.sh index 00de2ee2..a3ac677b 100755 --- a/scripts/build-component-9.7-docker.sh +++ b/scripts/build-component-9.7-docker.sh @@ -95,6 +95,8 @@ docker run --rm \ # so a failed configure would otherwise be skipped on the next run. if [ ! -f "$MYSQL_BLD/.configure-ok" ]; then cd "$MYSQL_BLD" + # WebAuthn: on by default from 9.7.4 (as in 26.10), it needs libudev/libfido2 + # headers this container does not have; the component build needs none of it. cmake .. \ -DCMAKE_C_COMPILER=/opt/rh/gcc-toolset-14/root/usr/bin/gcc \ -DCMAKE_CXX_COMPILER=/opt/rh/gcc-toolset-14/root/usr/bin/g++ \ @@ -106,6 +108,7 @@ docker run --rm \ -DWITH_NDB=OFF \ -DWITH_NDBCLUSTER=OFF \ -DWITH_GROUP_REPLICATION=OFF \ + -DWITH_AUTHENTICATION_WEBAUTHN=OFF \ -DWITH_EXAMPLE_STORAGE_ENGINE=OFF \ -DCMAKE_BUILD_TYPE=Release touch "$MYSQL_BLD/.configure-ok"