89 Commits
Author SHA1 Message Date
Alexander Kukushkin d422e16aad Implement reload of config.yaml on SIGHUP
If some changes require restart of postgres patroni will expose
`restart_pending` flag in DCS and via REST API
2016-05-13 13:31:21 +02:00
Alexander Kukushkin 45a52e21f0 Write postgres options to postgresql.conf
Originally we were passing postgresql options as an argument of `pg_ctl
start`. It was nice and convenient because doesn't require to touch
configuration files but this method has one significant drawback: it
wasn't possible to change values of options which were passed as an
arguments without restart (event for the case when option reqires only
reload). Instead of doing that (passing options as arguments) we will:
1) rename original postgresql.conf to postgresql-base.conf
2) write options into postgresql.conf which has `include
  'postgresql-base.conf'` on the the third line after comment that this
  file is generated by Patroni and you should not change it manually
3) listen_addresses and port are still passed as an arguments to the
  pg_ctl (just to be foolproof against ALTER SYSTEM set port to 'random')

In addition to that this commit makes some attributes of `Postgresql`
class private (prefixes them with _)
2016-05-13 12:40:04 +02:00
Alexander Kukushkin eabfd82a5d Implement Consul support 2016-04-27 10:59:01 +02:00
Alexander Kukushkin 499061918d Implement noloadbalance support
Mostly this tag is necessary to give a hint to load balancer
auto-configuration tool that node should not be included into
LB configuration.
In addition to that Patroni also should not return status_code=200
for a health check if the tag is present and value is not `False`.
2016-04-22 09:46:34 +02:00
Alexander Kukushkin cd6537c4d3 Refactor patroni/ctl.py
Until now get_dcs method was doing absolutely the same job as method
from Patroni class.
In addition to that I did small refactoring and clean up of unit tests
2016-04-18 17:36:30 +02:00
Alexander Kukushkin 24a2ea6cef Refactor acceptance tests to make them work against ZooKeeper
and make it easier to implement controllers for new DCS, i.e. consul
2016-04-10 10:37:43 +02:00
Oleksii Kliukin 60e6ed67e3 Add unit tests. 2016-04-04 10:06:28 +02:00
Alexander Kukushkin 0e0c8ed8d7 Implement delete_cluster interface in for all available dcs
In addition to that rename confusing `Etcd.client` and
`ZooKeeper.client` into `_client`. This attribute is available from
AbstractDCS and people had wrong impression that it provides the same
interface for different DCS implementations, which is obviously not the
case. For Etcd it has type etcd.Client and for ZooKeeper - KazooClient.
2016-03-15 16:25:48 +01:00
Alexander Kukushkin ce33090c0d Mock dcs.watch directly instead of using wraper 2016-02-23 11:48:52 +01:00
Alexander Kukushkin b973ed7e4f improve test coverage 2016-02-12 16:52:26 +01:00
Alexander Kukushkin df9b8fed2e Improve quality of code by resolving issues found by quantifiedcode and codacy 2016-02-12 12:23:49 +01:00
Oleksii Kliukin 1f9d8c039c Add tests for nofailover. 2015-10-26 17:19:35 +01:00
Alexander Kukushkin d8f4b09478 use Event.wait instead of sleep
it makes possible to break "sleep" for example from API

plus small bugfix: catch ValueError exception from json.loads
2015-10-02 10:26:48 +02:00
Alexander Kukushkin d09875a056 refactoring:
1. run touch_member from the main loop
2. move code which takes care about long tasks into separate class
3. change format of data stored in a DCS: use json instead of url
4. change Member class: from now it deserialize everything into data property
5. rework API: from now it takes into account state of the current node in a dcs
2015-10-01 17:06:42 +02:00
Alexander Kukushkin a6cb7563e5 catch all exceptions in change_replication_slots method 2015-10-01 08:06:00 +02:00
Alexander Kukushkin 1997f15a7a Run long time operations asynchronously
i.e. restart, reinitialize, demote
2015-09-30 17:08:15 +02:00
Alexander Kukushkin c218054d05 Implement manual failover
Implementation is done on top of feature/is-healthiest-via-api and
feature/api branches.
In order to trigger manual failover one has to create 'failover' key in
a configuration store with the value in following format:
'leader_name:member_name'
leader_name can be empty or should match with the name of current leader
member_name can be empty or should match with the name one of cluster
nodes
Leader always checks that either desired member (if specified) or one of
the memners is accessible and healthy before demote.
After leader has deomted himself other nodes are performig checks that
desired node is healthy. If it is not they are participating in a leader
race. In some cases (when accidently there is no healthy nodes) former
leader can also participate in a leader race.

