├── .gitignore ├── DEB ├── debian │ ├── compat │ ├── README.Debian │ ├── README.source │ ├── source │ │ └── format │ ├── install │ ├── patroni.substvars │ ├── files │ ├── patches │ │ ├── series │ │ ├── service-info-only-in-pretty-format.patch │ │ ├── better-startup-script.patch │ │ ├── add-sample-config.patch │ │ └── patronictl-reinit-wait-rebased-1.6.0.patch │ ├── watch.ex │ ├── control │ ├── rules │ ├── changelog │ ├── postinst │ └── copyright ├── .gitignore ├── Makefile ├── Dockerfile └── buildprocess.sh ├── RPM.fc30 ├── fc30.Dockerfile ├── Makefile ├── fc30.build.sh ├── patroni-watchdog.service ├── patroni.2.service ├── patches │ ├── service-info-only-in-pretty-format.patch │ ├── better-startup-script.patch │ ├── add-sample-config.patch │ └── patronictl-reinit-wait-rebased-1.6.0.patch ├── postgres-telia.yml └── fc30.patroni.spec ├── RPM ├── Dockerfile ├── Makefile ├── build.sh ├── patroni-watchdog.service ├── patroni.2.service ├── patches │ ├── better-startup-script.patch │ └── add-sample-config.patch ├── postgres-telia.yml └── patroni.spec ├── README.md └── package_migration.md /.gitignore: -------------------------------------------------------------------------------- 1 | rpms 2 | -------------------------------------------------------------------------------- /DEB/debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /DEB/debian/README.Debian: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /DEB/debian/README.source: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /DEB/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /DEB/debian/install: -------------------------------------------------------------------------------- 1 | extras/startup-scripts/patroni.service /lib/systemd/system 2 | patroni.yml.sample /etc/patroni 3 | -------------------------------------------------------------------------------- /DEB/debian/patroni.substvars: -------------------------------------------------------------------------------- 1 | shlibs:Depends=libc6 (>= 2.15), libyaml-0-2, zlib1g (>= 1:1.2.0) 2 | misc:Depends= 3 | misc:Pre-Depends= 4 | -------------------------------------------------------------------------------- /DEB/debian/files: -------------------------------------------------------------------------------- 1 | patroni-dbgsym_1.6.3-1_amd64.deb debug extra 2 | patroni_1.6.3-1_amd64.buildinfo libs optional 3 | patroni_1.6.3-1_amd64.deb libs optional 4 | -------------------------------------------------------------------------------- /DEB/debian/patches/series: -------------------------------------------------------------------------------- 1 | better-startup-script.patch 2 | add-sample-config.patch 3 | service-info-only-in-pretty-format.patch 4 | patronictl-reinit-wait-rebased-1.6.0.patch -------------------------------------------------------------------------------- /RPM.fc30/fc30.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:30 2 | RUN dnf install -y rpm-build python3 python3-pip python3-virtualenv python3-psycopg2 libyaml-devel gcc 3 | WORKDIR /patroni-packaging 4 | ENTRYPOINT ["/patroni-packaging/fc30.build.sh"] 5 | -------------------------------------------------------------------------------- /DEB/.gitignore: -------------------------------------------------------------------------------- 1 | patroni-*/ 2 | patroni-dbgsym_*.deb 3 | patroni_*.debian.tar.xz 4 | patroni_*.dsc 5 | patroni_*.build 6 | patroni_*.buildinfo 7 | patroni_*.changes 8 | patroni_*.deb 9 | patroni_*.orig.tar.gz 10 | 11 | vip-manager_*.deb 12 | *.log 13 | -------------------------------------------------------------------------------- /RPM/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | RUN yum install epel-release -y 3 | RUN yum install -y rpm-build python36 python36-pip python36-virtualenv python36-psycopg2 prelink libyaml-devel gcc 4 | WORKDIR /patroni-packaging 5 | ENTRYPOINT ["/patroni-packaging/build.sh"] 6 | -------------------------------------------------------------------------------- /RPM/Makefile: -------------------------------------------------------------------------------- 1 | help: 2 | $(error Run make docker-image to create build image, then make debs to create debian packaged) 3 | 4 | docker-image: 5 | docker build . --tag patroni-packaging:latest 6 | 7 | package: 8 | docker run --rm -e USER_ID=`id -u` -v `pwd`:/patroni-packaging:Z -i -t patroni-packaging:latest 9 | 10 | clean: 11 | rm -rf rpms 12 | -------------------------------------------------------------------------------- /RPM.fc30/Makefile: -------------------------------------------------------------------------------- 1 | help: 2 | $(error Run make podman-image to create build image, then make debs to create debian packaged) 3 | 4 | image: 5 | podman build -f fc30.Dockerfile . --tag patroni-packaging-fc30:latest 6 | 7 | package: 8 | podman run --rm -v `pwd`:/patroni-packaging:Z -i -t patroni-packaging-fc30:latest 9 | 10 | clean: 11 | rm -rf rpms 12 | 13 | -------------------------------------------------------------------------------- /DEB/Makefile: -------------------------------------------------------------------------------- 1 | help: 2 | $(error Run make docker-image to create build image, then make debs to create debian packaged) 3 | 4 | docker-image: 5 | docker build --tag=debian-build:9 . 6 | 7 | package: 8 | docker run --rm -v `pwd`:/debian-build:Z debian-build:9 /debian-build/buildprocess.sh 9 | 10 | clean: 11 | rm -rf *.build *.buildinfo *.changes *.tar.xz *.tar.gz *.deb *.dsc patroni-*/ -------------------------------------------------------------------------------- /RPM/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | mkdir -p /root/rpmbuild/SOURCES 6 | tar -czf /root/rpmbuild/SOURCES/patroni-customizations.tar.gz patroni.2.service patroni-watchdog.service postgres-telia.yml 7 | cp patches/*.patch /root/rpmbuild/SOURCES/ 8 | rpmbuild --rpmfcdebug -bb patroni.spec 9 | mkdir -p rpms 10 | cp /root/rpmbuild/RPMS/x86_64/patroni-*.rpm rpms/ 11 | if [ -n "$USER_ID" ]; then 12 | chown -R $USER_ID:$USER_ID rpms 13 | fi 14 | -------------------------------------------------------------------------------- /RPM.fc30/fc30.build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p /root/rpmbuild/SOURCES 3 | tar -czf /root/rpmbuild/SOURCES/patroni-customizations.tar.gz patroni.2.service patroni-watchdog.service postgres-telia.yml 4 | cp patches/*.patch /root/rpmbuild/SOURCES/ 5 | curl -L https://github.com/zalando/patroni/archive/v1.6.0.tar.gz -o /root/rpmbuild/SOURCES/patroni-1.6.0.tar.gz 6 | rpmbuild -bb fc30.patroni.spec 7 | mkdir -p rpms 8 | cp /root/rpmbuild/RPMS/x86_64/patroni-*.rpm rpms/ 9 | -------------------------------------------------------------------------------- /RPM/patroni-watchdog.service: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Unit] 4 | Description=Makes kernel watchdog device available for Patroni 5 | Before=patroni.service 6 | 7 | [Service] 8 | Type=oneshot 9 | 10 | Environment=WATCHDOG_MODULE=softdog 11 | Environment=WATCHDOG_DEVICE=/dev/watchdog 12 | Environment=PATRONI_USER=postgres 13 | 14 | ExecStart=/usr/sbin/modprobe ${WATCHDOG_MODULE} 15 | ExecStart=/bin/chown ${PATRONI_USER} ${WATCHDOG_DEVICE} 16 | 17 | [Install] 18 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /RPM.fc30/patroni-watchdog.service: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Unit] 4 | Description=Makes kernel watchdog device available for Patroni 5 | Before=patroni.service 6 | 7 | [Service] 8 | Type=oneshot 9 | 10 | Environment=WATCHDOG_MODULE=softdog 11 | Environment=WATCHDOG_DEVICE=/dev/watchdog 12 | Environment=PATRONI_USER=postgres 13 | 14 | ExecStart=/usr/sbin/modprobe ${WATCHDOG_MODULE} 15 | ExecStart=/bin/chown ${PATRONI_USER} ${WATCHDOG_DEVICE} 16 | 17 | [Install] 18 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /DEB/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:9 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | build-essential fakeroot devscripts \ 5 | python-psycopg2 python-setuptools python-dev libyaml-dev \ 6 | python3-virtualenv dh-virtualenv python3-psycopg2 \ 7 | wget git ruby ruby-dev rubygems build-essential \ 8 | curl \ 9 | && rm -rf /var/lib/apt/lists/* \ 10 | && gem install --no-ri --no-rdoc fpm \ 11 | && cd /opt \ 12 | && wget https://dl.google.com/go/go1.10.1.linux-amd64.tar.gz \ 13 | && tar -xzf go1.10.1.linux-amd64.tar.gz 14 | 15 | CMD ["bash"] 16 | -------------------------------------------------------------------------------- /DEB/buildprocess.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PATRONI_VERSION=1.6.3 4 | 5 | set -ex 6 | 7 | cd $(dirname $0) 8 | curl -L https://github.com/zalando/patroni/archive/v${PATRONI_VERSION}.tar.gz -o patroni_${PATRONI_VERSION}.orig.tar.gz 9 | tar -xzf patroni_${PATRONI_VERSION}.orig.tar.gz 10 | cp -r debian/ patroni-${PATRONI_VERSION} 11 | cd patroni-${PATRONI_VERSION} 12 | 13 | debuild -us -uc 14 | 15 | export PATH=/opt/go/bin:$PATH 16 | mkdir -p /build-tmp/gopath 17 | export GOPATH=/build-tmp/gopath 18 | go get github.com/cybertec-postgresql/vip-manager 19 | cd /build-tmp/gopath/src/github.com/cybertec-postgresql/vip-manager/ 20 | make vip-manager 21 | make package 22 | cp vip-manager*.deb /debian-build/ 23 | -------------------------------------------------------------------------------- /DEB/debian/watch.ex: -------------------------------------------------------------------------------- 1 | # Example watch control file for uscan 2 | # Rename this file to "watch" and then you can run the "uscan" command 3 | # to check for upstream updates and more. 4 | # See uscan(1) for format 5 | 6 | # Compulsory line, this is a version 3 file 7 | version=3 8 | 9 | # Uncomment to examine a Webpage 10 | # 11 | #http://www.example.com/downloads.php patroni-(.*)\.tar\.gz 12 | 13 | # Uncomment to examine a Webserver directory 14 | #http://www.example.com/pub/patroni-(.*)\.tar\.gz 15 | 16 | # Uncommment to examine a FTP server 17 | #ftp://ftp.example.com/pub/patroni-(.*)\.tar\.gz debian uupdate 18 | 19 | # Uncomment to find new files on sourceforge, for devscripts >= 2.9 20 | # http://sf.net/patroni/patroni-(.*)\.tar\.gz 21 | 22 | # Uncomment to find new files on GooglePages 23 | # http://example.googlepages.com/foo.html patroni-(.*)\.tar\.gz 24 | -------------------------------------------------------------------------------- /DEB/debian/control: -------------------------------------------------------------------------------- 1 | Source: patroni 2 | Priority: optional 3 | Maintainer: Ants Aasma 4 | Build-Depends: debhelper (>=9), python-psycopg2 (>=2.5.4), python-setuptools, python-dev, libyaml-dev 5 | Standards-Version: 3.9.6 6 | Section: libs 7 | X-Python-Version: all 8 | Homepage: https://github.com/zalando/patroni/ 9 | #Vcs-Git: git://anonscm.debian.org/collab-maint/patroni.git 10 | #Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/patroni.git 11 | 12 | Package: patroni 13 | Architecture: any 14 | Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-psycopg2 (>=2.5.4), libyaml-0-2 15 | Description: PostgreSQL HA with ZooKeeper, etcd or Consul 16 | Patroni is a template for you to create your own customized, 17 | high-availability solution using Python and - for maximum accessibility 18 | - a distributed configuration store like ZooKeeper, etcd or Consul. Database 19 | engineers, DBAs, DevOps engineers, and SREs who are looking to quickly 20 | deploy HA PostgreSQL in the datacenter-or anywhere else-will hopefully find 21 | it useful. 22 | -------------------------------------------------------------------------------- /DEB/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # See debhelper(7) (uncomment to enable) 3 | # output every command that modifies files on the build system. 4 | #export DH_VERBOSE = 1 5 | 6 | 7 | # see FEATURE AREAS in dpkg-buildflags(1) 8 | #export DEB_BUILD_MAINT_OPTIONS = hardening=+all 9 | 10 | # see ENVIRONMENT in dpkg-buildflags(1) 11 | # package maintainers to append CFLAGS 12 | #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic 13 | # package maintainers to append LDFLAGS 14 | #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed 15 | 16 | export DH_VIRTUALENV_INSTALL_ROOT=/opt/ 17 | export LC_ALL=C.UTF-8 18 | export LANG=C.UTF-8 19 | export DH_VIRTUALENV_ARGUMENTS=--system-site-packages 20 | export DH_UPGRADE_SETUPTOOLS= 21 | export DH_PIP_EXTRA_ARGS=-I 22 | 23 | %: 24 | dh $@ --no-test --use-system-packages --buildsystem=dh_virtualenv 25 | 26 | override_dh_auto_test: 27 | 28 | 29 | # dh_make generated override targets 30 | # This is example for Cmake (See https://bugs.debian.org/641051 ) 31 | #override_dh_auto_configure: 32 | # dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) 33 | 34 | -------------------------------------------------------------------------------- /DEB/debian/changelog: -------------------------------------------------------------------------------- 1 | patroni (1.6.3-1) UNRELEASED; urgency=low 2 | 3 | * Upgrade version to 1.6.3 4 | 5 | -- Pavel Zhbanov Wed, 22 Jan 2020 18:08:08 +0600 6 | 7 | patroni (1.6.0-1) UNRELEASED; urgency=low 8 | 9 | * Upgrade version to 1.6.0 10 | 11 | -- Julian Markwort Wed, 31 Jul 2019 15:57:54 +0200 12 | 13 | patroni (1.5.6-1) UNRELEASED; urgency=low 14 | 15 | * Upgrade version to 1.5.6 16 | 17 | -- Julian Markwort Wed, 31 Jul 2019 15:57:54 +0200 18 | 19 | patroni (1.5.5-1) UNRELEASED; urgency=low 20 | 21 | * Upgrade version to 1.5.5 22 | 23 | -- Anton Patsev Mon, 1 Apr 2019 12:08:01 +0600 24 | 25 | patroni (1.4.3-1) UNRELEASED; urgency=low 26 | 27 | * Upgrade version to 1.4.3 28 | 29 | -- Ants Aasma Thu, 5 Apr 2018 23:40:01 +0300 30 | 31 | patroni (1.4.2-1) UNRELEASED; urgency=low 32 | 33 | * Upgrade version to 1.4.2 34 | 35 | -- Ants Aasma Thu, 8 Feb 2018 14:06:12 +0200 36 | 37 | patroni (1.3.2-1) UNRELEASED; urgency=low 38 | 39 | * Upgrade version to 1.3.2 40 | 41 | -- Ants Aasma Sun, 6 Aug 2017 13:47:12 +0300 42 | 43 | patroni (1.2.5-1) UNRELEASED; urgency=low 44 | 45 | * Initial release 46 | 47 | -- Ants Aasma Fri, 21 Apr 2017 15:12:33 +0000 48 | -------------------------------------------------------------------------------- /RPM/patroni.2.service: -------------------------------------------------------------------------------- 1 | # It's not recommended to modify this file in-place, because it will be 2 | # overwritten during package upgrades. If you want to customize, the 3 | # best way is to create a file "/etc/systemd/system/patroni.service", 4 | # containing 5 | # .include /lib/systemd/system/patroni.service 6 | # Environment=PATRONI_CONFIG_LOCATION=... 7 | # For more info about custom unit files, see 8 | # http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F 9 | 10 | 11 | [Unit] 12 | Description=PostgreSQL high-availability manager 13 | After=syslog.target 14 | # Patroni needs to shut down before network interfaces. According to SystemD documentation 15 | # specifying network.target should be sufficient, but experiments show that this is not the case. 16 | After=network-online.target 17 | 18 | [Service] 19 | Type=simple 20 | 21 | User=postgres 22 | Group=postgres 23 | 24 | # Location of Patroni configuration 25 | Environment=PATRONI_CONFIG_LOCATION=/opt/app/patroni/etc/postgresql.yml 26 | 27 | # Disable OOM kill on the postmaster 28 | OOMScoreAdjust=-1000 29 | 30 | ExecStart=/opt/app/patroni/bin/patroni ${PATRONI_CONFIG_LOCATION} 31 | ExecReload=/bin/kill -HUP $MAINPID 32 | 33 | # Give a reasonable amount of time for the server to start up/shut down 34 | TimeoutSec=30 35 | TimeoutStopSec=120s 36 | 37 | # only kill the patroni process, not it's children, so it will gracefully stop postgres 38 | KillSignal=SIGINT 39 | KillMode=process 40 | 41 | [Install] 42 | WantedBy=multi-user.target 43 | -------------------------------------------------------------------------------- /RPM.fc30/patroni.2.service: -------------------------------------------------------------------------------- 1 | # It's not recommended to modify this file in-place, because it will be 2 | # overwritten during package upgrades. If you want to customize, the 3 | # best way is to create a file "/etc/systemd/system/patroni.service", 4 | # containing 5 | # .include /lib/systemd/system/patroni.service 6 | # Environment=PATRONI_CONFIG_LOCATION=... 7 | # For more info about custom unit files, see 8 | # http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F 9 | 10 | 11 | [Unit] 12 | Description=PostgreSQL high-availability manager 13 | After=syslog.target 14 | # Patroni needs to shut down before network interfaces. According to SystemD documentation 15 | # specifying network.target should be sufficient, but experiments show that this is not the case. 16 | After=network-online.target 17 | 18 | [Service] 19 | Type=simple 20 | 21 | User=postgres 22 | Group=postgres 23 | 24 | # Location of Patroni configuration 25 | Environment=PATRONI_CONFIG_LOCATION=/opt/app/patroni/etc/postgresql.yml 26 | 27 | # Disable OOM kill on the postmaster 28 | OOMScoreAdjust=-1000 29 | 30 | ExecStart=/opt/app/patroni/bin/patroni ${PATRONI_CONFIG_LOCATION} 31 | ExecReload=/bin/kill -HUP $MAINPID 32 | 33 | # Give a reasonable amount of time for the server to start up/shut down 34 | TimeoutSec=30 35 | TimeoutStopSec=120s 36 | 37 | # only kill the patroni process, not it's children, so it will gracefully stop postgres 38 | KillSignal=SIGINT 39 | KillMode=process 40 | 41 | [Install] 42 | WantedBy=multi-user.target 43 | -------------------------------------------------------------------------------- /DEB/debian/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postinst script for patroni 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | 8 | # summary of how this script can be called: 9 | # * `configure' 10 | # * `abort-upgrade' 11 | # * `abort-remove' `in-favour' 12 | # 13 | # * `abort-deconfigure' `in-favour' 14 | # `removing' 15 | # 16 | # for details, see /usr/share/doc/packaging-manual/ 17 | # 18 | # quoting from the policy: 19 | # Any necessary prompting should almost always be confined to the 20 | # post-installation script, and should be protected with a conditional 21 | # so that unnecessary prompting doesn't happen if a package's 22 | # installation fails and the `postinst' is called with `abort-upgrade', 23 | # `abort-remove' or `abort-deconfigure'. 24 | 25 | case "$1" in 26 | configure) 27 | update-alternatives --quiet --install /usr/bin/patroni patroni /opt/patroni/bin/patroni 50 28 | update-alternatives --quiet --install /usr/bin/patronictl patronictl /opt/patroni/bin/patronictl 50 29 | update-alternatives --quiet --auto patroni 30 | update-alternatives --quiet --auto patronictl 31 | ;; 32 | 33 | abort-upgrade|abort-remove|abort-deconfigure) 34 | 35 | ;; 36 | 37 | *) 38 | echo "postinst called with unknown argument \`$1'" >&2 39 | exit 0 40 | ;; 41 | esac 42 | 43 | # dh_installdeb will replace this with shell code automatically 44 | # generated by other debhelper scripts. 45 | 46 | #DEBHELPER# 47 | 48 | exit 0 49 | 50 | -------------------------------------------------------------------------------- /DEB/debian/patches/service-info-only-in-pretty-format.patch: -------------------------------------------------------------------------------- 1 | diff --git a/patroni/ctl.py b/patroni/ctl.py 2 | index 7f97986..b85dfaf 100644 3 | --- a/patroni/ctl.py 4 | +++ b/patroni/ctl.py 5 | @@ -713,20 +713,21 @@ def output_members(cluster, name, extended=False, fmt='pretty'): 6 | 7 | print_output(columns, rows, alignment, fmt) 8 | 9 | - service_info = [] 10 | - if cluster.is_paused(): 11 | - service_info.append('Maintenance mode: on') 12 | - 13 | - if cluster.failover and cluster.failover.scheduled_at: 14 | - info = 'Switchover scheduled at: ' + cluster.failover.scheduled_at.isoformat() 15 | - if cluster.failover.leader: 16 | - info += '\n from: ' + cluster.failover.leader 17 | - if cluster.failover.candidate: 18 | - info += '\n to: ' + cluster.failover.candidate 19 | - service_info.append(info) 20 | - 21 | - if service_info: 22 | - click.echo(' ' + '\n '.join(service_info)) 23 | + if fmt == "pretty": 24 | + service_info = [] 25 | + if cluster.is_paused(): 26 | + service_info.append('Maintenance mode: on') 27 | + 28 | + if cluster.failover and cluster.failover.scheduled_at: 29 | + info = 'Switchover scheduled at: ' + cluster.failover.scheduled_at.isoformat() 30 | + if cluster.failover.leader: 31 | + info += '\n from: ' + cluster.failover.leader 32 | + if cluster.failover.candidate: 33 | + info += '\n to: ' + cluster.failover.candidate 34 | + service_info.append(info) 35 | + 36 | + if service_info: 37 | + click.echo(' ' + '\n '.join(service_info)) 38 | 39 | 40 | @ctl.command('list', help='List the Patroni members for a given Patroni') 41 | -------------------------------------------------------------------------------- /RPM.fc30/patches/service-info-only-in-pretty-format.patch: -------------------------------------------------------------------------------- 1 | diff --git a/patroni/ctl.py b/patroni/ctl.py 2 | index 7f97986..b85dfaf 100644 3 | --- a/patroni/ctl.py 4 | +++ b/patroni/ctl.py 5 | @@ -713,20 +713,21 @@ def output_members(cluster, name, extended=False, fmt='pretty'): 6 | 7 | print_output(columns, rows, alignment, fmt) 8 | 9 | - service_info = [] 10 | - if cluster.is_paused(): 11 | - service_info.append('Maintenance mode: on') 12 | - 13 | - if cluster.failover and cluster.failover.scheduled_at: 14 | - info = 'Switchover scheduled at: ' + cluster.failover.scheduled_at.isoformat() 15 | - if cluster.failover.leader: 16 | - info += '\n from: ' + cluster.failover.leader 17 | - if cluster.failover.candidate: 18 | - info += '\n to: ' + cluster.failover.candidate 19 | - service_info.append(info) 20 | - 21 | - if service_info: 22 | - click.echo(' ' + '\n '.join(service_info)) 23 | + if fmt == "pretty": 24 | + service_info = [] 25 | + if cluster.is_paused(): 26 | + service_info.append('Maintenance mode: on') 27 | + 28 | + if cluster.failover and cluster.failover.scheduled_at: 29 | + info = 'Switchover scheduled at: ' + cluster.failover.scheduled_at.isoformat() 30 | + if cluster.failover.leader: 31 | + info += '\n from: ' + cluster.failover.leader 32 | + if cluster.failover.candidate: 33 | + info += '\n to: ' + cluster.failover.candidate 34 | + service_info.append(info) 35 | + 36 | + if service_info: 37 | + click.echo(' ' + '\n '.join(service_info)) 38 | 39 | 40 | @ctl.command('list', help='List the Patroni members for a given Patroni') 41 | -------------------------------------------------------------------------------- /RPM/patches/better-startup-script.patch: -------------------------------------------------------------------------------- 1 | diff --git a/extras/startup-scripts/patroni.service b/extras/startup-scripts/patroni.service 2 | index fb23ad9..99abd05 100644 3 | --- a/extras/startup-scripts/patroni.service 4 | +++ b/extras/startup-scripts/patroni.service 5 | @@ -1,8 +1,14 @@ 6 | -# This is an example systemd config file for Patroni 7 | -# You can copy it to "/etc/systemd/system/patroni.service", 8 | +# It's not recommended to modify this file in-place, because it will be 9 | +# overwritten during package upgrades. If you want to customize, the 10 | +# best way is to create a file "/etc/systemd/system/patroni.service", 11 | +# containing 12 | +# .include /lib/systemd/system/patroni.service 13 | +# Environment=PATRONI_CONFIG_LOCATION=... 14 | +# For more info about custom unit files, see 15 | +# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F 16 | 17 | [Unit] 18 | -Description=Runners to orchestrate a high-availability PostgreSQL 19 | +Description=PostgreSQL high-availability manager 20 | After=syslog.target network.target 21 | 22 | [Service] 23 | @@ -19,6 +25,11 @@ WorkingDirectory=~ 24 | # Where to send early-startup messages from the server 25 | # This is normally controlled by the global default set by systemd 26 | #StandardOutput=syslog 27 | +# Location of Patroni configuration 28 | +Environment=PATRONI_CONFIG_LOCATION=/etc/patroni/patroni.yml 29 | + 30 | +# Disable OOM kill on the postmaster 31 | +OOMScoreAdjust=-1000 32 | 33 | # Pre-commands to start watchdog device 34 | # Uncomment if watchdog is part of your patroni setup 35 | @@ -26,7 +37,7 @@ WorkingDirectory=~ 36 | #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog 37 | 38 | # Start the patroni process 39 | -ExecStart=/bin/patroni /etc/patroni.yml 40 | +ExecStart=/usr/bin/patroni ${PATRONI_CONFIG_LOCATION} 41 | 42 | # Send HUP to reload from patroni.yml 43 | ExecReload=/bin/kill -s HUP $MAINPID 44 | -------------------------------------------------------------------------------- /DEB/debian/patches/better-startup-script.patch: -------------------------------------------------------------------------------- 1 | diff --git a/extras/startup-scripts/patroni.service b/extras/startup-scripts/patroni.service 2 | index fb23ad9..99abd05 100644 3 | --- a/extras/startup-scripts/patroni.service 4 | +++ b/extras/startup-scripts/patroni.service 5 | @@ -1,8 +1,14 @@ 6 | -# This is an example systemd config file for Patroni 7 | -# You can copy it to "/etc/systemd/system/patroni.service", 8 | +# It's not recommended to modify this file in-place, because it will be 9 | +# overwritten during package upgrades. If you want to customize, the 10 | +# best way is to create a file "/etc/systemd/system/patroni.service", 11 | +# containing 12 | +# .include /lib/systemd/system/patroni.service 13 | +# Environment=PATRONI_CONFIG_LOCATION=... 14 | +# For more info about custom unit files, see 15 | +# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F 16 | 17 | [Unit] 18 | -Description=Runners to orchestrate a high-availability PostgreSQL 19 | +Description=PostgreSQL high-availability manager 20 | After=syslog.target network.target 21 | 22 | [Service] 23 | @@ -19,6 +25,11 @@ WorkingDirectory=~ 24 | # Where to send early-startup messages from the server 25 | # This is normally controlled by the global default set by systemd 26 | #StandardOutput=syslog 27 | +# Location of Patroni configuration 28 | +Environment=PATRONI_CONFIG_LOCATION=/etc/patroni/patroni.yml 29 | + 30 | +# Disable OOM kill on the postmaster 31 | +OOMScoreAdjust=-1000 32 | 33 | # Pre-commands to start watchdog device 34 | # Uncomment if watchdog is part of your patroni setup 35 | @@ -26,7 +37,7 @@ WorkingDirectory=~ 36 | #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog 37 | 38 | # Start the patroni process 39 | -ExecStart=/bin/patroni /etc/patroni.yml 40 | +ExecStart=/usr/bin/patroni ${PATRONI_CONFIG_LOCATION} 41 | 42 | # Send HUP to reload from patroni.yml 43 | ExecReload=/bin/kill -s HUP $MAINPID 44 | -------------------------------------------------------------------------------- /RPM.fc30/patches/better-startup-script.patch: -------------------------------------------------------------------------------- 1 | diff --git a/extras/startup-scripts/patroni.service b/extras/startup-scripts/patroni.service 2 | index fb23ad9..99abd05 100644 3 | --- a/extras/startup-scripts/patroni.service 4 | +++ b/extras/startup-scripts/patroni.service 5 | @@ -1,8 +1,14 @@ 6 | -# This is an example systemd config file for Patroni 7 | -# You can copy it to "/etc/systemd/system/patroni.service", 8 | +# It's not recommended to modify this file in-place, because it will be 9 | +# overwritten during package upgrades. If you want to customize, the 10 | +# best way is to create a file "/etc/systemd/system/patroni.service", 11 | +# containing 12 | +# .include /lib/systemd/system/patroni.service 13 | +# Environment=PATRONI_CONFIG_LOCATION=... 14 | +# For more info about custom unit files, see 15 | +# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F 16 | 17 | [Unit] 18 | -Description=Runners to orchestrate a high-availability PostgreSQL 19 | +Description=PostgreSQL high-availability manager 20 | After=syslog.target network.target 21 | 22 | [Service] 23 | @@ -19,6 +25,11 @@ WorkingDirectory=~ 24 | # Where to send early-startup messages from the server 25 | # This is normally controlled by the global default set by systemd 26 | #StandardOutput=syslog 27 | +# Location of Patroni configuration 28 | +Environment=PATRONI_CONFIG_LOCATION=/etc/patroni/patroni.yml 29 | + 30 | +# Disable OOM kill on the postmaster 31 | +OOMScoreAdjust=-1000 32 | 33 | # Pre-commands to start watchdog device 34 | # Uncomment if watchdog is part of your patroni setup 35 | @@ -26,7 +37,7 @@ WorkingDirectory=~ 36 | #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog 37 | 38 | # Start the patroni process 39 | -ExecStart=/bin/patroni /etc/patroni.yml 40 | +ExecStart=/usr/bin/patroni ${PATRONI_CONFIG_LOCATION} 41 | 42 | # Send HUP to reload from patroni.yml 43 | ExecReload=/bin/kill -s HUP $MAINPID 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This project is now deprecated! :warning: 2 | 3 | Since [postgresql.org](https://www.postgresql.org/download/) provides [packaging](https://git.postgresql.org/gitweb/?p=pgrpms.git;a=blob;f=rpm/redhat/master/common/patroni/master/patroni.spec) for patroni on most distributions, we feel that we should not work on solving the same things in different ways. Thus we'll be deprecating this repository and the packages. 4 | 5 | Please check [this document](package_migration.md) for migration steps. 6 | 7 | 8 | # patroni-packaging 9 | 10 | This project packages patroni, along with all necessary libs that aren't easily available as packages themselves. 11 | 12 | You're probably looking for prebuilt packages, right? Then head over to the releases and download the newest version there! 13 | 14 | ## building the packages yourself 15 | 16 | > you'll need docker installed and running 17 | 18 | 1. navigate to the `DEB` or `RPM` directory (depending of what you'd like to build). 19 | 2. execute `make docker-image` to generate a custom docker image based on either debian or centos, within which the package will be built. 20 | 3. execute `make package` to build the package. (The Debian side of things will also build vip-manager.) This may take some time, as all necessary python libraries are installed into a virtualenv, which is then packaged. 21 | 4. If you're building .debs, the packages will be in the `DEB` directory at the end of the build process. On the other hand, after building .rpms, the package will reside in the `RPM/rpms` directory. 22 | 23 | ## dependencies of the produced packages 24 | 25 | ### rpm 26 | 27 | You'll need to install the EPEL repositories, which is the only straight forward way to get psycopg2 in a version newer than 2.5.4 (centos 7 repos only provide 2.5.1), which is a requirement of patroni. 28 | 29 | > Due to the fact that the python packages on fedora are named `python3-something`, the packages produced by centos won't work currently, as they require `python36-something`. 30 | 31 | ### deb 32 | 33 | Haven't tested yet. probably `python-psycopg2` will suffice. Can probably be automatically installed after apt has finished the dependency check. 34 | 35 | > The deb packages are still packaged with python2! 36 | -------------------------------------------------------------------------------- /DEB/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: patroni 3 | Source: https://github.com/zalando/patroni/ 4 | 5 | Files: * 6 | Copyright: 2015 Compose, Zalando SE 7 | License: The MIT License (MIT) 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | . 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | . 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | 26 | Files: debian/* 27 | Copyright: 2017 Ants Aasma 28 | License: GPL-2+ 29 | This package is free software; you can redistribute it and/or modify 30 | it under the terms of the GNU General Public License as published by 31 | the Free Software Foundation; either version 2 of the License, or 32 | (at your option) any later version. 33 | . 34 | This package is distributed in the hope that it will be useful, 35 | but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 | GNU General Public License for more details. 38 | . 39 | You should have received a copy of the GNU General Public License 40 | along with this program. If not, see 41 | . 42 | On Debian systems, the complete text of the GNU General 43 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". 44 | 45 | -------------------------------------------------------------------------------- /RPM/postgres-telia.yml: -------------------------------------------------------------------------------- 1 | scope: batman 2 | #namespace: /service/ 3 | name: postgresql0 4 | 5 | restapi: 6 | listen: 0.0.0.0:8008 7 | connect_address: 10.0.0.1:8008 8 | # certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem 9 | # keyfile: /etc/ssl/private/ssl-cert-snakeoil.key 10 | # authentication: 11 | # username: username 12 | # password: password 13 | 14 | etcd: 15 | host: 127.0.0.1:2379 16 | 17 | bootstrap: 18 | # this section will be written into Etcd:///config after initializing new cluster 19 | # and all other cluster members will use it as a `global configuration` 20 | dcs: 21 | ttl: 30 22 | loop_wait: 10 23 | retry_timeout: 10 24 | maximum_lag_on_failover: 1048576 25 | # master_start_timeout: 300 26 | # synchronous_mode: false 27 | postgresql: 28 | use_pg_rewind: true 29 | use_slots: true 30 | parameters: 31 | # wal_level: hot_standby 32 | # hot_standby: "on" 33 | # wal_keep_segments: 8 34 | # max_wal_senders: 5 35 | # max_replication_slots: 5 36 | # wal_log_hints: "on" 37 | # archive_mode: "on" 38 | # archive_timeout: 1800s 39 | # archive_command: mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f 40 | # recovery_conf: 41 | # restore_command: cp ../wal_archive/%f %p 42 | 43 | # some desired options for 'initdb' 44 | initdb: # Note: It needs to be a list (some options need values, others are switches) 45 | - encoding: UTF8 46 | - data-checksums 47 | 48 | pg_hba: # Add following lines to pg_hba.conf after running 'initdb' 49 | - host replication replicator 127.0.0.1/32 md5 50 | - host all all 0.0.0.0/0 md5 51 | # - hostssl all all 0.0.0.0/0 md5 52 | 53 | # Additional script to be launched after initial cluster creation (will be passed the connection URL as parameter) 54 | # post_init: /usr/local/bin/setup_cluster.sh 55 | 56 | # Some additional users users which needs to be created after initializing new cluster 57 | users: 58 | admin: 59 | password: admin 60 | options: 61 | - createrole 62 | - createdb 63 | 64 | postgresql: 65 | listen: 0.0.0.0:5432 66 | connect_address: 10.0.0.1:5432 67 | data_dir: /var/lib/pgsql/9.5/data 68 | bin_dir: /usr/pgsql-9.5/bin 69 | pgpass: /tmp/pgpass0 70 | authentication: 71 | replication: 72 | username: replicator 73 | password: ... 74 | superuser: 75 | username: postgres 76 | password: ... 77 | 78 | #watchdog: 79 | # mode: automatic # Allowed values: off, automatic, required 80 | # device: /dev/watchdog 81 | # safety_margin: 5 82 | 83 | tags: 84 | nofailover: false 85 | noloadbalance: false 86 | clonefrom: false 87 | nosync: false 88 | -------------------------------------------------------------------------------- /RPM.fc30/postgres-telia.yml: -------------------------------------------------------------------------------- 1 | scope: batman 2 | #namespace: /service/ 3 | name: postgresql0 4 | 5 | restapi: 6 | listen: 0.0.0.0:8008 7 | connect_address: 10.0.0.1:8008 8 | # certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem 9 | # keyfile: /etc/ssl/private/ssl-cert-snakeoil.key 10 | # authentication: 11 | # username: username 12 | # password: password 13 | 14 | etcd: 15 | host: 127.0.0.1:2379 16 | 17 | bootstrap: 18 | # this section will be written into Etcd:///config after initializing new cluster 19 | # and all other cluster members will use it as a `global configuration` 20 | dcs: 21 | ttl: 30 22 | loop_wait: 10 23 | retry_timeout: 10 24 | maximum_lag_on_failover: 1048576 25 | # master_start_timeout: 300 26 | # synchronous_mode: false 27 | postgresql: 28 | use_pg_rewind: true 29 | use_slots: true 30 | parameters: 31 | # wal_level: hot_standby 32 | # hot_standby: "on" 33 | # wal_keep_segments: 8 34 | # max_wal_senders: 5 35 | # max_replication_slots: 5 36 | # wal_log_hints: "on" 37 | # archive_mode: "on" 38 | # archive_timeout: 1800s 39 | # archive_command: mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f 40 | # recovery_conf: 41 | # restore_command: cp ../wal_archive/%f %p 42 | 43 | # some desired options for 'initdb' 44 | initdb: # Note: It needs to be a list (some options need values, others are switches) 45 | - encoding: UTF8 46 | - data-checksums 47 | 48 | pg_hba: # Add following lines to pg_hba.conf after running 'initdb' 49 | - host replication replicator 127.0.0.1/32 md5 50 | - host all all 0.0.0.0/0 md5 51 | # - hostssl all all 0.0.0.0/0 md5 52 | 53 | # Additional script to be launched after initial cluster creation (will be passed the connection URL as parameter) 54 | # post_init: /usr/local/bin/setup_cluster.sh 55 | 56 | # Some additional users users which needs to be created after initializing new cluster 57 | users: 58 | admin: 59 | password: admin 60 | options: 61 | - createrole 62 | - createdb 63 | 64 | postgresql: 65 | listen: 0.0.0.0:5432 66 | connect_address: 10.0.0.1:5432 67 | data_dir: /var/lib/pgsql/9.5/data 68 | bin_dir: /usr/pgsql-9.5/bin 69 | pgpass: /tmp/pgpass0 70 | authentication: 71 | replication: 72 | username: replicator 73 | password: ... 74 | superuser: 75 | username: postgres 76 | password: ... 77 | 78 | #watchdog: 79 | # mode: automatic # Allowed values: off, automatic, required 80 | # device: /dev/watchdog 81 | # safety_margin: 5 82 | 83 | tags: 84 | nofailover: false 85 | noloadbalance: false 86 | clonefrom: false 87 | nosync: false 88 | -------------------------------------------------------------------------------- /RPM/patches/add-sample-config.patch: -------------------------------------------------------------------------------- 1 | Add sample configuration file 2 | --- /dev/null 3 | +++ b/patroni.yml.sample 4 | @@ -0,0 +1,86 @@ 5 | +scope: batman 6 | +#namespace: /service/ 7 | +name: postgresql0 8 | + 9 | +restapi: 10 | + listen: 0.0.0.0:8008 11 | + connect_address: 10.0.0.1:8008 12 | +# certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem 13 | +# keyfile: /etc/ssl/private/ssl-cert-snakeoil.key 14 | +# authentication: 15 | +# username: username 16 | +# password: password 17 | + 18 | +etcd: 19 | + host: 127.0.0.1:2379 20 | + 21 | +bootstrap: 22 | + # this section will be written into Etcd:///config after initializing new cluster 23 | + # and all other cluster members will use it as a `global configuration` 24 | + dcs: 25 | + ttl: 30 26 | + loop_wait: 10 27 | + retry_timeout: 10 28 | + maximum_lag_on_failover: 1048576 29 | +# master_start_timeout: 300 30 | +# synchronous_mode: false 31 | + postgresql: 32 | + use_pg_rewind: true 33 | + use_slots: true 34 | + parameters: 35 | +# wal_level: hot_standby 36 | +# hot_standby: "on" 37 | +# wal_keep_segments: 8 38 | +# max_wal_senders: 5 39 | +# max_replication_slots: 5 40 | +# wal_log_hints: "on" 41 | +# archive_mode: "on" 42 | +# archive_timeout: 1800s 43 | +# archive_command: mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f 44 | +# recovery_conf: 45 | +# restore_command: cp ../wal_archive/%f %p 46 | + 47 | + # some desired options for 'initdb' 48 | + initdb: # Note: It needs to be a list (some options need values, others are switches) 49 | + - encoding: UTF8 50 | + - data-checksums 51 | + 52 | + pg_hba: # Add following lines to pg_hba.conf after running 'initdb' 53 | + - host replication replicator 0.0.0.0/0 md5 54 | + - host all all 0.0.0.0/0 md5 55 | +# - hostssl all all 0.0.0.0/0 md5 56 | + 57 | + # Additional script to be launched after initial cluster creation (will be passed the connection URL as parameter) 58 | +# post_init: /usr/local/bin/setup_cluster.sh 59 | + 60 | + # Some additional users users which needs to be created after initializing new cluster 61 | + users: 62 | + admin: 63 | + password: admin 64 | + options: 65 | + - createrole 66 | + - createdb 67 | + 68 | +postgresql: 69 | + listen: 0.0.0.0:5432 70 | + connect_address: 10.0.0.1:5432 71 | + data_dir: /var/lib/postgresql/9.6/main 72 | + bin_dir: /usr/lib/postgresql/9.6/bin/ 73 | + pgpass: /tmp/pgpass0 74 | + authentication: 75 | + replication: 76 | + username: replicator 77 | + password: ... 78 | + superuser: 79 | + username: postgres 80 | + password: ... 81 | + 82 | +#watchdog: 83 | +# mode: automatic # Allowed values: off, automatic, required 84 | +# device: /dev/watchdog 85 | + 86 | +tags: 87 | + nofailover: false 88 | + noloadbalance: false 89 | + clonefrom: false 90 | + nosync: false 91 | -------------------------------------------------------------------------------- /DEB/debian/patches/add-sample-config.patch: -------------------------------------------------------------------------------- 1 | Add sample configuration file 2 | --- /dev/null 3 | +++ b/patroni.yml.sample 4 | @@ -0,0 +1,86 @@ 5 | +scope: batman 6 | +#namespace: /service/ 7 | +name: postgresql0 8 | + 9 | +restapi: 10 | + listen: 0.0.0.0:8008 11 | + connect_address: 10.0.0.1:8008 12 | +# certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem 13 | +# keyfile: /etc/ssl/private/ssl-cert-snakeoil.key 14 | +# authentication: 15 | +# username: username 16 | +# password: password 17 | + 18 | +etcd: 19 | + host: 127.0.0.1:2379 20 | + 21 | +bootstrap: 22 | + # this section will be written into Etcd:///config after initializing new cluster 23 | + # and all other cluster members will use it as a `global configuration` 24 | + dcs: 25 | + ttl: 30 26 | + loop_wait: 10 27 | + retry_timeout: 10 28 | + maximum_lag_on_failover: 1048576 29 | +# master_start_timeout: 300 30 | +# synchronous_mode: false 31 | + postgresql: 32 | + use_pg_rewind: true 33 | + use_slots: true 34 | + parameters: 35 | +# wal_level: hot_standby 36 | +# hot_standby: "on" 37 | +# wal_keep_segments: 8 38 | +# max_wal_senders: 5 39 | +# max_replication_slots: 5 40 | +# wal_log_hints: "on" 41 | +# archive_mode: "on" 42 | +# archive_timeout: 1800s 43 | +# archive_command: mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f 44 | +# recovery_conf: 45 | +# restore_command: cp ../wal_archive/%f %p 46 | + 47 | + # some desired options for 'initdb' 48 | + initdb: # Note: It needs to be a list (some options need values, others are switches) 49 | + - encoding: UTF8 50 | + - data-checksums 51 | + 52 | + pg_hba: # Add following lines to pg_hba.conf after running 'initdb' 53 | + - host replication replicator 0.0.0.0/0 md5 54 | + - host all all 0.0.0.0/0 md5 55 | +# - hostssl all all 0.0.0.0/0 md5 56 | + 57 | + # Additional script to be launched after initial cluster creation (will be passed the connection URL as parameter) 58 | +# post_init: /usr/local/bin/setup_cluster.sh 59 | + 60 | + # Some additional users users which needs to be created after initializing new cluster 61 | + users: 62 | + admin: 63 | + password: admin 64 | + options: 65 | + - createrole 66 | + - createdb 67 | + 68 | +postgresql: 69 | + listen: 0.0.0.0:5432 70 | + connect_address: 10.0.0.1:5432 71 | + data_dir: /var/lib/postgresql/9.6/main 72 | + bin_dir: /usr/lib/postgresql/9.6/bin/ 73 | + pgpass: /tmp/pgpass0 74 | + authentication: 75 | + replication: 76 | + username: replicator 77 | + password: ... 78 | + superuser: 79 | + username: postgres 80 | + password: ... 81 | + 82 | +#watchdog: 83 | +# mode: automatic # Allowed values: off, automatic, required 84 | +# device: /dev/watchdog 85 | + 86 | +tags: 87 | + nofailover: false 88 | + noloadbalance: false 89 | + clonefrom: false 90 | + nosync: false 91 | -------------------------------------------------------------------------------- /RPM.fc30/patches/add-sample-config.patch: -------------------------------------------------------------------------------- 1 | Add sample configuration file 2 | --- /dev/null 3 | +++ b/patroni.yml.sample 4 | @@ -0,0 +1,86 @@ 5 | +scope: batman 6 | +#namespace: /service/ 7 | +name: postgresql0 8 | + 9 | +restapi: 10 | + listen: 0.0.0.0:8008 11 | + connect_address: 10.0.0.1:8008 12 | +# certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem 13 | +# keyfile: /etc/ssl/private/ssl-cert-snakeoil.key 14 | +# authentication: 15 | +# username: username 16 | +# password: password 17 | + 18 | +etcd: 19 | + host: 127.0.0.1:2379 20 | + 21 | +bootstrap: 22 | + # this section will be written into Etcd:///config after initializing new cluster 23 | + # and all other cluster members will use it as a `global configuration` 24 | + dcs: 25 | + ttl: 30 26 | + loop_wait: 10 27 | + retry_timeout: 10 28 | + maximum_lag_on_failover: 1048576 29 | +# master_start_timeout: 300 30 | +# synchronous_mode: false 31 | + postgresql: 32 | + use_pg_rewind: true 33 | + use_slots: true 34 | + parameters: 35 | +# wal_level: hot_standby 36 | +# hot_standby: "on" 37 | +# wal_keep_segments: 8 38 | +# max_wal_senders: 5 39 | +# max_replication_slots: 5 40 | +# wal_log_hints: "on" 41 | +# archive_mode: "on" 42 | +# archive_timeout: 1800s 43 | +# archive_command: mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f 44 | +# recovery_conf: 45 | +# restore_command: cp ../wal_archive/%f %p 46 | + 47 | + # some desired options for 'initdb' 48 | + initdb: # Note: It needs to be a list (some options need values, others are switches) 49 | + - encoding: UTF8 50 | + - data-checksums 51 | + 52 | + pg_hba: # Add following lines to pg_hba.conf after running 'initdb' 53 | + - host replication replicator 0.0.0.0/0 md5 54 | + - host all all 0.0.0.0/0 md5 55 | +# - hostssl all all 0.0.0.0/0 md5 56 | + 57 | + # Additional script to be launched after initial cluster creation (will be passed the connection URL as parameter) 58 | +# post_init: /usr/local/bin/setup_cluster.sh 59 | + 60 | + # Some additional users users which needs to be created after initializing new cluster 61 | + users: 62 | + admin: 63 | + password: admin 64 | + options: 65 | + - createrole 66 | + - createdb 67 | + 68 | +postgresql: 69 | + listen: 0.0.0.0:5432 70 | + connect_address: 10.0.0.1:5432 71 | + data_dir: /var/lib/postgresql/9.6/main 72 | + bin_dir: /usr/lib/postgresql/9.6/bin/ 73 | + pgpass: /tmp/pgpass0 74 | + authentication: 75 | + replication: 76 | + username: replicator 77 | + password: ... 78 | + superuser: 79 | + username: postgres 80 | + password: ... 81 | + 82 | +#watchdog: 83 | +# mode: automatic # Allowed values: off, automatic, required 84 | +# device: /dev/watchdog 85 | + 86 | +tags: 87 | + nofailover: false 88 | + noloadbalance: false 89 | + clonefrom: false 90 | + nosync: false 91 | -------------------------------------------------------------------------------- /DEB/debian/patches/patronictl-reinit-wait-rebased-1.6.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/patroni/api.py b/patroni/api.py 2 | index 894064f..6560ae7 100644 3 | --- a/patroni/api.py 4 | +++ b/patroni/api.py 5 | @@ -82,6 +82,7 @@ class RestApiHandler(BaseHTTPRequestHandler): 6 | lost = patroni.logger.records_lost 7 | if lost: 8 | response['logger_records_lost'] = lost 9 | + response['action'] = self.server.patroni.ha.action 10 | self._write_json_response(status_code, response) 11 | 12 | def do_GET(self, write_status_code_only=False): 13 | diff --git a/patroni/ctl.py b/patroni/ctl.py 14 | index a4df213..ab102de 100644 15 | --- a/patroni/ctl.py 16 | +++ b/patroni/ctl.py 17 | @@ -585,20 +585,37 @@ def restart(obj, cluster_name, member_names, force, role, p_any, scheduled, vers 18 | @click.argument('cluster_name') 19 | @click.argument('member_names', nargs=-1) 20 | @option_force 21 | +@click.option('--wait', help='Wait until reinitialization completes', is_flag=True) 22 | @click.pass_obj 23 | -def reinit(obj, cluster_name, member_names, force): 24 | +def reinit(obj, cluster_name, member_names, force, wait): 25 | cluster = get_dcs(obj, cluster_name).get_cluster() 26 | members = get_members(cluster, cluster_name, member_names, None, force, 'reinitialize') 27 | 28 | + wait_on_members = [] 29 | for member in members: 30 | body = {'force': force} 31 | while True: 32 | r = request_patroni(member, 'post', 'reinitialize', body, auth_header(obj)) 33 | - if not check_response(r, member.name, 'reinitialize') and r.text.endswith(' already in progress') \ 34 | + started = check_response(r, member.name, 'reinitialize') 35 | + if not started and r.text.endswith(' already in progress') \ 36 | and not force and click.confirm('Do you want to cancel it and reinitialize anyway?'): 37 | body['force'] = True 38 | continue 39 | break 40 | + if started and wait: 41 | + wait_on_members.append(member) 42 | + 43 | + last_display = [] 44 | + while wait_on_members: 45 | + if wait_on_members != last_display: 46 | + click.echo('Waiting for reinitialize to complete on: {0}'.format( 47 | + ", ".join(member.name for member in wait_on_members)) 48 | + ) 49 | + last_display[:] = wait_on_members 50 | + time.sleep(2) 51 | + for member in wait_on_members: 52 | + if request_patroni(member, 'get', 'patroni').json().get('action') != 'reinitialize': 53 | + wait_on_members.remove(member) 54 | 55 | 56 | def _do_failover_or_switchover(obj, action, cluster_name, master, candidate, force, scheduled=None): 57 | diff --git a/patroni/ha.py b/patroni/ha.py 58 | index 403f512..bfd0de5 100644 59 | --- a/patroni/ha.py 60 | +++ b/patroni/ha.py 61 | @@ -1118,6 +1118,13 @@ class Ha(object): 62 | 63 | return self._async_executor.scheduled_action + ' in progress' 64 | 65 | + @property 66 | + def action(self): 67 | + with self._async_executor: 68 | + if self._async_executor.busy: 69 | + return self._async_executor.scheduled_action 70 | + return None 71 | + 72 | @staticmethod 73 | def sysid_valid(sysid): 74 | # sysid does tv_sec << 32, where tv_sec is the number of seconds sine 1970, 75 | diff --git a/tests/test_api.py b/tests/test_api.py 76 | index 327dbf8..5bf8c85 100644 77 | --- a/tests/test_api.py 78 | +++ b/tests/test_api.py 79 | @@ -100,6 +100,8 @@ class MockHa(object): 80 | def is_standby_cluster(): 81 | return False 82 | 83 | + action = None 84 | + 85 | 86 | class MockLogger(object): 87 | 88 | -------------------------------------------------------------------------------- /RPM.fc30/patches/patronictl-reinit-wait-rebased-1.6.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/patroni/api.py b/patroni/api.py 2 | index 894064f..6560ae7 100644 3 | --- a/patroni/api.py 4 | +++ b/patroni/api.py 5 | @@ -82,6 +82,7 @@ class RestApiHandler(BaseHTTPRequestHandler): 6 | lost = patroni.logger.records_lost 7 | if lost: 8 | response['logger_records_lost'] = lost 9 | + response['action'] = self.server.patroni.ha.action 10 | self._write_json_response(status_code, response) 11 | 12 | def do_GET(self, write_status_code_only=False): 13 | diff --git a/patroni/ctl.py b/patroni/ctl.py 14 | index a4df213..ab102de 100644 15 | --- a/patroni/ctl.py 16 | +++ b/patroni/ctl.py 17 | @@ -585,20 +585,37 @@ def restart(obj, cluster_name, member_names, force, role, p_any, scheduled, vers 18 | @click.argument('cluster_name') 19 | @click.argument('member_names', nargs=-1) 20 | @option_force 21 | +@click.option('--wait', help='Wait until reinitialization completes', is_flag=True) 22 | @click.pass_obj 23 | -def reinit(obj, cluster_name, member_names, force): 24 | +def reinit(obj, cluster_name, member_names, force, wait): 25 | cluster = get_dcs(obj, cluster_name).get_cluster() 26 | members = get_members(cluster, cluster_name, member_names, None, force, 'reinitialize') 27 | 28 | + wait_on_members = [] 29 | for member in members: 30 | body = {'force': force} 31 | while True: 32 | r = request_patroni(member, 'post', 'reinitialize', body, auth_header(obj)) 33 | - if not check_response(r, member.name, 'reinitialize') and r.text.endswith(' already in progress') \ 34 | + started = check_response(r, member.name, 'reinitialize') 35 | + if not started and r.text.endswith(' already in progress') \ 36 | and not force and click.confirm('Do you want to cancel it and reinitialize anyway?'): 37 | body['force'] = True 38 | continue 39 | break 40 | + if started and wait: 41 | + wait_on_members.append(member) 42 | + 43 | + last_display = [] 44 | + while wait_on_members: 45 | + if wait_on_members != last_display: 46 | + click.echo('Waiting for reinitialize to complete on: {0}'.format( 47 | + ", ".join(member.name for member in wait_on_members)) 48 | + ) 49 | + last_display[:] = wait_on_members 50 | + time.sleep(2) 51 | + for member in wait_on_members: 52 | + if request_patroni(member, 'get', 'patroni').json().get('action') != 'reinitialize': 53 | + wait_on_members.remove(member) 54 | 55 | 56 | def _do_failover_or_switchover(obj, action, cluster_name, master, candidate, force, scheduled=None): 57 | diff --git a/patroni/ha.py b/patroni/ha.py 58 | index 403f512..bfd0de5 100644 59 | --- a/patroni/ha.py 60 | +++ b/patroni/ha.py 61 | @@ -1118,6 +1118,13 @@ class Ha(object): 62 | 63 | return self._async_executor.scheduled_action + ' in progress' 64 | 65 | + @property 66 | + def action(self): 67 | + with self._async_executor: 68 | + if self._async_executor.busy: 69 | + return self._async_executor.scheduled_action 70 | + return None 71 | + 72 | @staticmethod 73 | def sysid_valid(sysid): 74 | # sysid does tv_sec << 32, where tv_sec is the number of seconds sine 1970, 75 | diff --git a/tests/test_api.py b/tests/test_api.py 76 | index 327dbf8..5bf8c85 100644 77 | --- a/tests/test_api.py 78 | +++ b/tests/test_api.py 79 | @@ -100,6 +100,8 @@ class MockHa(object): 80 | def is_standby_cluster(): 81 | return False 82 | 83 | + action = None 84 | + 85 | 86 | class MockLogger(object): 87 | 88 | -------------------------------------------------------------------------------- /RPM.fc30/fc30.patroni.spec: -------------------------------------------------------------------------------- 1 | %define ENVNAME patroni 2 | %define INSTALLPATH /opt/app/patroni 3 | %define debug_package %{nil} 4 | Name: patroni 5 | Version: 1.6.0 6 | Release: 1.fc30 7 | License: MIT 8 | Summary: PostgreSQL high-availability manager 9 | Source: patroni-1.6.0.tar.gz 10 | Source1: patroni-customizations.tar.gz 11 | Patch0: service-info-only-in-pretty-format.patch 12 | Patch1: patronictl-reinit-wait-rebased-1.6.0.patch 13 | Patch2: add-sample-config.patch 14 | Patch3: better-startup-script.patch 15 | BuildRoot: %{_tmppath}/%{buildprefix}-buildroot 16 | Requires: /usr/bin/python3, python3-psycopg2 >= 2.5.4, libffi, postgresql-server, libyaml 17 | BuildRequires: libyaml-devel gcc 18 | Requires(post): %{_sbindir}/update-alternatives 19 | Requires(postun): %{_sbindir}/update-alternatives 20 | 21 | %global __requires_exclude_from ^%{INSTALLPATH}/lib/python3.7/site-packages/(psycopg2/|_cffi_backend.so|_cffi_backend.cpython-37m-x86_64-linux-gnu.so|.libs_cffi_backend/libffi-.*.so.6.0.4) 22 | %global __provides_exclude_from ^%{INSTALLPATH}/lib/python3.7/ 23 | 24 | %global __python %{__python3.7} 25 | 26 | %description 27 | Packaged version of Patroni HA manager. 28 | 29 | %prep 30 | %setup 31 | %setup -D -T -a 1 32 | %patch0 -p1 33 | %patch1 -p1 34 | %patch2 -p1 35 | %patch3 -p1 36 | 37 | %build 38 | # remove some things 39 | #rm -f $RPM_BUILD_ROOT/%{prefix}/*.spec 40 | 41 | %install 42 | rm -rf $RPM_BUILD_ROOT 43 | mkdir -p $RPM_BUILD_ROOT%{INSTALLPATH} 44 | virtualenv --distribute --system-site-packages $RPM_BUILD_ROOT%{INSTALLPATH} 45 | grep -v psycopg2 requirements.txt | sed 's/kubernetes=.*/kubernetes/' > requirements-venv.txt 46 | $RPM_BUILD_ROOT%{INSTALLPATH}/bin/pip3.7 install -U setuptools 47 | $RPM_BUILD_ROOT%{INSTALLPATH}/bin/pip3.7 install -r requirements-venv.txt 48 | $RPM_BUILD_ROOT%{INSTALLPATH}/bin/pip3.7 install --no-deps . 49 | rm $RPM_BUILD_ROOT%{INSTALLPATH}/lib/python3.7/site-packages/consul/aio.py 50 | 51 | rm -rf $RPM_BUILD_ROOT/usr/ 52 | 53 | #cleanup against .build_id conflicts... 54 | rm $RPM_BUILD_ROOT%{INSTALLPATH}/bin/python3.7 55 | rm $RPM_BUILD_ROOT%{INSTALLPATH}/bin/python3 56 | 57 | virtualenv --relocatable $RPM_BUILD_ROOT%{INSTALLPATH} 58 | sed -i "s#$RPM_BUILD_ROOT##" $RPM_BUILD_ROOT%{INSTALLPATH}/bin/activate* 59 | 60 | #find $(VENV_PATH) -name \*py[co] -exec rm {} \; 61 | #find $(VENV_PATH) -name no-global-site-packages.txt -exec rm {} \; 62 | cp -r extras/ $RPM_BUILD_ROOT%{INSTALLPATH} 63 | 64 | mkdir -p $RPM_BUILD_ROOT/lib/systemd/system/ 65 | cp patroni.2.service $RPM_BUILD_ROOT/lib/systemd/system/patroni.service 66 | cp patroni-watchdog.service $RPM_BUILD_ROOT/lib/systemd/system/patroni-watchdog.service 67 | 68 | mkdir -p $RPM_BUILD_ROOT%{INSTALLPATH}/etc/ 69 | cp postgres-telia.yml $RPM_BUILD_ROOT%{INSTALLPATH}/etc/postgresql.yml.sample 70 | chmod 0600 $RPM_BUILD_ROOT%{INSTALLPATH}/etc/postgresql.yml.sample 71 | 72 | # undo prelinking 73 | #find $RPM_BUILD_ROOT%{INSTALLPATH}/bin/ -type f -perm /u+x,g+x -exec /usr/sbin/prelink -u {} \; 74 | # Remove debug info containing BUILDROOT. Hopefully nobody needs to debug or profile the python modules 75 | find $RPM_BUILD_ROOT%{INSTALLPATH}/lib/ -type f -name '*.so' -exec /usr/bin/strip -g {} \; 76 | 77 | 78 | %post 79 | %{_sbindir}/update-alternatives --install %{_bindir}/patroni \ 80 | patroni %{INSTALLPATH}/bin/patroni 10 \ 81 | --slave %{_bindir}/patronictl patroni-patronictl %{INSTALLPATH}/bin/patronictl 82 | 83 | %postun 84 | if [ $1 -eq 0 ] ; then 85 | %{_sbindir}/update-alternatives --remove patroni %{INSTALLPATH}/bin/patroni 86 | fi 87 | 88 | %clean 89 | rm -rf $RPM_BUILD_ROOT 90 | 91 | %files 92 | %defattr(-,root,root) 93 | /opt/app/patroni 94 | %attr(-, postgres, postgres) /opt/app/patroni/etc 95 | %attr(664, root, root) /lib/systemd/system/patroni.service 96 | %attr(664, root, root) /lib/systemd/system/patroni-watchdog.service 97 | 98 | %changelog 99 | * Mon Apr 8 2019 Julian Markwort 1.6.0-1.rhel7 100 | - Update to 1.6.0 101 | 102 | * Mon Apr 8 2019 Ants Aasma 1.5.6-1.rhel7 103 | - Update to 1.5.6 104 | 105 | * Mon Apr 1 2019 Anton Patsev 1.5.5-1.rhel7 106 | - Update to 1.5.5 107 | 108 | * Fri Sep 21 2018 Ants Aasma 1.5.0-1.rhel7 109 | - Update to 1.5.0 110 | 111 | * Wed May 23 2018 Ants Aasma 1.4.4-1.rhel7 112 | - Update to 1.4.4 113 | - Add patronictl reinit --wait feature 114 | 115 | * Thu May 10 2018 Ants Aasma 1.4.3-2.rhel7 116 | - Only display service info output in pretty format. 117 | 118 | * Tue May 8 2018 Ants Aasma 1.4.3-1.rhel7 119 | - Update to 1.4.3 120 | 121 | * Fri Dec 8 2017 Ants Aasma 1.3.6-1.rhel7 122 | - Update to 1.3.6 123 | 124 | * Sat Sep 30 2017 Ants Aasma 1.3.4-2.rhel7 125 | - Add warning for cluster being in paused mode 126 | - Pull in master changes up to cfdda23e 127 | 128 | -------------------------------------------------------------------------------- /RPM/patroni.spec: -------------------------------------------------------------------------------- 1 | %define VERSION 1.6.5 2 | # SHA256SUM of the patroni source archive 3 | %define SRC_SHA256SUM a72e18e901be2404831f819b4a22c4df67d5fbb013e455d22fdc352f1e171be6 4 | 5 | %define ENVNAME patroni 6 | %define INSTALLPATH /opt/app/patroni 7 | %define debug_package %{nil} 8 | 9 | # Fetch remote sources 10 | %undefine _disable_source_fetch 11 | 12 | Name: patroni 13 | Version: %{VERSION} 14 | Release: 1.rhel7 15 | License: MIT 16 | Summary: PostgreSQL high-availability manager 17 | Source: https://github.com/zalando/patroni/archive/v%{version}.tar.gz 18 | Source1: patroni-customizations.tar.gz 19 | Patch0: add-sample-config.patch 20 | Patch1: better-startup-script.patch 21 | BuildRoot: %{_tmppath}/%{buildprefix}-buildroot 22 | Requires: python3, python3-psycopg2 >= 2.5.4, libffi, postgresql-server, libyaml 23 | BuildRequires: prelink libyaml-devel gcc 24 | Requires(post): %{_sbindir}/update-alternatives 25 | Requires(postun): %{_sbindir}/update-alternatives 26 | 27 | %global __requires_exclude_from ^%{INSTALLPATH}/lib/python3.6/site-packages/(psycopg2/|_cffi_backend.so|_cffi_backend.cpython-36m-x86_64-linux-gnu.so|.libs_cffi_backend/libffi-.*.so.6.0.4) 28 | %global __provides_exclude_from ^%{INSTALLPATH}/lib/python3.6/ 29 | 30 | %global __python %{__python3} 31 | 32 | %description 33 | Packaged version of Patroni HA manager. 34 | 35 | %prep 36 | # Check SHA256 sum of the fetched source 37 | echo "%{SRC_SHA256SUM} %{SOURCE0}" | sha256sum -c - 38 | %setup 39 | %setup -D -T -a 1 40 | %patch0 -p1 41 | %patch1 -p1 42 | 43 | %build 44 | # remove some things 45 | #rm -f $RPM_BUILD_ROOT/%{prefix}/*.spec 46 | 47 | %install 48 | rm -rf $RPM_BUILD_ROOT 49 | mkdir -p $RPM_BUILD_ROOT%{INSTALLPATH} 50 | virtualenv-3 --distribute --system-site-packages $RPM_BUILD_ROOT%{INSTALLPATH} 51 | grep -v psycopg2 requirements.txt | sed 's/kubernetes=.*/kubernetes/' > requirements-venv.txt 52 | $RPM_BUILD_ROOT%{INSTALLPATH}/bin/pip3 install -U setuptools 53 | $RPM_BUILD_ROOT%{INSTALLPATH}/bin/pip3 install -r requirements-venv.txt 54 | $RPM_BUILD_ROOT%{INSTALLPATH}/bin/pip3 install --no-deps . 55 | #rm $RPM_BUILD_ROOT%{INSTALLPATH}/lib/python3*/site-packages/consul/aio.py 56 | 57 | rm -rf $RPM_BUILD_ROOT/usr/ 58 | 59 | virtualenv-3.6 --relocatable $RPM_BUILD_ROOT%{INSTALLPATH} 60 | sed -i "s#$RPM_BUILD_ROOT##" $RPM_BUILD_ROOT%{INSTALLPATH}/bin/activate* 61 | 62 | #find $(VENV_PATH) -name \*py[co] -exec rm {} \; 63 | #find $(VENV_PATH) -name no-global-site-packages.txt -exec rm {} \; 64 | cp -r extras/ $RPM_BUILD_ROOT%{INSTALLPATH} 65 | 66 | mkdir -p $RPM_BUILD_ROOT/lib/systemd/system/ 67 | cp patroni.2.service $RPM_BUILD_ROOT/lib/systemd/system/patroni.service 68 | cp patroni-watchdog.service $RPM_BUILD_ROOT/lib/systemd/system/patroni-watchdog.service 69 | 70 | mkdir -p $RPM_BUILD_ROOT%{INSTALLPATH}/etc/ 71 | cp postgres-telia.yml $RPM_BUILD_ROOT%{INSTALLPATH}/etc/postgresql.yml.sample 72 | chmod 0600 $RPM_BUILD_ROOT%{INSTALLPATH}/etc/postgresql.yml.sample 73 | 74 | # undo prelinking 75 | find $RPM_BUILD_ROOT%{INSTALLPATH}/bin/ -type f -perm /u+x,g+x -exec /usr/sbin/prelink -u {} \; 76 | # Remove debug info containing BUILDROOT. Hopefully nobody needs to debug or profile the python modules 77 | find $RPM_BUILD_ROOT%{INSTALLPATH}/lib/ -type f -name '*.so' -exec /usr/bin/strip -g {} \; 78 | 79 | 80 | %post 81 | %{_sbindir}/update-alternatives --install %{_bindir}/patroni \ 82 | patroni %{INSTALLPATH}/bin/patroni 10 \ 83 | --slave %{_bindir}/patronictl patroni-patronictl %{INSTALLPATH}/bin/patronictl 84 | 85 | %postun 86 | if [ $1 -eq 0 ] ; then 87 | %{_sbindir}/update-alternatives --remove patroni %{INSTALLPATH}/bin/patroni 88 | fi 89 | 90 | %clean 91 | rm -rf $RPM_BUILD_ROOT 92 | 93 | %files 94 | %defattr(-,root,root) 95 | /opt/app/patroni 96 | %attr(-, postgres, postgres) /opt/app/patroni/etc 97 | %attr(664, root, root) /lib/systemd/system/patroni.service 98 | %attr(664, root, root) /lib/systemd/system/patroni-watchdog.service 99 | 100 | %changelog 101 | * Mon May 18 2020 Ants Aasma 1.6.5-1.thel7 102 | - Update to 1.6.5 103 | 104 | * Mon Mar 30 2020 Ants Aasma 1.6.4-2.rhel7 105 | - Change python dependency names to python3 and python3-psycopg2 106 | 107 | * Wed Jan 29 2020 Pavel Zhbanov 1.6.4-1.rhel7 108 | - Update to 1.6.4 109 | 110 | * Wed Jan 22 2020 Pavel Zhbanov 1.6.3-1.rhel7 111 | - Update to 1.6.3 112 | 113 | * Mon Apr 8 2019 Julian Markwort 1.6.0-1.rhel7 114 | - Update to 1.6.0 115 | 116 | * Mon Apr 8 2019 Ants Aasma 1.5.6-1.rhel7 117 | - Update to 1.5.6 118 | 119 | * Mon Apr 1 2019 Anton Patsev 1.5.5-1.rhel7 120 | - Update to 1.5.5 121 | 122 | * Fri Sep 21 2018 Ants Aasma 1.5.0-1.rhel7 123 | - Update to 1.5.0 124 | 125 | * Wed May 23 2018 Ants Aasma 1.4.4-1.rhel7 126 | - Update to 1.4.4 127 | - Add patronictl reinit --wait feature 128 | 129 | * Thu May 10 2018 Ants Aasma 1.4.3-2.rhel7 130 | - Only display service info output in pretty format. 131 | 132 | * Tue May 8 2018 Ants Aasma 1.4.3-1.rhel7 133 | - Update to 1.4.3 134 | 135 | * Fri Dec 8 2017 Ants Aasma 1.3.6-1.rhel7 136 | - Update to 1.3.6 137 | 138 | * Sat Sep 30 2017 Ants Aasma 1.3.4-2.rhel7 139 | - Add warning for cluster being in paused mode 140 | - Pull in master changes up to cfdda23e 141 | 142 | -------------------------------------------------------------------------------- /package_migration.md: -------------------------------------------------------------------------------- 1 | # Migrating from CYBERTEC's _patroni-packaging_ RPM to postgresql.org RPM 2 | 3 | Since there was no Patroni package for several distributions for quite a while, CYBERTEC packaged patroni both as RPM and DEB packages and provided it here: 4 | 5 | https://github.com/cybertec-postgresql/patroni-packaging 6 | 7 | Since summer 2020 the Postgresql.org project provides packages for most RPM-based distributions in the newly formed "common" repository: 8 | e.g. for EL7: 9 | 10 | https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-7-x86_64/patroni-2.0.2-2.rhel7.x86_64.rpm 11 | 12 | For Debian-based distributions, there exist both repositories by the distributors, and postgresql.org 13 | e.g. for Debian Buster: 14 | 15 | https://apt.postgresql.org/pub/repos/apt/pool/main/p/patroni/patroni_2.1.0-1.pgdg100+1_all.deb 16 | e.g. for Ubuntu 20.04: 17 | 18 | https://apt.postgresql.org/pub/repos/apt/pool/main/p/patroni/patroni_2.1.0-1.pgdg20.04+1_all.deb 19 | 20 | Comparing the packages by postgresql.org and CYBERTEC, there are two different approaches: 21 | - The CYBERTEC package installs all dependencies into a Python virtualenv 22 | - The postgresql.org package pulls in necessary dependencies via system repositories, EPEL, or from the postgresql.org repository itself, in some cases. 23 | 24 | The former approach means that patroni is unlikely to be influenced by other updates happening on the system. At the same time, this makes the package very big and difficult to maintain. 25 | 26 | CYBERTEC would rather move the resources invested into helping to improve patroni and the postgresql.org packagin directly. 27 | As a result, we are deprecating this package, and recommend everybody switches to the postgresql.org alternative. 28 | 29 | 30 | ## Migration abstract 31 | 32 | 1. Check what is running your patroni instances 33 | - from a service file installed with the RPM package (`/usr/lib/systemd/system/patroni.service`)? 34 | - from a custom systemd service file (e.g. postfixed with a cluster name `/usr/lib/systemd/system/patroni_cluster123.service`)? 35 | 2. Check where the config file used by patroni is located 36 | - in the location where the RPM package's systemd service file expects it (`/opt/app/patroni/etc/postgresql.yml`)? 37 | - in a custom location, e.g. `/etc/patroni/config.yml`, `/etc/patroni_cluster123/config.yml`, `/etc/patroni/postgresql.yml`, `/etc/patroni/patroni.yml` - this would need to be referenced in the currently used systemd service! 38 | 3. Create a backup of the service files and config files (from all cluster members!) Also record all privileges for files and which user is used to run patroni inside of the service. 39 | 4. Pause the patroni cluster: `patronictl -c /some/path/config.yml pause` 40 | 5. Stop the service that is running patroni. Make sure that your service only stops patroni (`KillMode=process`), and not postgres! 41 | 5. uninstall the patroni RPM 42 | 6. install the new patroni RPM 43 | 7. depending on your preference, adapt the service file installed by the new RPM, move the config file into the expected location, or create a new custom service. 44 | 8. start and enable the new service. Make sure that the default service is disabled when using a custom service. 45 | 9. check the cluster state using `patronictl -c /some/path/config.yml list` 46 | 10. when the cluster member show up as "running" in the previous step's output, you can resume patroni: `patronictl -c /some/path/config.yml resume` 47 | 48 | ## Migration on a vanilla EL7 machine. 49 | 50 | The package patroni-1.6.5-1.rhel7.x86_64.rpm packaged by CYBERTEC was installed: 51 | 52 |
show 53 |

