stop deploy.sh from pulling a new copy of itself out from under bash
bash اسکریپت را یکجا نمیخواند؛ حین اجرا از روی دیسک ادامه میدهد. پس وقتی `git pull` همین فایل را عوض میکند، ادامهی اجرا مخلوطی از نسخهی قدیم و جدید است. یک بار همین اتفاق افتاد و گران تمام شد: نسخهی قدیمی که در حال اجرا بود سرویسِ تیمِ دیگری را ریاستارت کرد، در حالی که نسخهی اصلاحشده همان لحظه روی دیسک نشسته بود. حالا امضای فایل قبل و بعدِ pull مقایسه میشود و اگر عوض شده باشد، نسخهی تازه از اول اجرا میشود (با SKIP_PULL=1 و یک نگهبان در برابرِ حلقهی بیپایان). و یک حفرهی کوچکترِ همخانواده: اگر زمانِ بالا آمدنِ سرویس اصلاً خوانده نشود، دیگر موفقیت فرض نمیشود. «نمیدانم» همان چیزی بود که دو روز پنهانش کرد. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
26
deploy.sh
26
deploy.sh
@@ -42,7 +42,26 @@ fi
|
|||||||
# ─── ۱. کدِ تازه ────────────────────────────────────────────────────────────
|
# ─── ۱. کدِ تازه ────────────────────────────────────────────────────────────
|
||||||
if [ "${SKIP_PULL:-0}" != "1" ]; then
|
if [ "${SKIP_PULL:-0}" != "1" ]; then
|
||||||
step "گرفتنِ کدِ تازه"
|
step "گرفتنِ کدِ تازه"
|
||||||
|
# امضای خودِ این فایل قبل از pull. توضیحش پایینتر.
|
||||||
|
SELF_BEFORE="$(cksum "$0" 2>/dev/null || true)"
|
||||||
git pull --ff-only || fail "git pull نشد. اگر تغییرِ محلی دارید اول تعیین تکلیفش کنید."
|
git pull --ff-only || fail "git pull نشد. اگر تغییرِ محلی دارید اول تعیین تکلیفش کنید."
|
||||||
|
|
||||||
|
# اگر همین اسکریپت در pull عوض شد، نسخهی تازه از اول اجرا میشود.
|
||||||
|
#
|
||||||
|
# چرا لازم است: bash اسکریپت را یکجا نمیخواند، حین اجرا از روی دیسک ادامه
|
||||||
|
# میدهد. پس وقتی pull همین فایل را زیر پای خودش عوض میکند، ادامهی اجرا
|
||||||
|
# مخلوطی از نسخهی قدیم و جدید میشود. یک بار همین اتفاق افتاد: نسخهی قدیمی
|
||||||
|
# که هنوز در حال اجرا بود سرویسِ تیمِ دیگری را ریاستارت کرد، در حالی که
|
||||||
|
# نسخهی اصلاحشده همان لحظه روی دیسک نشسته بود.
|
||||||
|
#
|
||||||
|
# DEPLOY_REEXEC جلوی حلقهی بیپایان را میگیرد: نسخهی تازه دیگر خودش را
|
||||||
|
# صدا نمیزند چون بعد از pullِ دوم دیگر چیزی عوض نمیشود.
|
||||||
|
if [ "${DEPLOY_REEXEC:-0}" != "1" ] \
|
||||||
|
&& [ -n "$SELF_BEFORE" ] \
|
||||||
|
&& [ "$SELF_BEFORE" != "$(cksum "$0" 2>/dev/null || true)" ]; then
|
||||||
|
printf ' این اسکریپت خودش بهروز شد؛ نسخهی تازه از اول اجرا میشود.\n'
|
||||||
|
DEPLOY_REEXEC=1 SKIP_PULL=1 exec "$0" "$@"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
step "گرفتنِ کد رد شد (SKIP_PULL=1)"
|
step "گرفتنِ کد رد شد (SKIP_PULL=1)"
|
||||||
fi
|
fi
|
||||||
@@ -175,7 +194,12 @@ if [ -n "$SERVICE" ]; then
|
|||||||
BEFORE="$(systemctl show "$SERVICE" -p ActiveEnterTimestamp --value 2>/dev/null || true)"
|
BEFORE="$(systemctl show "$SERVICE" -p ActiveEnterTimestamp --value 2>/dev/null || true)"
|
||||||
if sudo systemctl restart "$SERVICE"; then
|
if sudo systemctl restart "$SERVICE"; then
|
||||||
AFTER="$(systemctl show "$SERVICE" -p ActiveEnterTimestamp --value 2>/dev/null || true)"
|
AFTER="$(systemctl show "$SERVICE" -p ActiveEnterTimestamp --value 2>/dev/null || true)"
|
||||||
if [ -n "$BEFORE" ] && [ "$BEFORE" = "$AFTER" ]; then
|
if [ -z "$BEFORE" ] || [ -z "$AFTER" ]; then
|
||||||
|
# نتوانستیم ثابت کنیم ریاستارت شده. «نمیدانم» را موفقیت حساب نمیکنیم —
|
||||||
|
# همین اشتباه بود که دو روز پنهان ماند.
|
||||||
|
warn "زمانِ بالا آمدنِ $SERVICE خوانده نشد، پس ریاستارت تأیید نشد.
|
||||||
|
خودتان بررسی کنید: systemctl status $SERVICE"
|
||||||
|
elif [ "$BEFORE" = "$AFTER" ]; then
|
||||||
warn "دستورِ ریاستارت خطا نداد ولی سرویس بالا نیامد (هنوز از $BEFORE در حال اجراست).
|
warn "دستورِ ریاستارت خطا نداد ولی سرویس بالا نیامد (هنوز از $BEFORE در حال اجراست).
|
||||||
یعنی کدِ جدید بار نشده. لاگ: sudo journalctl -u $SERVICE -n 50 --no-pager"
|
یعنی کدِ جدید بار نشده. لاگ: sudo journalctl -u $SERVICE -n 50 --no-pager"
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user