#!/bin/bash TEST_MACHINES=$( cat <<'HEREDOC' lrineau@bonnard lrineau@cgal cgaltest@friedrich lrineau@rubens HEREDOC ) machine_title() { printf '\n## %s ##\n' $1 } machine_tested_images() { echo echo '```plain' ssh $1 cat /home/$2/.config/CGAL/test_cgal_docker_images echo '```' } docker_is_active_cmd() { systemctl is-active -q docker return $? } declare -xf docker_is_active_cmd docker_cmd() { if docker_is_active_cmd; then docker $@ else podman --url unix:/var/run/podman/podman.sock $@ fi } declare -xf docker_cmd list_of_containers_cmd() { docker_cmd ps -a --format '{{.Names}}' --filter name="CGAL-" } declare -xf list_of_containers_cmd container_status_cmd() { docker_cmd inspect --format '{{.State.Status}}' $1 } declare -xf container_status_cmd container_human_readable_status_cmd() { docker_cmd ps --all --filter name=$1 --format '{{.Status}}' } declare -xf container_human_readable_status_cmd simplify_date_cmd() { date=$1 pattern=' \+[0-9]{4} [+]?[A-Z0-9]{3,}$' if [[ $date =~ $pattern ]]; then date=${date% *} fi echo "$date" } declare -xf simplify_date_cmd container_start_time_cmd() { simplify_date_cmd "$(docker_cmd inspect --format '{{.State.StartedAt}}' $1)" } declare -xf container_start_time_cmd container_end_time_cmd() { simplify_date_cmd "$(docker_cmd inspect --format '{{.State.FinishedAt}}' $1)" } declare -xf container_end_time_cmd container_running_time_cmd() { start_time=$(container_start_time_cmd $1) end_time=$(container_end_time_cmd $1) status=$(container_status_cmd $1) if [ "$status" = "running" ]; then end_time=$(date -u '+%Y-%m-%dT%H:%M:%S.%NZ') fi secs=$(($(date -d "$end_time" +%s) - $(date -d "$start_time" +%s))) printf '%02dh:%02dm:%02ds\n' $((secs / 3600)) $((secs % 3600 / 60)) $((secs % 60)) } declare -xf container_running_time_cmd display_one_container_line_cmd() { printf '%s\t%s\t%s\t%s\t%s\n' "$1" "$2" "$3" "$4" "$5" } declare -xf display_one_container_line_cmd list_cgal_test_container_cmd() { # docker_cmd ps -a --filter name=CGAL- display_one_container_line_cmd "CONTAINER" "START TIME" "END TIME" "RUNNING TIME" "STATUS" for container in $(list_of_containers_cmd); do start_time="$(container_start_time_cmd $container)" end_time="$(container_end_time_cmd $container)" dur=$(container_running_time_cmd $container) status="$(container_status_cmd $container) - $(container_human_readable_status_cmd $container)" display_one_container_line_cmd "$container" "$start_time" "$end_time" "$dur" "$status" done } declare -xf list_cgal_test_container_cmd display_all_exported_cmd_functions() { funcs=$(declare -F | awk '/ -fx .*_cmd$/ {print $3}') for func in $funcs; do declare -f $func done } machine_list_cgal_test_container() { printf '\n```tsv\n' remote_script=$( display_all_exported_cmd_functions printf "export PS4='+ %s >> %s'\n" "$1" "$PS4" echo list_cgal_test_container_cmd ) ssh $1 bash -$- -s <<<"$remote_script" printf '```\n' } help() { cat </dev/null || { error_out 'sed is required' } if [[ $1 == --table ]] && ! command -v pandoc >/dev/null; then error_out 'pandoc is required for the option --table' fi if [[ $1 == --column ]] && ! command -v column >/dev/null; then error_out 'column is required for the option --column' fi if [[ $1 == --bat ]] && ! command -v bat >/dev/null; then error_out 'bat is required for the option --bat' fi set_pretty_csv_to_md_table() { pretty_csv() ( echo sed '/```/ d; /^$/ d' | pandoc -f tsv -t gfm ) } set_pretty_csv_to_column() { pretty_csv() { echo column -t -s $'\t' -o $'\t' | sed 's/^\(```[^ ]*\) *\t.*/\1/' } } set_pretty_csv_to_bat() { pretty_csv() { bat --tabs=50 --paging=never --plain -l csv } } set_pretty_csv_to_cat() { pretty_csv() { cat } } case "$1" in --table) set_pretty_csv_to_md_table ;; --column) set_pretty_csv_to_column ;; --bat) set_pretty_csv_to_bat ;; --plain) set_pretty_csv_to_cat ;; '') if command -v bat >/dev/null; then set_pretty_csv_to_bat elif command -v column >/dev/null; then set_pretty_csv_to_column elif command -v pandoc >/dev/null; then set_pretty_csv_to_md_table else set_pretty_csv_to_cat fi ;; *) error_out "Unknown option $1" ;; esac ERROR_MACHINES="" for machine in $TEST_MACHINES; do USER=${machine%@*} HOST=${machine#*@} ssh "$HOST" test -f /home/$USER/.config/CGAL/test_cgal_docker_images || { ERROR_MACHINES="$ERROR_MACHINES $machine" } done if [ -n "$ERROR_MACHINES" ]; then for machine in $ERROR_MACHINES; do USER=${machine%@*} HOST=${machine#*@} printf 'ERROR: cannot read file `/home/%s/.config/CGAL/test_cgal_docker_images` on ssh host `%s`\n' $USER $HOST done exit 1 fi cat <