54 | 55 | ```bash 56 | [root@centos7-node-1 ~]# yum list installed | grep patroni 57 | patroni.x86_64 1.6.5-1.rhel7 @/patroni-1.6.5-1 58 | ``` 59 | 60 |

61 |
62 | 63 | The service file installed by the package was used as-is: 64 |
show 65 |

66 | 67 | ```bash 68 | [root@centos7-node-1 ~]# systemctl cat patroni 69 | # /usr/lib/systemd/system/patroni.service 70 | # It's not recommended to modify this file in-place, because it will be 71 | # overwritten during package upgrades. If you want to customize, the 72 | # best way is to create a file "/etc/systemd/system/patroni.service", 73 | # containing 74 | # .include /lib/systemd/system/patroni.service 75 | # Environment=PATRONI_CONFIG_LOCATION=... 76 | # For more info about custom unit files, see 77 | # http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F 78 | 79 | 80 | [Unit] 81 | Description=PostgreSQL high-availability manager 82 | After=syslog.target 83 | # Patroni needs to shut down before network interfaces. According to SystemD documentation 84 | # specifying network.target should be sufficient, but experiments show that this is not the case. 85 | After=network-online.target 86 | 87 | [Service] 88 | Type=simple 89 | 90 | User=postgres 91 | Group=postgres 92 | 93 | # Location of Patroni configuration 94 | Environment=PATRONI_CONFIG_LOCATION=/opt/app/patroni/etc/postgresql.yml 95 | 96 | # Disable OOM kill on the postmaster 97 | OOMScoreAdjust=-1000 98 | 99 | ExecStart=/opt/app/patroni/bin/patroni ${PATRONI_CONFIG_LOCATION} 100 | ExecReload=/bin/kill -HUP $MAINPID 101 | 102 | # Give a reasonable amount of time for the server to start up/shut down 103 | TimeoutSec=30 104 | TimeoutStopSec=120s 105 | 106 | # only kill the patroni process, not it's children, so it will gracefully stop postgres 107 | KillSignal=SIGINT 108 | KillMode=process 109 | 110 | [Install] 111 | WantedBy=multi-user.target 112 | ``` 113 | 114 |

