Skip to content

Commit 450863e

Browse files
smaheshwar-pltrkevinjqliuCopilot
authored
ci: replace MinIO with RustFS in S3 tests (#962)
* ci: replace MinIO with RustFS in S3 tests Use RustFS 1.0.0 for Docker and native test fixtures, and initialize the S3 bucket with the AWS CLI. Generated-by: Codex * ci: improve RustFS startup diagnostics and readiness Expose server logs, retry bucket initialization, verify native downloads, and disable the unused console. Generated-by: Codex * ci: use generic object store naming and improve startup diagnostics - Rename the CI step to "Start Object Store" - Enable shell tracing in start_object_store.sh - Print the native server log only when it was started natively - Replace MinIO-specific wording in S3 comments Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Kevin Liu <kevin.jq.liu@gmail.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 2630339 commit 450863e

5 files changed

Lines changed: 141 additions & 165 deletions

File tree

‎.github/workflows/aws_test.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ jobs:
7474
bundle_awssdk: "ON"
7575
env:
7676
ICEBERG_TEST_S3_URI: s3://iceberg-test
77-
AWS_ACCESS_KEY_ID: minio
78-
AWS_SECRET_ACCESS_KEY: minio123
77+
AWS_ACCESS_KEY_ID: admin
78+
AWS_SECRET_ACCESS_KEY: password
7979
AWS_DEFAULT_REGION: us-east-1
8080
AWS_ENDPOINT_URL: http://127.0.0.1:9000
8181
AWS_EC2_METADATA_DISABLED: "TRUE"
@@ -114,10 +114,10 @@ jobs:
114114
run: |
115115
echo "CC=${{ matrix.CC }}" >> $GITHUB_ENV
116116
echo "CXX=${{ matrix.CXX }}" >> $GITHUB_ENV
117-
- name: Start MinIO
117+
- name: Start Object Store
118118
if: ${{ matrix.s3 == 'ON' }}
119119
shell: bash
120-
run: bash ci/scripts/start_minio.sh
120+
run: bash ci/scripts/start_object_store.sh
121121
- name: Set up sccache
122122
uses: ./.github/actions/setup-sccache
123123
with:

‎ci/scripts/start_minio.sh‎

Lines changed: 0 additions & 158 deletions
This file was deleted.

‎ci/scripts/start_object_store.sh‎

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
set -euxo pipefail
21+
22+
OBJECT_STORE_VERSION="${OBJECT_STORE_VERSION:-1.0.0}"
23+
OBJECT_STORE_IMAGE="${OBJECT_STORE_IMAGE:-rustfs/rustfs:${OBJECT_STORE_VERSION}}"
24+
OBJECT_STORE_CONTAINER_NAME="${OBJECT_STORE_CONTAINER_NAME:-iceberg-object-store}"
25+
OBJECT_STORE_ACCESS_KEY="${AWS_ACCESS_KEY_ID:-admin}"
26+
OBJECT_STORE_SECRET_KEY="${AWS_SECRET_ACCESS_KEY:-password}"
27+
OBJECT_STORE_PORT="${OBJECT_STORE_PORT:-9000}"
28+
OBJECT_STORE_BUCKET="${OBJECT_STORE_BUCKET:-iceberg-test}"
29+
OBJECT_STORE_ENDPOINT="${AWS_ENDPOINT_URL:-http://127.0.0.1:${OBJECT_STORE_PORT}}"
30+
OBJECT_STORE_DIR="${RUNNER_TEMP:-/tmp}/iceberg-object-store"
31+
OBJECT_STORE_LOG=""
32+
33+
wait_for_object_store() {
34+
for ((attempt = 0; attempt < 60; attempt++)); do
35+
if curl -fs --connect-timeout 1 --max-time 2 "${OBJECT_STORE_ENDPOINT}/health/ready" >/dev/null; then
36+
return 0
37+
fi
38+
sleep 1
39+
done
40+
echo "Object store did not become ready at ${OBJECT_STORE_ENDPOINT}." >&2
41+
if [ -n "${OBJECT_STORE_LOG}" ]; then
42+
cat "${OBJECT_STORE_LOG}" >&2
43+
else
44+
docker logs "${OBJECT_STORE_CONTAINER_NAME}" >&2 || true
45+
fi
46+
return 1
47+
}
48+
49+
start_object_store_docker() {
50+
if docker container inspect "${OBJECT_STORE_CONTAINER_NAME}" >/dev/null 2>&1; then
51+
docker rm -f "${OBJECT_STORE_CONTAINER_NAME}"
52+
fi
53+
54+
docker run -d --name "${OBJECT_STORE_CONTAINER_NAME}" \
55+
-p "${OBJECT_STORE_PORT}:9000" \
56+
-e "RUSTFS_ACCESS_KEY=${OBJECT_STORE_ACCESS_KEY}" \
57+
-e "RUSTFS_SECRET_KEY=${OBJECT_STORE_SECRET_KEY}" \
58+
-e RUSTFS_CONSOLE_ENABLE=false \
59+
-e RUSTFS_OBS_LOG_STDOUT_ENABLED=true \
60+
"${OBJECT_STORE_IMAGE}" /data
61+
}
62+
63+
start_object_store_native() {
64+
local platform binary
65+
case "$(uname -s)-$(uname -m)" in
66+
Darwin-arm64)
67+
platform=macos-aarch64
68+
binary=rustfs
69+
;;
70+
MINGW*-x86_64|MSYS*-x86_64|CYGWIN*-x86_64)
71+
platform=windows-x86_64
72+
binary=rustfs.exe
73+
;;
74+
*)
75+
echo "Use Docker to run RustFS on $(uname -s)-$(uname -m)." >&2
76+
return 1
77+
;;
78+
esac
79+
80+
local archive="rustfs-${platform}-v${OBJECT_STORE_VERSION}.zip"
81+
local release_url="https://github.com/rustfs/rustfs/releases/download/${OBJECT_STORE_VERSION}"
82+
mkdir -p "${OBJECT_STORE_DIR}/data"
83+
curl -fsSL --retry 3 \
84+
"${release_url}/${archive}" -o "${OBJECT_STORE_DIR}/${archive}"
85+
curl -fsSL --retry 3 "${release_url}/SHA256SUMS" -o "${OBJECT_STORE_DIR}/SHA256SUMS"
86+
(
87+
cd "${OBJECT_STORE_DIR}"
88+
grep -F " ${archive}" SHA256SUMS > rustfs.sha256
89+
if command -v sha256sum >/dev/null 2>&1; then
90+
sha256sum --check rustfs.sha256
91+
else
92+
shasum -a 256 --check rustfs.sha256
93+
fi
94+
)
95+
unzip -o "${OBJECT_STORE_DIR}/${archive}" -d "${OBJECT_STORE_DIR}"
96+
chmod +x "${OBJECT_STORE_DIR}/${binary}"
97+
OBJECT_STORE_LOG="${OBJECT_STORE_DIR}/rustfs.log"
98+
RUSTFS_ACCESS_KEY="${OBJECT_STORE_ACCESS_KEY}" \
99+
RUSTFS_SECRET_KEY="${OBJECT_STORE_SECRET_KEY}" \
100+
RUSTFS_ADDRESS=":${OBJECT_STORE_PORT}" \
101+
RUSTFS_CONSOLE_ENABLE=false \
102+
"${OBJECT_STORE_DIR}/${binary}" "${OBJECT_STORE_DIR}/data" \
103+
>"${OBJECT_STORE_LOG}" 2>&1 &
104+
}
105+
106+
create_bucket() {
107+
export AWS_ACCESS_KEY_ID="${OBJECT_STORE_ACCESS_KEY}"
108+
export AWS_SECRET_ACCESS_KEY="${OBJECT_STORE_SECRET_KEY}"
109+
export AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION:-us-east-1}"
110+
# The health endpoint can pass before S3 requests are accepted.
111+
for ((attempt = 0; attempt < 5; attempt++)); do
112+
if aws --endpoint-url "${OBJECT_STORE_ENDPOINT}" s3api head-bucket --bucket "${OBJECT_STORE_BUCKET}" >/dev/null 2>&1 || \
113+
aws --endpoint-url "${OBJECT_STORE_ENDPOINT}" s3api create-bucket --bucket "${OBJECT_STORE_BUCKET}"; then
114+
return 0
115+
fi
116+
sleep 2
117+
done
118+
echo "Failed to create bucket ${OBJECT_STORE_BUCKET} at ${OBJECT_STORE_ENDPOINT}." >&2
119+
return 1
120+
}
121+
122+
if ! command -v aws >/dev/null 2>&1; then
123+
echo "AWS CLI is required to create the test bucket." >&2
124+
exit 1
125+
fi
126+
127+
if command -v docker >/dev/null 2>&1 && [ "$(docker info --format '{{.OSType}}' 2>/dev/null)" = linux ]; then
128+
start_object_store_docker
129+
else
130+
start_object_store_native
131+
fi
132+
133+
wait_for_object_store
134+
create_bucket

