1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
import os
import shutil
import time
from multiprocessing import cpu_count, Process, Queue
from subprocess import call, STDOUT
from tempfile import TemporaryFile
from utils.logging import log
class PgCluster(object):
'basic manipulation of postgres cluster (init, start, stop, destroy)'
def __init__(self, outdir, bin_path, data_path):
self._outdir = outdir
self._bin = bin_path
self._data = data_path
self._env = os.environ
self._env['PATH'] = ':'.join([bin_path, self._env['PATH']])
self._options = ""
def _initdb(self):
'initialize the data directory'
with TemporaryFile() as strout:
log("initializing cluster into '%s'" % (self._data,))
call(['pg_ctl', '-D', self._data, 'init'], env=self._env,
stdout=strout, stderr=STDOUT)
def _configure(self, config):
'build options list to use with pg_ctl'
for k in config:
self._options += ''.join([" -c ", k, "='", str(config[k]), "'"])
def _destroy(self):
"""
forced cleanup of possibly existing cluster processes and data
directory
"""
with TemporaryFile() as strout:
log("killing all existing postgres processes")
call(['killall', 'postgres'], stdout=strout, stderr=STDOUT)
# remove the data directory
if os.path.exists(self._data):
shutil.rmtree(self._data)
def start(self, config, destroy=True):
'init, configure and start the cluster'
# cleanup any previous cluster running, remove data dir if it exists
if destroy:
self._destroy()
self._initdb()
self._configure(config)
with TemporaryFile() as strout:
log("starting cluster in '%s' using '%s' binaries" %
(self._data, self._bin))
cmd = ['pg_ctl', '-D', self._data, '-l',
''.join([self._outdir, '/pg.log']), '-w']
if len(self._options) > 0:
cmd.extend(['-o', self._options])
cmd.append('start')
call(cmd, env=self._env, stdout=strout, stderr=STDOUT)
def stop(self, destroy=True):
'stop the cluster'
with TemporaryFile() as strout:
log("stopping cluster in '%s' using '%s' binaries" %
(self._data, self._bin))
call(['pg_ctl', '-D', self._data, '-w', '-t', '60', 'stop'],
env=self._env, stdout=strout, stderr=STDOUT)
# kill any remaining processes, remove the data dir
if destroy:
self._destroy()
|