115 |
116 | 117 | A cluster was configured using the config file location (`/opt/app/patroni/etc/postgresql.yml`) 118 |
show 119 |

120 | 121 | ```bash 122 | [root@centos7-node-1 ~]# stat /opt/app/patroni/etc/postgresql.yml 123 | File: ‘/opt/app/patroni/etc/postgresql.yml’ 124 | Size: 2170 Blocks: 8 IO Block: 4096 regular file 125 | Device: fd00h/64768d Inode: 829634 Links: 1 126 | Access: (0660/-rw-rw----) Uid: ( 26/postgres) Gid: ( 26/postgres) 127 | Context: system_u:object_r:usr_t:s0 128 | Access: 2021-07-13 13:30:22.845581386 +0000 129 | Modify: 2021-07-13 13:30:05.796139000 +0000 130 | Change: 2021-07-13 13:30:06.071554673 +0000 131 | Birth: - 132 | ``` 133 | 134 |

135 |
136 | 137 | referenced by the RPM package's systemd service file. 138 | This is the running service: 139 | 140 |
show 141 |

142 | 143 | ```bash 144 | [root@centos7-node-1 ~]# systemctl status patroni 145 | ● patroni.service - PostgreSQL high-availability manager 146 | Loaded: loaded (/usr/lib/systemd/system/patroni.service; disabled; vendor preset: disabled) 147 | Active: active (running) since Tue 2021-07-13 13:30:51 UTC; 1min 35s ago 148 | Main PID: 5502 (python3.6) 149 | CGroup: /system.slice/patroni.service 150 | ├─5502 python3.6 /opt/app/patroni/bin/patroni /opt/app/patroni/etc/postgresql.yml 151 | ├─5527 /usr/pgsql-12/bin/postgres -D /data/pgsql/12/data_cluster2 --config-file=/data/pgsql/12/data_cluster2/postgresql.conf --l... 152 | ├─5529 postgres: cluster2: logger 153 | ├─5532 postgres: cluster2: checkpointer 154 | ├─5533 postgres: cluster2: background writer 155 | ├─5534 postgres: cluster2: walwriter 156 | ├─5535 postgres: cluster2: autovacuum launcher 157 | ├─5536 postgres: cluster2: stats collector 158 | ├─5537 postgres: cluster2: logical replication launcher 159 | ├─5540 postgres: cluster2: postgres postgres 127.0.0.1(38986) idle 160 | └─5565 postgres: cluster2: walsender replicator 192.168.178.247(60802) streaming 0/3000060 161 | 162 | Jul 13 13:31:43 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:31:43,147 INFO: Lock owner: centos7-node-1; I am centos7-node-1 163 | Jul 13 13:31:43 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:31:43,155 INFO: no action. i am the leader with the lock 164 | Jul 13 13:31:53 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:31:53,147 INFO: Lock owner: centos7-node-1; I am centos7-node-1 165 | Jul 13 13:31:53 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:31:53,157 INFO: no action. i am the leader with the lock 166 | Jul 13 13:32:03 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:03,147 INFO: Lock owner: centos7-node-1; I am centos7-node-1 167 | Jul 13 13:32:03 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:03,156 INFO: no action. i am the leader with the lock 168 | Jul 13 13:32:13 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:13,146 INFO: Lock owner: centos7-node-1; I am centos7-node-1 169 | Jul 13 13:32:13 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:13,156 INFO: no action. i am the leader with the lock 170 | Jul 13 13:32:23 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:23,160 INFO: Lock owner: centos7-node-1; I am centos7-node-1 171 | Jul 13 13:32:23 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:23,167 INFO: no action. i am the leader with the lock 172 | ``` 173 | 174 |

