fix(ci): стек CouchDB после переезда остаётся на своём хосте #3087
1 changed files with 63 additions and 20 deletions
|
|
@ -32,13 +32,21 @@ name: Deploy Obsidian
|
|||
# v1.5.0 означает ssh.InsecureIgnoreHostKey(), то есть ровно как до этого PR.
|
||||
# Включается одной настройкой, как INFRA_DEPLOY_HOST (#3059) и fail-open у
|
||||
# TRADEIN_INTERNAL_AUTH_SECRET (#2989).
|
||||
# NB: этот workflow ходит на secrets.DEPLOY_HOST, поэтому и отпечаток берётся
|
||||
# DEPLOY_SSH_FINGERPRINT — пара «хост+отпечаток» обязана меняться вместе. Но
|
||||
# CouchDB по плану ОСТАЁТСЯ на Beget вместе с Forgejo/GlitchTip (#3062), а
|
||||
# DEPLOY_HOST после 30.08 будет указывать на Selectel. Значит у этого файла есть
|
||||
# отдельная, ещё не закрытая проблема адресата — тот же класс, что #3059. Здесь
|
||||
# намеренно НЕ трогаем: правка про подлинность хоста, а не про маршрутизацию.
|
||||
# При переводе на INFRA_DEPLOY_HOST не забыть переключить и отпечаток.
|
||||
# АДРЕСАТ (#3062). CouchDB/Obsidian ОСТАЁТСЯ на Beget вместе с Forgejo и
|
||||
# GlitchTip, а DEPLOY_HOST после 30.08 будет указывать на Selectel. Раньше этот
|
||||
# workflow ходил на DEPLOY_HOST безусловно — то есть в день переезда молча начал
|
||||
# бы разворачивать стек CouchDB не на той машине: git reset на /opt/gendesign
|
||||
# продуктового хоста, а волт на Beget тем временем перестал бы обновляться.
|
||||
# Отказа при этом не было бы — деплой зелёный, адресат другой.
|
||||
#
|
||||
# Теперь адресат берётся как INFRA_DEPLOY_HOST, а если он не задан — DEPLOY_HOST.
|
||||
# До переезда это одна и та же машина, поэтому поведение не меняется; после —
|
||||
# workflow сам остаётся на инфраструктурном хосте, без правки этого файла.
|
||||
#
|
||||
# Отпечаток идёт В ПАРЕ с адресатом и БЕЗ перекрёстного фолбэка: сверять ключ
|
||||
# Beget'а с отпечатком Selectel'а — гарантированный отказ. Задан INFRA_DEPLOY_HOST
|
||||
# → берётся INFRA_DEPLOY_SSH_FINGERPRINT; не задан → DEPLOY_SSH_FINGERPRINT.
|
||||
# Пусто в выбранной ветке → проверка подлинности пропускается, как и раньше.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
on:
|
||||
push:
|
||||
|
|
@ -68,17 +76,46 @@ jobs:
|
|||
# кого, отказ сломал бы деплой в момент мержа этого PR, а правило здесь —
|
||||
# «инертно по умолчанию, включается одной настройкой». Заведут секрет —
|
||||
# предупреждение исчезнет само.
|
||||
- name: Подлинность хоста — статус проверки (#3029)
|
||||
- name: Адресат и подлинность хоста (#3062, #3029)
|
||||
id: target
|
||||
env:
|
||||
HOST_FINGERPRINT: ${{ secrets.DEPLOY_SSH_FINGERPRINT }}
|
||||
INFRA_HOST: ${{ secrets.INFRA_DEPLOY_HOST }}
|
||||
INFRA_FINGERPRINT: ${{ secrets.INFRA_DEPLOY_SSH_FINGERPRINT }}
|
||||
MAIN_FINGERPRINT: ${{ secrets.DEPLOY_SSH_FINGERPRINT }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ -n "${HOST_FINGERPRINT:-}" ]; then
|
||||
echo "Подлинность хоста: сверяется по DEPLOY_SSH_FINGERPRINT."
|
||||
# Отпечаток — публичный хеш ключа хоста, не секрет: его можно
|
||||
# передать через output. Приватный ключ так передавать нельзя,
|
||||
# поэтому он остаётся прямой ссылкой на секрет в шаге ниже.
|
||||
if [ -n "${INFRA_HOST:-}" ]; then
|
||||
echo "Адресат: INFRA_DEPLOY_HOST — хосты разъехались, стек CouchDB едет на инфраструктурный хост."
|
||||
HOST_FINGERPRINT="${INFRA_FINGERPRINT:-}"
|
||||
FINGERPRINT_SOURCE="INFRA_DEPLOY_SSH_FINGERPRINT"
|
||||
else
|
||||
echo '::warning title=SSH без проверки подлинности хоста::DEPLOY_SSH_FINGERPRINT не задан — ключ хоста НЕ проверяется (#3029). По каналу едет DEPLOY_SSH_KEY и разворачивается стек CouchDB/Obsidian. После переезда на Selectel (#3057) соединение идёт через интернет. Как снять отпечаток — см. шапку этого файла.'
|
||||
echo "Адресат: DEPLOY_HOST — INFRA_DEPLOY_HOST не задан, хосты ещё одна машина."
|
||||
HOST_FINGERPRINT="${MAIN_FINGERPRINT:-}"
|
||||
FINGERPRINT_SOURCE="DEPLOY_SSH_FINGERPRINT"
|
||||
fi
|
||||
# $GITHUB_OUTPUT — формат «ключ=значение» построчно, поэтому перевод
|
||||
# строки внутри значения означает инъекцию произвольного output'а.
|
||||
# Отпечаток однострочный по определению (SHA256:...), а вот копипаста
|
||||
# в поле секрета лишний \n добавляет легко — шапка этого файла об этом
|
||||
# прямо предупреждает. Не вычищаем молча: сверка побайтовая, тихий trim
|
||||
# изменил бы результат проверки. Падаем с внятным текстом.
|
||||
case "${HOST_FINGERPRINT}" in
|
||||
*[![:print:]]*)
|
||||
echo "ОШИБКА: ${FINGERPRINT_SOURCE} содержит перевод строки или непечатный символ." >&2
|
||||
echo "ОШИБКА: значение должно быть одной строкой вида SHA256:xxxx — перезадай секрет без лишних символов." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "fingerprint=${HOST_FINGERPRINT}" >> "$GITHUB_OUTPUT"
|
||||
if [ -n "${HOST_FINGERPRINT:-}" ]; then
|
||||
echo "Подлинность хоста: сверяется по ${FINGERPRINT_SOURCE}."
|
||||
else
|
||||
echo "::warning title=SSH без проверки подлинности хоста::${FINGERPRINT_SOURCE} не задан — ключ хоста НЕ проверяется (#3029). По каналу едет ssh-ключ и разворачивается стек CouchDB/Obsidian. После разъезда хостов (#3057) соединение идёт через интернет. Как снять отпечаток — см. шапку этого файла."
|
||||
echo '###############################################################'
|
||||
echo '# ВНИМАНИЕ (#3029): DEPLOY_SSH_FINGERPRINT не задан.'
|
||||
echo "# ВНИМАНИЕ (#3029): ${FINGERPRINT_SOURCE} не задан."
|
||||
echo '# Ключ хоста НЕ проверяется — канал уязвим к MITM.'
|
||||
echo '# Как снять отпечаток — см. шапку этого файла.'
|
||||
echo '###############################################################'
|
||||
|
|
@ -87,13 +124,19 @@ jobs:
|
|||
- name: Deploy obsidian stack via SSH
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
host: ${{ secrets.DEPLOY_HOST }}
|
||||
username: ${{ secrets.DEPLOY_USER }}
|
||||
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
port: ${{ secrets.DEPLOY_PORT || 22 }}
|
||||
# #3029: подлинность хоста. Секрет НЕ задан → пустая строка → easyssh-proxy
|
||||
# оставляет ssh.InsecureIgnoreHostKey(), то есть сегодняшнее поведение.
|
||||
fingerprint: ${{ secrets.DEPLOY_SSH_FINGERPRINT }}
|
||||
# #3062: адресат — инфраструктурный хост, если хосты уже разъехались.
|
||||
# До этого INFRA_DEPLOY_HOST пуст и всё идёт на DEPLOY_HOST, как раньше.
|
||||
host: ${{ secrets.INFRA_DEPLOY_HOST || secrets.DEPLOY_HOST }}
|
||||
# user/key/port с фолбэком: у двух хостов они совпадают, а отдельные
|
||||
# INFRA_*-секреты может и не завести — тогда работают общие.
|
||||
username: ${{ secrets.INFRA_DEPLOY_USER || secrets.DEPLOY_USER }}
|
||||
key: ${{ secrets.INFRA_DEPLOY_SSH_KEY || secrets.DEPLOY_SSH_KEY }}
|
||||
port: ${{ secrets.INFRA_DEPLOY_PORT || secrets.DEPLOY_PORT || 22 }}
|
||||
# #3029: подлинность хоста. Отпечаток выбран шагом выше В ПАРЕ с
|
||||
# адресатом — перекрёстного фолбэка здесь быть не должно, иначе после
|
||||
# переезда ключ Beget'а сверялся бы с отпечатком Selectel'а.
|
||||
# Пусто → easyssh-proxy оставляет ssh.InsecureIgnoreHostKey(), как сегодня.
|
||||
fingerprint: ${{ steps.target.outputs.fingerprint }}
|
||||
script: |
|
||||
set -euo pipefail
|
||||
cd /opt/gendesign
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue