Skip to content

Commit 334bb22

Browse files
author
vshepard
committed
Add function pg_update
1 parent 79a8dc5 commit 334bb22

File tree

5 files changed

+87
-24
lines changed

5 files changed

+87
-24
lines changed

testgres/cache.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,20 @@
2222
from .operations.os_ops import OsOperations
2323

2424

25-
def cached_initdb(data_dir, logfile=None, params=None, os_ops: OsOperations = LocalOperations()):
25+
def cached_initdb(data_dir, logfile=None, params=None, os_ops: OsOperations = LocalOperations(), bin_path=None, cached=True):
2626
"""
2727
Perform initdb or use cached node files.
2828
"""
2929

3030
def call_initdb(initdb_dir, log=logfile):
3131
try:
32-
_params = [get_bin_path("initdb"), "-D", initdb_dir, "-N"]
32+
initdb_path = os.path.join(bin_path, 'initdb') if bin_path else get_bin_path("initdb")
33+
_params = [initdb_path, "-D", initdb_dir, "-N"]
3334
execute_utility(_params + (params or []), log)
3435
except ExecUtilException as e:
3536
raise_from(InitNodeException("Failed to run initdb"), e)
3637

37-
if params or not testgres_config.cache_initdb:
38+
if params or not testgres_config.cache_initdb or not cached:
3839
call_initdb(data_dir, logfile)
3940
else:
4041
# Fetch cached initdb dir

testgres/node.py

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,23 @@ def __repr__(self):
127127

128128

129129
class PostgresNode(object):
130-
def __init__(self, name=None, port=None, base_dir=None, conn_params: ConnectionParams = ConnectionParams()):
130+
def __init__(self, name=None, port=None, base_dir=None, conn_params: ConnectionParams = ConnectionParams(), bin_dir=None, prefix=None):
131131
"""
132132
PostgresNode constructor.
133133
134134
Args:
135135
name: node's application name.
136136
port: port to accept connections.
137137
base_dir: path to node's data directory.
138+
bin_dir: path to node's binary directory.
138139
"""
139140

140141
# private
141-
self._pg_version = PgVer(get_pg_version())
142+
self._pg_version = PgVer(get_pg_version(bin_dir))
142143
self._should_free_port = port is None
143144
self._base_dir = base_dir
145+
self._bin_dir = bin_dir
146+
self._prefix = prefix
144147
self._logger = None
145148
self._master = None
146149

@@ -281,14 +284,20 @@ def master(self):
281284
@property
282285
def base_dir(self):
283286
if not self._base_dir:
284-
self._base_dir = self.os_ops.mkdtemp(prefix=TMP_NODE)
287+
self._base_dir = self.os_ops.mkdtemp(prefix=self._prefix or TMP_NODE)
285288

286289
# NOTE: it's safe to create a new dir
287290
if not self.os_ops.path_exists(self._base_dir):
288291
self.os_ops.makedirs(self._base_dir)
289292

290293
return self._base_dir
291294

295+
@property
296+
def bin_dir(self):
297+
if not self._bin_dir:
298+
self._bin_dir = os.path.dirname(get_bin_path("pg_config"))
299+
return self._bin_dir
300+
292301
@property
293302
def logs_dir(self):
294303
path = os.path.join(self.base_dir, LOGS_DIR)
@@ -441,7 +450,7 @@ def _collect_special_files(self):
441450

442451
return result
443452

444-
def init(self, initdb_params=None, **kwargs):
453+
def init(self, initdb_params=None, cached=True, **kwargs):
445454
"""
446455
Perform initdb for this node.
447456
@@ -460,7 +469,9 @@ def init(self, initdb_params=None, **kwargs):
460469
data_dir=self.data_dir,
461470
logfile=self.utils_log_file,
462471
os_ops=self.os_ops,
463-
params=initdb_params)
472+
params=initdb_params,
473+
bin_path=self.bin_dir,
474+
cached=False)
464475

465476
# initialize default config files
466477
self.default_conf(**kwargs)
@@ -619,7 +630,7 @@ def status(self):
619630

620631
try:
621632
_params = [
622-
get_bin_path("pg_ctl"),
633+
self._get_bin_path('pg_ctl'),
623634
"-D", self.data_dir,
624635
"status"
625636
] # yapf: disable
@@ -645,7 +656,7 @@ def get_control_data(self):
645656
"""
646657

