Привет.
Задача: у нас есть прод-среда (prod-server) и тестовая среда (test-server). На обеих серверах есть база данных postgres, и иногда наши аналитики ставят задачу на «рефреш» базы данных (сдампить прод-среду и перелить данные на тестовую). Мне это надоело руками делать и пришла в голову гениальная идея: сделать это через Jenkins.
Чтобы аналитики заходили в Jenkins, нажимали одну кнопку и сами обновляли базу без нашего участия. Типа этого:
https://imgur.com/a/hU1AEwS
Вопрос 1:
Aдекватно ли использовать Jenkins в данном случае? Просто Jenkins создан в первую очередь для разработки, а не таких задач, насколько я понимаю... Если не адекватно — что можно использовать? Надо бесплатное решение и Open Source, компания вряд ли будет закупать что-то новое по нашим хотелкам.
----------------------------
Окей, я написал такой простой сценарий в Jenkins:
#enable debug mode and stop script ib case of errors
set -x
set -e
unset PGCLUSTER
#generate file name
if [[ "$databse_dump_date" == "latest" ]]
then
dump_name=bars_web_bb_`date -d "1 day ago" "+%F"`.dump
else
dump_name=bars_web_bb_$databse_dump_date.dump
fi
#copy dump from backup server to /tmp/
scp -o "ProxyCommand=ssh -q -N -W %h:%p my_username@192.168.221.35" root@172.153.153.54:/backups/daily_backups/$dump_name /tmp/
#block all new connection
psql -c "ALTER DATABASE web_bb_chelyab CONNECTION LIMIT 0;"
#recreate database
psql -c "select pg_terminate_backend(pid) from pg_stat_activity where datname='web_bb_chelyab';"
psql -c "DROP DATABASE web_bb_chelyab;"
psql -c "CREATE DATABASE web_bb_chelyab OWNER bars_web_bb;"
#restore_database
pg_restore -U bars_web_bb -d web_bb_chelyab -j 2 /tmp/$dump_name
psql -c "ALTER DATABASE web_bb_chelyab CONNECTION LIMIT -1;"
#remove dump
rm -f /tmp/$dump_name
То есть просто копируем дамп через scp, пересоздаём базу данных, делаем pg_restore. Всё бы хорошо, но нет. При тестировании обнаружил ошибку:
+ pg_restore -U bars_web_bb -d web_bb_chelyab -j 2 /tmp/bars_web_bb_2019-08-15.dump
CREATE DATABASE
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 34405; 0 0 COMMENT EXTENSION plpgsql
pg_restore: [archiver (db)] could not execute query: ERROR: must be owner of extension plpgsql
Command was: COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
WARNING: errors ignored on restore: 1
[SSH] exit-status: 1
Build step 'Execute shell script on remote host using ssh' marked build as failure
[BFA] Scanning build for known causes...
[BFA] No failure causes found
[BFA] Done. 0s
Finished: FAILURE
И Jenkins-job завершился аварийно, так как при выполнении команды pg_restore произошли незначительные ошибки.
Углубившись в эту тему, я нашёл тему на stackoverflow:
https://stackoverflow.com/questions/32147653/how-do-i-reliably-determine-whet...
Типа pg_restore почти всегда игнорирует ошибки при восстанволении, и, в конечном счёте, возвращает не 0, а 1. Он не умеет определять, какие ошибки критичные, а какие нет. В моём случае из-за незначительных ошибок jenkins-job не завершился корректно.
Вопрос 2: как лучше поступить в моём случае, чтобы Jenkins-Job игноировал незначительные ошибки? В голову приходит только этот вариант:
set -x
set -e
...
[копирование дампа, set -e нужен, чтобы не начинать восстанволение, если scp авершится неудачно]
set +e #убираем set -e, чтобы не прерывать скрипт в случае незначительных ошибок в pg_restore
pg_restore -U bars_web_bb -d web_bb_chelyab -j 2 /tmp/$dump_name
set -e [снова включаем set -e]
psql -c "ALTER DATABASE web_bb_chelyab CONNECTION LIMIT -1;"
#remove dump
rm -f /tmp/$dump_name
Этот вариант адекватен? Есть ли лучше способы?