Commit 5e065f15 authored by Ivan Mazhukin's avatar Ivan Mazhukin

add "--exec" for executing custom commands inside containers

parent 902cbfd2
...@@ -39,6 +39,15 @@ ...@@ -39,6 +39,15 @@
./epm-docker-test.sh ayugram --preset all ./epm-docker-test.sh ayugram --preset all
``` ```
Выполнить произвольную команду в контейнере:
```bash
./epm-docker-test.sh --exec "cat /etc/os-release | head -3" fedora alt:p11
./epm-docker-test.sh --exec "epm install wget && wget --version" --preset main
```
При использовании `--exec` имя приложения не указывается — позиционные аргументы трактуются как системы.
Параллельный запуск: Параллельный запуск:
```bash ```bash
...@@ -106,6 +115,7 @@ ...@@ -106,6 +115,7 @@
- `--builder-path <path>`: явный builder64-путь вместо дефолта - `--builder-path <path>`: явный builder64-путь вместо дефолта
- `--preset <all|russian|main>`: добавить набор систем - `--preset <all|russian|main>`: добавить набор систем
- `--latest`: передать `--latest` в `epm play` (принудительно последняя версия) - `--latest`: передать `--latest` в `epm play` (принудительно последняя версия)
- `--exec <cmd>`: выполнить произвольную shell-команду вместо `epm play` (bootstrap системы выполняется как обычно)
- `--parallel`: запустить все тесты параллельно - `--parallel`: запустить все тесты параллельно
- `-j <N>`: запустить не более N тестов одновременно - `-j <N>`: запустить не более N тестов одновременно
- `--log-root <path>`: каталог для логов - `--log-root <path>`: каталог для логов
......
...@@ -10,6 +10,7 @@ DEFAULT_LOG_ROOT="${XDG_STATE_HOME:-$HOME/.local/state}/epm-docker-test" ...@@ -10,6 +10,7 @@ DEFAULT_LOG_ROOT="${XDG_STATE_HOME:-$HOME/.local/state}/epm-docker-test"
COMMAND="play" COMMAND="play"
PLAY_FLAGS=() PLAY_FLAGS=()
EXEC_COMMAND=""
APP_NAME="" APP_NAME=""
SYSTEM_IMAGE="" SYSTEM_IMAGE=""
RUN_MODE="auto" RUN_MODE="auto"
...@@ -59,6 +60,7 @@ Usage: ...@@ -59,6 +60,7 @@ Usage:
epm-docker-test.sh [options] play <app> <system> [<system> ...] epm-docker-test.sh [options] play <app> <system> [<system> ...]
epm-docker-test.sh [options] <app> <system> [<system> ...] epm-docker-test.sh [options] <app> <system> [<system> ...]
epm-docker-test.sh [options] <app> --preset <name> epm-docker-test.sh [options] <app> --preset <name>
epm-docker-test.sh --exec <cmd> [options] <system> [<system> ...]
Options: Options:
--mode <auto|local|remote> Runner mode. Default: auto --mode <auto|local|remote> Runner mode. Default: auto
...@@ -74,6 +76,7 @@ Options: ...@@ -74,6 +76,7 @@ Options:
--preset <all|russian|main> --preset <all|russian|main>
Add a named system preset Add a named system preset
--latest Pass --latest to epm play --latest Pass --latest to epm play
--exec <cmd> Run arbitrary shell command instead of epm play
--parallel Run tests in parallel (all at once) --parallel Run tests in parallel (all at once)
-j <N> Run up to N tests in parallel -j <N> Run up to N tests in parallel
--log-root <path> Directory for saved logs --log-root <path> Directory for saved logs
...@@ -85,6 +88,7 @@ Examples: ...@@ -85,6 +88,7 @@ Examples:
epm-docker-test.sh telegram --preset main epm-docker-test.sh telegram --preset main
epm-docker-test.sh play telegram Fedora/43 epm-docker-test.sh play telegram Fedora/43
epm-docker-test.sh --remote-user builder-robot --eepm-source builder64 telegram fedora:43 epm-docker-test.sh --remote-user builder-robot --eepm-source builder64 telegram fedora:43
epm-docker-test.sh --exec "epm install wget && wget --version" fedora alt:p11
EOF EOF
} }
...@@ -387,7 +391,7 @@ create_log_file() { ...@@ -387,7 +391,7 @@ create_log_file() {
[[ -w "$log_root" ]] || fatal "Could not write to log root: $log_root" [[ -w "$log_root" ]] || fatal "Could not write to log root: $log_root"
fi fi
safe_app="$(sanitize_name "$APP_NAME")" safe_app="$(sanitize_name "${APP_NAME:-exec}")"
safe_system="$(sanitize_name "$SYSTEM_IMAGE")" safe_system="$(sanitize_name "$SYSTEM_IMAGE")"
timestamp="$(date +%Y%m%d-%H%M%S)" timestamp="$(date +%Y%m%d-%H%M%S)"
log_name="${safe_app}-${safe_system}-${timestamp}.log" log_name="${safe_app}-${safe_system}-${timestamp}.log"
...@@ -474,9 +478,7 @@ build_container_script() { ...@@ -474,9 +478,7 @@ build_container_script() {
set -eu set -eu
TEST_COMMAND="$1" TEST_COMMAND="$1"
APP_NAME="$2" shift
shift 2
EXTRA_FLAGS="$*"
SOURCE_DIR="/work/eepm" SOURCE_DIR="/work/eepm"
run_eepm() { run_eepm() {
...@@ -531,7 +533,12 @@ esac ...@@ -531,7 +533,12 @@ esac
case "$TEST_COMMAND" in case "$TEST_COMMAND" in
play) play)
exec bash ./bin/eepm play --auto $EXTRA_FLAGS "$APP_NAME" APP_NAME="$1"
shift
exec bash ./bin/eepm play --auto "$@" "$APP_NAME"
;;
exec)
exec bash -c "$1"
;; ;;
*) *)
printf '[container] unsupported test command: %s\n' "$TEST_COMMAND" >&2 printf '[container] unsupported test command: %s\n' "$TEST_COMMAND" >&2
...@@ -548,13 +555,20 @@ run_container_locally() { ...@@ -548,13 +555,20 @@ run_container_locally() {
local inner_script container_name local inner_script container_name
local current_user local current_user
local status local status
local -a inner_args
require_command docker require_command docker
inner_script="$(mktemp "${TMPDIR:-/tmp}/epm-docker-test-inner.XXXXXX.sh")" inner_script="$(mktemp "${TMPDIR:-/tmp}/epm-docker-test-inner.XXXXXX.sh")"
build_container_script "$inner_script" build_container_script "$inner_script"
container_name="epm-test-$(sanitize_name "$APP_NAME")-$(sanitize_name "$SYSTEM_IMAGE")-$$" if [[ -n "$EXEC_COMMAND" ]]; then
inner_args=(exec "$EXEC_COMMAND")
container_name="epm-test-exec-$(sanitize_name "$SYSTEM_IMAGE")-$$"
else
inner_args=(play "$APP_NAME" "${PLAY_FLAGS[@]}")
container_name="epm-test-$(sanitize_name "$APP_NAME")-$(sanitize_name "$SYSTEM_IMAGE")-$$"
fi
info "Using eepm tree: $resolved_source" info "Using eepm tree: $resolved_source"
info "Target image: $SYSTEM_IMAGE" info "Target image: $SYSTEM_IMAGE"
...@@ -572,7 +586,7 @@ run_container_locally() { ...@@ -572,7 +586,7 @@ run_container_locally() {
--volume "$resolved_source:/work/eepm:ro" \ --volume "$resolved_source:/work/eepm:ro" \
--volume "$inner_script:/tmp/epm-docker-test-inner.sh:ro" \ --volume "$inner_script:/tmp/epm-docker-test-inner.sh:ro" \
"$SYSTEM_IMAGE" \ "$SYSTEM_IMAGE" \
sh /tmp/epm-docker-test-inner.sh "$COMMAND" "$APP_NAME" "${PLAY_FLAGS[@]}"; then sh /tmp/epm-docker-test-inner.sh "${inner_args[@]}"; then
status=0 status=0
else else
status=$? status=$?
...@@ -610,7 +624,11 @@ build_remote_args() { ...@@ -610,7 +624,11 @@ build_remote_args() {
[[ -n "$BUILDER_PATH" ]] && REMOTE_ARGS+=(--builder-path "$BUILDER_PATH") [[ -n "$BUILDER_PATH" ]] && REMOTE_ARGS+=(--builder-path "$BUILDER_PATH")
fi fi
REMOTE_ARGS+=("$COMMAND" "$APP_NAME" "$SYSTEM_IMAGE") if [[ -n "$EXEC_COMMAND" ]]; then
REMOTE_ARGS+=(--exec "$EXEC_COMMAND" "$SYSTEM_IMAGE")
else
REMOTE_ARGS+=("$COMMAND" "$APP_NAME" "$SYSTEM_IMAGE")
fi
} }
run_container_via_ssh() { run_container_via_ssh() {
...@@ -633,7 +651,13 @@ run_container_via_ssh() { ...@@ -633,7 +651,13 @@ run_container_via_ssh() {
bash -s -- bash -s --
) )
if ssh "${ssh_args[@]}" "${REMOTE_ARGS[@]}" <"$SCRIPT_PATH"; then local -a escaped_args
local arg
for arg in "${REMOTE_ARGS[@]}"; do
escaped_args+=("$(printf '%q' "$arg")")
done
if ssh "${ssh_args[@]}" "${escaped_args[@]}" <"$SCRIPT_PATH"; then
status=0 status=0
else else
status=$? status=$?
...@@ -674,29 +698,39 @@ run_once() { ...@@ -674,29 +698,39 @@ run_once() {
esac esac
} }
test_description() {
if [[ -n "$EXEC_COMMAND" ]]; then
printf 'exec: %s' "$EXEC_COMMAND"
else
printf 'epm %s %s' "$COMMAND" "$APP_NAME"
fi
}
run_for_system() { run_for_system() {
local system_image="$1" local system_image="$1"
local index="$2" local index="$2"
local total="$3" local total="$3"
local status local status
local desc
SYSTEM_IMAGE="$system_image" SYSTEM_IMAGE="$system_image"
LOG_FILE="$(create_log_file)" LOG_FILE="$(create_log_file)"
desc="$(test_description)"
if ((total > 1)); then if ((total > 1)); then
info "Run [$index/$total]: epm $COMMAND $APP_NAME on $SYSTEM_IMAGE" info "Run [$index/$total]: $desc on $SYSTEM_IMAGE"
fi fi
info "Log file: $LOG_FILE" info "Log file: $LOG_FILE"
info "Normalized system: $SYSTEM_IMAGE" info "Normalized system: $SYSTEM_IMAGE"
info "Test command: epm $COMMAND $APP_NAME" info "Test command: $desc"
run_once 2>&1 | tee "$LOG_FILE" && status=0 || status=$? run_once 2>&1 | tee "$LOG_FILE" && status=0 || status=$?
if ((status == 0)); then if ((status == 0)); then
printf '\nTest passed: epm %s %s on %s\n' "$COMMAND" "$APP_NAME" "$SYSTEM_IMAGE" printf '\nTest passed: %s on %s\n' "$desc" "$SYSTEM_IMAGE"
printf 'Log: %s\n' "$LOG_FILE" printf 'Log: %s\n' "$LOG_FILE"
else else
printf '\nTest failed: epm %s %s on %s\n' "$COMMAND" "$APP_NAME" "$SYSTEM_IMAGE" >&2 printf '\nTest failed: %s on %s\n' "$desc" "$SYSTEM_IMAGE" >&2
printf 'Log: %s\n' "$LOG_FILE" >&2 printf 'Log: %s\n' "$LOG_FILE" >&2
print_failure_excerpt print_failure_excerpt
fi fi
...@@ -802,6 +836,11 @@ parse_args() { ...@@ -802,6 +836,11 @@ parse_args() {
PLAY_FLAGS+=(--latest) PLAY_FLAGS+=(--latest)
shift shift
;; ;;
--exec)
[[ $# -ge 2 ]] || fatal "--exec requires a value"
EXEC_COMMAND="$2"
shift 2
;;
--log-root) --log-root)
[[ $# -ge 2 ]] || fatal "--log-root requires a value" [[ $# -ge 2 ]] || fatal "--log-root requires a value"
LOG_ROOT="$2" LOG_ROOT="$2"
...@@ -832,14 +871,17 @@ parse_args() { ...@@ -832,14 +871,17 @@ parse_args() {
esac esac
done done
if ((${#positional[@]} < 1)); then if [[ -n "$EXEC_COMMAND" ]]; then
usage >&2 SYSTEM_INPUTS=("${positional[@]}")
exit 1 else
if ((${#positional[@]} < 1)); then
usage >&2
exit 1
fi
APP_NAME="${positional[0]}"
SYSTEM_INPUTS=("${positional[@]:1}")
fi fi
APP_NAME="${positional[0]}"
SYSTEM_INPUTS=("${positional[@]:1}")
if ((${#SYSTEM_INPUTS[@]} == 0 && ${#PRESET_NAMES[@]} == 0)); then if ((${#SYSTEM_INPUTS[@]} == 0 && ${#PRESET_NAMES[@]} == 0)); then
fatal "At least one target system or --preset is required" fatal "At least one target system or --preset is required"
fi fi
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment