forked from SeattleTestbed/dist
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate_and_build.py
282 lines (226 loc) · 9.12 KB
/
update_and_build.py
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
"""
<Program Name>
update_and_build.py
<Started>
December 1, 2008
Amended June 9, 2009
<Author>
Carter Butaud
Zachary Boka
<Purpose>
Builds an installer from the latest code and in the process
copies the proper files to the directory that the software
updaters check for updates.
"""
import make_base_installers
import os
import sys
import shutil
import subprocess
import tempfile
DEBUG = False
# For unique temp folders
PROGRAM_NAME = "build_and_update"
UPDATER_SITE = "/home/couvb/public_html/updatesite/0.1"
if DEBUG:
UPDATER_SITE = "/home/zack/test/updatesite"
INSTALL_DIR = "seattle_repy"
DIST_DIR = "/var/www/dist"
if DEBUG:
DIST_DIR = "/home/zack/test/dist"
def get_digits(key):
"""
Utility function, returns all the digits from the given string.
"""
digits = ""
for c in key:
if c.isdigit():
digits += c
return digits
def confirm_paths_version(trunk_location, pubkey, version):
"""
<Purpose>
Checks to make sure that the keys and updater site in the softwareupdater
script are the same as the ones that this script was given, and that the
version's release is the same as the version specified in the nodemanager
script.
<Arguments>
trunk_location:
The path to the repository's trunk, used to find the softwareupdater
and nodemanager scripts.
pubkey:
Path to the public key that will be used when building the metainfo file
for the installers and the softwareupdater.
version:
Version of the intended release.
<Exceptions>
IOError if the softwareupdater script, nodemanager script, or public key
are not found.
<Side Effects>
None.
<Returns>
A tuple representing which checks passed and failed (True for pass,
for for fail). The first element represents the url check, the second
represents the public key check, and the third represents the version
check.
"""
softwareupdater_path = trunk_location + "/softwareupdater/softwareupdater.py"
nm_path = trunk_location + "/nodemanager/nmmain.py"
if not os.path.exists(softwareupdater_path):
raise IOError("Could not find softwareupdater script at " + softwareupdater_path)
if not os.path.exists(nm_path):
raise IOError("Could not find nodemanager script at " + nm_path)
# Find the values in the softwareupdater script
script_f = open(softwareupdater_path)
script_url = None
script_key = []
for line in script_f:
if "softwareurl = " in line:
script_url = line.split('"')[1]
if "softwareupdatepublickey = " in line:
script_key.append(get_digits(line.split(",")[0]))
script_key.append(get_digits(line.split(",")[1]))
script_f.close()
# Find the version in the nodemanager script
script_f = open(nm_path)
script_version = None
for line in script_f:
if "version = " in line:
script_version = line.split('"')[1]
script_f.close()
# Get the public key info from the given key.
key_f = open(pubkey)
given_key = []
for line in key_f:
if line:
given_key.append(line.split(" ")[0])
given_key.append(line.split(" ")[1])
# Get the relevant part of the script url (everything that comes
# after "couvb")
script_url_end = script_url[script_url.find("couvb") + len("couvb"):]
if script_url_end[-1] == "/":
script_url_end = script_url_end[:-1]
# Check and see if the updater path ends the same way.
# Zack: Used boolean zen
urls_match = UPDATER_SITE.endswith(script_url_end) \
or UPDATER_SITE.endswith(script_url_end + "/")
# Check to see if the script key and the given key match
# Zack: Used boolean zen
keys_match = script_key[0] == given_key[0] and script_key[1] == given_key[1]
# Check to see if the script version and the given version match.
# Zack: Used boolean zen
versions_match = script_version == version
return (urls_match, keys_match, versions_match)
def build_and_update(trunk_location, pubkey, privkey, version):
"""
<Purpose>
Builds the installers, copying the proper files to the software updater
directory in the process, and deposits the installers in the dist
directory. Only meant to be run on the actual seattle server.
<Arguments>
trunk_location:
The path to the repository's trunk directory.
pubkey:
The public key to be used in the installers.
privkey:
The private key to be used in the installers.
version:
The version of the distribution which will be appended to the base name of
each installer.
<Exceptions>
IOError on bad filepaths.
<Side Effects>
None.
<Returns>
None.
"""
# Check that the urls, keys, and version this script wants to use matches up
# with the information in the trunk (namely softwarupdater.mix and nmmain.py)
urls_match, keys_match, versions_match = confirm_paths_version(trunk_location,
pubkey, version)
if not (urls_match and keys_match and versions_match):
if not urls_match:
print "Updater location does not match with url in softwareupdater.py."
if not keys_match:
print "Given public key does not match with key in softwareupdater.py."
if not versions_match:
print "Given version does not match with version in nmmain.py"
return
print "Confirmation of url and key paths match."
print "Confirmation of version match."
print ""
print "Building installers and copying files to the software updater..."
# First, make the temp directories
# Zack: Created temporary directory for the installation
temp_install_dir = tempfile.mkdtemp()
# Zack: Created temporary directory for creating the tarball(s)
temp_tarball_dir = tempfile.mkdtemp()
# Next, prepare the installation files
install_files = make_base_installers.prepare_gen_files(trunk_location,
temp_install_dir, False, pubkey, privkey, True)
# Remove the files in UPDATER_SITE, then copy the general installer files to
# the updater site
os.chdir(UPDATER_SITE)
for fname in os.listdir(UPDATER_SITE):
os.remove(fname)
# Zack: Copy files to UPDATER_SITE, excluding the files that did not belong in
# the metainfo file
os.chdir(temp_install_dir)
for fname in install_files:
if "nodeman.cfg" != fname and "resources.offcut" != fname:
shutil.copy2(fname, UPDATER_SITE)
# Now, package each installer
win_instname = make_base_installers.get_inst_name("win", version)
winmob_instname = make_base_installers.get_inst_name("winmob", version)
linux_instname = make_base_installers.get_inst_name("linux", version)
mac_instname = make_base_installers.get_inst_name("mac", version)
make_base_installers.package_win_or_winmob(trunk_location, temp_install_dir,
temp_tarball_dir, win_instname, install_files)
make_base_installers.package_win_or_winmob(trunk_location, temp_install_dir,
temp_tarball_dir, winmob_instname, install_files)
make_base_installers.package_linux_or_mac(trunk_location, temp_install_dir,
temp_tarball_dir, linux_instname, install_files)
make_base_installers.package_linux_or_mac(trunk_location, temp_install_dir,
temp_tarball_dir, mac_instname, install_files)
# Zack: Move the installers to the specified output directory
os.chdir(temp_tarball_dir)
for tarball in os.listdir(temp_tarball_dir):
shutil.copy2(tarball, DIST_DIR)
# Copy each versioned installer name over the corresponding base
# base installer
for dist in ["win", "winmob", "linux", "mac"]:
versioned_name = make_base_installers.get_inst_name(dist, version)
unversioned_name = make_base_installers.get_inst_name(dist, "")
shutil.copy2(DIST_DIR + "/" + versioned_name,
DIST_DIR + "/" + unversioned_name)
# Zack: Remove the temp directory when done.
shutil.rmtree(temp_install_dir)
shutil.rmtree(temp_tarball_dir)
print "Done!"
def main():
if len(sys.argv) < 5:
print "usage: python update_and_build.py trunk/location/ publickey privatekey version"
trunk_location = os.path.realpath(sys.argv[1])
pubkey = os.path.realpath(sys.argv[2])
privkey = os.path.realpath(sys.argv[3])
# Zack: test the arguments here in main rather than elsewhere in the program
if not os.path.exists(trunk_location):
raise IOError("Trunk could not be found at " + trunk_location)
elif not os.path.exists(pubkey):
raise IOError("Could not find public key at " + os.path.realpath(pubkey))
elif not os.path.exists(privkey):
raise IOError("Could not find private key at " + os.path.realpath(privkey))
else:
if not DEBUG:
# Confirm that the user really wants to update all the software
print "This will update all of the client software!"
print "Are you sure you want to proceed? (y/n)"
if raw_input()[0].lower() != "y":
print "Use make_base_installers instead to just create base installers."
return
else:
# If we're in DEBUG mode, don't bother to confirm
print "Operating in debug mode..."
build_and_update(trunk_location, pubkey, privkey, sys.argv[4])
if __name__ == "__main__":
main()