mirror of
https://github.com/apache/kafka.git
synced 2026-10-28 16:35:34 +08:00
Prefer `docker compose` when running Docker image sanity tests, with a fallback to `docker-compose` when the compose subcommand is unavailable. The Compose command detection is shared through `common.py`, and the detected command is passed into the sanity test runner so the build test and the compose up/down steps use the same command. ### Testing ```bash .venv/bin/python docker_build_test.py kafka/test \ --image-tag local-snapshot \ --image-type jvm \ --kafka-archive /home/russole/kafka/kafka/core/build/distributions/kafka_2.13-4.5.0-SNAPSHOT.tgz \ --test ``` Reviewers: Chia-Ping Tsai <chia7712@gmail.com>
104 lines
3.9 KiB
Python
104 lines
3.9 KiB
Python
#!/usr/bin/env python
|
|
|
|
# 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.
|
|
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
import os
|
|
import shutil
|
|
|
|
SUPPORTED_CONTAINER_RUNTIMES = ("docker", "podman")
|
|
|
|
def execute(command):
|
|
if subprocess.run(command).returncode != 0:
|
|
raise SystemError("Failure in executing following command:- ", " ".join(command))
|
|
|
|
def detect_compose_command(container_runtime):
|
|
compose_command = [container_runtime, "compose"]
|
|
try:
|
|
if subprocess.run(
|
|
compose_command + ["version"],
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
).returncode == 0:
|
|
return compose_command
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
legacy_compose_command = f"{container_runtime}-compose"
|
|
if shutil.which(legacy_compose_command) is not None:
|
|
return [legacy_compose_command]
|
|
|
|
raise RuntimeError(
|
|
f"No Compose command found. Tried '{container_runtime} compose' and "
|
|
f"'{legacy_compose_command}'. Please install Compose and ensure it "
|
|
"is available on PATH."
|
|
)
|
|
|
|
def get_input(message):
|
|
value = input(message)
|
|
if value == "":
|
|
raise ValueError("This field cannot be empty")
|
|
return value
|
|
|
|
def build_docker_image_runner(command, image_type, kafka_archive=None):
|
|
temp_dir_path = tempfile.mkdtemp()
|
|
current_dir = os.path.dirname(os.path.realpath(__file__))
|
|
shutil.copytree(f"{current_dir}/{image_type}", f"{temp_dir_path}/{image_type}", dirs_exist_ok=True)
|
|
shutil.copytree(f"{current_dir}/resources", f"{temp_dir_path}/{image_type}/resources", dirs_exist_ok=True)
|
|
shutil.copy(f"{current_dir}/server.properties", f"{temp_dir_path}/{image_type}")
|
|
|
|
kafka_archive_path = Path(temp_dir_path) / image_type / "kafka.tgz"
|
|
if kafka_archive:
|
|
shutil.copy(kafka_archive, kafka_archive_path)
|
|
else:
|
|
# Podman requires the COPY source to exist before kafka_url is
|
|
# downloaded by the Dockerfile.
|
|
kafka_archive_path.touch()
|
|
command = command.replace("$DOCKER_FILE", f"{temp_dir_path}/{image_type}/Dockerfile")
|
|
command = command.replace("$DOCKER_DIR", f"{temp_dir_path}/{image_type}")
|
|
try:
|
|
execute(command.split())
|
|
except Exception as e:
|
|
raise SystemError("Container image build failed") from e
|
|
finally:
|
|
shutil.rmtree(temp_dir_path)
|
|
|
|
def detect_container_runtime():
|
|
configured_runtime = os.environ.get("CONTAINER_RUNTIME")
|
|
|
|
if configured_runtime:
|
|
if configured_runtime not in SUPPORTED_CONTAINER_RUNTIMES:
|
|
raise ValueError(
|
|
f"Unsupported container runtime: {configured_runtime}. "
|
|
f"Supported runtimes: {', '.join(SUPPORTED_CONTAINER_RUNTIMES)}"
|
|
)
|
|
if shutil.which(configured_runtime) is None:
|
|
raise RuntimeError(
|
|
f"Container runtime '{configured_runtime}' was not found"
|
|
)
|
|
return configured_runtime
|
|
|
|
for runtime in SUPPORTED_CONTAINER_RUNTIMES:
|
|
if shutil.which(runtime):
|
|
return runtime
|
|
|
|
raise RuntimeError(
|
|
"No supported container runtime found. "
|
|
"Please install Docker or Podman, or set CONTAINER_RUNTIME."
|
|
)
|