175 |
176 | 177 | The cluster consists of a primary and a replica, both are currently running: 178 |
show 179 |

180 | 181 | ```bash 182 | [root@centos7-node-1 ~]# patronictl -c /opt/app/patroni/etc/postgresql.yml list 183 | + Cluster: cluster2 (6984403026804426127) --+---------+----+-----------+ 184 | | Member | Host | Role | State | TL | Lag in MB | 185 | +----------------+-----------------+--------+---------+----+-----------+ 186 | | centos7-node-1 | 192.168.178.246 | Leader | running | 1 | | 187 | | centos7-node-2 | 192.168.178.247 | | running | 1 | 0 | 188 | +----------------+-----------------+--------+---------+----+-----------+ 189 | ``` 190 | 191 |

192 |
193 | 194 | Let's pause the cluster management: 195 |
show 196 |

197 | 198 | ```bash 199 | [root@centos7-node-1 ~]# patronictl -c /opt/app/patroni/etc/postgresql.yml pause 200 | Success: cluster management is paused 201 | [root@centos7-node-1 ~]# patronictl -c /opt/app/patroni/etc/postgresql.yml list 202 | + Cluster: cluster2 (6984403026804426127) --+---------+----+-----------+ 203 | | Member | Host | Role | State | TL | Lag in MB | 204 | +----------------+-----------------+--------+---------+----+-----------+ 205 | | centos7-node-1 | 192.168.178.246 | Leader | running | 1 | | 206 | | centos7-node-2 | 192.168.178.247 | | running | 1 | 0 | 207 | +----------------+-----------------+--------+---------+----+-----------+ 208 | Maintenance mode: on 209 | ``` 210 | 211 |