‎src/iceberg/arrow/s3/arrow_s3_file_io.cc‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ Result<::arrow::fs::S3Options> ConfigureS3Options(
109109
options.region = *region;
110110
}
111111

112-
// Configure endpoint (for MinIO, LocalStack, etc.)
112+
// Configure endpoint (for S3-compatible object stores)
113113
if (const auto* endpoint = FindProperty(properties, S3Properties::kEndpoint);
114114
endpoint != nullptr) {
115115
options.endpoint_override = SplitEndpointScheme(*endpoint, options);

‎src/iceberg/arrow/s3/s3_properties.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ struct S3Properties {
4444
static constexpr std::string_view kSessionToken = "s3.session-token";
4545
/// AWS region, standard Iceberg client property.
4646
static constexpr std::string_view kClientRegion = "client.region";
47-
/// Custom endpoint override (for MinIO, LocalStack, etc.)
47+
/// Custom endpoint override (for S3-compatible object stores)
4848
static constexpr std::string_view kEndpoint = "s3.endpoint";
49-
/// Whether to use path-style access (needed for MinIO)
49+
/// Whether to use path-style access (needed for some S3-compatible object stores)
5050
static constexpr std::string_view kPathStyleAccess = "s3.path-style-access";
5151
/// Whether SSL is enabled
5252
static constexpr std::string_view kSslEnabled = "s3.ssl.enabled";

0 commit comments

Comments
 (0)