mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
Different minor fixes (#551)
* Use unix line endings * Make flake8 happy
This commit is contained in:
+144
-144
@@ -1,144 +1,144 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
### BEGIN INIT INFO
|
### BEGIN INIT INFO
|
||||||
# Provides: patroni
|
# Provides: patroni
|
||||||
# Required-Start: $remote_fs $syslog
|
# Required-Start: $remote_fs $syslog
|
||||||
# Required-Stop: $remote_fs $syslog
|
# Required-Stop: $remote_fs $syslog
|
||||||
# Default-Start: 2 3 4 5
|
# Default-Start: 2 3 4 5
|
||||||
# Default-Stop: 0 1 6
|
# Default-Stop: 0 1 6
|
||||||
# Short-Description: Patroni init script
|
# Short-Description: Patroni init script
|
||||||
# Description: Runners to orchestrate a high-availability PostgreSQL
|
# Description: Runners to orchestrate a high-availability PostgreSQL
|
||||||
### END INIT INFO
|
### END INIT INFO
|
||||||
|
|
||||||
### BEGIN USER CONFIGURATION
|
### BEGIN USER CONFIGURATION
|
||||||
|
|
||||||
CONF="/etc/patroni/postgres.yml"
|
CONF="/etc/patroni/postgres.yml"
|
||||||
LOGFILE="/var/log/patroni.log"
|
LOGFILE="/var/log/patroni.log"
|
||||||
USER="postgres"
|
USER="postgres"
|
||||||
GROUP="postgres"
|
GROUP="postgres"
|
||||||
|
|
||||||
NAME=patroni
|
NAME=patroni
|
||||||
PATRONI="/opt/patroni/$NAME.py"
|
PATRONI="/opt/patroni/$NAME.py"
|
||||||
PIDFILE="/var/run/$NAME.pid"
|
PIDFILE="/var/run/$NAME.pid"
|
||||||
|
|
||||||
# Set this parameter, if you have several Postgres versions installed
|
# Set this parameter, if you have several Postgres versions installed
|
||||||
# POSTGRES_VERSION="9.4"
|
# POSTGRES_VERSION="9.4"
|
||||||
POSTGRES_VERSION=""
|
POSTGRES_VERSION=""
|
||||||
|
|
||||||
### END USER CONFIGURATION
|
### END USER CONFIGURATION
|
||||||
|
|
||||||
. /lib/lsb/init-functions
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
# Loading this library for get_versions() function
|
# Loading this library for get_versions() function
|
||||||
if test ! -e /usr/share/postgresql-common/init.d-functions; then
|
if test ! -e /usr/share/postgresql-common/init.d-functions; then
|
||||||
log_failure_msg "Probably postgresql-common does not installed."
|
log_failure_msg "Probably postgresql-common does not installed."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
. /usr/share/postgresql-common/init.d-functions
|
. /usr/share/postgresql-common/init.d-functions
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Is there Patroni executable?
|
# Is there Patroni executable?
|
||||||
if test ! -e $PATRONI; then
|
if test ! -e $PATRONI; then
|
||||||
log_failure_msg "Patroni executable $PATRONI does not exist."
|
log_failure_msg "Patroni executable $PATRONI does not exist."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Is there Patroni configuration file?
|
# Is there Patroni configuration file?
|
||||||
if test ! -e $CONF; then
|
if test ! -e $CONF; then
|
||||||
log_failure_msg "Patroni configuration file $CONF does not exist."
|
log_failure_msg "Patroni configuration file $CONF does not exist."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create logfile if doesn't exist
|
# Create logfile if doesn't exist
|
||||||
if test ! -e $LOGFILE; then
|
if test ! -e $LOGFILE; then
|
||||||
log_action_msg "Creating logfile for Patroni..."
|
log_action_msg "Creating logfile for Patroni..."
|
||||||
touch $LOGFILE
|
touch $LOGFILE
|
||||||
chown $USER:$GROUP $LOGFILE
|
chown $USER:$GROUP $LOGFILE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
prepare_pgpath() {
|
prepare_pgpath() {
|
||||||
if [ "$POSTGRES_VERSION" != "" ]; then
|
if [ "$POSTGRES_VERSION" != "" ]; then
|
||||||
if [ -x /usr/lib/postgresql/$POSTGRES_VERSION/bin/pg_ctl ]; then
|
if [ -x /usr/lib/postgresql/$POSTGRES_VERSION/bin/pg_ctl ]; then
|
||||||
PGPATH="/usr/lib/postgresql/$POSTGRES_VERSION/bin"
|
PGPATH="/usr/lib/postgresql/$POSTGRES_VERSION/bin"
|
||||||
else
|
else
|
||||||
log_failure_msg "Postgres version incorrect, check POSTGRES_VERSION variable."
|
log_failure_msg "Postgres version incorrect, check POSTGRES_VERSION variable."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
get_versions
|
get_versions
|
||||||
if echo $versions | grep -q -e "\s"; then
|
if echo $versions | grep -q -e "\s"; then
|
||||||
log_warning_msg "You have several Postgres versions installed. Please, use POSTGRES_VERSION to define correct environment."
|
log_warning_msg "You have several Postgres versions installed. Please, use POSTGRES_VERSION to define correct environment."
|
||||||
else
|
else
|
||||||
versions=`echo $versions | sed -e 's/^[ \t]*//'`
|
versions=`echo $versions | sed -e 's/^[ \t]*//'`
|
||||||
PGPATH="/usr/lib/postgresql/$versions/bin"
|
PGPATH="/usr/lib/postgresql/$versions/bin"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
get_pid() {
|
get_pid() {
|
||||||
if test -e $PIDFILE; then
|
if test -e $PIDFILE; then
|
||||||
PID=`cat $PIDFILE`
|
PID=`cat $PIDFILE`
|
||||||
CHILDPID=`ps --ppid $PID -o %p --no-headers`
|
CHILDPID=`ps --ppid $PID -o %p --no-headers`
|
||||||
else
|
else
|
||||||
log_failure_msg "Could not find PID file. Patroni probably down."
|
log_failure_msg "Could not find PID file. Patroni probably down."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start)
|
||||||
prepare_pgpath
|
prepare_pgpath
|
||||||
PGPATH=$PATH:$PGPATH
|
PGPATH=$PATH:$PGPATH
|
||||||
log_success_msg "Starting Patroni\n"
|
log_success_msg "Starting Patroni\n"
|
||||||
exec start-stop-daemon --start --quiet \
|
exec start-stop-daemon --start --quiet \
|
||||||
--background \
|
--background \
|
||||||
--pidfile $PIDFILE --make-pidfile \
|
--pidfile $PIDFILE --make-pidfile \
|
||||||
--chuid $USER:$GROUP \
|
--chuid $USER:$GROUP \
|
||||||
--chdir `eval echo ~$USER` \
|
--chdir `eval echo ~$USER` \
|
||||||
--exec $PATRONI \
|
--exec $PATRONI \
|
||||||
--startas /bin/sh -- \
|
--startas /bin/sh -- \
|
||||||
-c "/usr/bin/env PATH=$PGPATH /usr/bin/python $PATRONI $CONF >> $LOGFILE 2>&1"
|
-c "/usr/bin/env PATH=$PGPATH /usr/bin/python $PATRONI $CONF >> $LOGFILE 2>&1"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
stop)
|
stop)
|
||||||
log_success_msg "Stopping Patroni"
|
log_success_msg "Stopping Patroni"
|
||||||
get_pid
|
get_pid
|
||||||
start-stop-daemon --stop --pid $CHILDPID
|
start-stop-daemon --stop --pid $CHILDPID
|
||||||
start-stop-daemon --stop --pidfile $PIDFILE --remove-pidfile --quiet
|
start-stop-daemon --stop --pidfile $PIDFILE --remove-pidfile --quiet
|
||||||
;;
|
;;
|
||||||
|
|
||||||
reload)
|
reload)
|
||||||
log_success_msg "Reloading Patroni configuration"
|
log_success_msg "Reloading Patroni configuration"
|
||||||
get_pid
|
get_pid
|
||||||
kill -HUP $CHILDPID
|
kill -HUP $CHILDPID
|
||||||
;;
|
;;
|
||||||
|
|
||||||
status)
|
status)
|
||||||
get_pid
|
get_pid
|
||||||
if start-stop-daemon -T --pid $CHILDPID; then
|
if start-stop-daemon -T --pid $CHILDPID; then
|
||||||
log_success_msg "Patroni is running\n"
|
log_success_msg "Patroni is running\n"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
log_warning_msg "Patroni in not running\n"
|
log_warning_msg "Patroni in not running\n"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
restart)
|
restart)
|
||||||
$0 stop
|
$0 stop
|
||||||
$0 start
|
$0 start
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "Usage: /etc/init.d/$NAME {start|stop|restart|reload|status}"
|
echo "Usage: /etc/init.d/$NAME {start|stop|restart|reload|status}"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo .
|
echo .
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo " failed"
|
echo " failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ class PatroniController(AbstractController):
|
|||||||
if not os.path.exists(pidfile):
|
if not os.path.exists(pidfile):
|
||||||
return None
|
return None
|
||||||
return int(open(pidfile).readline().strip())
|
return int(open(pidfile).readline().strip())
|
||||||
except:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def database_is_running(self):
|
def database_is_running(self):
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class AsyncExecutor(object):
|
|||||||
# if the func returned something (not None) - wake up main HA loop
|
# if the func returned something (not None) - wake up main HA loop
|
||||||
wakeup = func(*args) if args else func()
|
wakeup = func(*args) if args else func()
|
||||||
return wakeup
|
return wakeup
|
||||||
except:
|
except Exception:
|
||||||
logger.exception('Exception during execution of long running task %s', self.scheduled_action)
|
logger.exception('Exception during execution of long running task %s', self.scheduled_action)
|
||||||
finally:
|
finally:
|
||||||
with self:
|
with self:
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ class AbstractDCS(object):
|
|||||||
with self._cluster_thread_lock:
|
with self._cluster_thread_lock:
|
||||||
try:
|
try:
|
||||||
self._load_cluster()
|
self._load_cluster()
|
||||||
except:
|
except Exception:
|
||||||
self._cluster = None
|
self._cluster = None
|
||||||
raise
|
raise
|
||||||
return self._cluster
|
return self._cluster
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ class Consul(AbstractDCS):
|
|||||||
self._cluster = Cluster(initialize, config, leader, last_leader_operation, members, failover, sync)
|
self._cluster = Cluster(initialize, config, leader, last_leader_operation, members, failover, sync)
|
||||||
except NotFound:
|
except NotFound:
|
||||||
self._cluster = Cluster(None, None, None, None, [], None, None)
|
self._cluster = Cluster(None, None, None, None, [], None, None)
|
||||||
except:
|
except Exception:
|
||||||
logger.exception('get_cluster')
|
logger.exception('get_cluster')
|
||||||
raise ConsulError('Consul is not responding properly')
|
raise ConsulError('Consul is not responding properly')
|
||||||
|
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ class ZooKeeper(AbstractDCS):
|
|||||||
try:
|
try:
|
||||||
self._client.retry(self._client.create, path, value.encode('utf-8'), **kwargs)
|
self._client.retry(self._client.create, path, value.encode('utf-8'), **kwargs)
|
||||||
return True
|
return True
|
||||||
except:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def attempt_to_acquire_leader(self, permanent=False):
|
def attempt_to_acquire_leader(self, permanent=False):
|
||||||
@@ -221,7 +221,7 @@ class ZooKeeper(AbstractDCS):
|
|||||||
return True
|
return True
|
||||||
except NoNodeError:
|
except NoNodeError:
|
||||||
return value == '' or (index is None and self._create(self.failover_path, value))
|
return value == '' or (index is None and self._create(self.failover_path, value))
|
||||||
except:
|
except Exception:
|
||||||
logging.exception('set_failover_value')
|
logging.exception('set_failover_value')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ class ZooKeeper(AbstractDCS):
|
|||||||
self._client.delete_async(self.member_path).get(timeout=1)
|
self._client.delete_async(self.member_path).get(timeout=1)
|
||||||
except NoNodeError:
|
except NoNodeError:
|
||||||
pass
|
pass
|
||||||
except:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
member = None
|
member = None
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ class ZooKeeper(AbstractDCS):
|
|||||||
self._client.set_async(self.member_path, data).get(timeout=1)
|
self._client.set_async(self.member_path, data).get(timeout=1)
|
||||||
self._my_member_data = data
|
self._my_member_data = data
|
||||||
return True
|
return True
|
||||||
except:
|
except Exception:
|
||||||
logger.exception('touch_member')
|
logger.exception('touch_member')
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@@ -285,9 +285,9 @@ class ZooKeeper(AbstractDCS):
|
|||||||
try:
|
try:
|
||||||
self._client.create_async(self.leader_optime_path, last_operation, makepath=True).get(timeout=1)
|
self._client.create_async(self.leader_optime_path, last_operation, makepath=True).get(timeout=1)
|
||||||
return True
|
return True
|
||||||
except:
|
except Exception:
|
||||||
logger.exception('Failed to create %s', self.leader_optime_path)
|
logger.exception('Failed to create %s', self.leader_optime_path)
|
||||||
except:
|
except Exception:
|
||||||
logger.exception('Failed to update %s', self.leader_optime_path)
|
logger.exception('Failed to update %s', self.leader_optime_path)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ class ZooKeeper(AbstractDCS):
|
|||||||
def cancel_initialization(self):
|
def cancel_initialization(self):
|
||||||
try:
|
try:
|
||||||
self._client.retry(self._cancel_initialization)
|
self._client.retry(self._cancel_initialization)
|
||||||
except:
|
except Exception:
|
||||||
logger.exception("Unable to delete initialize key")
|
logger.exception("Unable to delete initialize key")
|
||||||
|
|
||||||
def delete_cluster(self):
|
def delete_cluster(self):
|
||||||
@@ -322,7 +322,7 @@ class ZooKeeper(AbstractDCS):
|
|||||||
return True
|
return True
|
||||||
except NoNodeError:
|
except NoNodeError:
|
||||||
return value == '' or (index is None and self._create(self.sync_path, value))
|
return value == '' or (index is None and self._create(self.sync_path, value))
|
||||||
except:
|
except Exception:
|
||||||
logging.exception('set_sync_state_value')
|
logging.exception('set_sync_state_value')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -91,7 +91,7 @@ class Ha(object):
|
|||||||
if write_leader_optime:
|
if write_leader_optime:
|
||||||
try:
|
try:
|
||||||
self.dcs.write_leader_optime(self.state_handler.last_operation())
|
self.dcs.write_leader_optime(self.state_handler.last_operation())
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ class Ha(object):
|
|||||||
if not self._async_executor.busy and data['state'] in ['running', 'restarting', 'starting']:
|
if not self._async_executor.busy and data['state'] in ['running', 'restarting', 'starting']:
|
||||||
try:
|
try:
|
||||||
data['xlog_location'] = self.state_handler.wal_position(retry=False)
|
data['xlog_location'] = self.state_handler.wal_position(retry=False)
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
if self.patroni.scheduled_restart:
|
if self.patroni.scheduled_restart:
|
||||||
scheduled_restart_data = self.patroni.scheduled_restart.copy()
|
scheduled_restart_data = self.patroni.scheduled_restart.copy()
|
||||||
|
|||||||
+5
-5
@@ -95,17 +95,17 @@ def strtol(value, strict=True):
|
|||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
value = str(value).strip()
|
value = str(value).strip()
|
||||||
l = len(value)
|
ln = len(value)
|
||||||
i = 0
|
i = 0
|
||||||
# skip sign:
|
# skip sign:
|
||||||
if i < l and value[i] in ('-', '+'):
|
if i < ln and value[i] in ('-', '+'):
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# we always expect to get digit in the beginning
|
# we always expect to get digit in the beginning
|
||||||
if i < l and value[i].isdigit():
|
if i < ln and value[i].isdigit():
|
||||||
if value[i] == '0':
|
if value[i] == '0':
|
||||||
i += 1
|
i += 1
|
||||||
if i < l and value[i] in ('x', 'X'): # '0' followed by 'x': HEX
|
if i < ln and value[i] in ('x', 'X'): # '0' followed by 'x': HEX
|
||||||
base = 16
|
base = 16
|
||||||
i += 1
|
i += 1
|
||||||
else: # just starts with '0': OCT
|
else: # just starts with '0': OCT
|
||||||
@@ -114,7 +114,7 @@ def strtol(value, strict=True):
|
|||||||
base = 10
|
base = 10
|
||||||
|
|
||||||
ret = None
|
ret = None
|
||||||
while i <= l:
|
while i <= ln:
|
||||||
try: # try to find maximally long number
|
try: # try to find maximally long number
|
||||||
i += 1 # by giving to `int` longer and longer strings
|
i += 1 # by giving to `int` longer and longer strings
|
||||||
ret = int(value[:i], base)
|
ret = int(value[:i], base)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class PyTest(TestCommand):
|
|||||||
def run_tests(self):
|
def run_tests(self):
|
||||||
try:
|
try:
|
||||||
import pytest
|
import pytest
|
||||||
except:
|
except Exception:
|
||||||
raise RuntimeError('py.test is not installed, run: pip install pytest')
|
raise RuntimeError('py.test is not installed, run: pip install pytest')
|
||||||
params = {'args': self.test_args}
|
params = {'args': self.test_args}
|
||||||
if self.cov:
|
if self.cov:
|
||||||
|
|||||||
+4
-4
@@ -35,7 +35,7 @@ def get_cluster_not_initialized_without_leader():
|
|||||||
def get_cluster_initialized_without_leader(leader=False, failover=None, sync=None):
|
def get_cluster_initialized_without_leader(leader=False, failover=None, sync=None):
|
||||||
m1 = Member(0, 'leader', 28, {'conn_url': 'postgres://replicator:[email protected]:5435/postgres',
|
m1 = Member(0, 'leader', 28, {'conn_url': 'postgres://replicator:[email protected]:5435/postgres',
|
||||||
'api_url': 'http://127.0.0.1:8008/patroni', 'xlog_location': 4})
|
'api_url': 'http://127.0.0.1:8008/patroni', 'xlog_location': 4})
|
||||||
l = Leader(0, 0, m1) if leader else None
|
leader = Leader(0, 0, m1) if leader else None
|
||||||
m2 = Member(0, 'other', 28, {'conn_url': 'postgres://replicator:[email protected]:5436/postgres',
|
m2 = Member(0, 'other', 28, {'conn_url': 'postgres://replicator:[email protected]:5436/postgres',
|
||||||
'api_url': 'http://127.0.0.1:8011/patroni',
|
'api_url': 'http://127.0.0.1:8011/patroni',
|
||||||
'state': 'running',
|
'state': 'running',
|
||||||
@@ -43,7 +43,7 @@ def get_cluster_initialized_without_leader(leader=False, failover=None, sync=Non
|
|||||||
'scheduled_restart': {'schedule': "2100-01-01 10:53:07.560445+00:00",
|
'scheduled_restart': {'schedule': "2100-01-01 10:53:07.560445+00:00",
|
||||||
'postgres_version': '99.0.0'}})
|
'postgres_version': '99.0.0'}})
|
||||||
syncstate = SyncState(0 if sync else None, sync and sync[0], sync and sync[1])
|
syncstate = SyncState(0 if sync else None, sync and sync[0], sync and sync[1])
|
||||||
return get_cluster(True, l, [m1, m2], failover, syncstate)
|
return get_cluster(True, leader, [m1, m2], failover, syncstate)
|
||||||
|
|
||||||
|
|
||||||
def get_cluster_initialized_with_leader(failover=None, sync=None):
|
def get_cluster_initialized_with_leader(failover=None, sync=None):
|
||||||
@@ -51,8 +51,8 @@ def get_cluster_initialized_with_leader(failover=None, sync=None):
|
|||||||
|
|
||||||
|
|
||||||
def get_cluster_initialized_with_only_leader(failover=None):
|
def get_cluster_initialized_with_only_leader(failover=None):
|
||||||
l = get_cluster_initialized_without_leader(leader=True, failover=failover).leader
|
leader = get_cluster_initialized_without_leader(leader=True, failover=failover).leader
|
||||||
return get_cluster(True, l, [l], failover, None)
|
return get_cluster(True, leader, [leader], failover, None)
|
||||||
|
|
||||||
|
|
||||||
def get_node_status(reachable=True, in_recovery=True, wal_position=10, nofailover=False, watchdog_failed=False):
|
def get_node_status(reachable=True, in_recovery=True, wal_position=10, nofailover=False, watchdog_failed=False):
|
||||||
|
|||||||
Reference in New Issue
Block a user