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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
import os
import shutil
from multiprocessing import cpu_count
from subprocess import call, STDOUT
from tempfile import TemporaryFile
from utils.logging import log
class GitRepository(object):
'a simple management of a git repository / source building'
def __init__(self, url, path):
'url - repository URL, path - local directory for the clone'
self._url = url
self._path = path
def _exists(self):
'check that a local repository clone exists'
# TODO verify that the repository uses the proper upstream url
return os.path.exists(self._path)
def _clone(self):
''
log("cloning repository '%s' to '%s'" % (self._url, self._path))
with TemporaryFile() as strout:
call(['git', 'clone', self._url, self._path], stdout=strout,
stderr=STDOUT)
def _update(self):
'update an existing repository clone'
log("updating repository '%s' from '%s'" % (self._path, self._url))
# simply call git-pull and redirect stdout/stderr
# FIXME should verify that the repository uses the proper upstream url
with TemporaryFile() as strout:
call(['git', 'pull'], cwd=self._path, stdout=strout, stderr=STDOUT)
def current_branch(self):
'returns current branch'
with TemporaryFile() as strout:
call(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], cwd=self._path,
stdout=strout, stderr=STDOUT)
strout.seek(0)
return strout.read().strip()
def current_commit(self):
'returns current commit hash'
with TemporaryFile() as strout:
call(['git', 'rev-parse', 'HEAD'], cwd=self._path, stdout=strout,
stderr=STDOUT)
strout.seek(0)
return strout.read().strip()
def clone_or_update(self):
'refreshes the repository (either clone from scratch or refresh)'
if self._exists():
self._update()
else:
self._clone()
log("current branch '%s'" % (self.current_branch(),))
log("current commit '%s'" % (self.current_commit(),))
def build_and_install(self, path, remove=True):
'builds and installs the sources'
# TODO collect output of configure and make commands
if os.path.exists(path):
shutil.rmtree(path)
with TemporaryFile() as strout:
log("configuring sources in '%s' with prefix '%s'" %
(self._path, path))
call(['./configure', '--prefix', path], cwd=self._path,
stdout=strout, stderr=STDOUT)
with TemporaryFile() as strout:
log("building sources and installing into '%s'" % (path,))
# cleanup and build using multiple cpus
call(['make', '-s', 'clean'], cwd=self._path, stdout=strout,
stderr=STDOUT)
call(['make', '-s', '-j', str(cpu_count()), 'install'],
cwd=self._path, stdout=strout, stderr=STDOUT)
# Various things needs to be installed because of various changes
# changes between releases. Take a systematic approach and check
# if the directory exist, then try to install it.
items = [
'src/bin/initdb',
'src/bin/pg_ctl',
'src/bin/scripts',
'src/bin/psql',
'src/bin/pgbench',
'contrib/pgbench',
]
for item in items:
srcdir = ''.join([self._path, '/', item])
if os.path.isdir(srcdir):
call(['make', '-s', '-j', str(cpu_count()), 'install'],
cwd=srcdir, stdout=strout, stderr=STDOUT)
|