pglift-cli 1.6.0__tar.gz → 1.7.0__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.
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/PKG-INFO +5 -3
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/pyproject.toml +2 -1
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/base.py +4 -1
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/database.py +53 -39
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/instance.py +39 -25
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/main.py +2 -2
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/model.py +151 -49
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/pgbackrest/__init__.py +3 -3
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/pgconf.py +13 -9
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/postgres.py +1 -1
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/prometheus.py +2 -2
- pglift_cli-1.7.0/src/pglift_cli/py.typed +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/role.py +60 -27
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/util.py +86 -44
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/.gitignore +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/README.md +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/hatch.toml +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/__init__.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/__main__.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/_settings.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/_site.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/console.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/hookspecs.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/patroni.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/pgbackrest/repo_path.py +0 -0
- {pglift_cli-1.6.0 → pglift_cli-1.7.0}/src/pglift_cli/pm.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pglift_cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: Command-line interface for pglift
|
|
5
5
|
Project-URL: Documentation, https://pglift.readthedocs.io/
|
|
6
6
|
Project-URL: Source, https://gitlab.com/dalibo/pglift/
|
|
@@ -31,7 +31,8 @@ Requires-Dist: pyyaml>=6.0.1
|
|
|
31
31
|
Requires-Dist: rich>=11.0.0
|
|
32
32
|
Provides-Extra: dev
|
|
33
33
|
Requires-Dist: anyio; extra == 'dev'
|
|
34
|
-
Requires-Dist: mypy
|
|
34
|
+
Requires-Dist: mypy!=1.11.*,>=1.10.0; (python_version < '3.10') and extra == 'dev'
|
|
35
|
+
Requires-Dist: mypy>=1.10.0; (python_version >= '3.10') and extra == 'dev'
|
|
35
36
|
Requires-Dist: patroni[etcd]>=2.1.5; extra == 'dev'
|
|
36
37
|
Requires-Dist: port-for; extra == 'dev'
|
|
37
38
|
Requires-Dist: prysk[pytest-plugin]>=0.14.0; extra == 'dev'
|
|
@@ -48,7 +49,8 @@ Requires-Dist: pytest; extra == 'test'
|
|
|
48
49
|
Requires-Dist: pytest-cov; extra == 'test'
|
|
49
50
|
Requires-Dist: trustme; extra == 'test'
|
|
50
51
|
Provides-Extra: typing
|
|
51
|
-
Requires-Dist: mypy
|
|
52
|
+
Requires-Dist: mypy!=1.11.*,>=1.10.0; (python_version < '3.10') and extra == 'typing'
|
|
53
|
+
Requires-Dist: mypy>=1.10.0; (python_version >= '3.10') and extra == 'typing'
|
|
52
54
|
Requires-Dist: types-pyyaml>=6.0.12.10; extra == 'typing'
|
|
53
55
|
Description-Content-Type: text/markdown
|
|
54
56
|
|
|
@@ -38,7 +38,10 @@ class CLIGroup(click.Group):
|
|
|
38
38
|
|
|
39
39
|
def list_commands(self, context: click.Context) -> list[str]:
|
|
40
40
|
main_commands = super().list_commands(context)
|
|
41
|
-
plugins_commands: list[str] = sorted(
|
|
41
|
+
plugins_commands: list[str] = sorted(
|
|
42
|
+
g.name # type: ignore[misc]
|
|
43
|
+
for g in hooks(_site.PLUGIN_MANAGER, h.command)
|
|
44
|
+
)
|
|
42
45
|
return main_commands + self.submodules + plugins_commands
|
|
43
46
|
|
|
44
47
|
def get_command(self, context: click.Context, name: str) -> click.Command | None:
|
|
@@ -30,7 +30,7 @@ from .util import (
|
|
|
30
30
|
manifest_option,
|
|
31
31
|
model_dump,
|
|
32
32
|
output_format_option,
|
|
33
|
-
|
|
33
|
+
pass_postgresql_instance,
|
|
34
34
|
print_argspec,
|
|
35
35
|
print_json_for,
|
|
36
36
|
print_schema,
|
|
@@ -63,11 +63,11 @@ def cli(**kwargs: Any) -> None:
|
|
|
63
63
|
|
|
64
64
|
@cli.command("create")
|
|
65
65
|
@model.as_parameters(interface.Database, "create")
|
|
66
|
-
@
|
|
66
|
+
@pass_postgresql_instance
|
|
67
67
|
@click.pass_obj
|
|
68
68
|
@async_command
|
|
69
69
|
async def create(
|
|
70
|
-
obj: Obj, instance: system.
|
|
70
|
+
obj: Obj, instance: system.PostgreSQLInstance, database: interface.Database
|
|
71
71
|
) -> None:
|
|
72
72
|
"""Create a database in a PostgreSQL instance"""
|
|
73
73
|
with obj.lock, audit():
|
|
@@ -79,13 +79,13 @@ async def create(
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
@cli.command("alter") # type: ignore[arg-type]
|
|
82
|
-
@model.as_parameters(interface.Database, "update"
|
|
82
|
+
@model.as_parameters(interface.Database, "update")
|
|
83
83
|
@click.argument("dbname")
|
|
84
|
-
@
|
|
84
|
+
@pass_postgresql_instance
|
|
85
85
|
@click.pass_obj
|
|
86
86
|
@async_command
|
|
87
87
|
async def alter(
|
|
88
|
-
obj: Obj, instance: system.
|
|
88
|
+
obj: Obj, instance: system.PostgreSQLInstance, dbname: str, **changes: Any
|
|
89
89
|
) -> None:
|
|
90
90
|
"""Alter a database in a PostgreSQL instance"""
|
|
91
91
|
with obj.lock, audit():
|
|
@@ -100,14 +100,14 @@ async def alter(
|
|
|
100
100
|
@manifest_option
|
|
101
101
|
@output_format_option
|
|
102
102
|
@dry_run_option
|
|
103
|
-
@
|
|
103
|
+
@pass_postgresql_instance
|
|
104
104
|
@click.pass_obj
|
|
105
105
|
@async_command
|
|
106
106
|
async def apply(
|
|
107
107
|
obj: Obj,
|
|
108
|
-
instance: system.
|
|
108
|
+
instance: system.PostgreSQLInstance,
|
|
109
109
|
data: ManifestData,
|
|
110
|
-
output_format: OutputFormat,
|
|
110
|
+
output_format: OutputFormat | None,
|
|
111
111
|
dry_run: bool,
|
|
112
112
|
) -> None:
|
|
113
113
|
"""Apply manifest as a database"""
|
|
@@ -118,38 +118,44 @@ async def apply(
|
|
|
118
118
|
with obj.lock, audit():
|
|
119
119
|
async with postgresql.running(instance):
|
|
120
120
|
ret = await databases.apply(instance, database)
|
|
121
|
-
if output_format ==
|
|
121
|
+
if output_format == "json":
|
|
122
122
|
print_json_for(ret)
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
@cli.command("get")
|
|
126
126
|
@output_format_option
|
|
127
127
|
@click.argument("name")
|
|
128
|
-
@
|
|
128
|
+
@pass_postgresql_instance
|
|
129
129
|
@async_command
|
|
130
130
|
async def get(
|
|
131
|
-
instance: system.
|
|
131
|
+
instance: system.PostgreSQLInstance, name: str, output_format: OutputFormat | None
|
|
132
132
|
) -> None:
|
|
133
133
|
"""Get the description of a database"""
|
|
134
134
|
async with postgresql.running(instance):
|
|
135
135
|
db = await databases.get(instance, name)
|
|
136
|
-
if output_format ==
|
|
136
|
+
if output_format == "json":
|
|
137
137
|
print_json_for(model_dump(db))
|
|
138
138
|
else:
|
|
139
|
-
print_table_for(
|
|
140
|
-
[db],
|
|
141
|
-
functools.partial(model_dump, exclude={"extensions", "schemas"}),
|
|
142
|
-
box=None,
|
|
143
|
-
)
|
|
139
|
+
print_table_for([db], functools.partial(model_dump, mode="pretty"), box=None)
|
|
144
140
|
|
|
145
141
|
|
|
146
142
|
@cli.command("list")
|
|
147
143
|
@output_format_option
|
|
144
|
+
@click.option(
|
|
145
|
+
"-x",
|
|
146
|
+
"--exclude-database",
|
|
147
|
+
"exclude_dbnames",
|
|
148
|
+
multiple=True,
|
|
149
|
+
help="Database to exclude from listing.",
|
|
150
|
+
)
|
|
148
151
|
@click.argument("dbname", nargs=-1)
|
|
149
|
-
@
|
|
152
|
+
@pass_postgresql_instance
|
|
150
153
|
@async_command
|
|
151
154
|
async def ls(
|
|
152
|
-
instance: system.
|
|
155
|
+
instance: system.PostgreSQLInstance,
|
|
156
|
+
dbname: Sequence[str],
|
|
157
|
+
exclude_dbnames: Sequence[str],
|
|
158
|
+
output_format: OutputFormat | None,
|
|
153
159
|
) -> None:
|
|
154
160
|
"""List databases (all or specified ones)
|
|
155
161
|
|
|
@@ -157,8 +163,10 @@ async def ls(
|
|
|
157
163
|
"""
|
|
158
164
|
|
|
159
165
|
async with postgresql.running(instance):
|
|
160
|
-
dbs = await databases.ls(
|
|
161
|
-
|
|
166
|
+
dbs = await databases.ls(
|
|
167
|
+
instance, dbnames=dbname, exclude_dbnames=exclude_dbnames
|
|
168
|
+
)
|
|
169
|
+
if output_format == "json":
|
|
162
170
|
print_json_for([model_dump(db) for db in dbs])
|
|
163
171
|
else:
|
|
164
172
|
print_table_for(dbs, model_dump)
|
|
@@ -166,11 +174,13 @@ async def ls(
|
|
|
166
174
|
|
|
167
175
|
@cli.command("drop")
|
|
168
176
|
@model.as_parameters(interface.DatabaseDropped, "create")
|
|
169
|
-
@
|
|
177
|
+
@pass_postgresql_instance
|
|
170
178
|
@click.pass_obj
|
|
171
179
|
@async_command
|
|
172
180
|
async def drop(
|
|
173
|
-
obj: Obj,
|
|
181
|
+
obj: Obj,
|
|
182
|
+
instance: system.PostgreSQLInstance,
|
|
183
|
+
databasedropped: interface.DatabaseDropped,
|
|
174
184
|
) -> None:
|
|
175
185
|
"""Drop a database"""
|
|
176
186
|
with obj.lock, audit():
|
|
@@ -183,14 +193,14 @@ async def drop(
|
|
|
183
193
|
@click.option("-r", "--role", "roles", multiple=True, help="Role to inspect")
|
|
184
194
|
@click.option("--default", "defaults", is_flag=True, help="Display default privileges")
|
|
185
195
|
@output_format_option
|
|
186
|
-
@
|
|
196
|
+
@pass_postgresql_instance
|
|
187
197
|
@async_command
|
|
188
198
|
async def list_privileges(
|
|
189
|
-
instance: system.
|
|
199
|
+
instance: system.PostgreSQLInstance,
|
|
190
200
|
name: str,
|
|
191
201
|
roles: Sequence[str],
|
|
192
202
|
defaults: bool,
|
|
193
|
-
output_format: OutputFormat,
|
|
203
|
+
output_format: OutputFormat | None,
|
|
194
204
|
) -> None:
|
|
195
205
|
"""List privileges on a database."""
|
|
196
206
|
async with postgresql.running(instance):
|
|
@@ -201,7 +211,7 @@ async def list_privileges(
|
|
|
201
211
|
)
|
|
202
212
|
except ValueError as e:
|
|
203
213
|
raise click.ClickException(str(e)) from None
|
|
204
|
-
if output_format ==
|
|
214
|
+
if output_format == "json":
|
|
205
215
|
print_json_for([model_dump(p) for p in prvlgs])
|
|
206
216
|
else:
|
|
207
217
|
print_table_for(prvlgs, model_dump)
|
|
@@ -220,14 +230,14 @@ async def list_privileges(
|
|
|
220
230
|
help="Database to not run command on",
|
|
221
231
|
)
|
|
222
232
|
@output_format_option
|
|
223
|
-
@
|
|
233
|
+
@pass_postgresql_instance
|
|
224
234
|
@async_command
|
|
225
235
|
async def run(
|
|
226
|
-
instance: system.
|
|
236
|
+
instance: system.PostgreSQLInstance,
|
|
227
237
|
sql_command: str,
|
|
228
238
|
dbnames: Sequence[str],
|
|
229
239
|
exclude_dbnames: Sequence[str],
|
|
230
|
-
output_format: OutputFormat,
|
|
240
|
+
output_format: OutputFormat | None,
|
|
231
241
|
) -> None:
|
|
232
242
|
"""Run given command on databases of a PostgreSQL instance"""
|
|
233
243
|
async with postgresql.running(instance):
|
|
@@ -240,7 +250,7 @@ async def run(
|
|
|
240
250
|
)
|
|
241
251
|
except psycopg.ProgrammingError as e:
|
|
242
252
|
raise click.ClickException(str(e)) from None
|
|
243
|
-
if output_format ==
|
|
253
|
+
if output_format == "json":
|
|
244
254
|
print_json_for(result)
|
|
245
255
|
else:
|
|
246
256
|
for dbname, rows in result.items():
|
|
@@ -256,9 +266,11 @@ async def run(
|
|
|
256
266
|
help="Write dump file(s) to DIRECTORY instead of default dumps directory.",
|
|
257
267
|
)
|
|
258
268
|
@click.argument("dbname")
|
|
259
|
-
@
|
|
269
|
+
@pass_postgresql_instance
|
|
260
270
|
@async_command
|
|
261
|
-
async def dump(
|
|
271
|
+
async def dump(
|
|
272
|
+
instance: system.PostgreSQLInstance, dbname: str, output: Path | None
|
|
273
|
+
) -> None:
|
|
262
274
|
"""Dump a database"""
|
|
263
275
|
async with postgresql.running(instance):
|
|
264
276
|
await databases.dump(instance, dbname, output)
|
|
@@ -267,17 +279,19 @@ async def dump(instance: system.Instance, dbname: str, output: Path | None) -> N
|
|
|
267
279
|
@cli.command("dumps")
|
|
268
280
|
@click.argument("dbname", nargs=-1)
|
|
269
281
|
@output_format_option
|
|
270
|
-
@
|
|
282
|
+
@pass_postgresql_instance
|
|
271
283
|
@async_command
|
|
272
284
|
async def dumps(
|
|
273
|
-
instance: system.
|
|
285
|
+
instance: system.PostgreSQLInstance,
|
|
286
|
+
dbname: Sequence[str],
|
|
287
|
+
output_format: OutputFormat | None,
|
|
274
288
|
) -> None:
|
|
275
289
|
"""List the database dumps
|
|
276
290
|
|
|
277
291
|
Only dumps created in the default dumps directory are listed.
|
|
278
292
|
"""
|
|
279
293
|
values = [asdict(dump) async for dump in databases.dumps(instance, dbnames=dbname)]
|
|
280
|
-
if output_format ==
|
|
294
|
+
if output_format == "json":
|
|
281
295
|
print_json_for(values)
|
|
282
296
|
else:
|
|
283
297
|
dbnames = ", ".join(dbname) if dbname else "all databases"
|
|
@@ -287,10 +301,10 @@ async def dumps(
|
|
|
287
301
|
@cli.command("restore")
|
|
288
302
|
@click.argument("dump_id")
|
|
289
303
|
@click.argument("targetdbname", required=False)
|
|
290
|
-
@
|
|
304
|
+
@pass_postgresql_instance
|
|
291
305
|
@async_command
|
|
292
306
|
async def restore(
|
|
293
|
-
instance: system.
|
|
307
|
+
instance: system.PostgreSQLInstance, dump_id: str, targetdbname: str | None
|
|
294
308
|
) -> None:
|
|
295
309
|
"""Restore a database dump
|
|
296
310
|
|
|
@@ -26,9 +26,8 @@ from pglift.settings import default_postgresql_version
|
|
|
26
26
|
from pglift.settings._postgresql import PostgreSQLVersion
|
|
27
27
|
from pglift.types import Operation, Status, validation_context
|
|
28
28
|
|
|
29
|
-
from . import _site
|
|
29
|
+
from . import _site, model
|
|
30
30
|
from . import hookspecs as h
|
|
31
|
-
from . import model
|
|
32
31
|
from .util import (
|
|
33
32
|
ManifestData,
|
|
34
33
|
Obj,
|
|
@@ -42,6 +41,7 @@ from .util import (
|
|
|
42
41
|
manifest_option,
|
|
43
42
|
model_dump,
|
|
44
43
|
output_format_option,
|
|
44
|
+
postgresql_instance_identifier,
|
|
45
45
|
print_argspec,
|
|
46
46
|
print_json_for,
|
|
47
47
|
print_schema,
|
|
@@ -115,13 +115,13 @@ async def create(obj: Obj, instance: interface.Instance, drop_on_error: bool) ->
|
|
|
115
115
|
|
|
116
116
|
@cli.command("alter") # type: ignore[arg-type]
|
|
117
117
|
@instance_identifier(nargs=1)
|
|
118
|
-
@model.as_parameters(_site.INSTANCE_MODEL, "update"
|
|
118
|
+
@model.as_parameters(_site.INSTANCE_MODEL, "update")
|
|
119
119
|
@click.pass_obj
|
|
120
120
|
@async_command
|
|
121
121
|
async def alter(obj: Obj, instance: system.Instance, **changes: Any) -> None:
|
|
122
122
|
"""Alter PostgreSQL INSTANCE"""
|
|
123
123
|
with obj.lock, audit():
|
|
124
|
-
status = await postgresql.status(instance)
|
|
124
|
+
status = await postgresql.status(instance.postgresql)
|
|
125
125
|
manifest = await instances._get(instance, status)
|
|
126
126
|
values = manifest.model_dump(by_alias=True, exclude={"settings"})
|
|
127
127
|
values = deep_update(values, changes)
|
|
@@ -141,7 +141,7 @@ async def alter(obj: Obj, instance: system.Instance, **changes: Any) -> None:
|
|
|
141
141
|
@click.pass_obj
|
|
142
142
|
@async_command
|
|
143
143
|
async def apply(
|
|
144
|
-
obj: Obj, data: ManifestData, output_format: OutputFormat, dry_run: bool
|
|
144
|
+
obj: Obj, data: ManifestData, output_format: OutputFormat | None, dry_run: bool
|
|
145
145
|
) -> None:
|
|
146
146
|
"""Apply manifest as a PostgreSQL instance"""
|
|
147
147
|
name, version = data["name"], data.get("version")
|
|
@@ -159,7 +159,7 @@ async def apply(
|
|
|
159
159
|
else:
|
|
160
160
|
with obj.lock, audit():
|
|
161
161
|
ret = await instances.apply(_site.SETTINGS, instance)
|
|
162
|
-
if output_format ==
|
|
162
|
+
if output_format == "json":
|
|
163
163
|
print_json_for(ret)
|
|
164
164
|
|
|
165
165
|
|
|
@@ -177,14 +177,14 @@ async def promote(obj: Obj, instance: system.Instance) -> None:
|
|
|
177
177
|
@output_format_option
|
|
178
178
|
@instance_identifier(nargs=1)
|
|
179
179
|
@async_command
|
|
180
|
-
async def get(instance: system.Instance, output_format: OutputFormat) -> None:
|
|
180
|
+
async def get(instance: system.Instance, output_format: OutputFormat | None) -> None:
|
|
181
181
|
"""Get the description of PostgreSQL INSTANCE.
|
|
182
182
|
|
|
183
183
|
Unless --output-format is specified, 'settings' and 'state' fields are not
|
|
184
184
|
shown as well as 'standby' information if INSTANCE is not a standby.
|
|
185
185
|
"""
|
|
186
186
|
i = await instances.get(instance)
|
|
187
|
-
if output_format ==
|
|
187
|
+
if output_format == "json":
|
|
188
188
|
print_json_for(model_dump(i))
|
|
189
189
|
else:
|
|
190
190
|
exclude = {
|
|
@@ -194,7 +194,7 @@ async def get(instance: system.Instance, output_format: OutputFormat) -> None:
|
|
|
194
194
|
"wal_directory",
|
|
195
195
|
"powa",
|
|
196
196
|
}
|
|
197
|
-
if not instance.standby:
|
|
197
|
+
if not instance.postgresql.standby:
|
|
198
198
|
exclude.add("standby")
|
|
199
199
|
print_table_for([i], partial(model_dump, exclude=exclude), box=None)
|
|
200
200
|
|
|
@@ -207,10 +207,12 @@ async def get(instance: system.Instance, output_format: OutputFormat) -> None:
|
|
|
207
207
|
)
|
|
208
208
|
@output_format_option
|
|
209
209
|
@async_command
|
|
210
|
-
async def ls(
|
|
210
|
+
async def ls(
|
|
211
|
+
version: PostgreSQLVersion | None, output_format: OutputFormat | None
|
|
212
|
+
) -> None:
|
|
211
213
|
"""List the available instances"""
|
|
212
214
|
items = [i async for i in instances.ls(_site.SETTINGS, version=version)]
|
|
213
|
-
if output_format ==
|
|
215
|
+
if output_format == "json":
|
|
214
216
|
print_json_for([model_dump(m) for m in items])
|
|
215
217
|
else:
|
|
216
218
|
print_table_for(items, model_dump)
|
|
@@ -290,12 +292,12 @@ async def stop(
|
|
|
290
292
|
|
|
291
293
|
|
|
292
294
|
@cli.command("reload")
|
|
293
|
-
@
|
|
295
|
+
@postgresql_instance_identifier(nargs=-1)
|
|
294
296
|
@click.option("--all", "all_instances", is_flag=True, help="Reload all instances.")
|
|
295
297
|
@click.pass_obj
|
|
296
298
|
@async_command
|
|
297
299
|
async def reload(
|
|
298
|
-
obj: Obj, instance: tuple[system.
|
|
300
|
+
obj: Obj, instance: tuple[system.PostgreSQLInstance, ...], all_instances: bool
|
|
299
301
|
) -> None:
|
|
300
302
|
"""Reload PostgreSQL INSTANCE"""
|
|
301
303
|
with obj.lock, audit():
|
|
@@ -362,7 +364,7 @@ def shell(instance: system.Instance, shell: str) -> None:
|
|
|
362
364
|
@cli.command("env")
|
|
363
365
|
@instance_identifier(nargs=1)
|
|
364
366
|
@output_format_option
|
|
365
|
-
def env(instance: system.Instance, output_format: OutputFormat) -> None:
|
|
367
|
+
def env(instance: system.Instance, output_format: OutputFormat | None) -> None:
|
|
366
368
|
"""Output environment variables suitable to handle to PostgreSQL INSTANCE.
|
|
367
369
|
|
|
368
370
|
This can be injected in shell using:
|
|
@@ -370,7 +372,7 @@ def env(instance: system.Instance, output_format: OutputFormat) -> None:
|
|
|
370
372
|
export $(pglift instance env myinstance)
|
|
371
373
|
"""
|
|
372
374
|
instance_env = instances.env_for(instance, path=True)
|
|
373
|
-
if output_format ==
|
|
375
|
+
if output_format == "json":
|
|
374
376
|
print_json_for(instance_env)
|
|
375
377
|
else:
|
|
376
378
|
for key, value in sorted(instance_env.items()):
|
|
@@ -379,8 +381,8 @@ def env(instance: system.Instance, output_format: OutputFormat) -> None:
|
|
|
379
381
|
|
|
380
382
|
@cli.command("logs")
|
|
381
383
|
@click.option("--follow/--no-follow", "-f/", default=False, help="Follow log output.")
|
|
382
|
-
@
|
|
383
|
-
def logs(instance: system.
|
|
384
|
+
@postgresql_instance_identifier(nargs=1)
|
|
385
|
+
def logs(instance: system.PostgreSQLInstance, follow: bool) -> None:
|
|
384
386
|
"""Output PostgreSQL logs of INSTANCE.
|
|
385
387
|
|
|
386
388
|
This assumes that the PostgreSQL instance is configured to use file-based
|
|
@@ -400,7 +402,7 @@ def logs(instance: system.Instance, follow: bool) -> None:
|
|
|
400
402
|
|
|
401
403
|
|
|
402
404
|
@cli.command("privileges")
|
|
403
|
-
@
|
|
405
|
+
@postgresql_instance_identifier(nargs=1)
|
|
404
406
|
@click.option(
|
|
405
407
|
"-d",
|
|
406
408
|
"--database",
|
|
@@ -413,11 +415,11 @@ def logs(instance: system.Instance, follow: bool) -> None:
|
|
|
413
415
|
@output_format_option
|
|
414
416
|
@async_command
|
|
415
417
|
async def list_privileges(
|
|
416
|
-
instance: system.
|
|
418
|
+
instance: system.PostgreSQLInstance,
|
|
417
419
|
databases: Sequence[str],
|
|
418
420
|
roles: Sequence[str],
|
|
419
421
|
defaults: bool,
|
|
420
|
-
output_format: OutputFormat,
|
|
422
|
+
output_format: OutputFormat | None,
|
|
421
423
|
) -> None:
|
|
422
424
|
"""List privileges on INSTANCE's databases."""
|
|
423
425
|
async with postgresql.running(instance):
|
|
@@ -427,7 +429,7 @@ async def list_privileges(
|
|
|
427
429
|
)
|
|
428
430
|
except ValueError as e:
|
|
429
431
|
raise click.ClickException(str(e)) from None
|
|
430
|
-
if output_format ==
|
|
432
|
+
if output_format == "json":
|
|
431
433
|
print_json_for([model_dump(p) for p in prvlgs])
|
|
432
434
|
else:
|
|
433
435
|
if defaults:
|
|
@@ -455,8 +457,9 @@ async def list_privileges(
|
|
|
455
457
|
"--jobs",
|
|
456
458
|
required=False,
|
|
457
459
|
type=click.INT,
|
|
458
|
-
help="Number of simultaneous processes or threads to use (from pg_upgrade).",
|
|
460
|
+
help="Number of simultaneous processes or threads to use (from pg_upgrade). Deprecated. Use extra options instead.",
|
|
459
461
|
)
|
|
462
|
+
@click.argument("extra_opts", nargs=-1, type=click.UNPROCESSED)
|
|
460
463
|
@click.pass_obj
|
|
461
464
|
@async_command
|
|
462
465
|
async def upgrade(
|
|
@@ -466,12 +469,23 @@ async def upgrade(
|
|
|
466
469
|
newname: str | None,
|
|
467
470
|
port: int | None,
|
|
468
471
|
jobs: int | None,
|
|
472
|
+
extra_opts: tuple[str, ...],
|
|
469
473
|
) -> None:
|
|
470
|
-
"""Upgrade INSTANCE using pg_upgrade
|
|
474
|
+
"""Upgrade INSTANCE using pg_upgrade
|
|
475
|
+
|
|
476
|
+
Extra options can be passed to the pg_upgrade command. They may need to be prefixed
|
|
477
|
+
with -- to separate them from the current command options when confusion arises. When using
|
|
478
|
+
extra options, providing the instance identifier is required.
|
|
479
|
+
"""
|
|
471
480
|
with obj.lock, audit():
|
|
472
|
-
await postgresql.check_status(instance, Status.not_running)
|
|
481
|
+
await postgresql.check_status(instance.postgresql, Status.not_running)
|
|
473
482
|
async with task.async_transaction():
|
|
474
483
|
new_instance = await instances.upgrade(
|
|
475
|
-
instance,
|
|
484
|
+
instance,
|
|
485
|
+
version=newversion,
|
|
486
|
+
name=newname,
|
|
487
|
+
port=port,
|
|
488
|
+
jobs=jobs,
|
|
489
|
+
extra_opts=extra_opts,
|
|
476
490
|
)
|
|
477
491
|
await instances.start(new_instance)
|
|
@@ -207,7 +207,7 @@ def site_settings(
|
|
|
207
207
|
/,
|
|
208
208
|
defaults: bool | None,
|
|
209
209
|
schema: bool,
|
|
210
|
-
output_format: OutputFormat,
|
|
210
|
+
output_format: OutputFormat | None,
|
|
211
211
|
) -> None:
|
|
212
212
|
"""Show site settings.
|
|
213
213
|
|
|
@@ -227,7 +227,7 @@ def site_settings(
|
|
|
227
227
|
value = _site.SETTINGS.model_dump(
|
|
228
228
|
mode="json", exclude_defaults=defaults is False
|
|
229
229
|
)
|
|
230
|
-
if output_format ==
|
|
230
|
+
if output_format == "json":
|
|
231
231
|
console.print_json(data=value)
|
|
232
232
|
else:
|
|
233
233
|
assert output_format is None
|