55
55
# You can lookup error message and cmdline in exception object attributes
56
56
class ProbackupException (Exception ):
57
57
def __init__ (self , message , cmd ):
58
- # print message
59
- # self.message = repr(message).strip("'")
60
58
self .message = message
61
59
self .cmd = cmd
62
60
#need that to make second raise
@@ -138,24 +136,31 @@ def __init__(self, *args, **kwargs):
138
136
139
137
self .helpers_path = os .path .dirname (os .path .realpath (__file__ ))
140
138
self .dir_path = os .path .abspath (os .path .join (self .helpers_path , os .pardir ))
139
+ self .tmp_path = os .path .abspath (os .path .join (self .dir_path , 'tmp_dirs' ))
141
140
try :
142
- os .makedirs (os .path .join (self .dir_path , " tmp_dirs" ))
141
+ os .makedirs (os .path .join (self .dir_path , ' tmp_dirs' ))
143
142
except :
144
143
pass
145
144
self .probackup_path = os .path .abspath (os .path .join (
146
- self .dir_path ,
147
- "../pg_probackup"
148
- ))
145
+ self .dir_path , "../pg_probackup" ))
149
146
150
147
def arcwal_dir (self , node ):
151
148
return "%s/backup/wal" % node .base_dir
152
149
153
- def backup_dir (self , node ):
154
- return os .path .abspath ("%s/backup" % node .base_dir )
150
+ def backup_dir (self , node = None , path = None ):
151
+ if node :
152
+ return os .path .abspath ("{0}/backup" .format (node .base_dir ))
153
+ if path :
154
+ return
155
155
156
- def make_simple_node (self , base_dir = None , set_replication = False ,
157
- set_archiving = False , initdb_params = [], pg_options = {}):
158
- real_base_dir = os .path .join (self .dir_path , base_dir )
156
+ def make_simple_node (
157
+ self ,
158
+ base_dir = None ,
159
+ set_replication = False ,
160
+ initdb_params = [],
161
+ pg_options = {}):
162
+
163
+ real_base_dir = os .path .join (self .tmp_path , base_dir )
159
164
shutil .rmtree (real_base_dir , ignore_errors = True )
160
165
161
166
node = get_new_node ('test' , base_dir = real_base_dir )
@@ -173,9 +178,6 @@ def make_simple_node(self, base_dir=None, set_replication=False,
173
178
# Allow replication in pg_hba.conf
174
179
if set_replication :
175
180
node .set_replication_conf ()
176
- # Setup archiving for node
177
- if set_archiving :
178
- self .set_archiving_conf (node , self .arcwal_dir (node ))
179
181
return node
180
182
181
183
def create_tblspace_in_node (self , node , tblspc_name , cfs = False ):
@@ -301,6 +303,7 @@ def check_ptrack_clean(self, idx_dict, size):
301
303
def run_pb (self , command , async = False ):
302
304
try :
303
305
self .cmd = [' ' .join (map (str ,[self .probackup_path ] + command ))]
306
+ print self .cmd
304
307
if async is True :
305
308
return subprocess .Popen (
306
309
[self .probackup_path ] + command ,
@@ -319,44 +322,55 @@ def run_pb(self, command, async=False):
319
322
for line in self .output .splitlines ():
320
323
if 'INFO: Backup' and 'completed' in line :
321
324
return line .split ()[2 ]
322
- # backup_id = line.split()[2]
323
- # return {'cmd': cmd, 'output': output, 'backup_id': backup_id}
324
325
else :
325
326
return self .output
326
- # return {'cmd': cmd, 'output': output}
327
327
except subprocess .CalledProcessError as e :
328
- raise ProbackupException (e .output , e .cmd )
328
+ raise ProbackupException (e .output , self .cmd )
329
329
330
- def init_pb (self , node ):
330
+ def init_pb (self , backup_dir ):
331
331
332
332
return self .run_pb ([
333
333
"init" ,
334
- "-B" , self .backup_dir (node ),
334
+ "-B" , backup_dir
335
+ ])
336
+
337
+ def add_instance (self , backup_dir , instance , node ):
338
+
339
+ return self .run_pb ([
340
+ "add-instance" ,
341
+ "--instance={0}" .format (instance ),
342
+ "-B" , backup_dir ,
343
+ "-D" , node .data_dir
344
+ ])
345
+
346
+ def del_instance (self , backup_dir , instance , node ):
347
+
348
+ return self .run_pb ([
349
+ "del-instance" ,
350
+ "--instance={0}" .format (instance ),
351
+ "-B" , backup_dir ,
335
352
"-D" , node .data_dir
336
353
])
337
354
338
355
def clean_pb (self , node ):
339
356
shutil .rmtree (self .backup_dir (node ), ignore_errors = True )
340
357
341
- def backup_pb (self , node = None , data_dir = None , backup_dir = None , backup_type = "full" , options = [], async = False ):
342
- if data_dir is None :
343
- data_dir = node .data_dir
344
- if backup_dir is None :
345
- backup_dir = self .backup_dir (node )
358
+ def backup_node (self , backup_dir , instance , node , backup_type = "full" , options = [], async = False ):
346
359
347
360
cmd_list = [
348
361
"backup" ,
349
362
"-B" , backup_dir ,
350
- "-D" , data_dir ,
363
+ "-D" , node . data_dir ,
351
364
"-p" , "%i" % node .port ,
352
- "-d" , "postgres"
365
+ "-d" , "postgres" ,
366
+ "--instance={0}" .format (instance )
353
367
]
354
368
if backup_type :
355
369
cmd_list += ["-b" , backup_type ]
356
370
357
371
return self .run_pb (cmd_list + options , async )
358
372
359
- def restore_pb (self , node = None , backup_dir = None , data_dir = None , id = None , options = []):
373
+ def restore_node (self , backup_dir , instance , data_dir = None , id = None , options = []):
360
374
if data_dir is None :
361
375
data_dir = node .data_dir
362
376
if backup_dir is None :
@@ -365,30 +379,35 @@ def restore_pb(self, node=None, backup_dir=None, data_dir=None, id=None, options
365
379
cmd_list = [
366
380
"restore" ,
367
381
"-B" , backup_dir ,
368
- "-D" , data_dir
382
+ "-D" , data_dir ,
383
+ "--instance={0}" .format (instance )
369
384
]
370
385
if id :
371
386
cmd_list += ["-i" , id ]
372
387
373
388
return self .run_pb (cmd_list + options )
374
389
375
- def show_pb (self , node , id = None , options = [], as_text = False ):
390
+ def show_pb (self , backup_dir , instance = None , backup_id = None , options = [], as_text = False ):
391
+
376
392
backup_list = []
377
393
specific_record = {}
378
394
cmd_list = [
379
395
"show" ,
380
- "-B" , self . backup_dir ( node ) ,
396
+ "-B" , backup_dir ,
381
397
]
382
- if id :
383
- cmd_list += ["-i" , id ]
398
+ if instance :
399
+ cmd_list += ["--instance={0}" .format (instance )]
400
+
401
+ if backup_id :
402
+ cmd_list += ["-i" , backup_id ]
384
403
385
404
if as_text :
386
405
# You should print it when calling as_text=true
387
406
return self .run_pb (cmd_list + options )
388
407
389
408
# get show result as list of lines
390
409
show_splitted = self .run_pb (cmd_list + options ).splitlines ()
391
- if id is None :
410
+ if instance is not None and backup_id is None :
392
411
# cut header(ID, Mode, etc) from show as single string
393
412
header = show_splitted [1 :2 ][0 ]
394
413
# cut backup records from show as single list with string for every backup record
@@ -430,36 +449,40 @@ def show_pb(self, node, id=None, options=[], as_text=False):
430
449
specific_record [name .strip ()] = var
431
450
return specific_record
432
451
433
- def validate_pb (self , node , id = None , options = []):
452
+ def validate_pb (self , backup_dir , instance = None , id = None , options = []):
453
+
434
454
cmd_list = [
435
455
"validate" ,
436
- "-B" , self . backup_dir ( node ) ,
456
+ "-B" , backup_dir ,
437
457
]
458
+ if instance :
459
+ cmd_list += ["--instance={0}" .format (instance )]
438
460
if id :
439
461
cmd_list += ["-i" , id ]
440
462
441
- # print(cmd_list)
442
463
return self .run_pb (cmd_list + options )
443
464
444
- def delete_pb (self , node , id = None , options = []):
465
+ def delete_pb (self , backup_dir , instance = None , id = None , options = []):
445
466
cmd_list = [
446
467
"delete" ,
447
468
"-B" , self .backup_dir (node ),
448
469
]
470
+ if instance :
471
+ cmd_list += ["--instance={0}" .format (instance )]
449
472
if id :
450
473
cmd_list += ["-i" , id ]
451
474
452
475
# print(cmd_list)
453
476
return self .run_pb (cmd_list + options )
454
477
455
- def delete_expired (self , node , options = []):
478
+ def delete_expired (self , backup_dir , instance = None , options = []):
456
479
cmd_list = [
457
480
"delete" , "--expired" ,
458
481
"-B" , self .backup_dir (node ),
459
482
]
460
483
return self .run_pb (cmd_list + options )
461
484
462
- def show_config (self , node ):
485
+ def show_config (self , backup_dir , instance = None ):
463
486
out_dict = {}
464
487
cmd_list = [
465
488
"show-config" ,
@@ -484,9 +507,7 @@ def get_recovery_conf(self, node):
484
507
out_dict [key .strip ()] = value .strip (" '" ).replace ("'\n " , "" )
485
508
return out_dict
486
509
487
- def set_archiving_conf (self , node , archive_dir = False , replica = False ):
488
- if not archive_dir :
489
- archive_dir = self .arcwal_dir (node )
510
+ def set_archiving (self , backup_dir , instance , node , replica = False ):
490
511
491
512
if replica :
492
513
archive_mode = 'always'
@@ -505,8 +526,8 @@ def set_archiving_conf(self, node, archive_dir=False, replica=False):
505
526
if os .name == 'posix' :
506
527
node .append_conf (
507
528
"postgresql.auto.conf" ,
508
- "archive_command = 'test ! -f {0}/%f && cp %p {0}/ %f'" .format (archive_dir )
509
- )
529
+ "archive_command = '{0} archive-push -B {1} --instance={2} --wal-file-path %p --wal-file-name %f'" .format (
530
+ self . probackup_path , backup_dir , instance ) )
510
531
#elif os.name == 'nt':
511
532
# node.append_conf(
512
533
# "postgresql.auto.conf",
0 commit comments