@@ -127,20 +127,23 @@ def __repr__(self):
127
127
128
128
129
129
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 ):
131
131
"""
132
132
PostgresNode constructor.
133
133
134
134
Args:
135
135
name: node's application name.
136
136
port: port to accept connections.
137
137
base_dir: path to node's data directory.
138
+ bin_dir: path to node's binary directory.
138
139
"""
139
140
140
141
# private
141
- self ._pg_version = PgVer (get_pg_version ())
142
+ self ._pg_version = PgVer (get_pg_version (bin_dir ))
142
143
self ._should_free_port = port is None
143
144
self ._base_dir = base_dir
145
+ self ._bin_dir = bin_dir
146
+ self ._prefix = prefix
144
147
self ._logger = None
145
148
self ._master = None
146
149
@@ -281,14 +284,20 @@ def master(self):
281
284
@property
282
285
def base_dir (self ):
283
286
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 )
285
288
286
289
# NOTE: it's safe to create a new dir
287
290
if not self .os_ops .path_exists (self ._base_dir ):
288
291
self .os_ops .makedirs (self ._base_dir )
289
292
290
293
return self ._base_dir
291
294
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
+
292
301
@property
293
302
def logs_dir (self ):
294
303
path = os .path .join (self .base_dir , LOGS_DIR )
@@ -441,7 +450,7 @@ def _collect_special_files(self):
441
450
442
451
return result
443
452
444
- def init (self , initdb_params = None , ** kwargs ):
453
+ def init (self , initdb_params = None , cached = True , ** kwargs ):
445
454
"""
446
455
Perform initdb for this node.
447
456
@@ -460,7 +469,9 @@ def init(self, initdb_params=None, **kwargs):
460
469
data_dir = self .data_dir ,
461
470
logfile = self .utils_log_file ,
462
471
os_ops = self .os_ops ,
463
- params = initdb_params )
472
+ params = initdb_params ,
473
+ bin_path = self .bin_dir ,
474
+ cached = False )
464
475
465
476
# initialize default config files
466
477
self .default_conf (** kwargs )
@@ -619,7 +630,7 @@ def status(self):
619
630
620
631
try :
621
632
_params = [
622
- get_bin_path ( " pg_ctl" ),
633
+ self . _get_bin_path ( ' pg_ctl' ),
623
634
"-D" , self .data_dir ,
624
635
"status"
625
636
] # yapf: disable
@@ -645,7 +656,7 @@ def get_control_data(self):
645
656
"""
646
657
647
658
# this one is tricky (blame PG 9.4)
648
- _params = [get_bin_path ("pg_controldata" )]
659
+ _params = [self . _get_bin_path ("pg_controldata" )]
649
660
_params += ["-D" ] if self ._pg_version >= PgVer ('9.5' ) else []
650
661
_params += [self .data_dir ]
651
662
@@ -708,7 +719,7 @@ def start(self, params=[], wait=True):
708
719
return self
709
720
710
721
_params = [
711
- get_bin_path ("pg_ctl" ),
722
+ self . _get_bin_path ("pg_ctl" ),
712
723
"-D" , self .data_dir ,
713
724
"-l" , self .pg_log_file ,
714
725
"-w" if wait else '-W' , # --wait or --no-wait
@@ -742,7 +753,7 @@ def stop(self, params=[], wait=True):
742
753
return self
743
754
744
755
_params = [
745
- get_bin_path ("pg_ctl" ),
756
+ self . _get_bin_path ("pg_ctl" ),
746
757
"-D" , self .data_dir ,
747
758
"-w" if wait else '-W' , # --wait or --no-wait
748
759
"stop"
@@ -782,7 +793,7 @@ def restart(self, params=[]):
782
793
"""
783
794
784
795
_params = [
785
- get_bin_path ("pg_ctl" ),
796
+ self . _get_bin_path ("pg_ctl" ),
786
797
"-D" , self .data_dir ,
787
798
"-l" , self .pg_log_file ,
788
799
"-w" , # wait
@@ -814,7 +825,7 @@ def reload(self, params=[]):
814
825
"""
815
826
816
827
_params = [
817
- get_bin_path ("pg_ctl" ),
828
+ self . _get_bin_path ("pg_ctl" ),
818
829
"-D" , self .data_dir ,
819
830
"reload"
820
831
] + params # yapf: disable
@@ -835,7 +846,7 @@ def promote(self, dbname=None, username=None):
835
846
"""
836
847
837
848
_params = [
838
- get_bin_path ("pg_ctl" ),
849
+ self . _get_bin_path ("pg_ctl" ),
839
850
"-D" , self .data_dir ,
840
851
"-w" , # wait
841
852
"promote"
@@ -871,7 +882,7 @@ def pg_ctl(self, params):
871
882
"""
872
883
873
884
_params = [
874
- get_bin_path ("pg_ctl" ),
885
+ self . _get_bin_path ("pg_ctl" ),
875
886
"-D" , self .data_dir ,
876
887
"-w" # wait
877
888
] + params # yapf: disable
@@ -945,7 +956,7 @@ def psql(self,
945
956
username = username or default_username ()
946
957
947
958
psql_params = [
948
- get_bin_path ("psql" ),
959
+ self . _get_bin_path ("psql" ),
949
960
"-p" , str (self .port ),
950
961
"-h" , self .host ,
951
962
"-U" , username ,
@@ -1066,7 +1077,7 @@ def tmpfile():
1066
1077
filename = filename or tmpfile ()
1067
1078
1068
1079
_params = [
1069
- get_bin_path ("pg_dump" ),
1080
+ self . _get_bin_path ("pg_dump" ),
1070
1081
"-p" , str (self .port ),
1071
1082
"-h" , self .host ,
1072
1083
"-f" , filename ,
@@ -1094,7 +1105,7 @@ def restore(self, filename, dbname=None, username=None):
1094
1105
username = username or default_username ()
1095
1106
1096
1107
_params = [
1097
- get_bin_path ("pg_restore" ),
1108
+ self . _get_bin_path ("pg_restore" ),
1098
1109
"-p" , str (self .port ),
1099
1110
"-h" , self .host ,
1100
1111
"-U" , username ,
@@ -1364,7 +1375,7 @@ def pgbench(self,
1364
1375
username = username or default_username ()
1365
1376
1366
1377
_params = [
1367
- get_bin_path ("pgbench" ),
1378
+ self . _get_bin_path ("pgbench" ),
1368
1379
"-p" , str (self .port ),
1369
1380
"-h" , self .host ,
1370
1381
"-U" , username ,
@@ -1416,7 +1427,7 @@ def pgbench_run(self, dbname=None, username=None, options=[], **kwargs):
1416
1427
username = username or default_username ()
1417
1428
1418
1429
_params = [
1419
- get_bin_path ("pgbench" ),
1430
+ self . _get_bin_path ("pgbench" ),
1420
1431
"-p" , str (self .port ),
1421
1432
"-h" , self .host ,
1422
1433
"-U" , username ,
@@ -1587,6 +1598,43 @@ def set_auto_conf(self, options, config='postgresql.auto.conf', rm_options={}):
1587
1598
1588
1599
self .os_ops .write (path , auto_conf , truncate = True )
1589
1600
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
+
1590
1638
1591
1639
class NodeApp :
1592
1640
0 commit comments