212 |
213 | 214 | Stop the service: 215 |
show 216 |

217 | 218 | ```bash 219 | [root@centos7-node-1 ~]# systemctl stop patroni 220 | [root@centos7-node-1 ~]# systemctl status patroni 221 | ● patroni.service - PostgreSQL high-availability manager 222 | Loaded: loaded (/usr/lib/systemd/system/patroni.service; disabled; vendor preset: disabled) 223 | Active: inactive (dead) since Tue 2021-07-13 13:32:53 UTC; 1min 20s ago 224 | Process: 5502 ExecStart=/opt/app/patroni/bin/patroni ${PATRONI_CONFIG_LOCATION} (code=exited, status=0/SUCCESS) 225 | Main PID: 5502 (code=exited, status=0/SUCCESS) 226 | CGroup: /system.slice/patroni.service 227 | ├─5527 /usr/pgsql-12/bin/postgres -D /data/pgsql/12/data_cluster2 --config-file=/data/pgsql/12/data_cluster2/postgresql.conf --l... 228 | ├─5529 postgres: cluster2: logger 229 | ├─5532 postgres: cluster2: checkpointer 230 | ├─5533 postgres: cluster2: background writer 231 | ├─5534 postgres: cluster2: walwriter 232 | ├─5535 postgres: cluster2: autovacuum launcher 233 | ├─5536 postgres: cluster2: stats collector 234 | ├─5537 postgres: cluster2: logical replication launcher 235 | └─5565 postgres: cluster2: walsender replicator 192.168.178.247(60802) streaming 0/3000060 236 | 237 | Jul 13 13:32:33 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:33,146 INFO: Lock owner: centos7-node-1; I am centos7-node-1 238 | Jul 13 13:32:33 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:33,152 INFO: no action. i am the leader with the lock 239 | Jul 13 13:32:43 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:43,146 INFO: Lock owner: centos7-node-1; I am centos7-node-1 240 | Jul 13 13:32:43 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:43,153 INFO: no action. i am the leader with the lock 241 | Jul 13 13:32:46 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:46,359 INFO: Lock owner: centos7-node-1; I am centos7-node-1 242 | Jul 13 13:32:46 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:46,368 INFO: PAUSE: no action. i am the leader with the lock 243 | Jul 13 13:32:46 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:46,373 INFO: No PostgreSQL configuration items changed, nothing to reload. 244 | Jul 13 13:32:53 centos7-node-1.fritz.box systemd[1]: Stopping PostgreSQL high-availability manager... 245 | Jul 13 13:32:53 centos7-node-1.fritz.box patroni[5502]: 2021-07-13 13:32:53,910 INFO: Leader key is not deleted and Postgresql is not stopped due paused state 246 | Jul 13 13:32:53 centos7-node-1.fritz.box systemd[1]: Stopped PostgreSQL high-availability manager. 247 | ``` 248 | 249 |