Current implementation does not provide REST API endpoint for a manual
failover.
2015-09-28 17:00:42 +02:00
Alexander Kukushkin e83651b57b Run initial cluster bootstrap from the main loop 2015-09-23 10:55:38 +02:00
Alexander Kukushkin d8982e1e5a Refactor Postgresql.query method to use common retry mechanism
query method in an api.py also needs retry in some cases (for example
when we are running is_healthiest_node check).
In all cases we should retry only when connection is closed or broken.
BUT, the connection status must be checked via cursor.connection (old
implementation was using general connection object for that). For
multi-threaded applications this is not appropriate, because some other
thread might restore connection.

In addition to that I've changed most of the unit tests to use `Mock` and
`patch` where it is possible.
2015-09-20 13:54:30 +02:00
Alexander Kukushkin afe1a2c92c During shutdown sigterm is send to all processes every second
First time is triggers some shutdown mechanisms in a patroni, but the
second one just terminates patroni. Solution is pretty simple, we need
to ignore all other sigterms which are coming after the first one.
2015-09-18 12:41:36 +02:00
Alexander Kukushkin 8a0af6985f Merge pull request #35 from zalando/feature/basic-auth
Basic-auth and SSL support
2015-09-17 16:22:23 +02:00
Alexander Kukushkin 918ac6a87d Merge pull request #39 from zalando/feature/reschedule-next-run
Feature/reschedule next run of ha cycle depending on return value of `watch`
2015-09-17 16:22:12 +02:00
Alexander Kukushkin dbcc5aff9b Track postgresql role in a Postgresql class 2015-09-16 16:22:10 +02:00
Alexander Kukushkin 7f8e95b334 Next run of ha cycle is rescheduled depending on return value of watch
Current etcd implementation does not yet support timeout option when
`wait=true`: https://github.com/coreos/etcd/issues/2468

Originaly I've implemented `watch` method for `Etcd` class in a
following manner: if the leader key was updated just because master
needs to update ttl and watch timeout is not yet expired, I was
recalculating timeout and starting `watch` call once again.
Usually after "restart" we were getting urllib3.exceptions.TimeoutError.
The only possible way to recover after such exception - close socket and
establish a new connection. With pure http it's relatively cheap, but
with https and some kind of authorization on etcd side it would became
rather expensive and should be avoided.
2015-09-16 10:38:34 +02:00
Alexander Kukushkin 01efcc8638 Merge branch 'master' of github.com:zalando/patroni into feature/basic-auth
Conflicts:
	tests/test_patroni.py
2015-09-15 09:33:18 +02:00
Oleksii Kliukin 51eacc5042 Handle the case when initialize flag is not set and leader is present. 2015-09-14 12:36:28 +02:00
Oleksii Kliukin cd312de252 Fix a flake8 warning.
Improve some unit tests by expecting specific exceptions.
2015-09-10 17:15:43 +02:00
Alexander Kukushkin abcaf2b94a Possibility to protect some endpoints with basic-auth
user:passwd pair should be configured in restapi section of main
configuration file in following format:
restapi:
  auth: 'username:password'

Plus implemented some simple routing mechanisms:
GET /foo => do_GET_foo()
POST /bar => do_POST_bar()
2015-09-10 15:25:08 +02:00
Oleksii Kliukin 92647b7aad Merge branch 'master' of https://github.com/zalando/patroni into feature/cleanup_on_failed_initialization 2015-09-08 14:54:52 +02:00
Oleksii Kliukin b842ed478b Make sure initialize flag is reset on failure.
Cleanup the initialize flag if the initializing node fails
to bootstrap its PostgreSQL database.

Rename dcs.race to initialize, since we only call it for the
initialize flag. Factored out PostgreSQL bootstrapping code
into a separate function.
2015-09-08 12:03:34 +02:00
Alexander Kukushkin 1774d6e31a Merge branches watch-leader-key and package-refactoring 2015-09-05 16:09:28 +02:00
Alexander Kukushkin 650e244904 Refactor directory structure in preparation for building pypi-package 2015-09-04 16:06:44 +02:00
Alexander Kukushkin c6abf85740 Bugfix: sleep method was renamed to watch 2015-09-02 08:42:47 +02:00
Alexander Kukushkin fab321c6b0 Watch for changes of leader key 2015-09-01 09:54:57 +02:00
Alexander Kukushkin 3b1efff53e Refactor Cluster object
`Cluster.leader` is not reference to `Member` anymore, but to `Leader`
`Leader` class contains field `index` (update index). This field is very
useful for watching for events which changing leader key. Also `Leader`
contains `member` field, which should reference real member.
2015-08-27 10:53:22 +02:00
Alexander Kukushkin 353fc58bee Do not inherit rest api port on fork 2015-08-26 15:14:44 +02:00
Alexander Kukushkin befd33555d Refactor helpers/etcd.py
Work with etcd cluster via high-level python-etcd module.
Plus change all unit tests accordingly.
2015-08-24 16:58:08 +02:00
Alexander Kukushkin 9df783cf9d use six module to support python 2 and 3 instead of conditional imports 2015-07-15 12:03:28 +02:00
Alexander Kukushkin c49580d6a7 Rename governor into patroni 2015-07-08 10:37:35 +02:00