mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
* Use YAML files to validate Postgres GUCs through Patroni. Patroni used to have a static list of Postgres GUCs validators in `patroni.postgresql.validator`. One problem with that approach, for example, is that it would not allow GUCs from custom Postgres builds to be validated/accepted. The idea that we had to work around that issue was to move the validators from the source code to an external and extendable source. With that Patroni will start reading the current validators from that external source plus whatever custom validators are found. From this commit onwards Patroni will read and parse all YAML files that are found under the `patroni/postgresql/available_parameters` directory to build its Postgres GUCs validation rules. All the details about how this work can be found in the docstring of the introduced function `_load_postgres_gucs_validators`.
183 lines
5.7 KiB
Python
183 lines
5.7 KiB
Python
#!/usr/bin/env python
|
|
|
|
"""
|
|
Setup file for patroni
|
|
"""
|
|
|
|
import inspect
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
from setuptools import Command, find_packages, setup
|
|
|
|
__location__ = os.path.join(os.getcwd(), os.path.dirname(inspect.getfile(inspect.currentframe())))
|
|
|
|
NAME = 'patroni'
|
|
MAIN_PACKAGE = NAME
|
|
DESCRIPTION = 'PostgreSQL High-Available orchestrator and CLI'
|
|
LICENSE = 'The MIT License'
|
|
URL = 'https://github.com/zalando/patroni'
|
|
AUTHOR = 'Alexander Kukushkin, Polina Bungina'
|
|
AUTHOR_EMAIL = '[email protected], [email protected]'
|
|
KEYWORDS = 'etcd governor patroni postgresql postgres ha haproxy confd' +\
|
|
' zookeeper exhibitor consul streaming replication kubernetes k8s'
|
|
|
|
EXTRAS_REQUIRE = {'aws': ['boto3'], 'etcd': ['python-etcd'], 'etcd3': ['python-etcd'],
|
|
'consul': ['python-consul'], 'exhibitor': ['kazoo'], 'zookeeper': ['kazoo'],
|
|
'kubernetes': [], 'raft': ['pysyncobj', 'cryptography']}
|
|
COVERAGE_XML = True
|
|
|
|
# Add here all kinds of additional classifiers as defined under
|
|
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
|
CLASSIFIERS = [
|
|
'Development Status :: 5 - Production/Stable',
|
|
'Environment :: Console',
|
|
'Intended Audience :: Developers',
|
|
'Intended Audience :: System Administrators',
|
|
'License :: OSI Approved :: MIT License',
|
|
'Operating System :: MacOS',
|
|
'Operating System :: POSIX :: Linux',
|
|
'Operating System :: POSIX :: BSD :: FreeBSD',
|
|
'Operating System :: Microsoft :: Windows',
|
|
'Programming Language :: Python',
|
|
'Programming Language :: Python :: 3',
|
|
'Programming Language :: Python :: 3.6',
|
|
'Programming Language :: Python :: 3.7',
|
|
'Programming Language :: Python :: 3.8',
|
|
'Programming Language :: Python :: 3.9',
|
|
'Programming Language :: Python :: 3.10',
|
|
'Programming Language :: Python :: 3.11',
|
|
'Programming Language :: Python :: Implementation :: CPython',
|
|
]
|
|
|
|
CONSOLE_SCRIPTS = ['patroni = patroni.__main__:main',
|
|
'patronictl = patroni.ctl:ctl',
|
|
'patroni_raft_controller = patroni.raft_controller:main',
|
|
"patroni_wale_restore = patroni.scripts.wale_restore:main",
|
|
"patroni_aws = patroni.scripts.aws:main"]
|
|
|
|
|
|
class _Command(Command):
|
|
user_options = []
|
|
|
|
def initialize_options(self):
|
|
pass
|
|
|
|
def finalize_options(self):
|
|
pass
|
|
|
|
|
|
class Flake8(_Command):
|
|
|
|
def package_files(self):
|
|
seen_package_directories = ()
|
|
directories = self.distribution.package_dir or {}
|
|
empty_directory_exists = "" in directories
|
|
packages = self.distribution.packages or []
|
|
for package in packages:
|
|
if package in directories:
|
|
package_directory = directories[package]
|
|
elif empty_directory_exists:
|
|
package_directory = os.path.join(directories[""], package)
|
|
else:
|
|
package_directory = package
|
|
|
|
if not package_directory.startswith(seen_package_directories):
|
|
seen_package_directories += (package_directory + ".",)
|
|
yield package_directory
|
|
|
|
def targets(self):
|
|
return [package for package in self.package_files()] + ['tests', 'setup.py']
|
|
|
|
def run(self):
|
|
from flake8.main.cli import main
|
|
|
|
logging.getLogger().setLevel(logging.ERROR)
|
|
raise SystemExit(main(self.targets()))
|
|
|
|
|
|
class PyTest(_Command):
|
|
|
|
def run(self):
|
|
try:
|
|
import pytest
|
|
except Exception:
|
|
raise RuntimeError('py.test is not installed, run: pip install pytest')
|
|
|
|
logging.getLogger().setLevel(logging.WARNING)
|
|
|
|
args = ['--verbose', 'tests', '--doctest-modules', MAIN_PACKAGE] +\
|
|
['-s' if logging.getLogger().getEffectiveLevel() < logging.WARNING else '--capture=fd'] +\
|
|
['--cov', MAIN_PACKAGE, '--cov-report', 'term-missing', '--cov-report', 'xml']
|
|
|
|
errno = pytest.main(args=args)
|
|
sys.exit(errno)
|
|
|
|
|
|
def read(fname):
|
|
with open(os.path.join(__location__, fname)) as fd:
|
|
return fd.read()
|
|
|
|
|
|
def setup_package(version):
|
|
logging.basicConfig(format='%(message)s', level=os.getenv('LOGLEVEL', logging.WARNING))
|
|
|
|
# Assemble additional setup commands
|
|
cmdclass = {'test': PyTest, 'flake8': Flake8}
|
|
|
|
install_requires = []
|
|
|
|
for r in read('requirements.txt').split('\n'):
|
|
r = r.strip()
|
|
if r == '':
|
|
continue
|
|
extra = False
|
|
for e, deps in EXTRAS_REQUIRE.items():
|
|
for i, v in enumerate(deps):
|
|
if r.startswith(v):
|
|
deps[i] = r
|
|
EXTRAS_REQUIRE[e] = deps
|
|
extra = True
|
|
break
|
|
if extra:
|
|
break
|
|
if not extra:
|
|
install_requires.append(r)
|
|
|
|
setup(
|
|
name=NAME,
|
|
version=version,
|
|
url=URL,
|
|
author=AUTHOR,
|
|
author_email=AUTHOR_EMAIL,
|
|
description=DESCRIPTION,
|
|
license=LICENSE,
|
|
keywords=KEYWORDS,
|
|
long_description=read('README.rst'),
|
|
classifiers=CLASSIFIERS,
|
|
packages=find_packages(exclude=['tests', 'tests.*']),
|
|
package_data={MAIN_PACKAGE: [
|
|
"postgresql/available_parameters/*.yml",
|
|
"postgresql/available_parameters/*.yaml",
|
|
]},
|
|
install_requires=install_requires,
|
|
extras_require=EXTRAS_REQUIRE,
|
|
cmdclass=cmdclass,
|
|
entry_points={'console_scripts': CONSOLE_SCRIPTS},
|
|
)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
old_modules = sys.modules.copy()
|
|
try:
|
|
from patroni import check_psycopg
|
|
from patroni.version import __version__
|
|
finally:
|
|
sys.modules.clear()
|
|
sys.modules.update(old_modules)
|
|
|
|
check_psycopg()
|
|
|
|
setup_package(__version__)
|