База bj на своём PostgreSQL; «Не заполнено: …» для пустых полей; запись канала ИШ — в фоне, с ходом на странице
- шаг «База bj»: перенос на сервер PostgreSQL организации (проверка подключения, версии, прав, пустой базы; pg_dump → psql; сверка числа строк по таблицам; переключение и перезапуск); прежняя база — запасная копия; резервные копии: дамп внешней базы по её подключению, восстановление её не трогает - все формы: пустые видимые обязательные поля называются по имени и подсвечиваются; DEPO — и на сервере - «Обновить/Создать канал»: в фоне bj, ход по этапам с таймером (и после перезагрузки страницы), переходы заблокированы до конца, в конце проверка, что шлюз загрузил канал; состояние ИШ во время записи — без очереди к root-обработчику (страница больше не висит на «Проверяю…») Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
@@ -47,7 +47,33 @@ tarok() { tar "$@"; local rc=$?; [ $rc -le 1 ]; }
|
||||
[ -n "$SHARE" ] || fail "не задано хранилище (Настройка → Резервное копирование)"
|
||||
[ -r "$CRED" ] || fail "нет логина хранилища (Настройка → Резервное копирование)"
|
||||
|
||||
runuser -u postgres -- pg_dump -Fc bj > "$W/bj.pgdump" || fail "дамп базы bj"
|
||||
# база bj: на этом сервере — от имени postgres; на сервере PostgreSQL организации (перенесена в мастере) — по её
|
||||
# подключению из настроек bj. Сервер организации новее нашего pg_dump — копия без базы, с пометкой: базу на сервере
|
||||
# организации резервирует её администратор баз.
|
||||
DBNOTE=""
|
||||
mapfile -t BJDB < <(python3 - <<'PY'
|
||||
import json,urllib.parse
|
||||
try:
|
||||
d=json.load(open("/var/lib/bj/.bj/setup.json")).get("postgres",{}).get("dsn","")
|
||||
u=urllib.parse.urlparse(d); h=(u.hostname or "").lower()
|
||||
if d and h not in ("","localhost","127.0.0.1","::1") and not h.startswith("/"):
|
||||
host="["+u.hostname+"]" if ":" in u.hostname else u.hostname
|
||||
netloc=(urllib.parse.quote(u.username or "")+"@" if u.username else "")+host+(":"+str(u.port) if u.port else "")
|
||||
print("ext"); print(urllib.parse.urlunparse((u.scheme,netloc,u.path,"",u.query,""))); print(urllib.parse.unquote(u.password or "")); print(u.hostname)
|
||||
except Exception: pass
|
||||
PY
|
||||
)
|
||||
if [ "${BJDB[0]:-}" = ext ]; then
|
||||
if ! PGPASSWORD="${BJDB[2]:-}" pg_dump -Fc --no-owner --no-privileges --dbname="${BJDB[1]}" > "$W/bj.pgdump" 2>"$W/pgdump.err"; then
|
||||
rm -f "$W/bj.pgdump"
|
||||
DBNOTE="база bj на сервере организации ${BJDB[3]} в копию не вошла ($(grep -v '^\s*$' "$W/pgdump.err" | tail -1 | head -c 160)) — её резервирует администратор баз"
|
||||
else
|
||||
DBNOTE="база bj — с сервера организации ${BJDB[3]}"
|
||||
fi
|
||||
rm -f "$W/pgdump.err"
|
||||
else
|
||||
runuser -u postgres -- pg_dump -Fc bj > "$W/bj.pgdump" || fail "дамп базы bj"
|
||||
fi
|
||||
if runuser -u postgres -- psql -Atc "select 1 from pg_database where datname='igate'" 2>/dev/null | grep -q 1; then
|
||||
runuser -u postgres -- pg_dump -Fc igate > "$W/igate.pgdump" || fail "дамп базы igate"
|
||||
fi
|
||||
@@ -83,5 +109,5 @@ smb "cd \"$DIR\"; ls" 2>/dev/null | awk '{print $1}' | grep -E '^[0-9]{4}-[0-9]{
|
||||
smb "cd \"$DIR/$d\"; prompt; mask *; mdel *; cd ..; rmdir \"$d\"" >/dev/null 2>&1 && echo "удалена старая копия $d"
|
||||
fi
|
||||
done
|
||||
status true "размер $SIZE"
|
||||
echo "копия $DIR/$TS готова ($SIZE)"
|
||||
status true "размер $SIZE${DBNOTE:+; $DBNOTE}"
|
||||
echo "копия $DIR/$TS готова ($SIZE)${DBNOTE:+; $DBNOTE}"
|
||||
|
||||
@@ -121,8 +121,17 @@ case "$cmd" in
|
||||
printf '%s' "$out" | grep -q "NT_STATUS" && err "не удалось скачать копию $name: $(printf '%s' "$out" | grep -o 'NT_STATUS[A-Z_]*' | head -1)"
|
||||
[ -s "$W/SHA256SUMS" ] || err "в копии $name нет SHA256SUMS — копия неполная"
|
||||
(cd "$W" && sha256sum -c SHA256SUMS >/dev/null 2>&1) || err "контрольные суммы копии $name не сходятся — копия повреждена"
|
||||
[ -s "$W/bj.pgdump" ] && [ -s "$W/bj-data.tar.gz" ] || err "в копии $name нет базы или данных bj"
|
||||
pg_restore -l < "$W/bj.pgdump" >/dev/null 2>&1 || err "база bj в копии $name не читается"
|
||||
[ -s "$W/bj-data.tar.gz" ] || err "в копии $name нет данных bj"
|
||||
if [ -s "$W/bj.pgdump" ]; then
|
||||
pg_restore -l < "$W/bj.pgdump" >/dev/null 2>&1 || err "база bj в копии $name не читается"
|
||||
elif [ -z "$(tar -xzOf "$W/bj-data.tar.gz" var/lib/bj/.bj/setup.json 2>/dev/null | python3 -c '
|
||||
import json,sys,urllib.parse
|
||||
try:
|
||||
h=(urllib.parse.urlparse(json.load(sys.stdin).get("postgres",{}).get("dsn","")).hostname or "").lower()
|
||||
print(h if h not in ("","localhost","127.0.0.1","::1") else "")
|
||||
except Exception: pass')" ]; then
|
||||
err "в копии $name нет базы bj"
|
||||
fi # база на сервере организации, не вошедшая в копию, — её резервирует администратор баз
|
||||
tar -tzf "$W/bj-data.tar.gz" >/dev/null 2>&1 || err "архив данных bj в копии $name не читается"
|
||||
ok "копия $name цела: $(cd "$W" && ls | grep -vc SHA256SUMS) файлов, $(du -sh "$W" | cut -f1), контрольные суммы сходятся, база и архивы читаются" ;;
|
||||
restore)
|
||||
@@ -148,14 +157,27 @@ PY
|
||||
st download "скачивание копии $NAME"
|
||||
smbclient "$SHARE" -A /run/bj-restore.cred -m SMB3 -c "cd \"$DIR/$NAME\"; lcd $W; prompt; mget *" >/dev/null 2>&1 || die "не удалось скачать копию $NAME"
|
||||
(cd "$W" && sha256sum -c SHA256SUMS >/dev/null 2>&1) || die "контрольные суммы копии не сходятся — копия повреждена"
|
||||
[ -s "$W/bj.pgdump" ] && [ -s "$W/bj-data.tar.gz" ] || die "в копии нет базы или данных bj"
|
||||
[ -s "$W/bj-data.tar.gz" ] || die "в копии нет данных bj"
|
||||
# база bj на сервере PostgreSQL организации (перенесена в мастере): её не восстанавливаем поверх — это база
|
||||
# организации, у неё свежие данные и свой администратор; bj после восстановления настроек подключится к ней
|
||||
EXTDB=$(tar -xzOf "$W/bj-data.tar.gz" var/lib/bj/.bj/setup.json 2>/dev/null | python3 -c '
|
||||
import json,sys,urllib.parse
|
||||
try:
|
||||
h=(urllib.parse.urlparse(json.load(sys.stdin).get("postgres",{}).get("dsn","")).hostname or "").lower()
|
||||
print(h if h not in ("","localhost","127.0.0.1","::1") else "")
|
||||
except Exception: pass')
|
||||
[ -n "$EXTDB" ] || [ -s "$W/bj.pgdump" ] || die "в копии нет базы bj"
|
||||
st stop "остановка bj и шлюза НРД"
|
||||
systemctl stop bj-lk bj-npr bj-server igate >/dev/null 2>&1
|
||||
if [ -n "$EXTDB" ]; then
|
||||
st db "база bj — на сервере организации $EXTDB: не восстанавливается, bj подключится к ней"
|
||||
else
|
||||
st db "восстановление базы bj"
|
||||
# каталог копии доступен только root — дамп подаём postgres через stdin; сообщения — по-английски для разбора ошибок
|
||||
LC_ALL=C PGOPTIONS='-c lc_messages=C' runuser -u postgres -- pg_restore --clean --if-exists -d bj < "$W/bj.pgdump" >/dev/null 2>"$W/pg.err"
|
||||
# «does not exist» при --clean на пустой базе — не ошибка; остальное — ошибка
|
||||
if grep -i "error" "$W/pg.err" | grep -vqi "does not exist"; then die "база bj: $(grep -i error "$W/pg.err" | grep -vi 'does not exist' | head -1)"; fi
|
||||
fi
|
||||
if [ -s "$W/igate.pgdump" ]; then
|
||||
st db "восстановление базы шлюза НРД"
|
||||
# новый сервер: ИШ ещё не ставили — готовим пользователя, роль, базу и доступ без пароля (как ставит
|
||||
|
||||
Reference in New Issue
Block a user