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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
#!/usr/bin/python
import re
import sys
import os
import tempfile
import urllib2
import subprocess
import tarfile
import shutil
import errno
# To ensure it exists on the system
import gzip
#
# Useful script for installing multiple versions of MongoDB on a machine
# Only really tested/works on Linux.
#
class MultiVersionDownloader :
def __init__(self, install_dir, link_dir, platform):
self.install_dir = install_dir
self.link_dir = link_dir
match = re.compile("(.*)\/(.*)").match(platform)
self.platform = match.group(1)
self.arch = match.group(2)
self.links = self.download_links()
def download_links(self):
href = "http://dl.mongodb.org/dl/%s/%s" \
% (self.platform.lower(), self.arch)
html = urllib2.urlopen(href).read()
links = {}
for line in html.split():
match = re.compile("http:\/\/downloads\.mongodb\.org\/%s/mongodb-%s-%s-([^\"]*)\.tgz" \
% (self.platform.lower(), self.platform.lower(), self.arch)).search(line)
if match == None: continue
link = match.group(0)
version = match.group(1)
links[version] = link
return links
def download_version(self, version):
try:
os.makedirs(self.install_dir)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(self.install_dir):
pass
else: raise
urls = []
for link_version, link_url in self.links.iteritems():
if link_version.startswith(version):
# If we have a "-" in our version, exact match only
if version.find("-") >= 0:
if link_version != version: continue
elif link_version.find("-") >= 0:
continue
urls.append((link_version, link_url))
if len(urls) == 0:
raise Exception("Cannot find a link for version %s, versions %s found." \
% (version, self.links))
urls.sort()
full_version = urls[-1][0]
url = urls[-1][1]
temp_dir = tempfile.mkdtemp()
temp_file = tempfile.mktemp(suffix=".tgz")
data = urllib2.urlopen(url)
print "Downloading data for version %s (%s)..." % (version, full_version)
with open(temp_file, 'wb') as f:
f.write(data.read())
print "Uncompressing data for version %s (%s)..." % (version, full_version)
# Can't use cool with syntax b/c of python 2.6
tf = tarfile.open(temp_file, 'r:gz')
try:
tf.extractall(path=temp_dir)
except:
tf.close()
raise
tf.close()
extract_dir = os.listdir(temp_dir)[0]
temp_install_dir = os.path.join(temp_dir, extract_dir)
shutil.move(temp_install_dir, self.install_dir)
shutil.rmtree(temp_dir)
os.remove(temp_file)
self.symlink_version(version, os.path.abspath(os.path.join(self.install_dir, extract_dir)))
def symlink_version(self, version, installed_dir):
try:
os.makedirs(self.link_dir)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(self.link_dir):
pass
else: raise
for executable in os.listdir(os.path.join(installed_dir, "bin")):
link_name = "%s-%s" % (executable, version)
os.symlink(os.path.join(installed_dir, "bin", executable),\
os.path.join(self.link_dir, link_name))
CL_HELP_MESSAGE = \
"""
Downloads and installs particular mongodb versions into an install directory and symlinks the binaries with versions to
another directory.
Usage: install_multiversion_mongodb.sh INSTALL_DIR LINK_DIR PLATFORM_AND_ARCH VERSION1 [VERSION2 VERSION3 ...]
Ex: install_multiversion_mongodb.sh ./install ./link "Linux/x86_64" "2.0.6" "2.0.3-rc0" "2.0" "2.2" "2.3"
If "rc" is included in the version name, we'll use the exact rc, otherwise we'll pull the highest non-rc
version compatible with the version specified.
"""
def parse_cl_args(args):
def raise_exception(msg):
print CL_HELP_MESSAGE
raise Exception(msg)
if len(args) == 0: raise_exception("Missing INSTALL_DIR")
install_dir = args[0]
args = args[1:]
if len(args) == 0: raise_exception("Missing LINK_DIR")
link_dir = args[0]
args = args[1:]
if len(args) == 0: raise_exception("Missing PLATFORM_AND_ARCH")
platform = args[0]
args = args[1:]
if re.compile(".*\/.*").match(platform) == None:
raise_exception("PLATFORM_AND_ARCH isn't of the correct format")
if len(args) == 0: raise_exception("Missing VERSION1")
versions = args
return (MultiVersionDownloader(install_dir, link_dir, platform), versions)
def main():
downloader, versions = parse_cl_args(sys.argv[1:])
for version in versions:
downloader.download_version(version)
if __name__ == '__main__':
main()
|