647658
# this one is tricky (blame PG 9.4)
648-
_params = [get_bin_path("pg_controldata")]
659+
_params = [self._get_bin_path("pg_controldata")]
649660
_params += ["-D"] if self._pg_version >= PgVer('9.5') else []
650661
_params += [self.data_dir]
651662

@@ -708,7 +719,7 @@ def start(self, params=[], wait=True):
708719
return self
709720

710721
_params = [
711-
get_bin_path("pg_ctl"),
722+
self._get_bin_path("pg_ctl"),
712723
"-D", self.data_dir,
713724
"-l", self.pg_log_file,
714725
"-w" if wait else '-W', # --wait or --no-wait
@@ -742,7 +753,7 @@ def stop(self, params=[], wait=True):
742753
return self
743754

744755
_params = [
745-
get_bin_path("pg_ctl"),
756+
self._get_bin_path("pg_ctl"),
746757
"-D", self.data_dir,
747758
"-w" if wait else '-W', # --wait or --no-wait
748759
"stop"
@@ -782,7 +793,7 @@ def restart(self, params=[]):
782793
"""
783794

784795
_params = [
785-
get_bin_path("pg_ctl"),
796+
self._get_bin_path("pg_ctl"),
786797
"-D", self.data_dir,
787798
"-l", self.pg_log_file,
788799
"-w", # wait
@@ -814,7 +825,7 @@ def reload(self, params=[]):
814825
"""
815826

816827
_params = [
817-
get_bin_path("pg_ctl"),
828+
self._get_bin_path("pg_ctl"),
818829
"-D", self.data_dir,
819830
"reload"
820831
] + params # yapf: disable
@@ -835,7 +846,7 @@ def promote(self, dbname=None, username=None):
835846
"""
836847

837848
_params = [
838-
get_bin_path("pg_ctl"),
849+
self._get_bin_path("pg_ctl"),
839850
"-D", self.data_dir,
840851
"-w", # wait
841852
"promote"
@@ -871,7 +882,7 @@ def pg_ctl(self, params):
871882
"""
872883

873884
_params = [
874-
get_bin_path("pg_ctl"),
885+
self._get_bin_path("pg_ctl"),
875886
"-D", self.data_dir,
876887
"-w" # wait
877888
] + params # yapf: disable
@@ -945,7 +956,7 @@ def psql(self,
945956
username = username or default_username()
946957

947958
psql_params = [
948-
get_bin_path("psql"),
959+
self._get_bin_path("psql"),
949960
"-p", str(self.port),
950961
"-h", self.host,
951962
"-U", username,
@@ -1066,7 +1077,7 @@ def tmpfile():
10661077
filename = filename or tmpfile()
10671078

10681079
_params = [
1069-
get_bin_path("pg_dump"),
1080+
self._get_bin_path("pg_dump"),
10701081
"-p", str(self.port),
10711082
"-h", self.host,
10721083
"-f", filename,
@@ -1094,7 +1105,7 @@ def restore(self, filename, dbname=None, username=None):
10941105
username = username or default_username()
10951106

10961107
_params = [
1097-
get_bin_path("pg_restore"),
1108+
self._get_bin_path("pg_restore"),
10981109
"-p", str(self.port),
10991110
"-h", self.host,
11001111
"-U", username,
@@ -1364,7 +1375,7 @@ def pgbench(self,
13641375
username = username or default_username()
13651376

13661377
_params = [
1367-
get_bin_path("pgbench"),
1378+
self._get_bin_path("pgbench"),
13681379
"-p", str(self.port),
13691380
"-h", self.host,
13701381
"-U", username,
@@ -1416,7 +1427,7 @@ def pgbench_run(self, dbname=None, username=None, options=[], **kwargs):
14161427
username = username or default_username()
14171428

14181429
_params = [
1419-
get_bin_path("pgbench"),
1430+
self._get_bin_path("pgbench"),
14201431
"-p", str(self.port),
14211432
"-h", self.host,
14221433
"-U", username,
@@ -1587,6 +1598,43 @@ def set_auto_conf(self, options, config='postgresql.auto.conf', rm_options={}):
15871598

15881599
self.os_ops.write(path, auto_conf, truncate=True)
15891600

1601+
def upgrade_from(self, old_node):
1602+
"""
1603+
Upgrade this node from an old node using pg_upgrade.
1604+
1605+
Args:
1606+
old_node: An instance of PostgresNode representing the old node.
1607+
"""
1608+
if not os.path.exists(old_node.data_dir):
1609+
raise Exception("Old node must be initialized")
1610+
1611+
if not os.path.exists(self.data_dir):
1612+
self.init()
1613+
1614+
pg_upgrade_binary = self._get_bin_path("pg_upgrade")
1615+
1616+
if not os.path.exists(pg_upgrade_binary):
1617+
raise Exception("pg_upgrade does not exist in the new node's binary path")
1618+
1619+
upgrade_command = [
1620+
pg_upgrade_binary,
1621+
"--old-bindir", old_node.bin_dir,
1622+
"--new-bindir", self.bin_dir,
1623+
"--old-datadir", old_node.data_dir,
1624+
"--new-datadir", self.data_dir,
1625+
"--old-port", str(old_node.port),
1626+
"--new-port", str(self.port),
1627+
]
1628+
1629+
return self.os_ops.exec_command(upgrade_command)
1630+
1631+
def _get_bin_path(self, filename):
1632+
if self.bin_dir:
1633+
bin_path = os.path.join(self.bin_dir, filename)
1634+
else:
1635+
bin_path = get_bin_path(filename)
1636+
return bin_path
1637+
15901638

15911639
class NodeApp:
15921640

testgres/operations/local_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def __init__(self, conn_params=None):
4444
def _raise_exec_exception(message, command, exit_code, output):
4545
"""Raise an ExecUtilException."""
4646
raise ExecUtilException(message=message.format(output),
47-
command=command,
47+
command=' '.join(command) if isinstance(command, list) else command,
4848
exit_code=exit_code,
4949
out=output)
5050

testgres/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,14 @@ def cache_pg_config_data(cmd):
172172
return cache_pg_config_data("pg_config")
173173

174174

175-
def get_pg_version():
175+
def get_pg_version(bin_dir=None):
176176
"""
177177
Return PostgreSQL version provided by postmaster.
178178
"""
179179

180180
# get raw version (e.g. postgres (PostgreSQL) 9.5.7)
181-
_params = [get_bin_path('postgres'), '--version']
181+
postgres_path = os.path.join(bin_dir, 'postgres') if bin_dir else get_bin_path('postgres')
182+
_params = [postgres_path, '--version']
182183
raw_ver = tconf.os_ops.exec_command(_params, encoding='utf-8')
183184

184185
# Remove "(Homebrew)" if present

tests/test_simple.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,19 @@ def test_child_process_dies(self):
10101010
# try to handle children list -- missing processes will have ptype "ProcessType.Unknown"
10111011
[ProcessProxy(p) for p in children]
10121012

1013+
def test_upgrade_node(self):
1014+
old_bin_dir = os.path.dirname(get_bin_path("pg_config"))
1015+
new_bin_dir = os.path.dirname(get_bin_path("pg_config"))
1016+
node_old = get_new_node(prefix='node_old', bin_dir=old_bin_dir)
1017+
node_old.init()
1018+
node_old.start()
1019+
node_old.stop()
1020+
node_new = get_new_node(prefix='node_new', bin_dir=new_bin_dir)
1021+
node_new.init(cached=False)
1022+
res = node_new.upgrade_from(old_node=node_old)
1023+
node_new.start()
1024+
self.assertTrue(b'Upgrade Complete' in res)
1025+
10131026

10141027
if __name__ == '__main__':
10151028
if os.environ.get('ALT_CONFIG'):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy