pglift-cli 2.5.0__tar.gz → 2.6.1__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.
Files changed (49) hide show
  1. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/PKG-INFO +2 -1
  2. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/pyproject.toml +1 -0
  3. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/pytest.ini +1 -0
  4. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/base.py +1 -0
  5. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/database.py +1 -1
  6. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/instance.py +1 -1
  7. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/model.py +1 -1
  8. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/pgconf.py +8 -6
  9. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/role.py +1 -1
  10. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/util.py +2 -3
  11. pglift_cli-2.6.1/src/pglift_cli/wal.py +49 -0
  12. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-cli-walkthrough.t +10 -0
  13. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-help.t +19 -0
  14. pglift_cli-2.6.1/tests/expect/test-standby.t +121 -0
  15. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/test_cli.py +1 -1
  16. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/.gitignore +0 -0
  17. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/README.md +0 -0
  18. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/hatch.toml +0 -0
  19. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/__init__.py +0 -0
  20. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/__main__.py +0 -0
  21. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/_settings.py +0 -0
  22. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/_site.py +0 -0
  23. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/console.py +0 -0
  24. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/hookspecs.py +0 -0
  25. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/main.py +0 -0
  26. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/patroni.py +0 -0
  27. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/pgbackrest/__init__.py +0 -0
  28. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/pgbackrest/repo_path.py +0 -0
  29. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/pghba.py +0 -0
  30. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/pm.py +0 -0
  31. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/postgres.py +0 -0
  32. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/prometheus.py +0 -0
  33. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/src/pglift_cli/py.typed +0 -0
  34. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/.gitignore +0 -0
  35. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-base.t +0 -0
  36. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-demote.t +0 -0
  37. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-port-validation.t +0 -0
  38. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-prometheus.t +0 -0
  39. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-standby-pgbackrest.t +0 -0
  40. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-transactions.t +0 -0
  41. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/expect/test-upgrade.t +0 -0
  42. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/__init__.py +0 -0
  43. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/conftest.py +0 -0
  44. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/test__site.py +0 -0
  45. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/test_audit.py +0 -0
  46. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/test_main.py +0 -0
  47. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/test_model.py +0 -0
  48. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/test_pm.py +0 -0
  49. {pglift_cli-2.5.0 → pglift_cli-2.6.1}/tests/unit/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pglift_cli
3
- Version: 2.5.0
3
+ Version: 2.6.1
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/
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
22
23
  Classifier: Topic :: Database
23
24
  Classifier: Topic :: System :: Systems Administration
24
25
  Classifier: Typing :: Typed
@@ -32,6 +32,7 @@ classifiers = [
32
32
  "Programming Language :: Python :: 3.11",
33
33
  "Programming Language :: Python :: 3.12",
34
34
  "Programming Language :: Python :: 3.13",
35
+ "Programming Language :: Python :: 3.14",
35
36
  "Programming Language :: Python :: 3 :: Only",
36
37
  "Typing :: Typed",
37
38
  ]
@@ -7,4 +7,5 @@ addopts = --strict-config --strict-markers
7
7
  filterwarnings =
8
8
  error
9
9
  ignore:cannot guess 'postgresql.versions' setting as 'bindir' is unset:RuntimeWarning
10
+ ignore:'asyncio.iscoroutinefunction':DeprecationWarning
10
11
  testpaths = tests/unit
@@ -27,6 +27,7 @@ class CLIGroup(click.Group):
27
27
  "database",
28
28
  "postgres",
29
29
  "pghba",
30
+ "wal",
30
31
  ]
31
32
 
32
33
  @classmethod
@@ -12,10 +12,10 @@ from typing import Any
12
12
  import click
13
13
  import psycopg
14
14
  from attrs import asdict
15
- from pydantic.v1.utils import deep_update
16
15
 
17
16
  from pglift import databases, diff, postgresql, privileges, task
18
17
  from pglift.models import PostgreSQLInstance, interface
18
+ from pglift.util import deep_update
19
19
 
20
20
  from . import model
21
21
  from .util import (
@@ -10,7 +10,6 @@ from functools import partial
10
10
  from typing import Any
11
11
 
12
12
  import click
13
- from pydantic.v1.utils import deep_update
14
13
 
15
14
  from pglift import (
16
15
  async_hooks,
@@ -31,6 +30,7 @@ from pglift.settings import (
31
30
  default_postgresql_version,
32
31
  )
33
32
  from pglift.types import Operation, Status, validation_context
33
+ from pglift.util import deep_update
34
34
 
35
35
  from . import _site, model
36
36
  from . import hookspecs as h
@@ -16,7 +16,6 @@ from typing import Any, ClassVar, TypeVar
16
16
  import click
17
17
  import pydantic
18
18
  from pydantic.fields import FieldInfo
19
- from pydantic.v1.utils import deep_update, lenient_issubclass
20
19
  from pydantic_core import ErrorDetails
21
20
 
22
21
  from pglift.annotations import cli
@@ -28,6 +27,7 @@ from pglift.types import (
28
27
  field_annotation,
29
28
  validation_context,
30
29
  )
30
+ from pglift.util import deep_update, lenient_issubclass
31
31
 
32
32
  from . import _site, logger
33
33
 
@@ -8,7 +8,7 @@ from collections.abc import Iterable
8
8
  from typing import Any
9
9
 
10
10
  import click
11
- import pgtoolkit.conf
11
+ import pgtoolkit.conf as pgconf
12
12
 
13
13
  from pglift import instances, manager, postgresql
14
14
  from pglift.models import Instance, PostgreSQLInstance
@@ -108,7 +108,7 @@ async def set_(
108
108
  pg_instance = instance.postgresql
109
109
  with obj.lock, audit(dry_run=dry_run), system_configure(dry_run=dry_run):
110
110
  status = await postgresql.status(pg_instance)
111
- manifest = await instances._get(instance, status)
111
+ manifest = await instances._get(instance, status, port_from_config=True)
112
112
  manifest.settings.update(parameters)
113
113
  with manager.from_instance(pg_instance):
114
114
  r = await instances.configure(
@@ -130,7 +130,7 @@ async def remove(
130
130
  pg_instance = instance.postgresql
131
131
  with obj.lock, audit(dry_run=dry_run), system_configure(dry_run=dry_run):
132
132
  status = await postgresql.status(pg_instance)
133
- manifest = await instances._get(instance, status)
133
+ manifest = await instances._get(instance, status, port_from_config=True)
134
134
  for p in parameters:
135
135
  try:
136
136
  del manifest.settings[p]
@@ -154,15 +154,17 @@ async def edit(obj: Obj, instance: Instance) -> None:
154
154
  pg_instance = instance.postgresql
155
155
  with obj.lock, audit():
156
156
  with manager.from_instance(pg_instance):
157
- actual_config = await instances.postgresql_editable_conf(pg_instance)
157
+ actual_config = "".join(
158
+ (await instances.postgresql_editable_conf(pg_instance)).lines
159
+ )
158
160
  edited = click.edit(text=actual_config)
159
161
  if edited is None:
160
162
  click.echo("no change", err=True)
161
163
  return
162
- config = pgtoolkit.conf.parse_string(edited)
164
+ config = pgconf.parse_string(edited)
163
165
  values = config.as_dict()
164
166
  status = await postgresql.status(pg_instance)
165
- manifest = await instances._get(instance, status)
167
+ manifest = await instances._get(instance, status, port_from_config=True)
166
168
  manifest.settings.clear()
167
169
  manifest.settings.update(values)
168
170
  with manager.from_instance(pg_instance):
@@ -9,11 +9,11 @@ from functools import partial
9
9
  from typing import Any
10
10
 
11
11
  import click
12
- from pydantic.v1.utils import deep_update
13
12
 
14
13
  from pglift import diff, manager, postgresql, privileges, profiles, roles
15
14
  from pglift.models import PostgreSQLInstance, interface
16
15
  from pglift.types import Operation, validation_context
16
+ from pglift.util import deep_update
17
17
 
18
18
  from . import _site, model
19
19
  from .util import (
@@ -600,9 +600,8 @@ def command_logging() -> Iterator[None]:
600
600
  exception will propagate to stderr.
601
601
  """
602
602
  logfilename = f"{time.time()}.log"
603
- logfile = Path(
604
- tempfile.NamedTemporaryFile(prefix="pglift-", suffix="-" + logfilename).name
605
- )
603
+ with tempfile.NamedTemporaryFile(prefix="pglift-", suffix="-" + logfilename) as tmp:
604
+ logfile = Path(tmp.name)
606
605
  logger.debug("debug logging at %s", logfile)
607
606
  handler = logging.FileHandler(logfile)
608
607
  formatter = logging.Formatter(
@@ -0,0 +1,49 @@
1
+ # SPDX-FileCopyrightText: 2025 Dalibo
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Any
8
+
9
+ import click
10
+
11
+ from pglift import instances, manager
12
+ from pglift.models import PostgreSQLInstance
13
+
14
+ from .util import (
15
+ Group,
16
+ Obj,
17
+ async_command,
18
+ audit,
19
+ instance_identifier_option,
20
+ pass_postgresql_instance,
21
+ )
22
+
23
+
24
+ @click.group(cls=Group)
25
+ @instance_identifier_option
26
+ def cli(**kwargs: Any) -> None:
27
+ """Manage WAL replay of a PostgreSQL instance."""
28
+
29
+
30
+ @cli.command("pause-replay")
31
+ @pass_postgresql_instance
32
+ @click.pass_obj
33
+ @async_command
34
+ async def pause_wal_replay(obj: Obj, instance: PostgreSQLInstance) -> None:
35
+ """Pause WAL replay on PostgreSQL standby INSTANCE"""
36
+ with obj.lock, audit():
37
+ with manager.from_instance(instance):
38
+ await instances.pause_wal_replay(instance)
39
+
40
+
41
+ @cli.command("resume-replay")
42
+ @pass_postgresql_instance
43
+ @click.pass_obj
44
+ @async_command
45
+ async def resume_wal_replay(obj: Obj, instance: PostgreSQLInstance) -> None:
46
+ """Resume WAL replay on PostgreSQL standby INSTANCE"""
47
+ with obj.lock, audit():
48
+ with manager.from_instance(instance):
49
+ await instances.resume_wal_replay(instance)
@@ -152,6 +152,14 @@ Create an instance
152
152
  INFO creating instance dumps directory: \$TMPDIR\/srv\/dumps\/1\d-main (re)
153
153
  INFO starting Prometheus postgres_exporter 1\d-main (re)
154
154
 
155
+ Try editing a parameter that already has a value defined in the pgbackrest template:
156
+
157
+ $ pglift pgconf set wal_level='logical'
158
+ INFO configuring PostgreSQL
159
+ INFO parameter 'wal_level' is overwritten by 'pgbackrest' configuration, 'replica' will be used instead of 'logical'
160
+ changes in 'wal_level' not applied
161
+ hint: either these changes have no effect (values already set) or specified parameters are already defined in an un-managed file (e.g. 'postgresql.conf')
162
+
155
163
  Error cases for instance operations
156
164
 
157
165
  $ pglift instance create main --pgbackrest-stanza=st --surole-password=s3per
@@ -200,6 +208,8 @@ Error cases for instance operations
200
208
  INFO - pglift_cli.audit - command completed \(\d+(\.\d+)? seconds\) (re)
201
209
  INFO - pglift_cli.audit - command: .*\/pglift --non-interactive instance create main --data-checksums --auth-host=ident --port=\d+ --surole-password=s3per --pgbackrest-stanza=main '--pgbackrest-password=b@ck up!' --prometheus-port=\d+ (re)
202
210
  INFO - pglift_cli.audit - command completed \(\d+(\.\d+)? seconds\) (re)
211
+ INFO - pglift_cli.audit - command: .*\/pglift --non-interactive pgconf set wal_level=logical (re)
212
+ INFO - pglift_cli.audit - command completed \(\d+(\.\d+)? seconds\) (re)
203
213
  INFO - pglift_cli.audit - command: .*\/pglift --non-interactive instance create main --pgbackrest-stanza=st --surole-password=s3per (re)
204
214
  ERROR - pglift_cli.audit - command failed \(\d+(\.\d+)? seconds\) (re)
205
215
 
@@ -96,6 +96,7 @@ Site settings
96
96
  role Manage roles.
97
97
  database Manage databases.
98
98
  pghba Manage entries in HBA configuration of a PostgreSQL...
99
+ wal Manage WAL replay of a PostgreSQL instance.
99
100
  patroni Handle Patroni service for an instance.
100
101
  postgres_exporter Handle Prometheus postgres_exporter
101
102
 
@@ -1066,3 +1067,21 @@ Patroni commands:
1066
1067
  Options:
1067
1068
  --help Show this message and exit.
1068
1069
 
1070
+ WAL commands
1071
+
1072
+ $ pglift wal --help
1073
+ Usage: pglift wal [OPTIONS] COMMAND [ARGS]...
1074
+
1075
+ Manage WAL replay of a PostgreSQL instance.
1076
+
1077
+ Options:
1078
+ -i, --instance <version>/<name>
1079
+ Instance identifier; the <version>/ prefix
1080
+ may be omitted if there's only one instance
1081
+ matching <name>. Required if there is more
1082
+ than one instance on system.
1083
+ --help Show this message and exit.
1084
+
1085
+ Commands:
1086
+ pause-replay Pause WAL replay on PostgreSQL standby INSTANCE
1087
+ resume-replay Resume WAL replay on PostgreSQL standby INSTANCE
@@ -0,0 +1,121 @@
1
+ # SPDX-FileCopyrightText: 2025 Dalibo
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+
5
+ Site settings and configuration
6
+
7
+ $ PASSWORDS=$TMPDIR/passwords.json
8
+ $ cat > $PASSWORDS << 'EOF'
9
+ > {
10
+ > "postgres": "s3per",
11
+ > "replication": "r3pl"
12
+ > }
13
+ > EOF
14
+
15
+ $ export PGLIFT_CLI__LOG_FORMAT="%(levelname)-4s %(message)s"
16
+ $ export PGLIFT_POSTGRESQL__AUTH__LOCAL=md5
17
+ $ export PGLIFT_POSTGRESQL__AUTH__PASSFILE=null
18
+ $ export PGLIFT_POSTGRESQL__AUTH__PASSWORD_COMMAND='["jq", "-r", ".{role}", "'$PASSWORDS'"]'
19
+ $ export PGLIFT_POSTGRESQL__REPLROLE=replication
20
+
21
+ $ export PGLIFT_CONFIG_DIR="$TMPDIR/$TESTFILE.conf.d"
22
+ $ mkdir -p $PGLIFT_CONFIG_DIR/postgresql
23
+ $ cat > $PGLIFT_CONFIG_DIR/postgresql/pg_hba.conf << 'EOF'
24
+ > local all {surole} {auth.local}
25
+ > local all all {auth.local}
26
+ > host all all 127.0.0.1/32 {auth.host}
27
+ > host all all ::1/128 {auth.host}
28
+ > local replication all {auth.local}
29
+ > host replication {replrole} 127.0.0.1/32 {auth.host}
30
+ > host replication {replrole} ::1/128 {auth.host}
31
+ > EOF
32
+
33
+ $ PREFIX1=$TMPDIR/primary
34
+ $ PREFIX2=$TMPDIR/secondary
35
+ $ RUN_PREFIX1=$PREFIX1/run
36
+ $ RUN_PREFIX2=$PREFIX2/run
37
+ $ PG1PORT=$(port-for pg1)
38
+ $ PG2PORT=$(port-for pg2)
39
+ $ alias pglift1="env PGLIFT_PREFIX=$PREFIX1 PGLIFT_RUN_PREFIX=$RUN_PREFIX1 pglift --log-level=INFO --non-interactive"
40
+ $ alias pglift2="env PGLIFT_PREFIX=$PREFIX2 PGLIFT_RUN_PREFIX=$RUN_PREFIX2 pglift --log-level=INFO --non-interactive"
41
+
42
+ $ pglift1 site-configure install
43
+ INFO creating PostgreSQL log directory: $TMPDIR/primary/log/postgresql
44
+ $ pglift2 site-configure install
45
+ INFO creating PostgreSQL log directory: $TMPDIR/secondary/log/postgresql
46
+
47
+ (Cleanup steps)
48
+
49
+ $ trap "
50
+ > pglift1 instance drop; \
51
+ > pglift2 instance drop; \
52
+ > pglift1 site-configure uninstall; \
53
+ > pglift2 site-configure uninstall; \
54
+ > port-for -u pg1; port-for -u pg2" \
55
+ > EXIT
56
+
57
+ Create a primary instance
58
+
59
+ $ cat > $TMPDIR/primary.yaml <<EOF
60
+ > name: pg1
61
+ > port: $PG1PORT
62
+ > surole_password: s3per
63
+ > replrole_password: r3pl
64
+ > data_checksums: true
65
+ > EOF
66
+ $ pglift1 instance apply -f $TMPDIR/primary.yaml
67
+ INFO initializing PostgreSQL
68
+ INFO configuring PostgreSQL authentication
69
+ INFO configuring PostgreSQL
70
+ INFO creating PostgreSQL socket directory directory: $TMPDIR/primary/run/postgresql
71
+ INFO starting PostgreSQL 1\d\/pg1 (re)
72
+ INFO creating role 'replication'
73
+ INFO creating instance dumps directory: \$TMPDIR\/primary\/srv\/dumps\/1\d-pg1 (re)
74
+
75
+ Create a standby instance
76
+
77
+ $ pglift2 instance create pg2 \
78
+ > --data-checksums \
79
+ > --standby-for="host=$RUN_PREFIX1/postgresql port=$PG1PORT user=replication" \
80
+ > --standby-password=r3pl \
81
+ > --port=$PG2PORT \
82
+ > --surole-password=s3per
83
+ INFO initializing PostgreSQL
84
+ INFO configuring PostgreSQL authentication
85
+ INFO configuring PostgreSQL
86
+ INFO creating PostgreSQL socket directory directory: $TMPDIR/secondary/run/postgresql
87
+ INFO starting PostgreSQL 1\d\/pg2 (re)
88
+ INFO creating instance dumps directory: \$TMPDIR\/secondary\/srv\/dumps\/1\d-pg2 (re)
89
+
90
+ Show standby information and pause/resume WAL replay on secondary
91
+
92
+ $ pglift2 instance get --output-format=json | jq -r '.standby.wal_replay_pause_state'
93
+ not paused
94
+ $ pglift2 wal pause-replay
95
+ INFO pausing WAL replay
96
+ $ pglift2 instance get --output-format=json | jq -r '.standby.wal_replay_pause_state'
97
+ paused
98
+ $ pglift2 wal resume-replay
99
+ INFO resuming WAL replay
100
+
101
+ Try to pause/resume WAL replay on primary
102
+
103
+ $ pglift1 wal pause-replay
104
+ Error: 1\d\/pg1 is not a standby (re)
105
+ [1]
106
+ $ pglift1 wal resume-replay
107
+ Error: 1\d\/pg1 is not a standby (re)
108
+ [1]
109
+
110
+ (Cleanup)
111
+
112
+ INFO dropping instance 1\d\/pg1 (re)
113
+ INFO stopping PostgreSQL 1\d\/pg1 (re)
114
+ INFO deleting PostgreSQL data and WAL directories
115
+ INFO dropping instance 1\d\/pg2 (re)
116
+ INFO stopping PostgreSQL 1\d\/pg2 (re)
117
+ INFO deleting PostgreSQL data and WAL directories
118
+ INFO deleting PostgreSQL log directory
119
+ INFO deleting PostgreSQL socket directory
120
+ INFO deleting PostgreSQL log directory
121
+ INFO deleting PostgreSQL socket directory (no-eol)
@@ -494,7 +494,7 @@ def test_pgconf_edit(
494
494
  )
495
495
  assert result.exit_code == 0, result.stderr
496
496
  status.assert_awaited_once_with(pg_instance)
497
- _get.assert_awaited_once_with(instance, Status.running)
497
+ _get.assert_awaited_once_with(instance, Status.running, port_from_config=True)
498
498
  edit.assert_called_once_with(text=postgresql_conf)
499
499
  assert manifest.settings == {"bonjour": "bonsoir"}
500
500
  configure.assert_awaited_once_with(pg_instance, manifest, _is_running=True)
File without changes
File without changes
File without changes