250 |
251 | 252 | The database should continue running: 253 |
show 254 |

255 | 256 | ```bash 257 | [root@centos7-node-1 ~]# ps -ef | grep bin/postgres 258 | postgres 5527 1 0 13:30 ? 00:00:00 /usr/pgsql-12/bin/postgres -D /data/pgsql/12/data_cluster2 --config-file=/data/pgsql/12/data_cluster2/postgresql.conf --listen_addresses=0.0.0.0 --port=5432 --cluster_name=cluster2 --wal_level=replica --hot_standby=on --max_connections=100 --max_wal_senders=10 --max_prepared_transactions=0 --max_locks_per_transaction=64 --track_commit_timestamp=off --max_replication_slots=10 --max_worker_processes=8 --wal_log_hints=on 259 | root 5616 5179 0 13:34 pts/0 00:00:00 grep --color=auto bin/postgres 260 | ``` 261 | 262 |

263 |
264 | 265 | After the member key has expired in the DCS, the stopped instance will no longer show up in patronictl list: 266 |
show 267 |

268 | 269 | ```bash 270 | [root@centos7-node-1 ~]# patronictl -c /opt/app/patroni/etc/postgresql.yml list 271 | + Cluster: cluster2 (6984403026804426127) +---------+----+-----------+ 272 | | Member | Host | Role | State | TL | Lag in MB | 273 | +----------------+-----------------+------+---------+----+-----------+ 274 | | centos7-node-2 | 192.168.178.247 | | running | 1 | 0 | 275 | +----------------+-----------------+------+---------+----+-----------+ 276 | Maintenance mode: on 277 | ``` 278 | 279 |

