fix(host): stop forcing compose -T so operator logs stream live

podman-compose and docker compose allocate a pseudo-TTY by default;
always passing -T block-buffered export progress. Omit -T for operator
runs and set DCE_COMPOSE_TTY=0 only for cron log append. Adds compose
TTY smokes and cron job env assertion.
This commit is contained in:
Copilot
2026-06-03 06:23:12 -05:00
parent d8742c5c7b
commit 14796e9c09
5 changed files with 111 additions and 4 deletions

View File

@@ -37,6 +37,8 @@ Environment:
DISCORD_TOKEN Direct token value (highest precedence after refresh).
DISCORD_TOKEN_FILE Optional path to a file containing the Discord token.
DCE_REAUTH_COMMAND Optional absolute path to an executable reauth script under the repo root.
DCE_COMPOSE_TTY When zero, compose run passes -T (no pseudo-TTY). Default omits -T
so compose backends allocate a TTY for line-buffered progress logs.
Notes:
When $ENV_FILE is missing, exported DISCORD_TOKEN or DISCORD_TOKEN_FILE is used instead.
@@ -255,11 +257,19 @@ resolve_compose_bin() {
COMPOSE_BIN=""
}
compose_tty_flag() {
if [[ "${DCE_COMPOSE_TTY:-1}" == "0" ]]; then
printf '%s' '-T'
fi
}
compose_run_args() {
local -n _out=$1
local subcommand=$2
local tty_flag
shift 2
tty_flag=$(compose_tty_flag)
resolve_compose_bin
_out=()
@@ -269,7 +279,9 @@ compose_run_args() {
--env-file "$COMPOSE_ENV_FILE"
-f "$COMPOSE_FILE"
run
-T
)
[[ -n "$tty_flag" ]] && _out+=("$tty_flag")
_out+=(
--rm
discord-scraper
"$subcommand"
@@ -280,7 +292,9 @@ compose_run_args() {
--env-file "$COMPOSE_ENV_FILE"
-f "$COMPOSE_FILE"
run
-T
)
[[ -n "$tty_flag" ]] && _out+=("$tty_flag")
_out+=(
--rm
discord-scraper
"$subcommand"
@@ -292,7 +306,9 @@ compose_run_args() {
--env-file "$COMPOSE_ENV_FILE"
-f "$COMPOSE_FILE"
run
-T
)
[[ -n "$tty_flag" ]] && _out+=("$tty_flag")
_out+=(
--rm
discord-scraper
"$subcommand"

View File

@@ -348,7 +348,7 @@ main() {
lock_prefix=""
fi
job_line="$cron_line cd $(printf '%q' "$REPO_ROOT") && ${lock_prefix}${scrape_command}>> $(printf '%q' "$LOG_FILE") 2>&1"
job_line="$cron_line cd $(printf '%q' "$REPO_ROOT") && DCE_COMPOSE_TTY=0 ${lock_prefix}${scrape_command}>> $(printf '%q' "$LOG_FILE") 2>&1"
local cron_block
cron_block=$(printf '%s\n%s\n%s\n' "$begin_marker" "$job_line" "$end_marker")

View File

@@ -103,6 +103,24 @@ run_host() {
"$REPO_ROOT/scripts/run-discord-scrape-host.sh" scrape --target demo
}
run_host_compose_capture() {
local env_path=${1:-$ENV_FILE}
local compose_bin=$2
local args_log=$3
shift 3
local -a extra_env=( "$@" )
env -u DISCORD_TOKEN \
DCE_SKIP_SCRAPE_LOCK=1 \
DCE_COMPOSE_BIN="$compose_bin" \
DCE_REPO_ROOT="$REPO_ROOT" \
DCE_ENV_FILE="$env_path" \
DCE_COMPOSE_FILE="$COMPOSE_FILE" \
FAKE_COMPOSE_ARGS_LOG="$args_log" \
"${extra_env[@]}" \
"$REPO_ROOT/scripts/run-discord-scrape-host.sh" scrape --target demo
}
run_host_with_shell_token() {
local mode=$1
local missing_env_path=$2
@@ -173,4 +191,33 @@ grep -q streaming-line2 "$STREAM_OUTPUT" || {
exit 1
}
COMPOSE_TTY_LOG="$TMP_DIR/compose-tty-default.log"
FAKE_COMPOSE="$TMP_DIR/fake-compose"
cat >"$FAKE_COMPOSE" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$*" >>"${FAKE_COMPOSE_ARGS_LOG:?}"
printf 'run succeeded\n'
EOF
chmod +x "$FAKE_COMPOSE"
run_host_compose_capture "$ENV_FILE" "$FAKE_COMPOSE" "$COMPOSE_TTY_LOG" >/dev/null
grep -q ' run --rm ' "$COMPOSE_TTY_LOG" || {
echo "expected default compose run to omit -T for live TTY allocation" >&2
cat "$COMPOSE_TTY_LOG" >&2
exit 1
}
grep -qE '(^|[[:space:]])-T([[:space:]]|$)' "$COMPOSE_TTY_LOG" && {
echo "expected default compose run not to pass -T" >&2
cat "$COMPOSE_TTY_LOG" >&2
exit 1
}
COMPOSE_NOTTY_LOG="$TMP_DIR/compose-tty-off.log"
run_host_compose_capture "$ENV_FILE" "$FAKE_COMPOSE" "$COMPOSE_NOTTY_LOG" DCE_COMPOSE_TTY=0 >/dev/null
grep -qE '(^|[[:space:]])-T([[:space:]]|$)' "$COMPOSE_NOTTY_LOG" || {
echo "expected DCE_COMPOSE_TTY=0 compose run to use -T" >&2
cat "$COMPOSE_NOTTY_LOG" >&2
exit 1
}
echo "run-discord-scrape-host smoke test passed"

View File

@@ -86,6 +86,7 @@ grep -q '^MAILTO=test@example.com$' "$CRONTAB_FILE" || { echo "expected unrelate
[[ "$(grep -c '^# BEGIN discord-scrape$' "$CRONTAB_FILE")" == "1" ]] || { echo "expected exactly one managed cron block after install" >&2; exit 1; }
grep -q 'compose --env-file' "$DOCKER_LOG" || { echo "expected docker preflight to run during install" >&2; exit 1; }
grep -q 'scripts/run-discord-scrape-host.sh' "$CRONTAB_FILE" || { echo "expected cron job to run host wrapper" >&2; exit 1; }
grep -q 'DCE_COMPOSE_TTY=0' "$CRONTAB_FILE" || { echo "expected cron job to disable compose TTY for log append" >&2; exit 1; }
run_setup
[[ "$(grep -c '^# BEGIN discord-scrape$' "$CRONTAB_FILE")" == "1" ]] || { echo "expected exactly one managed cron block after reinstall" >&2; exit 1; }