chartreuse 6.1.0__tar.gz → 7.0.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chartreuse-6.1.0/src/chartreuse.egg-info → chartreuse-7.0.0.dev0}/PKG-INFO +2 -2
- chartreuse-7.0.0.dev0/VERSION +1 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/pyproject.toml +2 -2
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse/chartreuse.py +0 -1
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse/config_loader.py +3 -6
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse/utils/alembic_migration_helper.py +1 -58
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0/src/chartreuse.egg-info}/PKG-INFO +2 -2
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse.egg-info/requires.txt +1 -1
- chartreuse-6.1.0/VERSION +0 -1
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/LICENCE.md +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/MANIFEST.in +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/README.md +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/setup.cfg +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse/__init__.py +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse/chartreuse_upgrade.py +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse/utils/__init__.py +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse.egg-info/SOURCES.txt +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse.egg-info/dependency_links.txt +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse.egg-info/entry_points.txt +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse.egg-info/top_level.txt +0 -0
- {chartreuse-6.1.0 → chartreuse-7.0.0.dev0}/src/chartreuse.egg-info/zip-safe +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chartreuse
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0.dev0
|
|
4
4
|
Summary: Helper for Alembic migrations within Kubernetes.
|
|
5
5
|
Author-email: wiremind <dev@wiremind.io>
|
|
6
6
|
License-Expression: LGPL-3.0-or-later
|
|
@@ -9,7 +9,7 @@ Requires-Python: >=3.11.0
|
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENCE.md
|
|
11
11
|
Requires-Dist: alembic
|
|
12
|
-
Requires-Dist:
|
|
12
|
+
Requires-Dist: psycopg[binary]
|
|
13
13
|
Requires-Dist: pydantic>=2.0.0
|
|
14
14
|
Requires-Dist: PyYAML
|
|
15
15
|
Requires-Dist: wiremind-kubernetes~=7.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
7.0.0-dev0
|
|
@@ -11,7 +11,7 @@ requires-python = ">=3.11.0"
|
|
|
11
11
|
|
|
12
12
|
dependencies = [
|
|
13
13
|
"alembic",
|
|
14
|
-
"
|
|
14
|
+
"psycopg[binary]",
|
|
15
15
|
"pydantic>=2.0.0",
|
|
16
16
|
"PyYAML",
|
|
17
17
|
"wiremind-kubernetes~=7.0",
|
|
@@ -76,4 +76,4 @@ known-first-party = ["chartreuse"]
|
|
|
76
76
|
log_level = "INFO"
|
|
77
77
|
# Deterministic ordering for tests; useful for pytest-xdist.
|
|
78
78
|
env = ["PYTHONHASHSEED=0"]
|
|
79
|
-
filterwarnings = ["ignore::pytest.PytestUnknownMarkWarning"]
|
|
79
|
+
filterwarnings = ["ignore::pytest.PytestUnknownMarkWarning"]
|
|
@@ -49,7 +49,6 @@ class Chartreuse:
|
|
|
49
49
|
allow_migration_for_empty_database=db_config.allow_migration_for_empty_database,
|
|
50
50
|
additional_parameters=additional_params,
|
|
51
51
|
alembic_section_name=db_name,
|
|
52
|
-
is_patroni_postgresql=db_config.is_patroni_postgresql,
|
|
53
52
|
)
|
|
54
53
|
self.migration_helpers[db_name] = helper
|
|
55
54
|
|
|
@@ -28,7 +28,6 @@ class DatabaseConfig(BaseModel):
|
|
|
28
28
|
# Optional migration settings
|
|
29
29
|
allow_migration_for_empty_database: bool = Field(default=True, description="Allow migrations on empty database")
|
|
30
30
|
additional_parameters: str = Field(default="", description="Additional Alembic parameters")
|
|
31
|
-
is_patroni_postgresql: bool = Field(default=False, description="Whether this is a Patroni PostgreSQL database")
|
|
32
31
|
|
|
33
32
|
@computed_field
|
|
34
33
|
@property
|
|
@@ -40,7 +39,7 @@ class DatabaseConfig(BaseModel):
|
|
|
40
39
|
@classmethod
|
|
41
40
|
def validate_dialect(cls, v: str) -> str:
|
|
42
41
|
"""Validate database dialect."""
|
|
43
|
-
supported_dialects = ["postgresql", "clickhouse"]
|
|
42
|
+
supported_dialects = ["postgresql+psycopg", "mysql", "sqlite", "oracle", "mssql", "clickhouse"]
|
|
44
43
|
if v.lower() not in supported_dialects:
|
|
45
44
|
logger.warning("Dialect '%s' might not be supported. Supported dialects: %s", v, supported_dialects)
|
|
46
45
|
return v
|
|
@@ -87,7 +86,7 @@ def load_multi_database_config(config_path: str) -> dict[str, DatabaseConfig]:
|
|
|
87
86
|
```yaml
|
|
88
87
|
databases:
|
|
89
88
|
main: # Database name/identifier
|
|
90
|
-
dialect: postgresql
|
|
89
|
+
dialect: postgresql+psycopg
|
|
91
90
|
user: app_user
|
|
92
91
|
password: app_password
|
|
93
92
|
host: postgres-main
|
|
@@ -97,11 +96,10 @@ def load_multi_database_config(config_path: str) -> dict[str, DatabaseConfig]:
|
|
|
97
96
|
alembic_config_file_path: alembic.ini
|
|
98
97
|
allow_migration_for_empty_database: true
|
|
99
98
|
additional_parameters: ""
|
|
100
|
-
is_patroni_postgresql: false
|
|
101
99
|
|
|
102
100
|
# For single database setups, just include one database:
|
|
103
101
|
# analytics:
|
|
104
|
-
# dialect: postgresql
|
|
102
|
+
# dialect: postgresql+psycopg
|
|
105
103
|
# user: analytics_user
|
|
106
104
|
# password: analytics_password
|
|
107
105
|
# host: postgres-analytics
|
|
@@ -111,7 +109,6 @@ def load_multi_database_config(config_path: str) -> dict[str, DatabaseConfig]:
|
|
|
111
109
|
# alembic_config_file_path: alembic.ini
|
|
112
110
|
# allow_migration_for_empty_database: false
|
|
113
111
|
# additional_parameters: ""
|
|
114
|
-
# is_patroni_postgresql: true
|
|
115
112
|
```
|
|
116
113
|
"""
|
|
117
114
|
try:
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
import os
|
|
3
2
|
import re
|
|
4
3
|
from configparser import ConfigParser
|
|
5
4
|
from subprocess import SubprocessError
|
|
6
|
-
from time import sleep, time
|
|
7
5
|
|
|
8
6
|
import sqlalchemy
|
|
9
|
-
from sqlalchemy import inspect
|
|
10
|
-
from sqlalchemy.pool import NullPool
|
|
7
|
+
from sqlalchemy import inspect
|
|
11
8
|
from wiremind_kubernetes.utils import run_command
|
|
12
9
|
|
|
13
10
|
logger = logging.getLogger(__name__)
|
|
@@ -26,7 +23,6 @@ class AlembicMigrationHelper:
|
|
|
26
23
|
configure: bool = True,
|
|
27
24
|
# skip_db_checks is used for testing purposes only
|
|
28
25
|
skip_db_checks: bool = False,
|
|
29
|
-
is_patroni_postgresql: bool = False,
|
|
30
26
|
):
|
|
31
27
|
if not database_url:
|
|
32
28
|
raise ValueError("database_url not set, not upgrading database.")
|
|
@@ -38,12 +34,6 @@ class AlembicMigrationHelper:
|
|
|
38
34
|
self.alembic_config_file_path = alembic_config_file_path
|
|
39
35
|
self.alembic_section_name = alembic_section_name
|
|
40
36
|
self.skip_db_checks = skip_db_checks
|
|
41
|
-
self.is_patroni_postgresql = is_patroni_postgresql
|
|
42
|
-
|
|
43
|
-
# Chartreuse will upgrade a PG managed/configured by postgres-operator
|
|
44
|
-
if self.is_patroni_postgresql and not skip_db_checks:
|
|
45
|
-
self.additional_parameters += " -x patroni_postgresql=yes"
|
|
46
|
-
self._wait_postgres_is_configured()
|
|
47
37
|
|
|
48
38
|
if configure:
|
|
49
39
|
self._configure()
|
|
@@ -73,53 +63,6 @@ class AlembicMigrationHelper:
|
|
|
73
63
|
|
|
74
64
|
logger.info("alembic.ini was configured for section %s.", self.alembic_section_name)
|
|
75
65
|
|
|
76
|
-
def _wait_postgres_is_configured(self) -> None:
|
|
77
|
-
"""
|
|
78
|
-
Make sure the user `wiremind_owner_user` was created by the postgres-operator
|
|
79
|
-
and that default privileges were configured.
|
|
80
|
-
# TODO: Maybe make this a readinessProbe on Patroni PG Pods
|
|
81
|
-
# We need to remove this, it's an open source tool...
|
|
82
|
-
"""
|
|
83
|
-
wait_timeout = int(os.getenv("CHARTREUSE_ALEMBIC_POSTGRES_WAIT_CONFIGURED_TIMEOUT", 60))
|
|
84
|
-
engine = sqlalchemy.create_engine(self.database_url, poolclass=NullPool, connect_args={"connect_timeout": 1})
|
|
85
|
-
|
|
86
|
-
default_privileges_checks: list[str] = [
|
|
87
|
-
"SET ROLE wiremind_owner", # The real owner, alembic will switch to it before running migrations.
|
|
88
|
-
"CREATE TABLE _chartreuse_test_default_privileges(id serial)",
|
|
89
|
-
"SET ROLE wiremind_writer_user",
|
|
90
|
-
"INSERT INTO _chartreuse_test_default_privileges VALUES(1)", # id = 1
|
|
91
|
-
"SET ROLE wiremind_reader_user",
|
|
92
|
-
"SELECT id from _chartreuse_test_default_privileges",
|
|
93
|
-
]
|
|
94
|
-
start_time = time()
|
|
95
|
-
|
|
96
|
-
while time() - start_time < wait_timeout:
|
|
97
|
-
try:
|
|
98
|
-
# Yes, we may create a connection each time.
|
|
99
|
-
with engine.connect() as connection:
|
|
100
|
-
transac = connection.begin()
|
|
101
|
-
# TODO: Use scalar_one() once sqlachemly >= 1.4
|
|
102
|
-
_id = connection.execute(text(";".join(default_privileges_checks))).scalar()
|
|
103
|
-
assert _id == 1
|
|
104
|
-
transac.rollback()
|
|
105
|
-
logger.info(
|
|
106
|
-
"The role wiremind_owner_user was created and the default privileges"
|
|
107
|
-
" were set by the postgres-operator."
|
|
108
|
-
)
|
|
109
|
-
return
|
|
110
|
-
except Exception as e:
|
|
111
|
-
# TODO: Learn about exceptions that should be caught here, otherwise we'll wait for nothing
|
|
112
|
-
logger.info("Caught: %s", e)
|
|
113
|
-
logger.info(
|
|
114
|
-
"Waiting for the postgres-operator to create the user wiremind_owner_user"
|
|
115
|
-
" (that alembic and I use) and to set default privileges..."
|
|
116
|
-
)
|
|
117
|
-
sleep(2)
|
|
118
|
-
raise Exception(
|
|
119
|
-
f"I'm fed up! Waited {wait_timeout}s for postgres-operator to configure the"
|
|
120
|
-
f" Postgres database. Check the Postgres logs and then postgres-operator for anything fishy."
|
|
121
|
-
)
|
|
122
|
-
|
|
123
66
|
def _get_table_list(self) -> list[str]:
|
|
124
67
|
return inspect(sqlalchemy.create_engine(self.database_url)).get_table_names()
|
|
125
68
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chartreuse
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0.dev0
|
|
4
4
|
Summary: Helper for Alembic migrations within Kubernetes.
|
|
5
5
|
Author-email: wiremind <dev@wiremind.io>
|
|
6
6
|
License-Expression: LGPL-3.0-or-later
|
|
@@ -9,7 +9,7 @@ Requires-Python: >=3.11.0
|
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENCE.md
|
|
11
11
|
Requires-Dist: alembic
|
|
12
|
-
Requires-Dist:
|
|
12
|
+
Requires-Dist: psycopg[binary]
|
|
13
13
|
Requires-Dist: pydantic>=2.0.0
|
|
14
14
|
Requires-Dist: PyYAML
|
|
15
15
|
Requires-Dist: wiremind-kubernetes~=7.0
|
chartreuse-6.1.0/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6.1.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|