280 |
281 | 282 | Let's uninstall the RPM: 283 |
show 284 |

285 | 286 | ```bash 287 | [root@centos7-node-1 ~]# yum remove patroni-1.6.5-1.rhel7.x86_64 288 | Loaded plugins: fastestmirror 289 | Resolving Dependencies 290 | --> Running transaction check 291 | ---> Package patroni.x86_64 0:1.6.5-1.rhel7 will be erased 292 | --> Finished Dependency Resolution 293 | 294 | Dependencies Resolved 295 | 296 | ============================================================================================================================================== 297 | Package Arch Version Repository Size 298 | ============================================================================================================================================== 299 | Removing: 300 | patroni x86_64 1.6.5-1.rhel7 @/patroni-1.6.5-1 76 M 301 | 302 | Transaction Summary 303 | ============================================================================================================================================== 304 | Remove 1 Package 305 | 306 | Installed size: 76 M 307 | Is this ok [y/N]: y 308 | Downloading packages: 309 | Running transaction check 310 | Running transaction test 311 | Transaction test succeeded 312 | Running transaction 313 | Erasing : patroni-1.6.5-1.rhel7.x86_64 1/1 314 | Verifying : patroni-1.6.5-1.rhel7.x86_64 1/1 315 | 316 | Removed: 317 | patroni.x86_64 0:1.6.5-1.rhel7 318 | 319 | Complete! 320 | ``` 321 | 322 |

