diff --git a/manage.sh b/manage.sh index 86ec8cf..f93a789 100755 --- a/manage.sh +++ b/manage.sh @@ -247,10 +247,15 @@ stack_group() { compose() { local stack="$1" shift + local -a docker_args=(compose) + + if [[ "${STACKS_QUIET_PROGRESS:-0}" == "1" ]]; then + docker_args+=(--progress quiet) + fi ( cd -- "$STACKS_DIR/$stack" || exit 1 - docker compose "$@" + docker "${docker_args[@]}" "$@" ) } @@ -285,10 +290,17 @@ run_group() { local action="$2" local group_name="${GROUP_NAMES[group_index]}" local limit="${GROUP_LIMITS[group_index]}" - local semaphore_dir semaphore_fifo semaphore_fd - local stack pid i status details - local failed=0 - local -a stacks=() pids=() pid_stacks=() + local stack pid finished_pid status result result_color success_result details + local next=0 running=0 completed=0 failed=0 + local success_color="" failure_color="" color_reset="" + local -a stacks=() + local -A pid_stacks=() + + if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then + success_color=$'\033[32m' + failure_color=$'\033[31m' + color_reset=$'\033[0m' + fi read -r -a stacks <<<"${GROUP_STACKS[group_index]}" ((${#stacks[@]} > 0)) || return 0 @@ -308,46 +320,50 @@ run_group() { echo echo "==> Group $group_name: $action ($details)" - semaphore_dir="$(mktemp -d "${TMPDIR:-/tmp}/stacks-manage.XXXXXX")" || - die "cannot create semaphore directory" - semaphore_fifo="$semaphore_dir/tokens" - mkfifo "$semaphore_fifo" || die "cannot create semaphore" - exec {semaphore_fd}<>"$semaphore_fifo" || die "cannot open semaphore" + case "$action" in + up | start) success_result="Started" ;; + restart) success_result="Restarted" ;; + stop) success_result="Stopped" ;; + down) success_result="Removed" ;; + pull) success_result="Pulled" ;; + update) success_result="Updated" ;; + esac - for ((i = 0; i < limit; i++)); do - printf '\n' >&"$semaphore_fd" - done + while ((next < ${#stacks[@]} || running > 0)); do + while ((next < ${#stacks[@]} && running < limit)); do + stack="${stacks[next]}" + STACKS_QUIET_PROGRESS=1 run_stack "$stack" "$action" 0 & + pid="$!" + pid_stacks["$pid"]="$stack" + ((next += 1, running += 1)) + done - for stack in "${stacks[@]}"; do - IFS= read -r -u "$semaphore_fd" + finished_pid="" + status=0 + wait -n -p finished_pid || status=$? + [[ -n "$finished_pid" ]] || die "cannot identify completed stack" - ( - status=0 - run_stack "$stack" "$action" 0 || status=$? - printf '\n' >&"$semaphore_fd" - exit "$status" - ) & + stack="${pid_stacks[$finished_pid]}" + unset 'pid_stacks[$finished_pid]' + ((running -= 1)) - pids+=("$!") - pid_stacks+=("$stack") - done - - for ((i = 0; i < ${#pids[@]}; i++)); do - pid="${pids[i]}" - stack="${pid_stacks[i]}" - - if wait "$pid"; then + if ((status == 0)); then + result="$success_result" + result_color="$success_color" ((RUN_SUCCESS += 1)) else + result="Failed" + result_color="$failure_color" ((RUN_FAILED += 1)) RUN_FAILED_STACKS+=("$stack") ((failed += 1)) fi - done - exec {semaphore_fd}>&- - rm -f -- "$semaphore_fifo" - rmdir -- "$semaphore_dir" + ((completed += 1)) + printf '[%d/%d] %s: %s%s%s\n' \ + "$completed" "${#stacks[@]}" "$stack" \ + "$result_color" "$result" "$color_reset" + done ((failed == 0)) }