You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fluss.apache.org by ab...@apache.org on 2026/08/28 16:22:39 UTC
(fluss) branch main updated: [gateway] Add binary distribution and container release flow (#4098)
This is an automated email from the ASF dual-hosted git repository.
fresh-borzoni pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fluss.git
The following commit(s) were added to refs/heads/main by this push:
new fa5b9fd72 [gateway] Add binary distribution and container release flow (#4098)
fa5b9fd72 is described below
commit fa5b9fd7221424982779669c455443c1926ebd68
Author: naivedogger <ya...@gmail.com>
AuthorDate: Sat Aug 29 00:22:34 2026 +0800
[gateway] Add binary distribution and container release flow (#4098)
* [gateway] Add binary distribution and container release flow
* [gateway] Pin the buildx action and address release review findings
* [gateway] Simplify image delivery flow
* [gateway] Align release config with current options
* [gateway] Handle image builds without Git metadata
* [gateway] Address additional release review feedback
* [gateway] Preserve snapshot versions in release tooling
* [gateway] Address final release review findings
---
fluss-gateway/.licenserc.yaml => .dockerignore | 42 +-
.github/workflows/gateway-ci.yml | 64 +-
docker/fluss-gateway/Dockerfile | 65 +
docker/fluss-gateway/Dockerfile.build | 42 +
docker/fluss-gateway/build.sh | 91 +
docker/fluss-gateway/prepare_build.sh | 70 +
docker/fluss-gateway/smoke-test.sh | 101 +
fluss-gateway/.licenserc.yaml | 2 +
fluss-gateway/Cargo.lock | 2 +-
fluss-gateway/Cargo.toml | 8 +-
fluss-gateway/DEPENDENCIES.rust.tsv | 2 +-
fluss-gateway/LICENSE-bin | 2743 ++++++++++++++++++++
fluss-gateway/NOTICE-bin | 24 +
fluss-gateway/README.md | 115 +-
.../bin/fluss-gateway.sh | 58 +-
fluss-gateway/conf/gateway.yaml | 139 +
fluss-gateway/justfile | 13 +
fluss-gateway/openapi.yaml | 2 +-
fluss-gateway/scripts/generate_binary_license.py | 392 +++
fluss-gateway/src/config.rs | 30 +
tools/releasing/create_gateway_release.sh | 171 ++
tools/releasing/update_branch_version.sh | 95 +-
.../how-to-release/creating-a-fluss-release.mdx | 78 +-
.../community/how-to-release/pre-rc-checklist.md | 16 +-
.../how-to-release/release-manager-preparation.md | 9 +-
.../how-to-release/verifying-a-fluss-release.md | 51 +-
26 files changed, 4333 insertions(+), 92 deletions(-)
diff --git a/fluss-gateway/.licenserc.yaml b/.dockerignore
similarity index 52%
copy from fluss-gateway/.licenserc.yaml
copy to .dockerignore
index df7a3ec35..8dc08fcdc 100644
--- a/fluss-gateway/.licenserc.yaml
+++ b/.dockerignore
@@ -15,23 +15,29 @@
# specific language governing permissions and limitations
# under the License.
-header:
- license:
- spdx-id: Apache-2.0
- copyright-owner: Apache Software Foundation
+# The pinned Gateway binary builder uses the repository root because
+# fluss-gateway has a path dependency on fluss-rust. The release image itself
+# uses docker/fluss-gateway as its build context.
+*
+!LICENSE
+!NOTICE
+!fluss-gateway/
+!fluss-gateway/**
+!fluss-rust/
+!fluss-rust/**
+!docker/
+!docker/fluss-gateway/
+!docker/fluss-gateway/**
- paths:
- - 'fluss-gateway/**'
+# Generated and local-only files inside the included Rust workspaces.
+fluss-gateway/target/
+fluss-gateway/.idea/
+fluss-gateway/.vscode/
+fluss-rust/target/
+fluss-rust/**/target/
+fluss-rust/.idea/
+fluss-rust/.vscode/
- paths-ignore:
- # bare (gitignore-style) patterns match the basename at any depth
- - '.gitignore'
- - 'Cargo.lock'
- - 'LICENSE'
- - 'NOTICE'
- - 'DISCLAIMER'
- - '**/*.md'
- - 'fluss-gateway/DEPENDENCIES.*.tsv'
- # The checked-in OpenAPI document is generated from the typed contract (`just openapi`).
- - 'fluss-gateway/openapi.yaml'
- comment: on-failure
+# Prepared image inputs belong to the release image build context, not to the
+# binary builder that runs from the repository root.
+docker/fluss-gateway/build-target/
diff --git a/.github/workflows/gateway-ci.yml b/.github/workflows/gateway-ci.yml
index d38c3af63..7026b7c0c 100644
--- a/.github/workflows/gateway-ci.yml
+++ b/.github/workflows/gateway-ci.yml
@@ -23,20 +23,35 @@ on:
push:
branches:
- main
+ - release-**
+ - ci-**
paths:
- 'fluss-gateway/**'
- 'fluss-rust/Cargo.toml'
- 'fluss-rust/crates/fluss/**'
- 'fluss-rpc/src/main/proto/**'
+ - 'LICENSE'
+ - 'NOTICE'
+ - 'docker/fluss-gateway/**'
+ - '.dockerignore'
+ - 'tools/releasing/create_gateway_release.sh'
+ - 'tools/releasing/update_branch_version.sh'
- '.github/workflows/gateway-ci.yml'
pull_request:
branches:
- main
+ - release-**
paths:
- 'fluss-gateway/**'
- 'fluss-rust/Cargo.toml'
- 'fluss-rust/crates/fluss/**'
- 'fluss-rpc/src/main/proto/**'
+ - 'LICENSE'
+ - 'NOTICE'
+ - 'docker/fluss-gateway/**'
+ - '.dockerignore'
+ - 'tools/releasing/create_gateway_release.sh'
+ - 'tools/releasing/update_branch_version.sh'
- '.github/workflows/gateway-ci.yml'
workflow_dispatch:
@@ -71,7 +86,7 @@ jobs:
- name: Build
run: cargo build --locked --all-targets
- - name: Unit Test
+ - name: Unit and Integration Tests
run: cargo test --locked --all-targets
env:
RUST_LOG: DEBUG
@@ -133,6 +148,9 @@ jobs:
cargo deny --locked list -f tsv -t 0.6 | sed 's/[[:space:]]*$//' > DEPENDENCIES.rust.tsv
git diff --exit-code DEPENDENCIES.rust.tsv
+ - name: Binary LICENSE and NOTICE drift check
+ run: python3 scripts/generate_binary_license.py --check
+
- name: Rust Cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
@@ -148,3 +166,47 @@ jobs:
run: cargo doc --locked --no-deps
env:
RUSTDOCFLAGS: -D warnings
+
+ - name: Check distribution shell scripts
+ run: |
+ bash -n bin/fluss-gateway.sh
+ bash -n ../docker/fluss-gateway/build.sh
+ bash -n ../docker/fluss-gateway/prepare_build.sh
+ bash -n ../docker/fluss-gateway/smoke-test.sh
+ bash -n ../tools/releasing/create_gateway_release.sh
+ bash -n ../tools/releasing/update_branch_version.sh
+
+ container-smoke-test:
+ name: "Gateway Distribution and Container (${{ matrix.arch }})"
+ timeout-minutes: 90
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - arch: amd64
+ runner: ubuntu-24.04
+ - arch: arm64
+ runner: ubuntu-24.04-arm
+ defaults:
+ run:
+ working-directory: .
+ steps:
+ - uses: actions/checkout@v6
+
+ # The ASF enterprise only permits third-party actions that its allowlist pins to
+ # an exact commit, so a moving tag such as @v3 fails the whole run before any job
+ # starts. This commit is the revision other ASF projects already build images with.
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
+
+ - name: Build and smoke test the distribution and image
+ env:
+ FLUSS_VERSION: smoke
+ GATEWAY_ARCH: ${{ matrix.arch }}
+ GATEWAY_BUILD_CACHE_FROM: type=gha,scope=fluss-gateway-${{ matrix.arch }}
+ GATEWAY_BUILD_CACHE_TO: type=gha,mode=max,scope=fluss-gateway-${{ matrix.arch }}
+ GATEWAY_IMAGE: fluss-gateway:smoke-${{ matrix.arch }}
+ RUN_SMOKE: "true"
+ VCS_REF: ${{ github.sha }}
+ run: docker/fluss-gateway/build.sh
diff --git a/docker/fluss-gateway/Dockerfile b/docker/fluss-gateway/Dockerfile
new file mode 100644
index 000000000..9458a512a
--- /dev/null
+++ b/docker/fluss-gateway/Dockerfile
@@ -0,0 +1,65 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Like the Java Fluss image, the release image only assembles a prepared
+# binary distribution. Rust compilation happens before this step so buildx
+# never compiles the Gateway through QEMU.
+FROM debian:bookworm-slim
+
+ARG TARGETARCH
+ARG FLUSS_VERSION=dev
+ARG VCS_REF=unknown
+
+LABEL org.opencontainers.image.title="Apache Fluss Gateway" \
+ org.opencontainers.image.description="Stateless REST Gateway for Apache Fluss" \
+ org.opencontainers.image.url="https://fluss.apache.org" \
+ org.opencontainers.image.source="https://github.com/apache/fluss" \
+ org.opencontainers.image.version="${FLUSS_VERSION}" \
+ org.opencontainers.image.revision="${VCS_REF}" \
+ org.opencontainers.image.licenses="Apache-2.0"
+
+RUN set -ex; \
+ apt-get update; \
+ apt-get install -y --no-install-recommends ca-certificates curl; \
+ rm -rf /var/lib/apt/lists/*; \
+ groupadd --system --gid=9999 fluss; \
+ useradd --system --home-dir /opt/fluss --create-home --uid=9999 --gid=fluss fluss
+
+ENV FLUSS_HOME=/opt/fluss \
+ FLUSS_CONF_DIR=/opt/fluss/conf \
+ FLUSS_GATEWAY_CONFIG=/opt/fluss/conf/gateway.yaml \
+ FLUSS_GATEWAY_HEALTH_URL=http://127.0.0.1:8080/health \
+ FLUSS_GATEWAY__REST__LISTEN=0.0.0.0:8080 \
+ FLUSS_GATEWAY__METRICS__EXPORTER__PROMETHEUS__LISTEN=0.0.0.0:9095 \
+ HOME=/opt/fluss \
+ PATH=/opt/fluss/bin:${PATH}
+
+WORKDIR ${FLUSS_HOME}
+
+COPY --chown=fluss:fluss build-target/${TARGETARCH}/ /opt/fluss/
+
+USER 9999:9999
+
+EXPOSE 8080 9095
+STOPSIGNAL SIGTERM
+
+HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=3 \
+ CMD curl --fail --silent --show-error --noproxy "*" --output /dev/null \
+ --max-time 3 "${FLUSS_GATEWAY_HEALTH_URL}"
+
+ENTRYPOINT ["/opt/fluss/bin/fluss-gateway.sh"]
diff --git a/docker/fluss-gateway/Dockerfile.build b/docker/fluss-gateway/Dockerfile.build
new file mode 100644
index 000000000..0895296f3
--- /dev/null
+++ b/docker/fluss-gateway/Dockerfile.build
@@ -0,0 +1,42 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Pin the compiler and glibc build environment used by the Linux convenience
+# binary. Run this target on a native machine for the requested platform.
+FROM rust:1.88-bookworm AS builder
+
+ENV RUSTUP_TOOLCHAIN=1.88.0
+
+WORKDIR /workspace
+COPY fluss-rust/ fluss-rust/
+COPY fluss-gateway/Cargo.toml \
+ fluss-gateway/Cargo.lock \
+ fluss-gateway/
+COPY fluss-gateway/src/ fluss-gateway/src/
+COPY fluss-gateway/tests/ fluss-gateway/tests/
+
+RUN cargo build \
+ --manifest-path fluss-gateway/Cargo.toml \
+ --release \
+ --locked \
+ --bin fluss-gateway
+
+FROM scratch AS artifact
+COPY --from=builder \
+ /workspace/fluss-gateway/target/release/fluss-gateway \
+ /fluss-gateway
diff --git a/docker/fluss-gateway/build.sh b/docker/fluss-gateway/build.sh
new file mode 100755
index 000000000..4777b87f7
--- /dev/null
+++ b/docker/fluss-gateway/build.sh
@@ -0,0 +1,91 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+REPOSITORY_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd -P)"
+IMAGE="${GATEWAY_IMAGE:-fluss-gateway:dev}"
+RELEASE_DIR="${GATEWAY_RELEASE_DIR:-${REPOSITORY_ROOT}/target/gateway-release}"
+# The Dockerfile reads build-target/<arch> relative to its build context, so this
+# location is fixed here and passed on explicitly rather than inherited.
+BUILD_DIR="${SCRIPT_DIR}/build-target"
+
+cleanup() {
+ rm -rf "${BUILD_DIR}"
+}
+trap cleanup EXIT
+
+gateway_version="$(
+ sed -n '/^\[package\]/,/^\[/p' "${REPOSITORY_ROOT}/fluss-gateway/Cargo.toml" \
+ | grep '^[[:space:]]*version[[:space:]]*=' \
+ | head -1 \
+ | sed -E 's/.*"([^"]+)".*/\1/'
+)"
+
+if [[ -z "${GATEWAY_ARCH:-}" ]]; then
+ case "$(docker info --format '{{.Architecture}}')" in
+ x86_64|amd64)
+ GATEWAY_ARCH="amd64"
+ ;;
+ aarch64|arm64)
+ GATEWAY_ARCH="arm64"
+ ;;
+ *)
+ echo "Cannot determine the Docker engine architecture." >&2
+ exit 1
+ ;;
+ esac
+fi
+
+mkdir -p "${RELEASE_DIR}"
+(
+ cd "${REPOSITORY_ROOT}/tools"
+ RELEASE_VERSION="${gateway_version}" \
+ GATEWAY_ARCH="${GATEWAY_ARCH}" \
+ GATEWAY_RELEASE_DIR="${RELEASE_DIR}" \
+ SKIP_GPG=true \
+ releasing/create_gateway_release.sh
+)
+
+RELEASE_VERSION="${gateway_version}" \
+GATEWAY_ARCHES="${GATEWAY_ARCH}" \
+GATEWAY_RELEASE_DIR="${RELEASE_DIR}" \
+GATEWAY_IMAGE_BUILD_DIR="${BUILD_DIR}" \
+ "${SCRIPT_DIR}/prepare_build.sh"
+
+image_version="${FLUSS_VERSION:-${gateway_version}}"
+image_revision="${VCS_REF:-$(git -C "${REPOSITORY_ROOT}" rev-parse HEAD 2>/dev/null || echo unknown)}"
+docker buildx build \
+ --load \
+ --platform "linux/${GATEWAY_ARCH}" \
+ --file "${SCRIPT_DIR}/Dockerfile" \
+ --build-arg "TARGETARCH=${GATEWAY_ARCH}" \
+ --build-arg "FLUSS_VERSION=${image_version}" \
+ --build-arg "VCS_REF=${image_revision}" \
+ --tag "${IMAGE}" \
+ "${SCRIPT_DIR}"
+
+if [[ "${RUN_SMOKE:-false}" == "true" ]]; then
+ GATEWAY_IMAGE="${IMAGE}" \
+ "${SCRIPT_DIR}/smoke-test.sh"
+fi
diff --git a/docker/fluss-gateway/prepare_build.sh b/docker/fluss-gateway/prepare_build.sh
new file mode 100755
index 000000000..71cdc1aea
--- /dev/null
+++ b/docker/fluss-gateway/prepare_build.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+if [[ -z "${RELEASE_VERSION:-}" ]]; then
+ echo "RELEASE_VERSION was not set." >&2
+ exit 1
+fi
+
+SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+REPOSITORY_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd -P)"
+RELEASE_DIR="${GATEWAY_RELEASE_DIR:-${REPOSITORY_ROOT}/tools/releasing/release}"
+BUILD_DIR="${GATEWAY_IMAGE_BUILD_DIR:-${SCRIPT_DIR}/build-target}"
+ARCHES="${GATEWAY_ARCHES:-amd64 arm64}"
+
+rm -rf "${BUILD_DIR}"
+mkdir -p "${BUILD_DIR}"
+
+for arch in ${ARCHES}; do
+ case "${arch}" in
+ amd64|arm64)
+ ;;
+ *)
+ echo "Unsupported Gateway image architecture: ${arch}" >&2
+ exit 1
+ ;;
+ esac
+
+ package_name="fluss-gateway-${RELEASE_VERSION}-bin-linux-${arch}"
+ archive="${RELEASE_DIR}/${package_name}.tgz"
+ if [[ ! -s "${archive}" ]]; then
+ echo "Gateway release archive is missing: ${archive}" >&2
+ exit 1
+ fi
+
+ extract_dir="${BUILD_DIR}/.${arch}"
+ mkdir -p "${extract_dir}"
+ tar -xzf "${archive}" -C "${extract_dir}"
+
+ package_dir="${extract_dir}/${package_name}"
+ if [[ ! -d "${package_dir}" ]]; then
+ echo "${archive} does not contain ${package_name}/." >&2
+ exit 1
+ fi
+ mkdir -p "${BUILD_DIR}/${arch}"
+ cp -a "${package_dir}/." "${BUILD_DIR}/${arch}/"
+ rm -rf "${extract_dir}"
+done
+
+echo "Prepared Gateway image inputs under ${BUILD_DIR}."
diff --git a/docker/fluss-gateway/smoke-test.sh b/docker/fluss-gateway/smoke-test.sh
new file mode 100755
index 000000000..e51c4f2d5
--- /dev/null
+++ b/docker/fluss-gateway/smoke-test.sh
@@ -0,0 +1,101 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+IMAGE="${GATEWAY_IMAGE:-fluss-gateway:dev}"
+CONTAINER="fluss-gateway-smoke-$$-${RANDOM}"
+
+cleanup() {
+ docker rm --force "${CONTAINER}" >/dev/null 2>&1 || true
+}
+trap cleanup EXIT
+
+docker run \
+ --detach \
+ --name "${CONTAINER}" \
+ --read-only \
+ --cap-drop ALL \
+ --security-opt no-new-privileges \
+ --publish 127.0.0.1::8080 \
+ --publish 127.0.0.1::9095 \
+ "${IMAGE}" >/dev/null
+
+for _ in $(seq 1 60); do
+ health="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{end}}' "${CONTAINER}")"
+ if [[ "${health}" == "healthy" ]]; then
+ break
+ fi
+ if [[ "$(docker inspect --format '{{.State.Running}}' "${CONTAINER}")" != "true" ]]; then
+ docker logs "${CONTAINER}"
+ echo "Gateway container exited before becoming healthy." >&2
+ exit 1
+ fi
+ sleep 1
+done
+
+if [[ "$(docker inspect --format '{{.State.Health.Status}}' "${CONTAINER}")" != "healthy" ]]; then
+ docker logs "${CONTAINER}"
+ echo "Gateway container did not become healthy." >&2
+ exit 1
+fi
+
+published_rest="$(docker port "${CONTAINER}" 8080/tcp | tail -1)"
+published_metrics="$(docker port "${CONTAINER}" 9095/tcp | tail -1)"
+curl --fail --silent --show-error --noproxy "*" --max-time 3 \
+ "http://${published_rest}/health" >/dev/null
+curl --fail --silent --show-error --noproxy "*" --max-time 3 \
+ "http://${published_rest}/ready" >/dev/null
+curl --fail --silent --show-error --noproxy "*" --max-time 3 \
+ "http://${published_metrics}/metrics" \
+ | grep -Fq "fluss_gateway_rest_requests_total"
+
+if [[ "$(docker exec "${CONTAINER}" id -u)" != "9999" ]]; then
+ echo "Gateway container must run as the fluss user (uid 9999)." >&2
+ exit 1
+fi
+docker exec "${CONTAINER}" test -r /opt/fluss/LICENSE
+docker exec "${CONTAINER}" test -r /opt/fluss/NOTICE
+
+docker stop --time 35 "${CONTAINER}" >/dev/null
+if [[ "$(docker inspect --format '{{.State.ExitCode}}' "${CONTAINER}")" != "0" ]]; then
+ docker logs "${CONTAINER}"
+ echo "Gateway did not exit cleanly after SIGTERM." >&2
+ exit 1
+fi
+docker rm "${CONTAINER}" >/dev/null
+
+if docker run \
+ --name "${CONTAINER}" \
+ --env FLUSS_GATEWAY__REST__LISTEN=not-an-address \
+ "${IMAGE}" >/dev/null 2>&1; then
+ echo "Gateway container accepted an invalid configuration." >&2
+ exit 1
+fi
+if [[ "$(docker inspect --format '{{.State.ExitCode}}' "${CONTAINER}")" != "2" ]]; then
+ docker logs "${CONTAINER}"
+ echo "Gateway container must exit with code 2 for an invalid configuration." >&2
+ exit 1
+fi
+docker rm "${CONTAINER}" >/dev/null
+
+echo "Gateway container smoke tests passed."
diff --git a/fluss-gateway/.licenserc.yaml b/fluss-gateway/.licenserc.yaml
index df7a3ec35..6a0de9a48 100644
--- a/fluss-gateway/.licenserc.yaml
+++ b/fluss-gateway/.licenserc.yaml
@@ -28,7 +28,9 @@ header:
- '.gitignore'
- 'Cargo.lock'
- 'LICENSE'
+ - 'LICENSE-bin'
- 'NOTICE'
+ - 'NOTICE-bin'
- 'DISCLAIMER'
- '**/*.md'
- 'fluss-gateway/DEPENDENCIES.*.tsv'
diff --git a/fluss-gateway/Cargo.lock b/fluss-gateway/Cargo.lock
index ec76ecd9f..a07288b62 100644
--- a/fluss-gateway/Cargo.lock
+++ b/fluss-gateway/Cargo.lock
@@ -800,7 +800,7 @@ dependencies = [
[[package]]
name = "fluss-gateway"
-version = "1.0.0"
+version = "1.0.0-SNAPSHOT"
dependencies = [
"async-trait",
"axum",
diff --git a/fluss-gateway/Cargo.toml b/fluss-gateway/Cargo.toml
index 63f77b5fe..f917bac1f 100644
--- a/fluss-gateway/Cargo.toml
+++ b/fluss-gateway/Cargo.toml
@@ -24,16 +24,16 @@ resolver = "3"
[package]
name = "fluss-gateway"
edition = "2024"
-version = "1.0.0"
+# Maven's 1.0-SNAPSHOT maps to Cargo's SemVer-compatible 1.0.0-SNAPSHOT.
+version = "1.0.0-SNAPSHOT"
license = "Apache-2.0"
# The floor matches fluss-rust, which the native backend links against.
rust-version = "1.88"
authors = ["Apache Fluss <de...@fluss.apache.org>"]
repository = "https://github.com/apache/fluss"
# The gateway ships as an executable, not a library on crates.io, so `rust-release.yml` does not
-# apply to it.
-# TODO: add a release path for the gateway's own artifacts (Linux binary, container image) and the
-# dependency inventory that goes with them; no workflow publishes them today.
+# apply to it. Linux binary archives and the container image are released with the main Fluss
+# version from the repository-level release tooling.
publish = false
description = "Stateless REST gateway for Apache Fluss"
diff --git a/fluss-gateway/DEPENDENCIES.rust.tsv b/fluss-gateway/DEPENDENCIES.rust.tsv
index cefc1de24..5d2cdad4b 100644
--- a/fluss-gateway/DEPENDENCIES.rust.tsv
+++ b/fluss-gateway/DEPENDENCIES.rust.tsv
@@ -66,7 +66,7 @@ errno@0.3.14 X X
fastrand@2.5.0 X X
find-msvc-tools@0.1.11 X X
flatbuffers@25.12.19 X
-fluss-gateway@1.0.0 X
+fluss-gateway@1.0.0-SNAPSHOT X
fluss-rs@1.0.0 X
foldhash@0.2.0 X
form_urlencoded@1.2.2 X X
diff --git a/fluss-gateway/LICENSE-bin b/fluss-gateway/LICENSE-bin
new file mode 100644
index 000000000..0c35b9d00
--- /dev/null
+++ b/fluss-gateway/LICENSE-bin
@@ -0,0 +1,2743 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+--------------------------------------------------------------------------------
+
+This LICENSE covers the supported amd64 and arm64 Linux Gateway
+convenience binaries. Their linked dependency sets are almost identical,
+but a target-specific crate may appear here even when it is not linked into
+the other architecture's executable.
+
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries include the following Rust crates
+under the Apache License, Version 2.0. Crates with additional conjunctive
+license obligations are also reproduced in the sections below.
+
+ahash@0.8.12
+anstream@1.0.0
+anstyle@1.0.14
+anstyle-parse@1.0.0
+anstyle-query@1.1.5
+anyhow@1.0.104
+arrow@59.2.0
+arrow-arith@59.2.0
+arrow-array@59.2.0
+arrow-buffer@59.2.0
+arrow-cast@59.2.0
+arrow-csv@59.2.0
+arrow-data@59.2.0
+arrow-ipc@59.2.0
+arrow-json@59.2.0
+arrow-ord@59.2.0
+arrow-row@59.2.0
+arrow-schema@59.2.0
+arrow-select@59.2.0
+arrow-string@59.2.0
+atomic-waker@1.1.2
+backon@1.6.0
+base64@0.22.1
+base64@0.23.1
+bigdecimal@0.4.10
+bitflags@1.3.2
+bitflags@2.13.1
+block-buffer@0.10.4
+cfg-if@1.0.4
+chacha20@0.10.1
+chrono@0.4.45
+clap@4.6.6
+clap_builder@4.6.6
+clap_lex@1.1.0
+colorchoice@1.0.5
+const-random@0.1.18
+cpufeatures@0.3.0
+crc32c@0.6.8
+crossbeam-epoch@0.9.20
+crossbeam-utils@0.8.22
+crypto-common@0.1.7
+defmt@1.1.1
+digest@0.10.7
+equivalent@1.0.2
+erased-serde@0.4.10
+errno@0.3.14
+fastrand@2.5.0
+flatbuffers@25.12.19
+form_urlencoded@1.2.2
+futures@0.3.34
+futures-channel@0.3.34
+futures-core@0.3.34
+futures-executor@0.3.34
+futures-io@0.3.34
+futures-sink@0.3.34
+futures-task@0.3.34
+futures-util@0.3.34
+getrandom@0.2.17
+getrandom@0.3.4
+getrandom@0.4.3
+half@2.7.1
+hashbrown@0.14.5
+hashbrown@0.16.1
+hashbrown@0.17.1
+http@1.5.0
+httparse@1.10.1
+httpdate@1.0.3
+hyper-rustls@0.27.9
+iana-time-zone@0.1.65
+idna@1.1.0
+idna_adapter@1.2.1
+indexmap@2.14.0
+ipnet@2.12.1
+is_terminal_polyfill@1.70.2
+itoa@1.0.18
+lexical-core@1.0.6
+lexical-parse-float@1.0.6
+lexical-parse-integer@1.0.6
+lexical-util@1.0.7
+lexical-write-float@1.0.6
+lexical-write-integer@1.0.6
+libc@0.2.189
+linked-hash-map@0.5.6
+linux-raw-sys@0.12.1
+lock_api@0.4.14
+log@0.4.33
+lru-slab@0.1.2
+md-5@0.10.6
+mime@0.3.17
+num-bigint@0.4.8
+num-bigint@0.5.1
+num-complex@0.4.6
+num-integer@0.1.47
+num-traits@0.2.19
+once_cell@1.21.4
+opendal@0.55.0
+parking_lot@0.12.5
+parking_lot_core@0.9.12
+parse-display@0.10.0
+percent-encoding@2.3.2
+pin-project-lite@0.2.17
+ppv-lite86@0.2.21
+prost@0.14.4
+quinn@0.11.11
+quinn-proto@0.11.17
+quinn-udp@0.5.15
+rand@0.10.2
+rand@0.8.7
+rand@0.9.5
+rand_chacha@0.9.0
+rand_core@0.10.1
+rand_core@0.6.4
+rand_core@0.9.5
+rand_pcg@0.10.2
+rand_xoshiro@0.7.0
+rapidhash@4.5.1
+regex@1.13.1
+regex-automata@0.4.18
+regex-syntax@0.8.11
+reqwest@0.12.28
+ring@0.17.14
+rustc-hash@2.1.3
+rustix@1.1.4
+rustls@0.23.43
+rustls-pki-types@1.15.1
+ryu@1.0.23
+scopeguard@1.2.0
+serde@1.0.229
+serde_core@1.0.229
+serde_fmt@1.1.0
+serde_json@1.0.151
+serde_path_to_error@0.1.20
+serde_urlencoded@0.7.1
+signal-hook-registry@1.4.8
+simdutf8@0.1.5
+sketches-ddsketch@0.3.1
+smallvec@1.15.2
+snafu@0.8.9
+socket2@0.6.5
+stable_deref_trait@1.2.1
+sval@2.21.1
+sval_buffer@2.21.1
+sval_dynamic@2.21.1
+sval_fmt@2.21.1
+sval_json@2.21.1
+sval_nested@2.21.1
+sval_ref@2.21.1
+sval_serde@2.21.1
+sync_wrapper@1.0.2
+tempfile@3.27.0
+thiserror@1.0.69
+thiserror@2.0.20
+tinyvec@1.12.0
+tinyvec_macros@0.1.1
+tokio-rustls@0.26.4
+typeid@1.0.3
+typenum@1.20.1
+url@2.5.8
+utf8_iter@1.0.4
+utf8parse@0.2.2
+utoipa@5.5.0
+utoipa-axum@0.2.0
+uuid@1.24.0
+value-bag@1.13.2
+value-bag-serde1@1.13.2
+value-bag-sval2@1.13.2
+zerocopy@0.8.56
+zeroize@1.9.0
+zstd-safe@7.2.4
+zstd-sys@2.0.16+zstd.1.5.7
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate aho-corasick@1.1.5.
+Project URL: https://github.com/BurntSushi/aho-corasick
+Declared license: Unlicense OR MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate byteorder@1.5.0.
+Project URL: https://github.com/BurntSushi/byteorder
+Declared license: Unlicense OR MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate csv@1.4.0.
+Project URL: https://github.com/BurntSushi/rust-csv
+Declared license: Unlicense/MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate csv-core@0.1.13.
+Project URL: https://github.com/BurntSushi/rust-csv
+Declared license: Unlicense/MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate jiff@0.2.35.
+Project URL: https://github.com/BurntSushi/jiff
+Declared license: Unlicense OR MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate jiff-core@0.1.0.
+Project URL: https://github.com/BurntSushi/jiff/tree/master/crates/jiff-core
+Declared license: Unlicense OR MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate memchr@2.8.3.
+Project URL: https://github.com/BurntSushi/memchr
+Declared license: Unlicense OR MIT
+Selected license obligations: MIT
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE-MIT
+| The MIT License (MIT)
+|
+| Copyright (c) 2015 Andrew Gallant
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate arrow-array@59.2.0.
+Project URL: https://github.com/apache/arrow-rs
+Declared license: Apache-2.0 AND MIT
+Selected license obligations: Apache-2.0 AND MIT
+
+License file: LICENSE-MIT
+| MIT License
+|
+| Copyright (c) 2020-2022 Oliver Margetts
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate atoi@2.0.0.
+Project URL: https://github.com/pacman82/atoi-rs
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| MIT License
+|
+| Copyright (c) 2017
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate axum@0.8.9.
+Project URL: https://github.com/tokio-rs/axum
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2019 axum Contributors
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate axum-core@0.5.6.
+Project URL: https://github.com/tokio-rs/axum
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| MIT License
+|
+| Copyright (c) 2019–2025 axum Contributors
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate bitvec@1.1.1.
+Project URL: https://bitvecto-rs.github.io/bitvec
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate wyz@0.5.1.
+Project URL: https://myrrlyn.net/crates/wyz
+Declared license: MIT
+Selected license obligations: MIT
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE.txt
+| MIT License
+|
+| Copyright (c) 2018 myrrlyn (Alexander Payne)
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate bytes@1.12.1.
+Project URL: https://github.com/tokio-rs/bytes
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2018 Carl Lerche
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate dashmap@6.2.1.
+Project URL: https://github.com/xacrimon/dashmap
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| MIT License
+|
+| Copyright (c) 2019 Acrimon
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate foldhash@0.2.0.
+Project URL: https://github.com/orlp/foldhash
+Declared license: Zlib
+Selected license obligations: Zlib
+
+License file: LICENSE
+| Copyright (c) 2024 Orson Peters
+|
+| This software is provided 'as-is', without any express or implied warranty. In
+| no event will the authors be held liable for any damages arising from the use of
+| this software.
+|
+| Permission is granted to anyone to use this software for any purpose, including
+| commercial applications, and to alter it and redistribute it freely, subject to
+| the following restrictions:
+|
+| 1. The origin of this software must not be misrepresented; you must not claim
+| that you wrote the original software. If you use this software in a product,
+| an acknowledgment in the product documentation would be appreciated but is
+| not required.
+|
+| 2. Altered source versions must be plainly marked as such, and must not be
+| misrepresented as being the original software.
+|
+| 3. This notice may not be removed or altered from any source distribution.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate funty@2.0.0.
+Project URL: https://github.com/myrrlyn/funty
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE.txt
+| MIT License
+|
+| Copyright (c) 2020 myrrlyn (Alexander Payne)
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate generic-array@0.14.7.
+Project URL: https://github.com/fizyk20/generic-array.git
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| The MIT License (MIT)
+|
+| Copyright (c) 2015 Bartłomiej Kamiński
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate http-body@1.1.0.
+Project URL: https://github.com/hyperium/http-body
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate http-body-util@0.1.5.
+Project URL: https://github.com/hyperium/http-body
+Declared license: MIT
+Selected license obligations: MIT
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE
+| Copyright (c) 2019-2026 Sean McArthur & Hyper Contributors
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate hyper@1.11.0.
+Project URL: https://hyper.rs
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2014-2026 Sean McArthur
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate hyper-util@0.1.20.
+Project URL: https://hyper.rs
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2023-2025 Sean McArthur
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate icu_collections@2.1.1.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate icu_locale_core@2.1.1.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate icu_normalizer@2.1.1.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate icu_normalizer_data@2.1.1.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate icu_properties@2.1.2.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate icu_properties_data@2.1.2.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate icu_provider@2.1.1.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate litemap@0.8.2.
+Project URL: https://github.com/unicode-org/icu4x
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate potential_utf@0.1.5.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate tinystr@0.8.3.
+Project URL: https://github.com/unicode-org/icu4x
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate writeable@0.6.3.
+Project URL: https://github.com/unicode-org/icu4x
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate yoke@0.8.3.
+Project URL: https://github.com/unicode-org/icu4x
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate zerofrom@0.1.8.
+Project URL: https://github.com/unicode-org/icu4x
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate zerotrie@0.2.4.
+Project URL: https://icu4x.unicode.org
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+The supported Linux Gateway binaries use the Rust crate zerovec@0.11.6.
+Project URL: https://github.com/unicode-org/icu4x
+Declared license: Unicode-3.0
+Selected license obligations: Unicode-3.0
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE
+| UNICODE LICENSE V3
+|
+| COPYRIGHT AND PERMISSION NOTICE
+|
+| Copyright © 2020-2024 Unicode, Inc.
+|
+| NOTICE TO USER: Carefully read the following legal agreement. BY
+| DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
+| SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+| TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
+| DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+|
+| Permission is hereby granted, free of charge, to any person obtaining a
+| copy of data files and any associated documentation (the "Data Files") or
+| software and any associated documentation (the "Software") to deal in the
+| Data Files or Software without restriction, including without limitation
+| the rights to use, copy, modify, merge, publish, distribute, and/or sell
+| copies of the Data Files or Software, and to permit persons to whom the
+| Data Files or Software are furnished to do so, provided that either (a)
+| this copyright and permission notice appear with all copies of the Data
+| Files or Software, or (b) this copyright and permission notice appear in
+| associated Documentation.
+|
+| THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+| KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+| THIRD PARTY RIGHTS.
+|
+| IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
+| BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
+| OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+| WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+| ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
+| FILES OR SOFTWARE.
+|
+| Except as contained in this notice, the name of a copyright holder shall
+| not be used in advertising or otherwise to promote the sale, use or other
+| dealings in these Data Files or Software without prior written
+| authorization of the copyright holder.
+|
+| SPDX-License-Identifier: Unicode-3.0
+|
+| —
+|
+| Portions of ICU4X may have been adapted from ICU4C and/or ICU4J.
+| ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate libm@0.2.16.
+Project URL: https://github.com/rust-lang/compiler-builtins
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE.txt
+| rust-lang/libm as a whole is available for use under the MIT license:
+|
+| ------------------------------------------------------------------------------
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+| ------------------------------------------------------------------------------
+|
+| As a contributor, you agree that your code can be used under either the MIT
+| license or the Apache-2.0 license:
+|
+| ------------------------------------------------------------------------------
+| Apache License
+| Version 2.0, January 2004
+| http://www.apache.org/licenses/
+|
+| TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+|
+| 1. Definitions.
+|
+| "License" shall mean the terms and conditions for use, reproduction,
+| and distribution as defined by Sections 1 through 9 of this document.
+|
+| "Licensor" shall mean the copyright owner or entity authorized by
+| the copyright owner that is granting the License.
+|
+| "Legal Entity" shall mean the union of the acting entity and all
+| other entities that control, are controlled by, or are under common
+| control with that entity. For the purposes of this definition,
+| "control" means (i) the power, direct or indirect, to cause the
+| direction or management of such entity, whether by contract or
+| otherwise, or (ii) ownership of fifty percent (50%) or more of the
+| outstanding shares, or (iii) beneficial ownership of such entity.
+|
+| "You" (or "Your") shall mean an individual or Legal Entity
+| exercising permissions granted by this License.
+|
+| "Source" form shall mean the preferred form for making modifications,
+| including but not limited to software source code, documentation
+| source, and configuration files.
+|
+| "Object" form shall mean any form resulting from mechanical
+| transformation or translation of a Source form, including but
+| not limited to compiled object code, generated documentation,
+| and conversions to other media types.
+|
+| "Work" shall mean the work of authorship, whether in Source or
+| Object form, made available under the License, as indicated by a
+| copyright notice that is included in or attached to the work
+| (an example is provided in the Appendix below).
+|
+| "Derivative Works" shall mean any work, whether in Source or Object
+| form, that is based on (or derived from) the Work and for which the
+| editorial revisions, annotations, elaborations, or other modifications
+| represent, as a whole, an original work of authorship. For the purposes
+| of this License, Derivative Works shall not include works that remain
+| separable from, or merely link (or bind by name) to the interfaces of,
+| the Work and Derivative Works thereof.
+|
+| "Contribution" shall mean any work of authorship, including
+| the original version of the Work and any modifications or additions
+| to that Work or Derivative Works thereof, that is intentionally
+| submitted to Licensor for inclusion in the Work by the copyright owner
+| or by an individual or Legal Entity authorized to submit on behalf of
+| the copyright owner. For the purposes of this definition, "submitted"
+| means any form of electronic, verbal, or written communication sent
+| to the Licensor or its representatives, including but not limited to
+| communication on electronic mailing lists, source code control systems,
+| and issue tracking systems that are managed by, or on behalf of, the
+| Licensor for the purpose of discussing and improving the Work, but
+| excluding communication that is conspicuously marked or otherwise
+| designated in writing by the copyright owner as "Not a Contribution."
+|
+| "Contributor" shall mean Licensor and any individual or Legal Entity
+| on behalf of whom a Contribution has been received by Licensor and
+| subsequently incorporated within the Work.
+|
+| 2. Grant of Copyright License. Subject to the terms and conditions of
+| this License, each Contributor hereby grants to You a perpetual,
+| worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+| copyright license to reproduce, prepare Derivative Works of,
+| publicly display, publicly perform, sublicense, and distribute the
+| Work and such Derivative Works in Source or Object form.
+|
+| 3. Grant of Patent License. Subject to the terms and conditions of
+| this License, each Contributor hereby grants to You a perpetual,
+| worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+| (except as stated in this section) patent license to make, have made,
+| use, offer to sell, sell, import, and otherwise transfer the Work,
+| where such license applies only to those patent claims licensable
+| by such Contributor that are necessarily infringed by their
+| Contribution(s) alone or by combination of their Contribution(s)
+| with the Work to which such Contribution(s) was submitted. If You
+| institute patent litigation against any entity (including a
+| cross-claim or counterclaim in a lawsuit) alleging that the Work
+| or a Contribution incorporated within the Work constitutes direct
+| or contributory patent infringement, then any patent licenses
+| granted to You under this License for that Work shall terminate
+| as of the date such litigation is filed.
+|
+| 4. Redistribution. You may reproduce and distribute copies of the
+| Work or Derivative Works thereof in any medium, with or without
+| modifications, and in Source or Object form, provided that You
+| meet the following conditions:
+|
+| (a) You must give any other recipients of the Work or
+| Derivative Works a copy of this License; and
+|
+| (b) You must cause any modified files to carry prominent notices
+| stating that You changed the files; and
+|
+| (c) You must retain, in the Source form of any Derivative Works
+| that You distribute, all copyright, patent, trademark, and
+| attribution notices from the Source form of the Work,
+| excluding those notices that do not pertain to any part of
+| the Derivative Works; and
+|
+| (d) If the Work includes a "NOTICE" text file as part of its
+| distribution, then any Derivative Works that You distribute must
+| include a readable copy of the attribution notices contained
+| within such NOTICE file, excluding those notices that do not
+| pertain to any part of the Derivative Works, in at least one
+| of the following places: within a NOTICE text file distributed
+| as part of the Derivative Works; within the Source form or
+| documentation, if provided along with the Derivative Works; or,
+| within a display generated by the Derivative Works, if and
+| wherever such third-party notices normally appear. The contents
+| of the NOTICE file are for informational purposes only and
+| do not modify the License. You may add Your own attribution
+| notices within Derivative Works that You distribute, alongside
+| or as an addendum to the NOTICE text from the Work, provided
+| that such additional attribution notices cannot be construed
+| as modifying the License.
+|
+| You may add Your own copyright statement to Your modifications and
+| may provide additional or different license terms and conditions
+| for use, reproduction, or distribution of Your modifications, or
+| for any such Derivative Works as a whole, provided Your use,
+| reproduction, and distribution of the Work otherwise complies with
+| the conditions stated in this License.
+|
+| 5. Submission of Contributions. Unless You explicitly state otherwise,
+| any Contribution intentionally submitted for inclusion in the Work
+| by You to the Licensor shall be under the terms and conditions of
+| this License, without any additional terms or conditions.
+| Notwithstanding the above, nothing herein shall supersede or modify
+| the terms of any separate license agreement you may have executed
+| with Licensor regarding such Contributions.
+|
+| 6. Trademarks. This License does not grant permission to use the trade
+| names, trademarks, service marks, or product names of the Licensor,
+| except as required for reasonable and customary use in describing the
+| origin of the Work and reproducing the content of the NOTICE file.
+|
+| 7. Disclaimer of Warranty. Unless required by applicable law or
+| agreed to in writing, Licensor provides the Work (and each
+| Contributor provides its Contributions) on an "AS IS" BASIS,
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+| implied, including, without limitation, any warranties or conditions
+| of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+| PARTICULAR PURPOSE. You are solely responsible for determining the
+| appropriateness of using or redistributing the Work and assume any
+| risks associated with Your exercise of permissions under this License.
+|
+| 8. Limitation of Liability. In no event and under no legal theory,
+| whether in tort (including negligence), contract, or otherwise,
+| unless required by applicable law (such as deliberate and grossly
+| negligent acts) or agreed to in writing, shall any Contributor be
+| liable to You for damages, including any direct, indirect, special,
+| incidental, or consequential damages of any character arising as a
+| result of this License or out of the use or inability to use the
+| Work (including but not limited to damages for loss of goodwill,
+| work stoppage, computer failure or malfunction, or any and all
+| other commercial damages or losses), even if such Contributor
+| has been advised of the possibility of such damages.
+|
+| 9. Accepting Warranty or Additional Liability. While redistributing
+| the Work or Derivative Works thereof, You may choose to offer,
+| and charge a fee for, acceptance of support, warranty, indemnity,
+| or other liability obligations and/or rights consistent with this
+| License. However, in accepting such obligations, You may act only
+| on Your own behalf and on Your sole responsibility, not on behalf
+| of any other Contributor, and only if You agree to indemnify,
+| defend, and hold each Contributor harmless for any liability
+| incurred by, or claims asserted against, such Contributor by reason
+| of your accepting any such warranty or additional liability.
+|
+| END OF TERMS AND CONDITIONS
+|
+| APPENDIX: How to apply the Apache License to your work.
+|
+| To apply the Apache License to your work, attach the following
+| boilerplate notice, with the fields enclosed by brackets "[]"
+| replaced with your own identifying information. (Don't include
+| the brackets!) The text should be enclosed in the appropriate
+| comment syntax for the file format. We also recommend that a
+| file or class name and description of purpose be included on the
+| same "printed page" as the copyright notice for easier
+| identification within third-party archives.
+|
+| Licensed under the Apache License, Version 2.0 (the "License");
+| you may not use this file except in compliance with the License.
+| You may obtain a copy of the License at
+|
+| http://www.apache.org/licenses/LICENSE-2.0
+|
+| Unless required by applicable law or agreed to in writing, software
+| distributed under the License is distributed on an "AS IS" BASIS,
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+| See the License for the specific language governing permissions and
+| limitations under the License.
+| ------------------------------------------------------------------------------
+|
+| This Rust library contains the following copyrights:
+|
+| Copyright (c) 2018 Jorge Aparicio
+|
+| Portions of this software are derived from third-party works licensed under
+| terms compatible with the above MIT license:
+|
+| * musl libc https://www.musl-libc.org/. This library contains the following
+| copyright:
+|
+| Copyright © 2005-2020 Rich Felker, et al.
+|
+| * The CORE-MATH project https://core-math.gitlabpages.inria.fr/. CORE-MATH
+| routines are available under the MIT license on a per-file basis.
+|
+| The musl libc COPYRIGHT file also includes the following notice relevant to
+| math portions of the library:
+|
+| ------------------------------------------------------------------------------
+| Much of the math library code (src/math/* and src/complex/*) is
+| Copyright © 1993,2004 Sun Microsystems or
+| Copyright © 2003-2011 David Schultz or
+| Copyright © 2003-2009 Steven G. Kargl or
+| Copyright © 2003-2009 Bruce D. Evans or
+| Copyright © 2008 Stephen L. Moshier or
+| Copyright © 2017-2018 Arm Limited
+| and labelled as such in comments in the individual source files. All
+| have been licensed under extremely permissive terms.
+| ------------------------------------------------------------------------------
+|
+| Copyright notices are retained in src/* files where relevant.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate lz4_flex@0.14.0.
+Project URL: https://github.com/pseitz/lz4_flex
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| The MIT License (MIT)
+|
+| Copyright (c) 2020 Pascal Seitz
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy of
+| this software and associated documentation files (the "Software"), to deal in
+| the Software without restriction, including without limitation the rights to
+| use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software is furnished to do so,
+| subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+| FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+| COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+| IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+| CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate matchit@0.8.4.
+Project URL: https://github.com/ibraheemdev/matchit
+Declared license: MIT AND BSD-3-Clause
+Selected license obligations: MIT AND BSD-3-Clause
+
+License file: LICENSE
+| MIT License
+|
+| Copyright (c) 2022 Ibraheem Ahmed
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+
+License file: LICENSE.httprouter
+| BSD 3-Clause License
+|
+| Copyright (c) 2013, Julien Schmidt
+| All rights reserved.
+|
+| Redistribution and use in source and binary forms, with or without
+| modification, are permitted provided that the following conditions are met:
+|
+| 1. Redistributions of source code must retain the above copyright notice, this
+| list of conditions and the following disclaimer.
+|
+| 2. Redistributions in binary form must reproduce the above copyright notice,
+| this list of conditions and the following disclaimer in the documentation
+| and/or other materials provided with the distribution.
+|
+| 3. Neither the name of the copyright holder nor the names of its
+| contributors may be used to endorse or promote products derived from
+| this software without specific prior written permission.
+|
+| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate metrics@0.24.6.
+Project URL: https://github.com/metrics-rs/metrics
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate metrics-exporter-prometheus@0.17.2.
+Project URL: https://github.com/metrics-rs/metrics
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate metrics-util@0.20.4.
+Project URL: https://github.com/metrics-rs/metrics
+Declared license: MIT
+Selected license obligations: MIT
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE
+| Copyright (c) 2021 Metrics Contributors
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate mio@1.2.2.
+Project URL: https://github.com/tokio-rs/mio
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2014 Carl Lerche and other MIO contributors
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate ordered-float@5.3.0.
+Project URL: https://github.com/reem/rust-ordered-float
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE-MIT
+| Copyright (c) 2015 Jonathan Reem
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate quanta@0.12.6.
+Project URL: https://github.com/metrics-rs/quanta
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| // Copyright (c) 2019 Nuclear Furnace
+| //
+| // Permission is hereby granted, free of charge, to any person obtaining a copy
+| // of this software and associated documentation files (the "Software"), to deal
+| // in the Software without restriction, including without limitation the rights
+| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| // copies of the Software, and to permit persons to whom the Software is
+| // furnished to do so, subject to the following conditions:
+| //
+| // The above copyright notice and this permission notice shall be included in all
+| // copies or substantial portions of the Software.
+| //
+| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| // SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate quick-xml@0.38.4.
+Project URL: https://github.com/tafia/quick-xml
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE-MIT.md
+| The MIT License (MIT)
+|
+| Copyright (c) 2016 Johann Tuffe
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate radium@0.7.0.
+Project URL: https://github.com/bitvecto-rs/radium
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE.txt
+| MIT License
+|
+| Copyright (c) 2019 kneecaw (Nika Layzell)
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate raw-cpuid@11.6.0.
+Project URL: https://github.com/gz/rust-cpuid
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE.md
+| The MIT License (MIT)
+|
+| Copyright (c) 2015 Gerd Zellweger
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate ring@0.17.14.
+Project URL: https://github.com/briansmith/ring
+Declared license: Apache-2.0 AND ISC
+Selected license obligations: Apache-2.0 AND ISC
+
+License file: LICENSE
+| *ring* uses an "ISC" license, like BoringSSL used to use, for new code
+| files. See LICENSE-other-bits for the text of that license.
+|
+| See LICENSE-BoringSSL for code that was sourced from BoringSSL under the
+| Apache 2.0 license. Some code that was sourced from BoringSSL under the ISC
+| license. In each case, the license info is at the top of the file.
+|
+| See src/polyfill/once_cell/LICENSE-APACHE and src/polyfill/once_cell/LICENSE-MIT
+| for the license to code that was sourced from the once_cell project.
+
+License file: LICENSE-BoringSSL
+|
+| Apache License
+| Version 2.0, January 2004
+| http://www.apache.org/licenses/
+|
+| TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+|
+| 1. Definitions.
+|
+| "License" shall mean the terms and conditions for use, reproduction,
+| and distribution as defined by Sections 1 through 9 of this document.
+|
+| "Licensor" shall mean the copyright owner or entity authorized by
+| the copyright owner that is granting the License.
+|
+| "Legal Entity" shall mean the union of the acting entity and all
+| other entities that control, are controlled by, or are under common
+| control with that entity. For the purposes of this definition,
+| "control" means (i) the power, direct or indirect, to cause the
+| direction or management of such entity, whether by contract or
+| otherwise, or (ii) ownership of fifty percent (50%) or more of the
+| outstanding shares, or (iii) beneficial ownership of such entity.
+|
+| "You" (or "Your") shall mean an individual or Legal Entity
+| exercising permissions granted by this License.
+|
+| "Source" form shall mean the preferred form for making modifications,
+| including but not limited to software source code, documentation
+| source, and configuration files.
+|
+| "Object" form shall mean any form resulting from mechanical
+| transformation or translation of a Source form, including but
+| not limited to compiled object code, generated documentation,
+| and conversions to other media types.
+|
+| "Work" shall mean the work of authorship, whether in Source or
+| Object form, made available under the License, as indicated by a
+| copyright notice that is included in or attached to the work
+| (an example is provided in the Appendix below).
+|
+| "Derivative Works" shall mean any work, whether in Source or Object
+| form, that is based on (or derived from) the Work and for which the
+| editorial revisions, annotations, elaborations, or other modifications
+| represent, as a whole, an original work of authorship. For the purposes
+| of this License, Derivative Works shall not include works that remain
+| separable from, or merely link (or bind by name) to the interfaces of,
+| the Work and Derivative Works thereof.
+|
+| "Contribution" shall mean any work of authorship, including
+| the original version of the Work and any modifications or additions
+| to that Work or Derivative Works thereof, that is intentionally
+| submitted to Licensor for inclusion in the Work by the copyright owner
+| or by an individual or Legal Entity authorized to submit on behalf of
+| the copyright owner. For the purposes of this definition, "submitted"
+| means any form of electronic, verbal, or written communication sent
+| to the Licensor or its representatives, including but not limited to
+| communication on electronic mailing lists, source code control systems,
+| and issue tracking systems that are managed by, or on behalf of, the
+| Licensor for the purpose of discussing and improving the Work, but
+| excluding communication that is conspicuously marked or otherwise
+| designated in writing by the copyright owner as "Not a Contribution."
+|
+| "Contributor" shall mean Licensor and any individual or Legal Entity
+| on behalf of whom a Contribution has been received by Licensor and
+| subsequently incorporated within the Work.
+|
+| 2. Grant of Copyright License. Subject to the terms and conditions of
+| this License, each Contributor hereby grants to You a perpetual,
+| worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+| copyright license to reproduce, prepare Derivative Works of,
+| publicly display, publicly perform, sublicense, and distribute the
+| Work and such Derivative Works in Source or Object form.
+|
+| 3. Grant of Patent License. Subject to the terms and conditions of
+| this License, each Contributor hereby grants to You a perpetual,
+| worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+| (except as stated in this section) patent license to make, have made,
+| use, offer to sell, sell, import, and otherwise transfer the Work,
+| where such license applies only to those patent claims licensable
+| by such Contributor that are necessarily infringed by their
+| Contribution(s) alone or by combination of their Contribution(s)
+| with the Work to which such Contribution(s) was submitted. If You
+| institute patent litigation against any entity (including a
+| cross-claim or counterclaim in a lawsuit) alleging that the Work
+| or a Contribution incorporated within the Work constitutes direct
+| or contributory patent infringement, then any patent licenses
+| granted to You under this License for that Work shall terminate
+| as of the date such litigation is filed.
+|
+| 4. Redistribution. You may reproduce and distribute copies of the
+| Work or Derivative Works thereof in any medium, with or without
+| modifications, and in Source or Object form, provided that You
+| meet the following conditions:
+|
+| (a) You must give any other recipients of the Work or
+| Derivative Works a copy of this License; and
+|
+| (b) You must cause any modified files to carry prominent notices
+| stating that You changed the files; and
+|
+| (c) You must retain, in the Source form of any Derivative Works
+| that You distribute, all copyright, patent, trademark, and
+| attribution notices from the Source form of the Work,
+| excluding those notices that do not pertain to any part of
+| the Derivative Works; and
+|
+| (d) If the Work includes a "NOTICE" text file as part of its
+| distribution, then any Derivative Works that You distribute must
+| include a readable copy of the attribution notices contained
+| within such NOTICE file, excluding those notices that do not
+| pertain to any part of the Derivative Works, in at least one
+| of the following places: within a NOTICE text file distributed
+| as part of the Derivative Works; within the Source form or
+| documentation, if provided along with the Derivative Works; or,
+| within a display generated by the Derivative Works, if and
+| wherever such third-party notices normally appear. The contents
+| of the NOTICE file are for informational purposes only and
+| do not modify the License. You may add Your own attribution
+| notices within Derivative Works that You distribute, alongside
+| or as an addendum to the NOTICE text from the Work, provided
+| that such additional attribution notices cannot be construed
+| as modifying the License.
+|
+| You may add Your own copyright statement to Your modifications and
+| may provide additional or different license terms and conditions
+| for use, reproduction, or distribution of Your modifications, or
+| for any such Derivative Works as a whole, provided Your use,
+| reproduction, and distribution of the Work otherwise complies with
+| the conditions stated in this License.
+|
+| 5. Submission of Contributions. Unless You explicitly state otherwise,
+| any Contribution intentionally submitted for inclusion in the Work
+| by You to the Licensor shall be under the terms and conditions of
+| this License, without any additional terms or conditions.
+| Notwithstanding the above, nothing herein shall supersede or modify
+| the terms of any separate license agreement you may have executed
+| with Licensor regarding such Contributions.
+|
+| 6. Trademarks. This License does not grant permission to use the trade
+| names, trademarks, service marks, or product names of the Licensor,
+| except as required for reasonable and customary use in describing the
+| origin of the Work and reproducing the content of the NOTICE file.
+|
+| 7. Disclaimer of Warranty. Unless required by applicable law or
+| agreed to in writing, Licensor provides the Work (and each
+| Contributor provides its Contributions) on an "AS IS" BASIS,
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+| implied, including, without limitation, any warranties or conditions
+| of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+| PARTICULAR PURPOSE. You are solely responsible for determining the
+| appropriateness of using or redistributing the Work and assume any
+| risks associated with Your exercise of permissions under this License.
+|
+| 8. Limitation of Liability. In no event and under no legal theory,
+| whether in tort (including negligence), contract, or otherwise,
+| unless required by applicable law (such as deliberate and grossly
+| negligent acts) or agreed to in writing, shall any Contributor be
+| liable to You for damages, including any direct, indirect, special,
+| incidental, or consequential damages of any character arising as a
+| result of this License or out of the use or inability to use the
+| Work (including but not limited to damages for loss of goodwill,
+| work stoppage, computer failure or malfunction, or any and all
+| other commercial damages or losses), even if such Contributor
+| has been advised of the possibility of such damages.
+|
+| 9. Accepting Warranty or Additional Liability. While redistributing
+| the Work or Derivative Works thereof, You may choose to offer,
+| and charge a fee for, acceptance of support, warranty, indemnity,
+| or other liability obligations and/or rights consistent with this
+| License. However, in accepting such obligations, You may act only
+| on Your own behalf and on Your sole responsibility, not on behalf
+| of any other Contributor, and only if You agree to indemnify,
+| defend, and hold each Contributor harmless for any liability
+| incurred by, or claims asserted against, such Contributor by reason
+| of your accepting any such warranty or additional liability.
+|
+| END OF TERMS AND CONDITIONS
+|
+| APPENDIX: How to apply the Apache License to your work.
+|
+| To apply the Apache License to your work, attach the following
+| boilerplate notice, with the fields enclosed by brackets "[]"
+| replaced with your own identifying information. (Don't include
+| the brackets!) The text should be enclosed in the appropriate
+| comment syntax for the file format. We also recommend that a
+| file or class name and description of purpose be included on the
+| same "printed page" as the copyright notice for easier
+| identification within third-party archives.
+|
+| Copyright [yyyy] [name of copyright owner]
+|
+| Licensed under the Apache License, Version 2.0 (the "License");
+| you may not use this file except in compliance with the License.
+| You may obtain a copy of the License at
+|
+| http://www.apache.org/licenses/LICENSE-2.0
+|
+| Unless required by applicable law or agreed to in writing, software
+| distributed under the License is distributed on an "AS IS" BASIS,
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+| See the License for the specific language governing permissions and
+| limitations under the License.
+|
+|
+| Licenses for support code
+| -------------------------
+|
+| Parts of the TLS test suite are under the Go license. This code is not included
+| in BoringSSL (i.e. libcrypto and libssl) when compiled, however, so
+| distributing code linked against BoringSSL does not trigger this license:
+|
+| Copyright (c) 2009 The Go Authors. All rights reserved.
+|
+| Redistribution and use in source and binary forms, with or without
+| modification, are permitted provided that the following conditions are
+| met:
+|
+| * Redistributions of source code must retain the above copyright
+| notice, this list of conditions and the following disclaimer.
+| * Redistributions in binary form must reproduce the above
+| copyright notice, this list of conditions and the following disclaimer
+| in the documentation and/or other materials provided with the
+| distribution.
+| * Neither the name of Google Inc. nor the names of its
+| contributors may be used to endorse or promote products derived from
+| this software without specific prior written permission.
+|
+| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+|
+|
+| BoringSSL uses the Chromium test infrastructure to run a continuous build,
+| trybots etc. The scripts which manage this, and the script for generating build
+| metadata, are under the Chromium license. Distributing code linked against
+| BoringSSL does not trigger this license.
+|
+| Copyright 2015 The Chromium Authors. All rights reserved.
+|
+| Redistribution and use in source and binary forms, with or without
+| modification, are permitted provided that the following conditions are
+| met:
+|
+| * Redistributions of source code must retain the above copyright
+| notice, this list of conditions and the following disclaimer.
+| * Redistributions in binary form must reproduce the above
+| copyright notice, this list of conditions and the following disclaimer
+| in the documentation and/or other materials provided with the
+| distribution.
+| * Neither the name of Google Inc. nor the names of its
+| contributors may be used to endorse or promote products derived from
+| this software without specific prior written permission.
+|
+| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License file: LICENSE-other-bits
+| Copyright 2015-2025 Brian Smith.
+|
+| Permission to use, copy, modify, and/or distribute this software for any
+| purpose with or without fee is hereby granted, provided that the above
+| copyright notice and this permission notice appear in all copies.
+|
+| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+| SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+| OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+| CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+License file: src/polyfill/once_cell/LICENSE-APACHE
+| Apache License
+| Version 2.0, January 2004
+| http://www.apache.org/licenses/
+|
+| TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+|
+| 1. Definitions.
+|
+| "License" shall mean the terms and conditions for use, reproduction,
+| and distribution as defined by Sections 1 through 9 of this document.
+|
+| "Licensor" shall mean the copyright owner or entity authorized by
+| the copyright owner that is granting the License.
+|
+| "Legal Entity" shall mean the union of the acting entity and all
+| other entities that control, are controlled by, or are under common
+| control with that entity. For the purposes of this definition,
+| "control" means (i) the power, direct or indirect, to cause the
+| direction or management of such entity, whether by contract or
+| otherwise, or (ii) ownership of fifty percent (50%) or more of the
+| outstanding shares, or (iii) beneficial ownership of such entity.
+|
+| "You" (or "Your") shall mean an individual or Legal Entity
+| exercising permissions granted by this License.
+|
+| "Source" form shall mean the preferred form for making modifications,
+| including but not limited to software source code, documentation
+| source, and configuration files.
+|
+| "Object" form shall mean any form resulting from mechanical
+| transformation or translation of a Source form, including but
+| not limited to compiled object code, generated documentation,
+| and conversions to other media types.
+|
+| "Work" shall mean the work of authorship, whether in Source or
+| Object form, made available under the License, as indicated by a
+| copyright notice that is included in or attached to the work
+| (an example is provided in the Appendix below).
+|
+| "Derivative Works" shall mean any work, whether in Source or Object
+| form, that is based on (or derived from) the Work and for which the
+| editorial revisions, annotations, elaborations, or other modifications
+| represent, as a whole, an original work of authorship. For the purposes
+| of this License, Derivative Works shall not include works that remain
+| separable from, or merely link (or bind by name) to the interfaces of,
+| the Work and Derivative Works thereof.
+|
+| "Contribution" shall mean any work of authorship, including
+| the original version of the Work and any modifications or additions
+| to that Work or Derivative Works thereof, that is intentionally
+| submitted to Licensor for inclusion in the Work by the copyright owner
+| or by an individual or Legal Entity authorized to submit on behalf of
+| the copyright owner. For the purposes of this definition, "submitted"
+| means any form of electronic, verbal, or written communication sent
+| to the Licensor or its representatives, including but not limited to
+| communication on electronic mailing lists, source code control systems,
+| and issue tracking systems that are managed by, or on behalf of, the
+| Licensor for the purpose of discussing and improving the Work, but
+| excluding communication that is conspicuously marked or otherwise
+| designated in writing by the copyright owner as "Not a Contribution."
+|
+| "Contributor" shall mean Licensor and any individual or Legal Entity
+| on behalf of whom a Contribution has been received by Licensor and
+| subsequently incorporated within the Work.
+|
+| 2. Grant of Copyright License. Subject to the terms and conditions of
+| this License, each Contributor hereby grants to You a perpetual,
+| worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+| copyright license to reproduce, prepare Derivative Works of,
+| publicly display, publicly perform, sublicense, and distribute the
+| Work and such Derivative Works in Source or Object form.
+|
+| 3. Grant of Patent License. Subject to the terms and conditions of
+| this License, each Contributor hereby grants to You a perpetual,
+| worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+| (except as stated in this section) patent license to make, have made,
+| use, offer to sell, sell, import, and otherwise transfer the Work,
+| where such license applies only to those patent claims licensable
+| by such Contributor that are necessarily infringed by their
+| Contribution(s) alone or by combination of their Contribution(s)
+| with the Work to which such Contribution(s) was submitted. If You
+| institute patent litigation against any entity (including a
+| cross-claim or counterclaim in a lawsuit) alleging that the Work
+| or a Contribution incorporated within the Work constitutes direct
+| or contributory patent infringement, then any patent licenses
+| granted to You under this License for that Work shall terminate
+| as of the date such litigation is filed.
+|
+| 4. Redistribution. You may reproduce and distribute copies of the
+| Work or Derivative Works thereof in any medium, with or without
+| modifications, and in Source or Object form, provided that You
+| meet the following conditions:
+|
+| (a) You must give any other recipients of the Work or
+| Derivative Works a copy of this License; and
+|
+| (b) You must cause any modified files to carry prominent notices
+| stating that You changed the files; and
+|
+| (c) You must retain, in the Source form of any Derivative Works
+| that You distribute, all copyright, patent, trademark, and
+| attribution notices from the Source form of the Work,
+| excluding those notices that do not pertain to any part of
+| the Derivative Works; and
+|
+| (d) If the Work includes a "NOTICE" text file as part of its
+| distribution, then any Derivative Works that You distribute must
+| include a readable copy of the attribution notices contained
+| within such NOTICE file, excluding those notices that do not
+| pertain to any part of the Derivative Works, in at least one
+| of the following places: within a NOTICE text file distributed
+| as part of the Derivative Works; within the Source form or
+| documentation, if provided along with the Derivative Works; or,
+| within a display generated by the Derivative Works, if and
+| wherever such third-party notices normally appear. The contents
+| of the NOTICE file are for informational purposes only and
+| do not modify the License. You may add Your own attribution
+| notices within Derivative Works that You distribute, alongside
+| or as an addendum to the NOTICE text from the Work, provided
+| that such additional attribution notices cannot be construed
+| as modifying the License.
+|
+| You may add Your own copyright statement to Your modifications and
+| may provide additional or different license terms and conditions
+| for use, reproduction, or distribution of Your modifications, or
+| for any such Derivative Works as a whole, provided Your use,
+| reproduction, and distribution of the Work otherwise complies with
+| the conditions stated in this License.
+|
+| 5. Submission of Contributions. Unless You explicitly state otherwise,
+| any Contribution intentionally submitted for inclusion in the Work
+| by You to the Licensor shall be under the terms and conditions of
+| this License, without any additional terms or conditions.
+| Notwithstanding the above, nothing herein shall supersede or modify
+| the terms of any separate license agreement you may have executed
+| with Licensor regarding such Contributions.
+|
+| 6. Trademarks. This License does not grant permission to use the trade
+| names, trademarks, service marks, or product names of the Licensor,
+| except as required for reasonable and customary use in describing the
+| origin of the Work and reproducing the content of the NOTICE file.
+|
+| 7. Disclaimer of Warranty. Unless required by applicable law or
+| agreed to in writing, Licensor provides the Work (and each
+| Contributor provides its Contributions) on an "AS IS" BASIS,
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+| implied, including, without limitation, any warranties or conditions
+| of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+| PARTICULAR PURPOSE. You are solely responsible for determining the
+| appropriateness of using or redistributing the Work and assume any
+| risks associated with Your exercise of permissions under this License.
+|
+| 8. Limitation of Liability. In no event and under no legal theory,
+| whether in tort (including negligence), contract, or otherwise,
+| unless required by applicable law (such as deliberate and grossly
+| negligent acts) or agreed to in writing, shall any Contributor be
+| liable to You for damages, including any direct, indirect, special,
+| incidental, or consequential damages of any character arising as a
+| result of this License or out of the use or inability to use the
+| Work (including but not limited to damages for loss of goodwill,
+| work stoppage, computer failure or malfunction, or any and all
+| other commercial damages or losses), even if such Contributor
+| has been advised of the possibility of such damages.
+|
+| 9. Accepting Warranty or Additional Liability. While redistributing
+| the Work or Derivative Works thereof, You may choose to offer,
+| and charge a fee for, acceptance of support, warranty, indemnity,
+| or other liability obligations and/or rights consistent with this
+| License. However, in accepting such obligations, You may act only
+| on Your own behalf and on Your sole responsibility, not on behalf
+| of any other Contributor, and only if You agree to indemnify,
+| defend, and hold each Contributor harmless for any liability
+| incurred by, or claims asserted against, such Contributor by reason
+| of your accepting any such warranty or additional liability.
+|
+| END OF TERMS AND CONDITIONS
+|
+| APPENDIX: How to apply the Apache License to your work.
+|
+| To apply the Apache License to your work, attach the following
+| boilerplate notice, with the fields enclosed by brackets "[]"
+| replaced with your own identifying information. (Don't include
+| the brackets!) The text should be enclosed in the appropriate
+| comment syntax for the file format. We also recommend that a
+| file or class name and description of purpose be included on the
+| same "printed page" as the copyright notice for easier
+| identification within third-party archives.
+|
+| Copyright [yyyy] [name of copyright owner]
+|
+| Licensed under the Apache License, Version 2.0 (the "License");
+| you may not use this file except in compliance with the License.
+| You may obtain a copy of the License at
+|
+| http://www.apache.org/licenses/LICENSE-2.0
+|
+| Unless required by applicable law or agreed to in writing, software
+| distributed under the License is distributed on an "AS IS" BASIS,
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+| See the License for the specific language governing permissions and
+| limitations under the License.
+
+License file: src/polyfill/once_cell/LICENSE-MIT
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHOR OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+
+License file: third_party/fiat/LICENSE
+| The Apache License, Version 2.0 (Apache-2.0)
+|
+| Copyright 2015-2020 the fiat-crypto authors (see the AUTHORS file)
+|
+| Licensed under the Apache License, Version 2.0 (the "License");
+| you may not use this file except in compliance with the License.
+| You may obtain a copy of the License at
+|
+| http://www.apache.org/licenses/LICENSE-2.0
+|
+| Unless required by applicable law or agreed to in writing, software
+| distributed under the License is distributed on an "AS IS" BASIS,
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+| See the License for the specific language governing permissions and
+| limitations under the License.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate rustls-webpki@0.103.14.
+Project URL: https://github.com/rustls/webpki
+Declared license: ISC
+Selected license obligations: ISC
+
+License file: LICENSE
+| Except as otherwise noted, this project is licensed under the following
+| (ISC-style) terms:
+|
+| Copyright 2015 Brian Smith.
+|
+| Permission to use, copy, modify, and/or distribute this software for any
+| purpose with or without fee is hereby granted, provided that the above
+| copyright notice and this permission notice appear in all copies.
+|
+| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+|
+| The files under third-party/chromium are licensed as described in
+| third-party/chromium/LICENSE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate serde_yaml_ng@0.10.0.
+Project URL: https://github.com/acatton/serde-yaml-ng
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| MIT License
+|
+| Copyright 2024 Antoine Catton
+| Copyright 2016-2024 David Tolnay
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy of
+| this software and associated documentation files (the “Software”), to deal in
+| the Software without restriction, including without limitation the rights to
+| use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+| of the Software, and to permit persons to whom the Software is furnished to do
+| so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate slab@0.4.12.
+Project URL: https://github.com/tokio-rs/slab
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2019 Carl Lerche
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate strsim@0.11.1.
+Project URL: https://github.com/rapidfuzz/strsim-rs
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| The MIT License (MIT)
+|
+| Copyright (c) 2015 Danny Guo
+| Copyright (c) 2016 Titus Wormer <ti...@gmail.com>
+| Copyright (c) 2018 Akash Kurdekar
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate strum@0.26.3.
+Project URL: https://github.com/Peternator7/strum
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| MIT License
+|
+| Copyright (c) 2019 Peter Glotfelty
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate subtle@2.6.1.
+Project URL: https://dalek.rs/
+Declared license: BSD-3-Clause
+Selected license obligations: BSD-3-Clause
+
+License file: LICENSE
+| Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved.
+| Copyright (c) 2016-2024 Isis Agora Lovecruft. All rights reserved.
+|
+| Redistribution and use in source and binary forms, with or without
+| modification, are permitted provided that the following conditions are
+| met:
+|
+| 1. Redistributions of source code must retain the above copyright
+| notice, this list of conditions and the following disclaimer.
+|
+| 2. Redistributions in binary form must reproduce the above copyright
+| notice, this list of conditions and the following disclaimer in the
+| documentation and/or other materials provided with the distribution.
+|
+| 3. Neither the name of the copyright holder nor the names of its
+| contributors may be used to endorse or promote products derived from
+| this software without specific prior written permission.
+|
+| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+| IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+| TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+| HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+| TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+| PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate tap@1.0.1.
+Project URL: https://github.com/myrrlyn/tap
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE.txt
+| MIT License
+|
+| Copyright (c) 2017 Elliot Linder <da...@gmail.com>
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate tokio@1.53.1.
+Project URL: https://tokio.rs
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate tokio-util@0.7.19.
+Project URL: https://tokio.rs
+Declared license: MIT
+Selected license obligations: MIT
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE
+| MIT License
+|
+| Copyright (c) Tokio Contributors
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate tower@0.5.3.
+Project URL: https://github.com/tower-rs/tower
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate tower-layer@0.3.3.
+Project URL: https://github.com/tower-rs/tower
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate tower-service@0.3.3.
+Project URL: https://github.com/tower-rs/tower
+Declared license: MIT
+Selected license obligations: MIT
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE
+| Copyright (c) 2019 Tower Contributors
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate tower-http@0.6.11.
+Project URL: https://github.com/tower-rs/tower-http
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2019-2021 Tower Contributors
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate tracing@0.1.44.
+Project URL: https://tokio.rs
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2019 Tokio Contributors
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate tracing-core@0.1.36.
+Project URL: https://tokio.rs
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2019 Tokio Contributors
+|
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+
+License file: src/spin/LICENSE
+| The MIT License (MIT)
+|
+| Copyright (c) 2014 Mathijs van de Nes
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate try-lock@0.2.5.
+Project URL: https://github.com/seanmonstar/try-lock
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2018-2023 Sean McArthur
+| Copyright (c) 2016 Alex Crichton
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate twox-hash@2.1.3.
+Project URL: https://github.com/shepmaster/twox-hash
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE.txt
+| The MIT License (MIT)
+|
+| Copyright (c) 2015 Jake Goulding
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all
+| copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+| SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate unsafe-libyaml@0.2.11.
+Project URL: https://github.com/dtolnay/unsafe-libyaml
+Declared license: MIT
+Selected license obligations: MIT
+
+The supported Linux Gateway binaries use the Rust crate zmij@1.0.23.
+Project URL: https://github.com/dtolnay/zmij
+Declared license: MIT
+Selected license obligations: MIT
+
+These crates ship identical license text, reproduced once below.
+
+License file: LICENSE-MIT
+| Permission is hereby granted, free of charge, to any
+| person obtaining a copy of this software and associated
+| documentation files (the "Software"), to deal in the
+| Software without restriction, including without
+| limitation the rights to use, copy, modify, merge,
+| publish, distribute, sublicense, and/or sell copies of
+| the Software, and to permit persons to whom the Software
+| is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice
+| shall be included in all copies or substantial portions
+| of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+| ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+| TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+| PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+| SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+| DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate untrusted@0.9.0.
+Project URL: https://github.com/briansmith/untrusted
+Declared license: ISC
+Selected license obligations: ISC
+
+License file: LICENSE.txt
+| // Copyright 2015-2016 Brian Smith.
+| //
+| // Permission to use, copy, modify, and/or distribute this software for any
+| // purpose with or without fee is hereby granted, provided that the above
+| // copyright notice and this permission notice appear in all copies.
+| //
+| // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+| // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+| // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+| // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+| // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+| // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+| // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate want@0.3.1.
+Project URL: https://github.com/seanmonstar/want
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| Copyright (c) 2018-2019 Sean McArthur
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate webpki-roots@1.0.9.
+Project URL: https://github.com/rustls/webpki-roots
+Declared license: CDLA-Permissive-2.0
+Selected license obligations: CDLA-Permissive-2.0
+
+License file: LICENSE
+| # Community Data License Agreement - Permissive - Version 2.0
+|
+| This is the Community Data License Agreement - Permissive, Version
+| 2.0 (the "agreement"). Data Provider(s) and Data Recipient(s) agree
+| as follows:
+|
+| ## 1. Provision of the Data
+|
+| 1.1. A Data Recipient may use, modify, and share the Data made
+| available by Data Provider(s) under this agreement if that Data
+| Recipient follows the terms of this agreement.
+|
+| 1.2. This agreement does not impose any restriction on a Data
+| Recipient's use, modification, or sharing of any portions of the
+| Data that are in the public domain or that may be used, modified,
+| or shared under any other legal exception or limitation.
+|
+| ## 2. Conditions for Sharing Data
+|
+| 2.1. A Data Recipient may share Data, with or without modifications, so
+| long as the Data Recipient makes available the text of this agreement
+| with the shared Data.
+|
+| ## 3. No Restrictions on Results
+|
+| 3.1. This agreement does not impose any restriction or obligations
+| with respect to the use, modification, or sharing of Results.
+|
+| ## 4. No Warranty; Limitation of Liability
+|
+| 4.1. All Data Recipients receive the Data subject to the following
+| terms:
+|
+| THE DATA IS PROVIDED ON AN "AS IS" BASIS, WITHOUT REPRESENTATIONS,
+| WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+| INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+| NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+|
+| NO DATA PROVIDER SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+| WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE DATA OR RESULTS,
+| EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+|
+| ## 5. Definitions
+|
+| 5.1. "Data" means the material received by a Data Recipient under
+| this agreement.
+|
+| 5.2. "Data Provider" means any person who is the source of Data
+| provided under this agreement and in reliance on a Data Recipient's
+| agreement to its terms.
+|
+| 5.3. "Data Recipient" means any person who receives Data directly
+| or indirectly from a Data Provider and agrees to the terms of this
+| agreement.
+|
+| 5.4. "Results" means any outcome obtained by computational analysis
+| of Data, including for example machine learning models and models'
+| insights.
+--------------------------------------------------------------------------------
+
+The supported Linux Gateway binaries use the Rust crate zstd@0.13.3.
+Project URL: https://github.com/gyscos/zstd-rs
+Declared license: MIT
+Selected license obligations: MIT
+
+License file: LICENSE
+| The MIT License (MIT)
+| Copyright (c) 2016 Alexandre Bury
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/fluss-gateway/NOTICE-bin b/fluss-gateway/NOTICE-bin
new file mode 100644
index 000000000..0bfc0d0a1
--- /dev/null
+++ b/fluss-gateway/NOTICE-bin
@@ -0,0 +1,24 @@
+Apache Fluss
+Copyright 2025-2026 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
+--------------------------------------------------------------------------------
+
+The following notice applies to: arrow-arith@59.2.0, arrow-array@59.2.0, arrow-buffer@59.2.0, arrow-cast@59.2.0, arrow-csv@59.2.0, arrow-data@59.2.0, arrow-ipc@59.2.0, arrow-json@59.2.0, arrow-ord@59.2.0, arrow-row@59.2.0, arrow-schema@59.2.0, arrow-select@59.2.0, arrow-string@59.2.0, arrow@59.2.0
+
+Apache Arrow
+Copyright 2016-2026 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This product includes software from the chronoutil crate (MIT)
+ * Copyright (c) 2020-2022 Oliver Margetts
+ * https://github.com/olliemath/chronoutil
+
+This product includes software from the compact-thrift project (Apache 2.0)
+ * Copyright Jörn Horstmann
+ * https://github.com/jhorstmann/compact-thrift
diff --git a/fluss-gateway/README.md b/fluss-gateway/README.md
index 8c57973fd..f7e384831 100644
--- a/fluss-gateway/README.md
+++ b/fluss-gateway/README.md
@@ -30,26 +30,101 @@ lock file or its generated dependency inventories.
## Status
-The gateway currently serves the process runtime and REST metadata discovery:
-configuration loading and validation (`gateway.yaml` with flat dotted keys), the
-HTTP listener with its request-id, body-size and deadline middleware,
-`GET /health`, `GET /ready`, `GET /v1/openapi.json`, `GET /v1/clusters`,
-`GET /v1/clusters/{cluster}/databases`,
-`GET /v1/clusters/{cluster}/databases/{database}/tables`, the Prometheus
-listener, and the backend runtime that owns one shared service connection per
-configured cluster. A connection is opened lazily on the first request that
-needs it, shared by every request to that cluster, released after the configured
+The gateway provides configuration validation, lifecycle management, request-id,
+body-size and deadline middleware, and a Prometheus listener. Its REST API
+currently supports:
+
+- health, readiness, the generated OpenAPI document, and cluster discovery;
+- paginated metadata reads for databases, tables, table definitions, and
+ partitions;
+- DDL operations to create and drop databases, create, alter, and drop tables,
+ and add and drop partitions; and
+- schema-aware batched append, upsert, and delete records through
+ `POST /v1/clusters/{cluster}/databases/{database}/tables/{table}/records`,
+ with per-entry outcomes.
+
+The backend runtime owns one shared service connection per configured cluster. A
+connection is opened lazily on the first request that needs it, shared by every
+request to that cluster, released after the configured
`connection.idle-timeout`, and drained during shutdown. Concurrent cold requests
serialize behind one connection attempt. Cancelling that request cancels its
-attempt and lets the next waiter retry; bootstrap timeout and retry behavior remain
-owned by `fluss-rust`.
+attempt and lets the next waiter retry; bootstrap timeout and retry behavior
+remain owned by `fluss-rust`.
Connections use Fluss's default plaintext protocol unless
`connection.security.protocol: sasl` selects the configured service account. A
broken transport is left to the native client, which reconnects the affected
server on its own.
`connection.identity-mode: user` is refused at startup until Fluss supports
-act-as. The describe-table, partition, DDL, write, and lookup APIs, and client
-authentication, land in follow-up pull requests.
+act-as. Lookup and prefix-lookup APIs, HTTP caller authentication, and user
+identity propagation remain follow-up work.
+
+## Distribution and container
+
+The Linux convenience distribution uses the same layout as the Java Fluss
+distribution:
+
+```text
+fluss-gateway-<version>-bin-linux-<arch>/
+├── bin/
+├── conf/
+├── openapi.yaml
+├── DEPENDENCIES.rust.tsv
+├── LICENSE
+└── NOTICE
+```
+
+Create it from the repository `tools/` directory:
+
+```bash
+RELEASE_VERSION=1.0.0 SKIP_GPG=true releasing/create_gateway_release.sh
+```
+
+The release script uses `docker/fluss-gateway/Dockerfile.build` to pin Rust
+1.88 and Debian Bookworm as the Linux build environment. It builds the host
+architecture by default; set `GATEWAY_ARCH=amd64` or
+`GATEWAY_ARCH=arm64` only when the selected buildx node is native for that
+platform.
+
+After extracting the archive, edit `conf/gateway.yaml` and start the foreground
+process:
+
+```bash
+bin/fluss-gateway.sh
+```
+
+The wrapper resolves `FLUSS_HOME` from its own location, uses
+`conf/gateway.yaml` by default, and forwards additional CLI options to the
+binary. The convenience distribution follows the Java distribution and binds
+listeners to loopback by default. Set `RUST_LOG=debug` when temporary diagnostic
+logging is needed.
+
+The container image also installs into `/opt/fluss`, uses the `fluss` user with
+UID/GID 9999, and reads `/opt/fluss/conf/gateway.yaml`. The image is assembled
+from the prepared binary distribution, matching the Java image's
+`build-target` flow. Typed environment defaults bind its REST and Prometheus
+listeners to `0.0.0.0` without modifying the packaged configuration.
+
+Build and run the local image:
+
+```bash
+just image
+docker run --rm \
+ --read-only \
+ --cap-drop ALL \
+ --security-opt no-new-privileges \
+ --stop-timeout 35 \
+ -p 8080:8080 \
+ -p 9095:9095 \
+ -e FLUSS_GATEWAY__CLUSTER__DEFAULT__BOOTSTRAP__SERVERS=host.docker.internal:9123 \
+ fluss-gateway:dev
+```
+
+The REST health and readiness endpoints are available at `/health` and
+`/ready`; Prometheus metrics are served on port `9095`. Use a cluster DNS name
+or container-network alias instead of `host.docker.internal` on Linux when that
+hostname is unavailable. Production deployments should terminate TLS at a
+trusted ingress and must not expose `trust` authentication outside a protected
+network boundary.
## Prerequisites
@@ -71,6 +146,8 @@ just fmt-check # cargo fmt --all -- --check
just clippy # cargo clippy --all-targets -- -D warnings
just doc # RUSTDOCFLAGS="-D warnings" cargo doc --no-deps
just licenses # cargo deny check licenses
+just image # build the Gateway container image
+just image-smoke # run container health and shutdown smoke tests
```
The E2E test requires Docker. It builds and invokes the `fluss-test-cluster`
@@ -98,10 +175,18 @@ Gateway changes are gated by a dedicated workflow, `.github/workflows/gateway-ci
(build and tests on Linux/macOS, MSRV 1.88, license headers, dependency
licenses via `cargo-deny`, formatting, clippy, rustdoc). Gateway-only changes
are excluded from the Java CI, mirroring `fluss-rust`, and the gateway workflow
-never builds the `fluss-rust` workspace.
+never builds the `fluss-rust` workspace. The container job builds the Gateway
+against the in-tree client on native `amd64` and `arm64` runners, packages the
+binary distribution, assembles the image from that distribution, and exercises
+startup, health, readiness, non-root execution, configuration errors, and
+SIGTERM draining.
## License enforcement
Like `fluss-rust`, the gateway carries its own license enforcement: source
headers are checked by `skywalking-eyes` (`.licenserc.yaml`) and dependency
-licenses by `cargo-deny` (`deny.toml`). Both run in CI.
+licenses by `cargo-deny` (`deny.toml`). `LICENSE-bin` and `NOTICE-bin` are
+generated from the normal Linux runtime dependency closure with
+`scripts/generate_binary_license.py`; build, development, and procedural-macro
+tooling is excluded because it is not linked into the distributed executable.
+CI rejects drift in all three dependency records.
diff --git a/tools/releasing/update_branch_version.sh b/fluss-gateway/bin/fluss-gateway.sh
similarity index 50%
copy from tools/releasing/update_branch_version.sh
copy to fluss-gateway/bin/fluss-gateway.sh
index 5c4cba3da..3d69ca29d 100755
--- a/tools/releasing/update_branch_version.sh
+++ b/fluss-gateway/bin/fluss-gateway.sh
@@ -1,6 +1,5 @@
#!/usr/bin/env bash
-
-#
+################################################################################
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -16,46 +15,27 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-#
-
-##
-## Variables with defaults (if not overwritten by environment)
-##
-MVN=${MVN:-mvn}
+################################################################################
-# fail immediately
set -o errexit
set -o nounset
-# print command before executing
-set -o xtrace
-
-CURR_DIR=`pwd`
-if [[ `basename $CURR_DIR` != "tools" ]] ; then
- echo "You have to call the script from the tools/ dir"
- exit 1
-fi
-
-###########################
-OLD_VERSION=${OLD_VERSION}
-NEW_VERSION=${NEW_VERSION}
-
-
-if [ -z "${OLD_VERSION}" ]; then
- echo "OLD_VERSION is unset"
- exit 1
-fi
-
-if [ -z "${NEW_VERSION}" ]; then
- echo "NEW_VERSION is unset"
- exit 1
+SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+FLUSS_HOME="${FLUSS_HOME:-$(cd -- "${SCRIPT_DIR}/.." && pwd -P)}"
+FLUSS_CONF_DIR="${FLUSS_CONF_DIR:-${FLUSS_HOME}/conf}"
+FLUSS_GATEWAY_CONFIG="${FLUSS_GATEWAY_CONFIG:-${FLUSS_CONF_DIR}/gateway.yaml}"
+FLUSS_GATEWAY_BIN="${FLUSS_GATEWAY_BIN:-${FLUSS_HOME}/bin/fluss-gateway}"
+
+has_config=false
+for arg in "$@"; do
+ if [[ "${arg}" == "--config" || "${arg}" == --config=* ]]; then
+ has_config=true
+ break
+ fi
+done
+
+if [[ "${has_config}" == "true" ]]; then
+ exec "${FLUSS_GATEWAY_BIN}" "$@"
fi
-cd ..
-
-#change version in all pom files
-find . -name 'pom.xml' -type f -exec perl -pi -e 's#<version>'$OLD_VERSION'</version>#<version>'$NEW_VERSION'</version>#; s#-'$OLD_VERSION'</version>#-'$NEW_VERSION'</version>#' {} \;
-
-git commit -am "Update version to $NEW_VERSION"
-
-echo "Don't forget to push the change."
+exec "${FLUSS_GATEWAY_BIN}" --config "${FLUSS_GATEWAY_CONFIG}" "$@"
diff --git a/fluss-gateway/conf/gateway.yaml b/fluss-gateway/conf/gateway.yaml
new file mode 100644
index 000000000..4ead4175e
--- /dev/null
+++ b/fluss-gateway/conf/gateway.yaml
@@ -0,0 +1,139 @@
+################################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+# Apache Fluss Gateway configuration.
+#
+# The format follows conf/server.yaml: flat, dot-separated keys with durations
+# and memory sizes written as human-readable values. Environment variables
+# override this file. For example:
+#
+# gateway.cluster.default.bootstrap.servers
+# -> FLUSS_GATEWAY__CLUSTER__DEFAULT__BOOTSTRAP__SERVERS
+#
+# Do not store credentials in this file when it is baked into an image. Mount a
+# separate file or inject the corresponding FLUSS_GATEWAY__* variables.
+
+# Optional stable identity used in logs and metrics. When omitted, the Gateway
+# does not invent a persistent identity.
+# gateway.instance-id: gateway-1
+
+#==============================================================================
+# REST Server
+#==============================================================================
+
+# Bind to loopback by default, matching the Java distribution's server.yaml.
+# The container image overrides this value through the typed environment
+# variable FLUSS_GATEWAY__REST__LISTEN.
+gateway.rest.listen: 127.0.0.1:8080
+
+# Maximum time allowed for receiving the complete HTTP request headers.
+gateway.rest.header-read-timeout: 10s
+
+# Server-side deadline for one REST request.
+gateway.rest.request-timeout: 30s
+
+# Maximum accepted request body size.
+gateway.rest.write.max-request-bytes: 32MiB
+
+#==============================================================================
+# Fluss Clusters
+#==============================================================================
+
+# Comma-separated logical cluster IDs. Each ID owns a gateway.cluster.<id>.*
+# namespace.
+gateway.clusters: default
+
+# Comma-separated Fluss client bootstrap servers in host:port form.
+gateway.cluster.default.bootstrap.servers: 127.0.0.1:9123
+
+# Timeout for establishing the native Fluss client connection.
+gateway.cluster.default.connect-timeout: 10s
+
+# Use plaintext or sasl. SASL requires both service account and service secret.
+gateway.cluster.default.connection.security.protocol: plaintext
+
+# Service mode shares one connection authenticated with the configured service
+# account. It is the only supported mode today; user mode is reserved for
+# per-caller identity propagation and is rejected at startup.
+gateway.cluster.default.connection.identity-mode: service
+
+# Configure both values when the Fluss cluster requires SASL/PLAIN.
+# gateway.cluster.default.connection.service.account: gateway-service
+# gateway.cluster.default.connection.service.secret: change-me
+
+# Reserved for the unsupported connection.identity-mode: user.
+# gateway.cluster.default.connection.max: 512
+# gateway.cluster.default.connection.idle-timeout: 10m
+
+#==============================================================================
+# HTTP Caller Authentication
+#==============================================================================
+
+# Only trust mode is implemented today. The password, token, and trusted-header
+# values are reserved for the caller-authentication follow-up and do not protect
+# requests in this release. Trust mode is suitable only for local development or
+# a deployment protected by a trusted network boundary.
+gateway.security.authentication: trust
+
+# Reserved password-mode user table.
+# gateway.security.users: alice:change-me
+
+# Reserved token-mode token table.
+# gateway.security.tokens: change-me:alice
+
+# Reserved trusted-header-mode header name.
+# gateway.security.trusted-header.name: x-forwarded-user
+
+#==============================================================================
+# Request Admission
+#==============================================================================
+
+# Maximum number of concurrent metadata requests accessing Fluss.
+gateway.rest.metadata.max-concurrent-requests: 16
+
+gateway.rest.write.max-rows: 10000
+gateway.rest.write.max-concurrent-requests: 64
+gateway.rest.write.rate-limit.enabled: false
+gateway.rest.write.rate-limit.requests-per-second: 1000
+gateway.rest.write.rate-limit.bytes-per-second: 64MiB
+
+gateway.rest.lookup.max-keys: 128
+gateway.rest.lookup.max-key-bytes: 1MiB
+gateway.rest.lookup.max-concurrent-requests: 64
+
+gateway.rest.prefix-lookup.max-prefixes: 16
+gateway.rest.prefix-lookup.max-rows-per-prefix: 1000
+gateway.rest.prefix-lookup.max-concurrent-requests: 32
+
+#==============================================================================
+# Metrics
+#==============================================================================
+
+gateway.metrics.enabled: true
+gateway.metrics.exporters: prometheus
+# The container image overrides this value through
+# FLUSS_GATEWAY__METRICS__EXPORTER__PROMETHEUS__LISTEN.
+gateway.metrics.exporter.prometheus.listen: 127.0.0.1:9095
+
+#==============================================================================
+# Shutdown
+#==============================================================================
+
+# Whole-process drain budget. Container stop timeouts must be greater than this
+# value so Docker or Kubernetes does not send SIGKILL during the drain.
+gateway.shutdown.drain-timeout: 30s
diff --git a/fluss-gateway/justfile b/fluss-gateway/justfile
index f81798893..062aa24e3 100644
--- a/fluss-gateway/justfile
+++ b/fluss-gateway/justfile
@@ -26,6 +26,15 @@ build:
build-release:
cargo build --release
+# Build the host-architecture Gateway distribution and image using the pinned
+# Linux builder.
+image image="fluss-gateway:dev":
+ GATEWAY_IMAGE={{image}} ../docker/fluss-gateway/build.sh
+
+# Build and exercise the Gateway distribution and image.
+image-smoke:
+ RUN_SMOKE=true ../docker/fluss-gateway/build.sh
+
# Run all unit and protocol tests of the gateway.
test:
cargo test --all-targets
@@ -70,3 +79,7 @@ licenses:
# Regenerate the checked-in dependency license inventory.
deps:
cargo deny --locked list -f tsv -t 0.6 | sed 's/[[:space:]]*$//' > DEPENDENCIES.rust.tsv
+
+# Regenerate the LICENSE and NOTICE used by the Linux binary distribution.
+binary-license:
+ python3 scripts/generate_binary_license.py
diff --git a/fluss-gateway/openapi.yaml b/fluss-gateway/openapi.yaml
index 1251fdbd1..1bb94565c 100644
--- a/fluss-gateway/openapi.yaml
+++ b/fluss-gateway/openapi.yaml
@@ -1058,7 +1058,7 @@ info:
name: Apache-2.0
url: https://www.apache.org/licenses/LICENSE-2.0
title: fluss-gateway
- version: 1.0.0
+ version: 1.0.0-SNAPSHOT
openapi: 3.1.0
paths:
/health:
diff --git a/fluss-gateway/scripts/generate_binary_license.py b/fluss-gateway/scripts/generate_binary_license.py
new file mode 100755
index 000000000..9db8f03c5
--- /dev/null
+++ b/fluss-gateway/scripts/generate_binary_license.py
@@ -0,0 +1,392 @@
+#!/usr/bin/env python3
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""Generate LICENSE-bin and NOTICE-bin for the shipped Linux Gateway binary."""
+
+import argparse
+import hashlib
+import json
+from pathlib import Path
+import re
+import subprocess
+from typing import Dict, Iterable, List, Set, Tuple
+
+
+TARGETS = (
+ "x86_64-unknown-linux-gnu",
+ "aarch64-unknown-linux-gnu",
+)
+LOCAL_PACKAGES = {"fluss-gateway", "fluss-rs"}
+SEPARATOR = "-" * 80
+
+
+def cargo_metadata(gateway_dir: Path, target: str) -> dict:
+ command = [
+ "cargo",
+ "metadata",
+ "--manifest-path",
+ str(gateway_dir / "Cargo.toml"),
+ "--locked",
+ "--format-version",
+ "1",
+ "--filter-platform",
+ target,
+ ]
+ return json.loads(subprocess.check_output(command, text=True))
+
+
+def is_proc_macro(package: dict) -> bool:
+ return any(
+ "proc-macro" in target["kind"] for target in package.get("targets", ())
+ )
+
+
+def runtime_packages(gateway_dir: Path) -> List[dict]:
+ packages: Dict[str, dict] = {}
+ runtime_ids: Set[str] = set()
+
+ for target in TARGETS:
+ metadata = cargo_metadata(gateway_dir, target)
+ target_packages = {
+ package["id"]: package for package in metadata["packages"]
+ }
+ packages.update(target_packages)
+ nodes = {node["id"]: node for node in metadata["resolve"]["nodes"]}
+ pending = [metadata["resolve"]["root"]]
+ target_ids: Set[str] = set()
+
+ while pending:
+ package_id = pending.pop()
+ if package_id in target_ids:
+ continue
+ target_ids.add(package_id)
+ runtime_ids.add(package_id)
+ for dependency in nodes[package_id]["deps"]:
+ if (
+ any(kind["kind"] is None for kind in dependency["dep_kinds"])
+ and not is_proc_macro(target_packages[dependency["pkg"]])
+ ):
+ pending.append(dependency["pkg"])
+
+ return sorted(
+ (packages[package_id] for package_id in runtime_ids),
+ key=lambda package: (package["name"], package["version"]),
+ )
+
+
+def license_terms(expression: str) -> Tuple[str, ...]:
+ """Select one compatible branch from each AND term in an SPDX expression."""
+
+ expression = expression.replace("/", " OR ")
+ selected: List[str] = []
+ preferences = (
+ "Apache-2.0",
+ "MIT",
+ "BSD-2-Clause",
+ "BSD-3-Clause",
+ "ISC",
+ "Unicode-3.0",
+ "Zlib",
+ "CC0-1.0",
+ "CDLA-Permissive-2.0",
+ )
+
+ for required_term in re.split(r"\s+AND\s+", expression.strip("()")):
+ alternatives = [
+ alternative.strip("() ")
+ for alternative in re.split(r"\s+OR\s+", required_term)
+ ]
+ for preferred in preferences:
+ if preferred in alternatives:
+ selected.append(preferred)
+ break
+ else:
+ raise RuntimeError(
+ "No approved binary license selection for expression "
+ f"{expression!r}."
+ )
+
+ return tuple(dict.fromkeys(selected))
+
+
+def license_files(package: dict, selected_terms: Tuple[str, ...]) -> List[Path]:
+ package_dir = Path(package["manifest_path"]).parent
+ candidates = sorted(
+ path
+ for path in package_dir.rglob("*")
+ if path.is_file()
+ and re.match(r"(?i)^(license|copying)", path.name)
+ and ".cargo-ok" not in path.name
+ )
+
+ if selected_terms == ("Apache-2.0",):
+ return []
+
+ tokens_by_license = {
+ "Apache-2.0": ("apache", "boringssl"),
+ "MIT": ("mit",),
+ "BSD-2-Clause": ("bsd",),
+ "BSD-3-Clause": ("bsd", "httprouter"),
+ "ISC": ("isc", "other-bits"),
+ "Unicode-3.0": ("unicode",),
+ "Zlib": ("zlib",),
+ "CC0-1.0": ("cc0",),
+ "CDLA-Permissive-2.0": ("cdla",),
+ }
+ tokens = tuple(
+ token
+ for selected in selected_terms
+ for token in tokens_by_license[selected]
+ )
+ matched = [
+ path
+ for path in candidates
+ if any(token in path.name.lower() for token in tokens)
+ ]
+
+ # A package with a generically named root LICENSE file has already
+ # declared which SPDX license it contains in Cargo.toml. Nested license
+ # files describe code incorporated from another project and must be
+ # retained even when their file name does not contain the SPDX identifier.
+ generic_root_names = {"license", "license.txt", "license.md"}
+ matched.extend(
+ path
+ for path in candidates
+ if path.parent != package_dir or path.name.lower() in generic_root_names
+ )
+ matched = sorted(set(matched))
+ matched = [
+ path
+ for path in matched
+ if path.parent != package_dir or not is_standalone_apache_license(path)
+ ]
+
+ if not matched:
+ raise RuntimeError(
+ f"Cannot locate the {' AND '.join(selected_terms)} text for "
+ f"{package['name']}@{package['version']}; candidates: "
+ + ", ".join(str(path.relative_to(package_dir)) for path in candidates)
+ )
+ return matched
+
+
+def is_standalone_apache_license(path: Path) -> bool:
+ text = path.read_text(encoding="utf-8")
+ first_line = next((line.strip() for line in text.splitlines() if line.strip()), "")
+ name = path.name.lower()
+ return (
+ "Apache License" in first_line
+ and "Version 2.0" in text
+ and "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION" in text
+ and (
+ "apache" in name
+ or name in {"license", "license.txt", "license.md"}
+ )
+ )
+
+
+def apache_license(repository_root: Path) -> str:
+ source_license = (repository_root / "LICENSE").read_text(encoding="utf-8")
+ lines = source_license.splitlines()
+ separator = next(
+ (
+ index
+ for index, line in enumerate(lines)
+ if len(line) >= 20 and set(line) == {"-"}
+ ),
+ None,
+ )
+ if separator is None:
+ raise RuntimeError("Cannot find the third-party section in the root LICENSE.")
+ return "\n".join(lines[:separator]).rstrip() + "\n"
+
+
+def gateway_notice(repository_root: Path) -> str:
+ source_notice = (repository_root / "NOTICE").read_text(encoding="utf-8")
+ asf_line = "The Apache Software Foundation (http://www.apache.org/)."
+ asf_end = source_notice.find(asf_line)
+ if asf_end < 0:
+ raise RuntimeError("Cannot find the ASF attribution in the root NOTICE.")
+ return source_notice[: asf_end + len(asf_line)].rstrip() + "\n"
+
+
+def indent(text: str) -> str:
+ lines = []
+ for line in text.rstrip().splitlines():
+ line = line.rstrip()
+ lines.append(f"| {line}" if line else "|")
+ return "\n".join(lines)
+
+
+def generate_license(repository_root: Path, packages: Iterable[dict]) -> str:
+ sections = [
+ apache_license(repository_root),
+ "",
+ SEPARATOR,
+ "",
+ "This LICENSE covers the supported amd64 and arm64 Linux Gateway",
+ "convenience binaries. Their linked dependency sets are almost identical,",
+ "but a target-specific crate may appear here even when it is not linked into",
+ "the other architecture's executable.",
+ ]
+ apache_dependencies: List[str] = []
+ # Crates that ship byte-identical license text share a single reproduction, which
+ # removes about a third of this file. The grouping key is the license text itself,
+ # so no reproduced text is ever rewritten, reordered or dropped, and every crate
+ # keeps its own attribution block.
+ reproductions: Dict[Tuple[Tuple[str, str], ...], List[List[str]]] = {}
+
+ for package in packages:
+ if package["source"] is None and package["name"] in LOCAL_PACKAGES:
+ continue
+ expression = package.get("license")
+ if not expression:
+ raise RuntimeError(
+ f"{package['name']}@{package['version']} has no SPDX license."
+ )
+ selected_terms = license_terms(expression)
+ package_name = f"{package['name']}@{package['version']}"
+ if "Apache-2.0" in selected_terms:
+ apache_dependencies.append(package_name)
+
+ files = license_files(package, selected_terms)
+ if not files:
+ continue
+
+ package_dir = Path(package["manifest_path"]).parent
+ homepage = package.get("homepage") or package.get("repository") or "(not provided)"
+ attribution = [
+ f"The supported Linux Gateway binaries use the Rust crate {package_name}.",
+ f"Project URL: {homepage}",
+ f"Declared license: {expression}",
+ f"Selected license obligations: {' AND '.join(selected_terms)}",
+ ]
+ reproduction = tuple(
+ (
+ str(path.relative_to(package_dir)),
+ path.read_text(encoding="utf-8").rstrip(),
+ )
+ for path in files
+ )
+ reproductions.setdefault(reproduction, []).append(attribution)
+
+ other_sections: List[str] = []
+ for reproduction, attributions in reproductions.items():
+ contents = [SEPARATOR]
+ for attribution in attributions:
+ contents.append("")
+ contents.extend(attribution)
+ if len(attributions) > 1:
+ contents.extend(
+ [
+ "",
+ "These crates ship identical license text, reproduced once below.",
+ ]
+ )
+ for file_name, text in reproduction:
+ contents.extend(["", f"License file: {file_name}", indent(text)])
+ other_sections.append("\n".join(contents))
+
+ sections.extend(
+ [
+ "",
+ SEPARATOR,
+ "",
+ "The supported Linux Gateway binaries include the following Rust crates",
+ "under the Apache License, Version 2.0. Crates with additional conjunctive",
+ "license obligations are also reproduced in the sections below.",
+ "",
+ "\n".join(apache_dependencies),
+ ]
+ )
+ sections.extend(other_sections)
+ return "\n".join(sections).rstrip() + "\n"
+
+
+def generate_notice(repository_root: Path, packages: Iterable[dict]) -> str:
+ unique_notices: Dict[str, Tuple[str, List[str]]] = {}
+
+ for package in packages:
+ if package["source"] is None and package["name"] in LOCAL_PACKAGES:
+ continue
+ package_dir = Path(package["manifest_path"]).parent
+ for path in sorted(package_dir.glob("NOTICE*")):
+ if not path.is_file():
+ continue
+ text = path.read_text(encoding="utf-8").rstrip()
+ digest = hashlib.sha256(text.encode("utf-8")).hexdigest()
+ if digest not in unique_notices:
+ unique_notices[digest] = (text, [])
+ unique_notices[digest][1].append(
+ f"{package['name']}@{package['version']}"
+ )
+
+ sections = [gateway_notice(repository_root)]
+ for text, package_names in sorted(
+ unique_notices.values(), key=lambda item: item[1]
+ ):
+ sections.extend(
+ [
+ "",
+ SEPARATOR,
+ "",
+ "The following notice applies to: "
+ + ", ".join(sorted(package_names)),
+ "",
+ text,
+ ]
+ )
+ return "\n".join(sections).rstrip() + "\n"
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--check",
+ action="store_true",
+ help="fail instead of updating files when generated content differs",
+ )
+ args = parser.parse_args()
+
+ gateway_dir = Path(__file__).resolve().parent.parent
+ repository_root = gateway_dir.parent
+ packages = runtime_packages(gateway_dir)
+ generated = {
+ gateway_dir / "LICENSE-bin": generate_license(repository_root, packages),
+ gateway_dir / "NOTICE-bin": generate_notice(repository_root, packages),
+ }
+
+ changed = []
+ for path, contents in generated.items():
+ current = path.read_text(encoding="utf-8") if path.exists() else None
+ if current == contents:
+ continue
+ changed.append(path)
+ if not args.check:
+ path.write_text(contents, encoding="utf-8")
+
+ if args.check and changed:
+ raise SystemExit(
+ "Gateway binary license files are stale: "
+ + ", ".join(str(path.relative_to(repository_root)) for path in changed)
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/fluss-gateway/src/config.rs b/fluss-gateway/src/config.rs
index 27363af87..847b30c3b 100644
--- a/fluss-gateway/src/config.rs
+++ b/fluss-gateway/src/config.rs
@@ -1753,6 +1753,36 @@ mod tests {
assert!(config.warnings().is_empty());
}
+ // conf/gateway.yaml ships in the binary distribution and the container image, so it is
+ // a release artifact rather than a sample: it has to parse, it has to document every
+ // option, and its values must not drift away from the compiled defaults.
+ #[test]
+ fn distribution_configuration_is_loadable_and_complete() {
+ let template = include_str!("../conf/gateway.yaml");
+ let config = load_file(template).unwrap();
+ let defaults = load(None, &no_env(), &CliOverrides::default()).unwrap();
+
+ assert_eq!(config, defaults);
+
+ // Cluster IDs are resolved before the typed entries, so this key is not in
+ // CONFIG_ENTRIES and would otherwise go undocumented unnoticed.
+ assert!(template.contains(&format!("{CLUSTERS_KEY}:")));
+ for entry in CONFIG_ENTRIES {
+ assert!(
+ template.contains(&format!("{}:", entry.key)),
+ "distribution configuration does not document {}",
+ entry.key
+ );
+ }
+ for entry in CLUSTER_ENTRIES {
+ let key = cluster_key(DEFAULT_CLUSTER_ID, entry.key);
+ assert!(
+ template.contains(&format!("{key}:")),
+ "distribution configuration does not document {key}"
+ );
+ }
+ }
+
#[test]
fn public_yaml_options_are_loaded() {
let config = load_file(
diff --git a/tools/releasing/create_gateway_release.sh b/tools/releasing/create_gateway_release.sh
new file mode 100755
index 000000000..937993637
--- /dev/null
+++ b/tools/releasing/create_gateway_release.sh
@@ -0,0 +1,171 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+SKIP_GPG=${SKIP_GPG:-false}
+
+if [[ -z "${RELEASE_VERSION:-}" ]]; then
+ echo "RELEASE_VERSION was not set." >&2
+ exit 1
+fi
+
+set -o errexit
+set -o nounset
+set -o pipefail
+set -o xtrace
+
+CURR_DIR="$(pwd)"
+if [[ "$(basename "${CURR_DIR}")" != "tools" ]]; then
+ echo "You have to call the script from the tools/ dir" >&2
+ exit 1
+fi
+
+if [[ "$(uname)" == "Darwin" ]]; then
+ SHASUM=(shasum -a 512)
+ TAR_OPTIONS=(--no-xattrs)
+ export COPYFILE_DISABLE=1
+else
+ SHASUM=(sha512sum)
+ TAR_OPTIONS=()
+fi
+
+FLUSS_DIR="$(cd .. && pwd -P)"
+GATEWAY_DIR="${FLUSS_DIR}/fluss-gateway"
+RELEASE_DIR="${GATEWAY_RELEASE_DIR:-${FLUSS_DIR}/tools/releasing/release}"
+mkdir -p "${RELEASE_DIR}"
+
+gateway_version="$(
+ sed -n '/^\[package\]/,/^\[/p' "${GATEWAY_DIR}/Cargo.toml" \
+ | grep '^[[:space:]]*version[[:space:]]*=' \
+ | head -1 \
+ | sed -E 's/.*"([^"]+)".*/\1/'
+)"
+if [[ "${gateway_version}" != "${RELEASE_VERSION}" ]]; then
+ echo "Gateway version ${gateway_version} does not match RELEASE_VERSION ${RELEASE_VERSION}." >&2
+ exit 1
+fi
+
+if [[ -z "${GATEWAY_ARCH:-}" ]]; then
+ case "$(uname -m)" in
+ x86_64)
+ GATEWAY_ARCH="amd64"
+ ;;
+ aarch64|arm64)
+ GATEWAY_ARCH="arm64"
+ ;;
+ *)
+ echo "Set GATEWAY_ARCH to amd64 or arm64." >&2
+ exit 1
+ ;;
+ esac
+fi
+
+case "${GATEWAY_ARCH}" in
+ amd64|arm64)
+ ;;
+ *)
+ echo "Unsupported Gateway release architecture: ${GATEWAY_ARCH}" >&2
+ exit 1
+ ;;
+esac
+
+temporary_dir="$(mktemp -d "${RELEASE_DIR}/.gateway-release.XXXXXX")"
+cleanup() {
+ rm -rf "${temporary_dir}"
+}
+trap cleanup EXIT
+
+if ! docker buildx version >/dev/null 2>&1; then
+ echo "Docker with buildx is required to build the Gateway release binary." >&2
+ exit 1
+fi
+
+# The release manager may run this on macOS, whose Bash 3.2 treats "${array[@]}"
+# as an unbound variable when the array is empty. Expand optional arguments with
+# the ${array[@]+...} guard so an empty array stays empty instead of aborting.
+build_cache_args=()
+if [[ -n "${GATEWAY_BUILD_CACHE_FROM:-}" ]]; then
+ build_cache_args+=(--cache-from "${GATEWAY_BUILD_CACHE_FROM}")
+fi
+if [[ -n "${GATEWAY_BUILD_CACHE_TO:-}" ]]; then
+ build_cache_args+=(--cache-to "${GATEWAY_BUILD_CACHE_TO}")
+fi
+docker buildx build \
+ --platform "linux/${GATEWAY_ARCH}" \
+ --file "${FLUSS_DIR}/docker/fluss-gateway/Dockerfile.build" \
+ --target artifact \
+ ${build_cache_args[@]+"${build_cache_args[@]}"} \
+ --output "type=local,dest=${temporary_dir}/binary" \
+ "${FLUSS_DIR}"
+gateway_binary="${temporary_dir}/binary/fluss-gateway"
+
+if [[ ! -x "${gateway_binary}" ]]; then
+ echo "Gateway binary is missing or not executable: ${gateway_binary}" >&2
+ exit 1
+fi
+
+case "$(uname -s)/$(uname -m)" in
+ Linux/x86_64)
+ native_arch="amd64"
+ ;;
+ Linux/aarch64|Linux/arm64)
+ native_arch="arm64"
+ ;;
+ *)
+ native_arch=""
+ ;;
+esac
+if [[ "${GATEWAY_ARCH}" == "${native_arch}" ]]; then
+ binary_version="$("${gateway_binary}" --version)"
+ if [[ "${binary_version}" != "fluss-gateway ${RELEASE_VERSION}" ]]; then
+ echo "Gateway binary version does not match RELEASE_VERSION: ${binary_version}" >&2
+ exit 1
+ fi
+fi
+
+package_name="fluss-gateway-${RELEASE_VERSION}-bin-linux-${GATEWAY_ARCH}"
+package_dir="${temporary_dir}/${package_name}"
+archive_name="${package_name}.tgz"
+archive="${RELEASE_DIR}/${archive_name}"
+
+rm -f "${archive}" "${archive}.asc" "${archive}.sha512"
+mkdir -p "${package_dir}/bin" "${package_dir}/conf"
+
+install -m 0755 "${gateway_binary}" "${package_dir}/bin/fluss-gateway"
+install -m 0755 "${GATEWAY_DIR}/bin/fluss-gateway.sh" "${package_dir}/bin/"
+install -m 0644 "${GATEWAY_DIR}/conf/gateway.yaml" "${package_dir}/conf/"
+install -m 0644 "${GATEWAY_DIR}/openapi.yaml" "${package_dir}/"
+install -m 0644 "${GATEWAY_DIR}/DEPENDENCIES.rust.tsv" "${package_dir}/"
+install -m 0644 "${GATEWAY_DIR}/LICENSE-bin" "${package_dir}/LICENSE"
+install -m 0644 "${GATEWAY_DIR}/NOTICE-bin" "${package_dir}/NOTICE"
+
+(
+ cd "${temporary_dir}"
+ tar ${TAR_OPTIONS[@]+"${TAR_OPTIONS[@]}"} -czf "${archive}" "${package_name}"
+)
+
+(
+ cd "${RELEASE_DIR}"
+ if [[ "${SKIP_GPG}" == "false" ]]; then
+ gpg --armor --detach-sig "${archive_name}"
+ fi
+ "${SHASUM[@]}" "${archive_name}" > "${archive_name}.sha512"
+)
+
+echo "Created ${archive}."
diff --git a/tools/releasing/update_branch_version.sh b/tools/releasing/update_branch_version.sh
index 5c4cba3da..90387c199 100755
--- a/tools/releasing/update_branch_version.sh
+++ b/tools/releasing/update_branch_version.sh
@@ -53,9 +53,100 @@ fi
cd ..
-#change version in all pom files
+# Keep the independently built Gateway executable on the same release version
+# as the Java distribution and shared repository tag.
+GATEWAY_CARGO_TOML="fluss-gateway/Cargo.toml"
+GATEWAY_CARGO_LOCK="fluss-gateway/Cargo.lock"
+GATEWAY_OPENAPI="fluss-gateway/openapi.yaml"
+GATEWAY_DEPENDENCIES="fluss-gateway/DEPENDENCIES.rust.tsv"
+
+# Maven development versions omit the patch component (for example,
+# 1.1-SNAPSHOT), while Cargo requires SemVer's major.minor.patch form. Preserve
+# the prerelease or build suffix when adding that missing component.
+gateway_version() {
+ local version="$1"
+ if [[ "${version}" =~ ^([0-9]+\.[0-9]+)([-+].+)$ ]]; then
+ version="${BASH_REMATCH[1]}.0${BASH_REMATCH[2]}"
+ elif [[ "${version}" =~ ^[0-9]+\.[0-9]+$ ]]; then
+ version="${version}.0"
+ fi
+ if [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?(\+[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?$ ]]; then
+ return 1
+ fi
+ printf '%s\n' "${version}"
+}
+
+if ! GATEWAY_OLD_VERSION="$(gateway_version "${OLD_VERSION}")"; then
+ echo "Cannot map OLD_VERSION ${OLD_VERSION} to a valid Gateway Cargo version." >&2
+ exit 1
+fi
+if ! GATEWAY_NEW_VERSION="$(gateway_version "${NEW_VERSION}")"; then
+ echo "Cannot map NEW_VERSION ${NEW_VERSION} to a valid Gateway Cargo version." >&2
+ exit 1
+fi
+
+CURRENT_GATEWAY_VERSION=$(sed -n '/^\[package\]/,/^\[/p' "${GATEWAY_CARGO_TOML}" \
+ | grep '^[[:space:]]*version[[:space:]]*=' \
+ | head -1 \
+ | sed -E 's/.*"([^"]+)".*/\1/')
+if [[ -z "${CURRENT_GATEWAY_VERSION}" ]]; then
+ echo "Cannot read the Gateway version from ${GATEWAY_CARGO_TOML}." >&2
+ exit 1
+fi
+if [[ "${CURRENT_GATEWAY_VERSION}" != "${GATEWAY_OLD_VERSION}" ]]; then
+ echo "Gateway version ${CURRENT_GATEWAY_VERSION} does not match OLD_VERSION ${OLD_VERSION} (${GATEWAY_OLD_VERSION})." >&2
+ exit 1
+fi
+if ! grep -A2 '^\[\[package\]\]$' "${GATEWAY_CARGO_LOCK}" \
+ | grep -A1 '^name = "fluss-gateway"$' \
+ | grep -Fq "version = \"${CURRENT_GATEWAY_VERSION}\""; then
+ echo "Cannot find Gateway version ${CURRENT_GATEWAY_VERSION} in ${GATEWAY_CARGO_LOCK}." >&2
+ exit 1
+fi
+if ! grep -Fxq " version: ${CURRENT_GATEWAY_VERSION}" "${GATEWAY_OPENAPI}"; then
+ echo "Cannot find Gateway version ${CURRENT_GATEWAY_VERSION} in ${GATEWAY_OPENAPI}." >&2
+ exit 1
+fi
+if ! cut -f1 "${GATEWAY_DEPENDENCIES}" \
+ | grep -Fxq "fluss-gateway@${CURRENT_GATEWAY_VERSION}"; then
+ echo "Cannot find Gateway version ${CURRENT_GATEWAY_VERSION} in ${GATEWAY_DEPENDENCIES}." >&2
+ exit 1
+fi
+
+# Change the Java and Gateway versions only after every input has been validated.
find . -name 'pom.xml' -type f -exec perl -pi -e 's#<version>'$OLD_VERSION'</version>#<version>'$NEW_VERSION'</version>#; s#-'$OLD_VERSION'</version>#-'$NEW_VERSION'</version>#' {} \;
-git commit -am "Update version to $NEW_VERSION"
+export CURRENT_GATEWAY_VERSION GATEWAY_NEW_VERSION
+perl -0pi -e 's#(\[\[package\]\]\nname = "fluss-gateway"\nversion = ")\Q$ENV{CURRENT_GATEWAY_VERSION}\E(")#$1$ENV{GATEWAY_NEW_VERSION}$2#' "${GATEWAY_CARGO_LOCK}"
+perl -0pi -e 's#(\[package\].*?version = ")\Q$ENV{CURRENT_GATEWAY_VERSION}\E(")#$1$ENV{GATEWAY_NEW_VERSION}$2#s' "${GATEWAY_CARGO_TOML}"
+perl -pi -e 's#^( version: )\Q$ENV{CURRENT_GATEWAY_VERSION}\E$#$1$ENV{GATEWAY_NEW_VERSION}#' "${GATEWAY_OPENAPI}"
+perl -pi -e 's#^(fluss-gateway@)\Q$ENV{CURRENT_GATEWAY_VERSION}\E(\t)#$1$ENV{GATEWAY_NEW_VERSION}$2#' "${GATEWAY_DEPENDENCIES}"
+
+if ! grep -A2 '^\[\[package\]\]$' "${GATEWAY_CARGO_LOCK}" \
+ | grep -A1 '^name = "fluss-gateway"$' \
+ | grep -Fq "version = \"${GATEWAY_NEW_VERSION}\""; then
+ echo "Failed to update the Gateway version in ${GATEWAY_CARGO_LOCK}." >&2
+ exit 1
+fi
+if [[ "$(
+ sed -n '/^\[package\]/,/^\[/p' "${GATEWAY_CARGO_TOML}" \
+ | grep '^[[:space:]]*version[[:space:]]*=' \
+ | head -1 \
+ | sed -E 's/.*"([^"]+)".*/\1/'
+)" != "${GATEWAY_NEW_VERSION}" ]]; then
+ echo "Failed to update the Gateway version in ${GATEWAY_CARGO_TOML}." >&2
+ exit 1
+fi
+if ! grep -Fxq " version: ${GATEWAY_NEW_VERSION}" "${GATEWAY_OPENAPI}"; then
+ echo "Failed to update the Gateway version in ${GATEWAY_OPENAPI}." >&2
+ exit 1
+fi
+if ! cut -f1 "${GATEWAY_DEPENDENCIES}" \
+ | grep -Fxq "fluss-gateway@${GATEWAY_NEW_VERSION}"; then
+ echo "Failed to update the Gateway version in ${GATEWAY_DEPENDENCIES}." >&2
+ exit 1
+fi
+
+git commit -am "[release] Update version to $NEW_VERSION"
echo "Don't forget to push the change."
diff --git a/website/community/how-to-release/creating-a-fluss-release.mdx b/website/community/how-to-release/creating-a-fluss-release.mdx
index b261605c2..4a261271a 100644
--- a/website/community/how-to-release/creating-a-fluss-release.mdx
+++ b/website/community/how-to-release/creating-a-fluss-release.mdx
@@ -337,6 +337,7 @@ Tag the release commit:
```bash
git tag -s ${TAG} -m "${TAG}"
+RELEASE_COMMIT="$(git rev-parse "${TAG}^{}")"
```
### 2. Create source release files
@@ -360,6 +361,26 @@ tools $ RELEASE_VERSION=$RELEASE_VERSION releasing/create_binary_release.sh
This command creates a binary tarball and signs it under `tools/releasing/release` directory.
+Create the Linux Gateway convenience binaries on native `amd64` and `arm64`
+Docker buildx nodes. The script uses the pinned `rust:1.88-bookworm` builder
+and therefore defines Debian Bookworm (glibc 2.36) as the supported binary
+baseline. Run each command on a builder with a native node for that platform;
+do not compile the other architecture through QEMU:
+
+```bash
+tools $ RELEASE_VERSION=$RELEASE_VERSION GATEWAY_ARCH=amd64 releasing/create_gateway_release.sh
+tools $ RELEASE_VERSION=$RELEASE_VERSION GATEWAY_ARCH=arm64 releasing/create_gateway_release.sh
+```
+
+If the commands run on separate machines, copy both archives, signatures, and
+checksums into the same `tools/releasing/release/` directory before continuing.
+
+The Gateway archive follows the Java distribution layout (`bin/`, `conf/`,
+`LICENSE`, and `NOTICE`) and also includes its OpenAPI document and checked-in
+Rust dependency inventory. Like the Java distribution, its `LICENSE` and
+`NOTICE` come from component-specific binary versions rather than the source
+release files.
+
### 4. Create Helm Chart package
Then, we create the Helm Chart packages:
@@ -379,6 +400,12 @@ releasing/release
├── fluss-1.0.0-bin.tgz
├── fluss-1.0.0-bin.tgz.asc
├── fluss-1.0.0-bin.tgz.sha512
+├── fluss-gateway-1.0.0-bin-linux-amd64.tgz
+├── fluss-gateway-1.0.0-bin-linux-amd64.tgz.asc
+├── fluss-gateway-1.0.0-bin-linux-amd64.tgz.sha512
+├── fluss-gateway-1.0.0-bin-linux-arm64.tgz
+├── fluss-gateway-1.0.0-bin-linux-arm64.tgz.asc
+├── fluss-gateway-1.0.0-bin-linux-arm64.tgz.sha512
├── fluss-1.0.0-src.tgz
├── fluss-1.0.0-src.tgz.asc
├── fluss-1.0.0-src.tgz.sha512
@@ -392,7 +419,7 @@ releasing/release
│ └── fluss-1.0.0.tgz.sha512
└── index.yaml
-3 directories, 13 files
+3 directories, 19 files
```
@@ -463,7 +490,7 @@ Close the staging repository on Apache Nexus. When prompted for a description, e
### 7. Stage Docker images
:::note
-Make sure that you are authenticated with your Docker ID, and that your Docker ID has access to `apache/fluss`: `docker login -u <username>`. If you do not have access, you should seek help via the dev mailing list.
+Make sure that you are authenticated with your Docker ID, and that your Docker ID has access to `apache/fluss`, `apache/fluss-gateway`, and `apache/fluss-quickstart-flink`: `docker login -u <username>`. If you do not have access, you should seek help via the dev mailing list.
If you can't login Docker ID in your region because of network issues, you can find a cloud machine that can access Docker Hub, and perform the following steps there.
:::
@@ -481,16 +508,52 @@ $ cd docker/fluss
docker/fluss $ docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag apache/fluss:${RELEASE_VERSION}-rc${RC_NUM} .
```
+Like the Java image, the Gateway image consumes a prepared binary distribution
+instead of compiling project sources in buildx, so both voted archives have to be
+unpacked into `docker/fluss-gateway/build-target/` first. Step 5 moved them out of
+`tools/releasing/release/`, so point `GATEWAY_RELEASE_DIR` at the staging working
+copy that now holds them:
+
+```bash
+docker/fluss $ cd ../..
+$ RELEASE_VERSION=$RELEASE_VERSION \
+ GATEWAY_RELEASE_DIR=tools/target/fluss/fluss-${RELEASE_VERSION}-rc${RC_NUM} \
+ docker/fluss-gateway/prepare_build.sh
+```
+
+If you build the images on a different machine than the one that created the
+archives, download both `fluss-gateway-${RELEASE_VERSION}-bin-linux-*.tgz` files
+from `https://dist.apache.org/repos/dist/dev/fluss/fluss-${RELEASE_VERSION}-rc${RC_NUM}/`
+into any directory and point `GATEWAY_RELEASE_DIR` there instead. Only the `.tgz`
+files are needed. Also copy the `RELEASE_COMMIT` value recorded when the RC tag
+was created and export it on the image-build machine; do not derive it from that
+machine's checkout.
+
+The Dockerfile selects the matching `build-target/<arch>` directory for each
+target platform:
+
+```bash
+$ cd docker/fluss-gateway
+docker/fluss-gateway $ docker buildx build \
+ --push \
+ --platform linux/arm64,linux/amd64 \
+ --build-arg FLUSS_VERSION=${RELEASE_VERSION} \
+ --build-arg VCS_REF=${RELEASE_COMMIT} \
+ --tag apache/fluss-gateway:${RELEASE_VERSION}-rc${RC_NUM} \
+ .
+```
+
Then, run the following commands to build and push the flink, a customized Apache Flink image that includes all necessary libraries and JARs for the Fluss Quickstart guide:
```bash
-docker/fluss $ cd ../quickstart-flink
+docker/fluss-gateway $ cd ../quickstart-flink
docker/quickstart-flink $ ./prepare_build.sh
docker/quickstart-flink $ docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag apache/fluss-quickstart-flink:1.20-${RELEASE_VERSION}-rc${RC_NUM} .
```
Verify the RC images are present:
- https://hub.docker.com/r/apache/fluss/tags
+- https://hub.docker.com/r/apache/fluss-gateway/tags
- https://hub.docker.com/r/apache/fluss-quickstart-flink/tags
Then, update the `dockerVersion` field for the current release RC version in the `website/fluss-versions.json` file on the `main` branch to the value of `${RELEASE_VERSION}-rc${RC_NUM}` (which includes the RC suffix, e.g., `1.0.0-rc1`). This update should be committed and pushed to the `main` branch.
@@ -531,7 +594,7 @@ The final publish to **crates.io** and **PyPI** happens when the release tag is
- Source & binary & helm-chart distribution deployed to the dev repository of [dist.apache.org](https://dist.apache.org/repos/dist/dev/fluss/)
- Maven artifacts deployed to the staging repository of [repository.apache.org](https://repository.apache.org/content/repositories/)
-- RC Docker images pushed to DockerHub ([apache/fluss](https://hub.docker.com/r/apache/fluss/tags), [apache/fluss-quickstart-flink](https://hub.docker.com/r/apache/fluss-quickstart-flink/tags))
+- RC Docker images pushed to DockerHub ([apache/fluss](https://hub.docker.com/r/apache/fluss/tags), [apache/fluss-gateway](https://hub.docker.com/r/apache/fluss-gateway/tags), [apache/fluss-quickstart-flink](https://hub.docker.com/r/apache/fluss-quickstart-flink/tags))
- RC tag pushed to the [official repository](https://github.com/apache/fluss/tags)
- Updated `dockerVersion` in `fluss-versions.json` on `main` branch
- Client RC artifacts published to TestPyPI, and `cargo publish --dry-run` for `fluss-rs` is green
@@ -591,6 +654,7 @@ Upgrade note for the new release:
Docker images for the release candidate:
* fluss
+* fluss-gateway
* quickstart-flink
Please download, verify and test. To learn more about how to verify:
@@ -711,12 +775,14 @@ Pushing the `v${RELEASE_VERSION}` tag also triggers the client release workflows
### 5. Publish Docker Images
:::note
-Make sure that you are authenticated with your Docker ID, and that your Docker ID has access to `apache/fluss`: `docker login -u <username>`. If you do not have access, you should seek help via the dev mailing list.
+Make sure that you are authenticated with your Docker ID, and that your Docker ID has access to `apache/fluss`, `apache/fluss-gateway`, and `apache/fluss-quickstart-flink`: `docker login -u <username>`. If you do not have access, you should seek help via the dev mailing list.
:::
```bash
docker buildx imagetools create apache/fluss:${RELEASE_VERSION}-rc${RC_NUM} --tag apache/fluss:${RELEASE_VERSION}
+docker buildx imagetools create apache/fluss-gateway:${RELEASE_VERSION}-rc${RC_NUM} --tag apache/fluss-gateway:${RELEASE_VERSION}
+
docker buildx imagetools create apache/fluss-quickstart-flink:1.20-${RELEASE_VERSION}-rc${RC_NUM} --tag apache/fluss-quickstart-flink:1.20-${RELEASE_VERSION}
```
@@ -750,7 +816,7 @@ In [GitHub Milestones](https://github.com/apache/fluss/milestones), mark the cur
- Helm Chart package available in the release repository of https://dist.apache.org/repos/dist/release/fluss/helm-chart/
- Dev repository https://dist.apache.org/repos/dist/dev/fluss/ is empty
- Release tagged in the source code repository
-- Docker images for the release pushed to DockerHub ([apache/fluss](https://hub.docker.com/r/apache/fluss/tags), [apache/fluss-quickstart-flink](https://hub.docker.com/r/apache/fluss-quickstart-flink/tags))
+- Docker images for the release pushed to DockerHub ([apache/fluss](https://hub.docker.com/r/apache/fluss/tags), [apache/fluss-gateway](https://hub.docker.com/r/apache/fluss-gateway/tags), [apache/fluss-quickstart-flink](https://hub.docker.com/r/apache/fluss-quickstart-flink/tags))
- Milestone marked as released in GitHub
## Promote the release
diff --git a/website/community/how-to-release/pre-rc-checklist.md b/website/community/how-to-release/pre-rc-checklist.md
index a83150a61..7eb96cdce 100644
--- a/website/community/how-to-release/pre-rc-checklist.md
+++ b/website/community/how-to-release/pre-rc-checklist.md
@@ -12,6 +12,9 @@ Run through this before cutting a release candidate. It catches the problems tha
- [ ] Maven Central (Apache Nexus) access for `org.apache.fluss` — see [Release Manager Preparation](release-manager-preparation.md)
- [ ] `CARGO_REGISTRY_TOKEN`, `PYPI_API_TOKEN`, and `TEST_PYPI_API_TOKEN` configured as repository secrets
- [ ] crates.io owner of `fluss-rs`; PyPI maintainer of `pyfluss`
+- [ ] The ASF Infra request for `apache/fluss-gateway` is resolved, the Docker
+ Hub repository exists, and the release manager has access to
+ `apache/fluss`, `apache/fluss-gateway`, and `apache/fluss-quickstart-flink`
- [ ] GPG key published to the Apache KEYS file
## Build and publish dry-runs
@@ -29,10 +32,21 @@ Run through this before cutting a release candidate. It catches the problems tha
cd fluss-rust/bindings/cpp && bazel build //...
```
+- [ ] On native `amd64` and `arm64` buildx nodes, the Gateway distribution and
+ container smoke tests pass:
+
+ ```bash
+ GATEWAY_ARCH=<amd64-or-arm64> \
+ RUN_SMOKE=true \
+ docker/fluss-gateway/build.sh
+ ```
+
## Audits
- [ ] `cargo deny check licenses` passes; the Rust dependency list is regenerated and committed
-- [ ] Java + Rust + binding CI is green on the release branch
+- [ ] `fluss-gateway/scripts/generate_binary_license.py --check` passes and
+ the Gateway binary `LICENSE` / `NOTICE` match its runtime dependency closure
+- [ ] Java + Rust + binding + Gateway CI is green on the release branch
- [ ] `LICENSE` / `NOTICE` cover any third-party content bundled in the source release (including under `fluss-rust/`)
Once these pass, proceed to [Creating a Fluss Release](creating-a-fluss-release.mdx).
diff --git a/website/community/how-to-release/release-manager-preparation.md b/website/community/how-to-release/release-manager-preparation.md
index a175e48ff..5be003a3d 100644
--- a/website/community/how-to-release/release-manager-preparation.md
+++ b/website/community/how-to-release/release-manager-preparation.md
@@ -232,6 +232,14 @@ Publishing is automated by the `rust-release.yml` and `python-release.yml` workf
Regenerating the Rust dependency/license list (an ASF requirement) needs the toolchain in `fluss-rust/rust-toolchain.toml`, [cargo-deny](https://embarkstudios.github.io/cargo-deny/), and Python 3.11+ (for `fluss-rust/scripts/dependencies.py`).
+## Docker Hub access
+
+Before the first Gateway release, file an ASF Infra request to create and
+authorize the `apache/fluss-gateway` Docker Hub repository. Confirm that the
+release manager can push to `apache/fluss`, `apache/fluss-gateway`, and
+`apache/fluss-quickstart-flink`; the Gateway image cannot be staged until the
+new repository exists.
+
## Further reading
It's recommended but not mandatory to read following documents before making a release to know more details about apache release:
@@ -242,4 +250,3 @@ It's recommended but not mandatory to read following documents before making a r
- Release publish: https://infra.apache.org/release-publishing.html
- Release download pages: https://infra.apache.org/release-download-pages.html
- Publishing maven artifacts: https://infra.apache.org/publishing-maven-artifacts.html
-
diff --git a/website/community/how-to-release/verifying-a-fluss-release.md b/website/community/how-to-release/verifying-a-fluss-release.md
index 561c4d98a..608814741 100644
--- a/website/community/how-to-release/verifying-a-fluss-release.md
+++ b/website/community/how-to-release/verifying-a-fluss-release.md
@@ -9,7 +9,7 @@ sidebar_position: 3
Release vote email includes links to:
-- Distribution archives (source, admin, server) on dist.apache.org
+- Distribution archives (source, Java server, Gateway) on dist.apache.org
- Signature files (.asc)
- Checksum files (.sha512)
- KEYS file
@@ -51,6 +51,7 @@ If the verification is successful, you will see a message like this:
```
fluss-1.0.0-bin.tgz.sha512: OK
+fluss-gateway-1.0.0-bin-linux-amd64.tgz.sha512: OK
fluss-1.0.0-src.tgz.sha512: OK
```
@@ -90,6 +91,51 @@ Per-language verification:
The Rust workspace's dependency licenses are checked with [cargo-deny](https://embarkstudios.github.io/cargo-deny/); the release manager regenerates the dependency audit before the release.
+## Verifying the Gateway distribution
+
+Extract the Gateway archive on the matching Linux architecture and check its
+version, configuration, health endpoint, and graceful shutdown:
+
+```bash
+tar -xzf fluss-gateway-${RELEASE_VERSION}-bin-linux-amd64.tgz
+cd fluss-gateway-${RELEASE_VERSION}-bin-linux-amd64
+
+bin/fluss-gateway --version
+bin/fluss-gateway.sh --bind-address 127.0.0.1:8080 &
+GATEWAY_PID=$!
+
+curl --fail --silent --show-error http://127.0.0.1:8080/health
+
+kill -TERM ${GATEWAY_PID}
+wait ${GATEWAY_PID}
+```
+
+Confirm that the process exits with status `0`, and review `LICENSE`, `NOTICE`,
+and `DEPENDENCIES.rust.tsv` against the packaged contents. Repeat the same
+verification for the `arm64` archive on an `arm64` Linux host.
+
+The convenience binaries are built with the pinned Rust 1.88 Debian Bookworm
+builder and support Debian Bookworm's glibc 2.36 baseline or newer.
+
+Confirm that the release-candidate image contains both architectures:
+
+```bash
+docker buildx imagetools inspect \
+ apache/fluss-gateway:${RELEASE_VERSION}-rc${RC_NUM}
+```
+
+Then verify the image on matching `amd64` and `arm64` Docker hosts:
+
+```bash
+docker pull apache/fluss-gateway:${RELEASE_VERSION}-rc${RC_NUM}
+
+# Run the checked-in smoke test from the root of the extracted Fluss source
+# release, not from the Gateway binary distribution used above.
+cd /path/to/fluss-${RELEASE_VERSION}
+GATEWAY_IMAGE=apache/fluss-gateway:${RELEASE_VERSION}-rc${RC_NUM} \
+ docker/fluss-gateway/smoke-test.sh
+```
+
## Release artifacts and publish targets
A release publishes to several registries; confirm each one carries the release version:
@@ -101,7 +147,8 @@ A release publishes to several registries; confirm each one carries the release
| Python | [PyPI](https://pypi.org/project/pyfluss/) (RC → [TestPyPI](https://test.pypi.org/project/pyfluss/)) | `pyfluss` |
| C++ | source archive only (no registry) | — |
| Elixir | Hex.pm (post-1.0; not yet published) | `fluss` |
-| Docker | Docker Hub | `apache/fluss`, `apache/fluss-quickstart-flink` |
+| Gateway | dist.apache.org | `fluss-gateway-<version>-bin-linux-<arch>.tgz` |
+| Docker | Docker Hub | `apache/fluss`, `apache/fluss-gateway`, `apache/fluss-quickstart-flink` |
Source archives, signatures, and checksums are on [dist.apache.org](https://dist.apache.org/repos/dist/dev/fluss/) (dev) and, after the vote, on [downloads.apache.org](https://downloads.apache.org/fluss/).