323 |
324 | 325 | If not already present (or if you don't yet have the common repository in your system), install the postgresql.org repository: 326 |
show 327 |

328 | 329 | ```bash 330 | sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm 331 | ``` 332 | 333 |

334 |
335 | 336 | Install the new package: 337 | > the common repository contains a `patroni` package, but you'll need to install one of the metapackages to pull in the dependencies for your chosen DCS, e.g. `patroni-etcd` or `patroni-consul`. 338 |
show 339 |

340 | 341 | ```bash 342 | [root@centos7-node-1 ~]# yum install patroni-etcd 343 | Loaded plugins: fastestmirror 344 | Loading mirror speeds from cached hostfile 345 | epel/x86_64/metalink | 29 kB 00:00:00 346 | * base: mirror.23media.com 347 | * epel: mirror.23media.com 348 | * extras: ftp.plusline.net 349 | * updates: ftp.rz.uni-frankfurt.de 350 | base | 3.6 kB 00:00:00 351 | extras | 2.9 kB 00:00:00 352 | pgdg-common/7/x86_64/signature | 198 B 00:00:00 353 | pgdg-common/7/x86_64/signature | 2.9 kB 00:00:00 !!! 354 | pgdg10/7/x86_64/signature | 198 B 00:00:00 355 | pgdg10/7/x86_64/signature | 3.6 kB 00:00:00 !!! 356 | pgdg11/7/x86_64/signature | 198 B 00:00:00 357 | pgdg11/7/x86_64/signature | 3.6 kB 00:00:00 !!! 358 | pgdg12/7/x86_64/signature | 198 B 00:00:00 359 | pgdg12/7/x86_64/signature | 3.6 kB 00:00:00 !!! 360 | pgdg13/7/x86_64/signature | 198 B 00:00:00 361 | pgdg13/7/x86_64/signature | 3.6 kB 00:00:00 !!! 362 | pgdg96/7/x86_64/signature | 198 B 00:00:00 363 | pgdg96/7/x86_64/signature | 3.6 kB 00:00:00 !!! 364 | updates | 2.9 kB 00:00:00 365 | Resolving Dependencies 366 | --> Running transaction check 367 | ---> Package patroni-etcd.x86_64 0:2.1.0-1.rhel7 will be installed 368 | --> Processing Dependency: patroni(x86-64) = 2.1.0-1.rhel7 for package: patroni-etcd-2.1.0-1.rhel7.x86_64 369 | --> Processing Dependency: python3-etcd >= 0.4.3 for package: patroni-etcd-2.1.0-1.rhel7.x86_64 370 | --> Processing Dependency: python36-urllib3 for package: patroni-etcd-2.1.0-1.rhel7.x86_64 371 | --> Processing Dependency: python36-dns for package: patroni-etcd-2.1.0-1.rhel7.x86_64 372 | --> Processing Dependency: python36-certifi for package: patroni-etcd-2.1.0-1.rhel7.x86_64 373 | --> Running transaction check 374 | ---> Package patroni.x86_64 0:2.1.0-1.rhel7 will be installed 375 | --> Processing Dependency: python36-six >= 1.7 for package: patroni-2.1.0-1.rhel7.x86_64 376 | --> Processing Dependency: python36-prettytable >= 0.7 for package: patroni-2.1.0-1.rhel7.x86_64 377 | --> Processing Dependency: python36-click >= 4.1 for package: patroni-2.1.0-1.rhel7.x86_64 378 | --> Processing Dependency: python3-ydiff >= 1.2 for package: patroni-2.1.0-1.rhel7.x86_64 379 | --> Processing Dependency: python3-psutil >= 2.0.0 for package: patroni-2.1.0-1.rhel7.x86_64 380 | --> Processing Dependency: python36-dateutil for package: patroni-2.1.0-1.rhel7.x86_64 381 | --> Processing Dependency: python36-PyYAML for package: patroni-2.1.0-1.rhel7.x86_64 382 | --> Processing Dependency: python3-cdiff for package: patroni-2.1.0-1.rhel7.x86_64 383 | ---> Package python3-etcd.noarch 0:0.4.5-20.rhel7 will be installed 384 | ---> Package python36-certifi.noarch 0:2018.10.15-5.el7 will be installed 385 | ---> Package python36-dns.noarch 0:1.16.0-1.el7 will be installed 386 | --> Processing Dependency: python36-crypto for package: python36-dns-1.16.0-1.el7.noarch 387 | ---> Package python36-urllib3.noarch 0:1.25.6-2.el7 will be installed 388 | --> Processing Dependency: python36-pysocks for package: python36-urllib3-1.25.6-2.el7.noarch 389 | --> Running transaction check 390 | ---> Package python3-cdiff.noarch 0:1.0-1.rhel7 will be installed 391 | ---> Package python3-ydiff.noarch 0:1.2-10.rhel7 will be installed 392 | ---> Package python36-PyYAML.x86_64 0:3.13-1.el7 will be installed 393 | ---> Package python36-click.noarch 0:6.7-8.el7 will be installed 394 | ---> Package python36-crypto.x86_64 0:2.6.1-16.el7 will be installed 395 | --> Processing Dependency: libtomcrypt.so.0()(64bit) for package: python36-crypto-2.6.1-16.el7.x86_64 396 | ---> Package python36-dateutil.noarch 1:2.4.2-5.el7 will be installed 397 | ---> Package python36-prettytable.noarch 0:0.7.2-19.el7 will be installed 398 | ---> Package python36-psutil.x86_64 0:5.6.7-1.el7 will be installed 399 | ---> Package python36-pysocks.noarch 0:1.6.8-7.el7 will be installed 400 | ---> Package python36-six.noarch 0:1.14.0-3.el7 will be installed 401 | --> Running transaction check 402 | ---> Package libtomcrypt.x86_64 0:1.17-26.el7 will be installed 403 | --> Processing Dependency: libtommath >= 0.42.0 for package: libtomcrypt-1.17-26.el7.x86_64 404 | --> Processing Dependency: libtommath.so.0()(64bit) for package: libtomcrypt-1.17-26.el7.x86_64 405 | --> Running transaction check 406 | ---> Package libtommath.x86_64 0:0.42.0-6.el7 will be installed 407 | --> Finished Dependency Resolution 408 | 409 | Dependencies Resolved 410 | 411 | ============================================================================================================================================== 412 | Package Arch Version Repository Size 413 | ============================================================================================================================================== 414 | Installing: 415 | patroni-etcd x86_64 2.1.0-1.rhel7 pgdg-common 3.4 k 416 | Installing for dependencies: 417 | libtomcrypt x86_64 1.17-26.el7 extras 224 k 418 | libtommath x86_64 0.42.0-6.el7 extras 36 k 419 | patroni x86_64 2.1.0-1.rhel7 pgdg-common 851 k 420 | python3-cdiff noarch 1.0-1.rhel7 pgdg-common 25 k 421 | python3-etcd noarch 0.4.5-20.rhel7 pgdg-common 77 k 422 | python3-ydiff noarch 1.2-10.rhel7 pgdg-common 26 k 423 | python36-PyYAML x86_64 3.13-1.el7 epel 149 k 424 | python36-certifi noarch 2018.10.15-5.el7 epel 13 k 425 | python36-click noarch 6.7-8.el7 epel 127 k 426 | python36-crypto x86_64 2.6.1-16.el7 epel 487 k 427 | python36-dateutil noarch 1:2.4.2-5.el7 epel 81 k 428 | python36-dns noarch 1.16.0-1.el7 epel 248 k 429 | python36-prettytable noarch 0.7.2-19.el7 epel 41 k 430 | python36-psutil x86_64 5.6.7-1.el7 epel 395 k 431 | python36-pysocks noarch 1.6.8-7.el7 epel 30 k 432 | python36-six noarch 1.14.0-3.el7 epel 34 k 433 | python36-urllib3 noarch 1.25.6-2.el7 epel 178 k 434 | 435 | Transaction Summary 436 | ============================================================================================================================================== 437 | Install 1 Package (+17 Dependent packages) 438 | 439 | Total download size: 3.0 M 440 | Installed size: 13 M 441 | Is this ok [y/d/N]: y 442 | Downloading packages: 443 | (1/18): libtommath-0.42.0-6.el7.x86_64.rpm | 36 kB 00:00:00 444 | (2/18): libtomcrypt-1.17-26.el7.x86_64.rpm | 224 kB 00:00:00 445 | (3/18): patroni-etcd-2.1.0-1.rhel7.x86_64.rpm | 3.4 kB 00:00:00 446 | (4/18): python3-cdiff-1.0-1.rhel7.noarch.rpm | 25 kB 00:00:00 447 | (5/18): patroni-2.1.0-1.rhel7.x86_64.rpm | 851 kB 00:00:00 448 | (6/18): python3-etcd-0.4.5-20.rhel7.noarch.rpm | 77 kB 00:00:00 449 | (7/18): python3-ydiff-1.2-10.rhel7.noarch.rpm | 26 kB 00:00:00 450 | (8/18): python36-PyYAML-3.13-1.el7.x86_64.rpm | 149 kB 00:00:00 451 | (9/18): python36-certifi-2018.10.15-5.el7.noarch.rpm | 13 kB 00:00:00 452 | (10/18): python36-click-6.7-8.el7.noarch.rpm | 127 kB 00:00:00 453 | (11/18): python36-crypto-2.6.1-16.el7.x86_64.rpm | 487 kB 00:00:00 454 | (12/18): python36-dateutil-2.4.2-5.el7.noarch.rpm | 81 kB 00:00:00 455 | (13/18): python36-dns-1.16.0-1.el7.noarch.rpm | 248 kB 00:00:00 456 | (14/18): python36-prettytable-0.7.2-19.el7.noarch.rpm | 41 kB 00:00:00 457 | (15/18): python36-psutil-5.6.7-1.el7.x86_64.rpm | 395 kB 00:00:00 458 | (16/18): python36-pysocks-1.6.8-7.el7.noarch.rpm | 30 kB 00:00:00 459 | (17/18): python36-six-1.14.0-3.el7.noarch.rpm | 34 kB 00:00:00 460 | (18/18): python36-urllib3-1.25.6-2.el7.noarch.rpm | 178 kB 00:00:00 461 | ---------------------------------------------------------------------------------------------------------------------------------------------- 462 | Total 2.8 MB/s | 3.0 MB 00:00:01 463 | Running transaction check 464 | Running transaction test 465 | Transaction test succeeded 466 | Running transaction 467 | Installing : python36-six-1.14.0-3.el7.noarch 1/18 468 | Installing : 1:python36-dateutil-2.4.2-5.el7.noarch 2/18 469 | Installing : python3-cdiff-1.0-1.rhel7.noarch 3/18 470 | Installing : python3-ydiff-1.2-10.rhel7.noarch 4/18 471 | Installing : python36-psutil-5.6.7-1.el7.x86_64 5/18 472 | Installing : python36-certifi-2018.10.15-5.el7.noarch 6/18 473 | Installing : python36-PyYAML-3.13-1.el7.x86_64 7/18 474 | Installing : python36-click-6.7-8.el7.noarch 8/18 475 | Installing : python36-pysocks-1.6.8-7.el7.noarch 9/18 476 | Installing : python36-urllib3-1.25.6-2.el7.noarch 10/18 477 | Installing : python36-prettytable-0.7.2-19.el7.noarch 11/18 478 | Installing : patroni-2.1.0-1.rhel7.x86_64 12/18 479 | Installing : libtommath-0.42.0-6.el7.x86_64 13/18 480 | Installing : libtomcrypt-1.17-26.el7.x86_64 14/18 481 | Installing : python36-crypto-2.6.1-16.el7.x86_64 15/18 482 | Installing : python36-dns-1.16.0-1.el7.noarch 16/18 483 | Installing : python3-etcd-0.4.5-20.rhel7.noarch 17/18 484 | Installing : patroni-etcd-2.1.0-1.rhel7.x86_64 18/18 485 | Verifying : python3-etcd-0.4.5-20.rhel7.noarch 1/18 486 | Verifying : python36-dns-1.16.0-1.el7.noarch 2/18 487 | Verifying : libtommath-0.42.0-6.el7.x86_64 3/18 488 | Verifying : python36-prettytable-0.7.2-19.el7.noarch 4/18 489 | Verifying : python36-pysocks-1.6.8-7.el7.noarch 5/18 490 | Verifying : python36-click-6.7-8.el7.noarch 6/18 491 | Verifying : python36-PyYAML-3.13-1.el7.x86_64 7/18 492 | Verifying : 1:python36-dateutil-2.4.2-5.el7.noarch 8/18 493 | Verifying : patroni-2.1.0-1.rhel7.x86_64 9/18 494 | Verifying : python36-crypto-2.6.1-16.el7.x86_64 10/18 495 | Verifying : python36-certifi-2018.10.15-5.el7.noarch 11/18 496 | Verifying : python36-urllib3-1.25.6-2.el7.noarch 12/18 497 | Verifying : python36-psutil-5.6.7-1.el7.x86_64 13/18 498 | Verifying : python36-six-1.14.0-3.el7.noarch 14/18 499 | Verifying : python3-ydiff-1.2-10.rhel7.noarch 15/18 500 | Verifying : libtomcrypt-1.17-26.el7.x86_64 16/18 501 | Verifying : python3-cdiff-1.0-1.rhel7.noarch 17/18 502 | Verifying : patroni-etcd-2.1.0-1.rhel7.x86_64 18/18 503 | 504 | Installed: 505 | patroni-etcd.x86_64 0:2.1.0-1.rhel7 506 | 507 | Dependency Installed: 508 | libtomcrypt.x86_64 0:1.17-26.el7 libtommath.x86_64 0:0.42.0-6.el7 patroni.x86_64 0:2.1.0-1.rhel7 509 | python3-cdiff.noarch 0:1.0-1.rhel7 python3-etcd.noarch 0:0.4.5-20.rhel7 python3-ydiff.noarch 0:1.2-10.rhel7 510 | python36-PyYAML.x86_64 0:3.13-1.el7 python36-certifi.noarch 0:2018.10.15-5.el7 python36-click.noarch 0:6.7-8.el7 511 | python36-crypto.x86_64 0:2.6.1-16.el7 python36-dateutil.noarch 1:2.4.2-5.el7 python36-dns.noarch 0:1.16.0-1.el7 512 | python36-prettytable.noarch 0:0.7.2-19.el7 python36-psutil.x86_64 0:5.6.7-1.el7 python36-pysocks.noarch 0:1.6.8-7.el7 513 | python36-six.noarch 0:1.14.0-3.el7 python36-urllib3.noarch 0:1.25.6-2.el7 514 | 515 | Complete! 516 | ``` 517 | 518 |

519 |
520 | 521 | The new Service file expects the configuration file to be in`/etc/patroni/patroni.yml`: 522 |
show 523 |

524 | 525 | ```bash 526 | [root@centos7-node-1 ~]# cat /usr/lib/systemd/system/patroni.service 527 | # It's not recommended to modify this file in-place, because it will be 528 | # overwritten during package upgrades. It is recommended to use systemd 529 | # "dropin" feature; i.e. create file with suffix .conf under 530 | # /etc/systemd/system/patroni.service.d directory overriding the 531 | # unit's defaults. You can also use "systemctl edit patroni" 532 | # Look at systemd.unit(5) manual page for more info. 533 | 534 | [Unit] 535 | Description=Runners to orchestrate a high-availability PostgreSQL 536 | After=syslog.target network.target 537 | 538 | [Service] 539 | Type=simple 540 | 541 | User=postgres 542 | Group=postgres 543 | 544 | # Read in configuration file if it exists, otherwise proceed 545 | EnvironmentFile=-/etc/patroni_env.conf 546 | 547 | # WorkingDirectory=/var/lib/pgsql 548 | 549 | # Where to send early-startup messages from the server 550 | # This is normally controlled by the global default set by systemd 551 | #StandardOutput=syslog 552 | 553 | # Pre-commands to start watchdog device 554 | # Uncomment if watchdog is part of your patroni setup 555 | #ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog 556 | #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog 557 | 558 | # Start the patroni process 559 | ExecStart=/usr/bin/patroni /etc/patroni/patroni.yml 560 | 561 | # Send HUP to reload from patroni.yml 562 | ExecReload=/usr/bin/kill -s HUP $MAINPID 563 | 564 | # only kill the patroni process, not it's children, so it will gracefully stop postgres 565 | KillMode=process 566 | 567 | # Give a reasonable amount of time for the server to start up/shut down 568 | TimeoutSec=30 569 | 570 | # Do not restart the service if it crashes, we want to manually inspect database on failure 571 | Restart=no 572 | 573 | [Install] 574 | WantedBy=multi-user.target 575 | ``` 576 | 577 |

578 |
579 | 580 | The easiest option will be to move the old config file to the new location: 581 | 582 |
show 583 |

584 | 585 | ```bash 586 | [root@centos7-node-1 ~]# mkdir /etc/patroni 587 | [root@centos7-node-1 ~]# mv /opt/app/patroni/etc/postgresql.yml /etc/patroni/patroni.yml 588 | [root@centos7-node-1 ~]# stat /etc/patroni/patroni.yml 589 | File: ‘/etc/patroni/patroni.yml’ 590 | Size: 2170 Blocks: 8 IO Block: 4096 regular file 591 | Device: fd00h/64768d Inode: 829634 Links: 1 592 | Access: (0660/-rw-rw----) Uid: ( 26/postgres) Gid: ( 26/postgres) 593 | Context: system_u:object_r:usr_t:s0 594 | Access: 2021-07-13 13:30:22.845581386 +0000 595 | Modify: 2021-07-13 13:30:05.796139000 +0000 596 | Change: 2021-07-13 13:39:55.873223511 +0000 597 | Birth: - 598 | ``` 599 | 600 |

601 |
602 | 603 | Then we can start and enable the patroni service again: 604 |
show 605 |

606 | 607 | ```bash 608 | [root@centos7-node-1 ~]# systemctl start patroni 609 | [root@centos7-node-1 ~]# systemctl enable patroni 610 | Created symlink from /etc/systemd/system/multi-user.target.wants/patroni.service to /usr/lib/systemd/system/patroni.service. 611 | ``` 612 | 613 |

614 |
615 | 616 | We can see that the patroni service has started again, the replica is already connected again and the patroni instance has acquired the leader lock (while in pause mode still): 617 |
show 618 |

619 | 620 | ```bash 621 | [root@centos7-node-1 ~]# systemctl status patroni 622 | ● patroni.service - Runners to orchestrate a high-availability PostgreSQL 623 | Loaded: loaded (/usr/lib/systemd/system/patroni.service; disabled; vendor preset: disabled) 624 | Active: active (running) since Tue 2021-07-13 13:42:22 UTC; 4s ago 625 | Main PID: 5728 (patroni) 626 | CGroup: /system.slice/patroni.service 627 | ├─5527 /usr/pgsql-12/bin/postgres -D /data/pgsql/12/data_cluster2 --config-file=/data/pgsql/12/data_cluster2/postgresql.conf --l... 628 | ├─5529 postgres: cluster2: logger 629 | ├─5532 postgres: cluster2: checkpointer 630 | ├─5533 postgres: cluster2: background writer 631 | ├─5534 postgres: cluster2: walwriter 632 | ├─5535 postgres: cluster2: autovacuum launcher 633 | ├─5536 postgres: cluster2: stats collector 634 | ├─5537 postgres: cluster2: logical replication launcher 635 | ├─5565 postgres: cluster2: walsender replicator 192.168.178.247(60802) streaming 0/3000148 636 | ├─5728 /usr/bin/python3 /usr/bin/patroni /etc/patroni/patroni.yml 637 | └─5735 postgres: cluster2: postgres postgres 127.0.0.1(39748) idle 638 | 639 | Jul 13 13:42:22 centos7-node-1.fritz.box systemd[1]: Started Runners to orchestrate a high-availability PostgreSQL. 640 | Jul 13 13:42:22 centos7-node-1.fritz.box patroni[5728]: 2021-07-13 13:42:22,956 INFO: Selected new etcd server http://192.168.178.247:2379 641 | Jul 13 13:42:22 centos7-node-1.fritz.box patroni[5728]: 2021-07-13 13:42:22,962 INFO: No PostgreSQL configuration items changed, nothing to reload. 642 | Jul 13 13:42:22 centos7-node-1.fritz.box patroni[5728]: 2021-07-13 13:42:22,965 INFO: establishing a new patroni connection to the postgres cluster 643 | Jul 13 13:42:22 centos7-node-1.fritz.box patroni[5728]: 2021-07-13 13:42:22,992 INFO: PAUSE: acquired session lock as a leader 644 | Jul 13 13:42:32 centos7-node-1.fritz.box patroni[5728]: 2021-07-13 13:42:32,994 INFO: PAUSE: no action. I am (centos7-node-1) the leader with the lock 645 | Jul 13 13:42:33 centos7-node-1.fritz.box patroni[5728]: 2021-07-13 13:42:33,019 INFO: PAUSE: no action. I am (centos7-node-1) the leader with the lock 646 | ``` 647 | 648 |

649 |
650 | 651 | The cluster member shows up in patronictl list again: 652 |
show 653 |

654 | 655 | ```bash 656 | [root@centos7-node-1 ~]# patronictl -c /etc/patroni/patroni.yml list 657 | + Cluster: cluster2 (6984403026804426127) ---+---------+----+-----------+ 658 | | Member | Host | Role | State | TL | Lag in MB | 659 | +----------------+-----------------+---------+---------+----+-----------+ 660 | | centos7-node-1 | 192.168.178.246 | Leader | running | 1 | | 661 | | centos7-node-2 | 192.168.178.247 | Replica | running | 1 | 0 | 662 | +----------------+-----------------+---------+---------+----+-----------+ 663 | Maintenance mode: on 664 | ``` 665 | 666 |

667 |
668 | 669 | 670 | You can now install the update on all other patroni members, taking the same steps (stopping the service, uninstalling the old and installing the new package, moving the config file, starting the patroni service again). 671 | 672 | At the end, resume from pause mode: 673 |
show 674 |

675 | 676 | ```bash 677 | [root@centos7-node-1 ~]# patronictl -c /etc/patroni/patroni.yml resume 678 | Success: cluster management is resumed 679 | [root@centos7-node-1 ~]# patronictl -c /etc/patroni/patroni.yml list 680 | + Cluster: cluster2 (6984403026804426127) ---+---------+----+-----------+ 681 | | Member | Host | Role | State | TL | Lag in MB | 682 | +----------------+-----------------+---------+---------+----+-----------+ 683 | | centos7-node-1 | 192.168.178.246 | Leader | running | 1 | | 684 | | centos7-node-2 | 192.168.178.247 | Replica | running | 1 | 0 | 685 | +----------------+-----------------+---------+---------+----+-----------+ 686 | ``` 687 | 688 |

689 |
690 | 691 | It is certainly possible to have different patroni versions running in the cluster at the same time: 692 |
show 693 |

694 | 695 | ```bash 696 | [root@centos7-node-1 ~]# curl -s http://192.168.178.246:8008 | jq 697 | { 698 | "state": "running", 699 | "postmaster_start_time": "2021-07-13 13:30:53.112059+00:00", 700 | "role": "master", 701 | "server_version": 120007, 702 | "cluster_unlocked": false, 703 | "xlog": { 704 | "location": 50332208 705 | }, 706 | "timeline": 1, 707 | "replication": [ 708 | { 709 | "usename": "replicator", 710 | "application_name": "centos7-node-2", 711 | "client_addr": "192.168.178.247", 712 | "state": "streaming", 713 | "sync_state": "async", 714 | "sync_priority": 0 715 | } 716 | ], 717 | "database_system_identifier": "6984403026804426127", 718 | "patroni": { 719 | "version": "2.1.0", 720 | "scope": "cluster2" 721 | } 722 | } 723 | [root@centos7-node-1 ~]# curl -s http://192.168.178.247:8008 | jq 724 | { 725 | "state": "running", 726 | "postmaster_start_time": "2021-07-13 13:31:20.660 UTC", 727 | "role": "replica", 728 | "server_version": 120007, 729 | "cluster_unlocked": false, 730 | "xlog": { 731 | "received_location": 50332208, 732 | "replayed_location": 50332208, 733 | "replayed_timestamp": null, 734 | "paused": false 735 | }, 736 | "timeline": 1, 737 | "database_system_identifier": "6984403026804426127", 738 | "patroni": { 739 | "version": "1.6.5", 740 | "scope": "cluster2" 741 | } 742 | } 743 | ``` 744 | 745 |

746 |
747 | 748 | --------------------------------------------------------------------------------