1 |
commit: ee9831262599e0ee02d8374e677c94462f87b006 |
2 |
Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Jan 3 18:42:26 2014 +0000 |
4 |
Commit: Brian Dolbec <brian.dolbec <AT> gmail <DOT> com> |
5 |
CommitDate: Sat Mar 22 18:01:29 2014 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/catalyst.git;a=commit;h=ee983126 |
7 |
|
8 |
Initial separation and creation of a hash_utils.py module |
9 |
|
10 |
--- |
11 |
catalyst/hash_utils.py | 137 +++++++++++++++++++++++++++++++ |
12 |
catalyst/main.py | 30 ++++--- |
13 |
catalyst/support.py | 62 -------------- |
14 |
catalyst/targets/generic_stage_target.py | 36 ++++---- |
15 |
catalyst/targets/livecd_stage2_target.py | 4 +- |
16 |
catalyst/targets/stage2_target.py | 7 +- |
17 |
6 files changed, 184 insertions(+), 92 deletions(-) |
18 |
|
19 |
diff --git a/catalyst/hash_utils.py b/catalyst/hash_utils.py |
20 |
new file mode 100644 |
21 |
index 0000000..b575ace |
22 |
--- /dev/null |
23 |
+++ b/catalyst/hash_utils.py |
24 |
@@ -0,0 +1,137 @@ |
25 |
+ |
26 |
+import os |
27 |
+from collections import namedtuple |
28 |
+from subprocess import Popen, PIPE |
29 |
+ |
30 |
+from support import CatalystError |
31 |
+ |
32 |
+ |
33 |
+# Use HashMap.fields for the value legend |
34 |
+# fields = ["func", "cmd", "args", "id"] |
35 |
+HASH_DEFINITIONS = { |
36 |
+ "adler32" :["calc_hash2", "shash", ["-a", "ADLER32"], "ADLER32"], |
37 |
+ "crc32" :["calc_hash2", "shash", ["-a", "CRC32"], "CRC32"], |
38 |
+ "crc32b" :["calc_hash2", "shash", ["-a", "CRC32B"], "CRC32B"], |
39 |
+ "gost" :["calc_hash2", "shash", ["-a", "GOST"], "GOST"], |
40 |
+ "haval128" :["calc_hash2", "shash", ["-a", "HAVAL128"], "HAVAL128"], |
41 |
+ "haval160" :["calc_hash2", "shash", ["-a", "HAVAL160"], "HAVAL160"], |
42 |
+ "haval192" :["calc_hash2", "shash", ["-a", "HAVAL192"], "HAVAL192"], |
43 |
+ "haval224" :["calc_hash2", "shash", ["-a", "HAVAL224"], "HAVAL224"], |
44 |
+ "haval256" :["calc_hash2", "shash", ["-a", "HAVAL256"], "HAVAL256"], |
45 |
+ "md2" :["calc_hash2", "shash", ["-a", "MD2"], "MD2"], |
46 |
+ "md4" :["calc_hash2", "shash", ["-a", "MD4"], "MD4"], |
47 |
+ "md5" :["calc_hash2", "shash", ["-a", "MD5"], "MD5"], |
48 |
+ "ripemd128":["calc_hash2", "shash", ["-a", "RIPEMD128"], "RIPEMD128"], |
49 |
+ "ripemd160":["calc_hash2", "shash", ["-a", "RIPEMD160"], "RIPEMD160"], |
50 |
+ "ripemd256":["calc_hash2", "shash", ["-a", "RIPEMD256"], "RIPEMD256"], |
51 |
+ "ripemd320":["calc_hash2", "shash", ["-a", "RIPEMD320"], "RIPEMD320"], |
52 |
+ "sha1" :["calc_hash2", "shash", ["-a", "SHA1"], "SHA1"], |
53 |
+ "sha224" :["calc_hash2", "shash", ["-a", "SHA224"], "SHA224"], |
54 |
+ "sha256" :["calc_hash2", "shash", ["-a", "SHA256"], "SHA256"], |
55 |
+ "sha384" :["calc_hash2", "shash", ["-a", "SHA384"], "SHA384"], |
56 |
+ "sha512" :["calc_hash2", "shash", ["-a", "SHA512"], "SHA512"], |
57 |
+ "snefru128":["calc_hash2", "shash", ["-a", "SNEFRU128"], "SNEFRU128"], |
58 |
+ "snefru256":["calc_hash2", "shash", ["-a", "SNEFRU256"], "SNEFRU256"], |
59 |
+ "tiger" :["calc_hash2", "shash", ["-a", "TIGER"], "TIGER"], |
60 |
+ "tiger128" :["calc_hash2", "shash", ["-a", "TIGER128"], "TIGER128"], |
61 |
+ "tiger160" :["calc_hash2", "shash", ["-a", "TIGER160"], "TIGER160"], |
62 |
+ "whirlpool":["calc_hash2", "shash", ["-a", "WHIRLPOOL"], "WHIRLPOOL"], |
63 |
+ } |
64 |
+ |
65 |
+ |
66 |
+class HashMap(object): |
67 |
+ '''Class for handling |
68 |
+ Catalyst's hash generation''' |
69 |
+ |
70 |
+ fields = ["func", "cmd", "args", "id"] |
71 |
+ |
72 |
+ |
73 |
+ def __init__(self, hashes=None): |
74 |
+ '''Class init |
75 |
+ |
76 |
+ @param hashes: dictionary of Key:[function, cmd, cmd_args, Print string] |
77 |
+ @param fields: list of ordered field names for the hashes |
78 |
+ eg: ["func", "cmd", "args", "id"] |
79 |
+ ''' |
80 |
+ if hashes is None: |
81 |
+ hashes = {} |
82 |
+ self.hash_map = {} |
83 |
+ |
84 |
+ # create the hash definition namedtuple classes |
85 |
+ for name in list(hashes): |
86 |
+ obj = namedtuple(name, self.fields) |
87 |
+ obj.__slots__ = () |
88 |
+ self.hash_map[name] = obj._make(hashes[name]) |
89 |
+ del obj |
90 |
+ |
91 |
+ |
92 |
+ def generate_hash(self, file_, hash_="crc32", verbose=False): |
93 |
+ '''Prefered method of generating a hash for the passed in file_ |
94 |
+ |
95 |
+ @param file_: the file to generate the hash for |
96 |
+ @param hash_: the hash algorythm to use |
97 |
+ @param verbose: boolean |
98 |
+ @returns the hash result |
99 |
+ ''' |
100 |
+ try: |
101 |
+ return getattr(self, self.hash_map[hash_].func)( |
102 |
+ file_, |
103 |
+ hash_, |
104 |
+ verbose |
105 |
+ ) |
106 |
+ except: |
107 |
+ raise CatalystError,"Error generating hash, is appropriate " + \ |
108 |
+ "utility installed on your system?" |
109 |
+ |
110 |
+ |
111 |
+ def calc_hash(self, file_, hash_, verbose=False): |
112 |
+ ''' |
113 |
+ Calculate the hash for "file_" |
114 |
+ |
115 |
+ @param file_: the file to generate the hash for |
116 |
+ @param hash_: the hash algorythm to use |
117 |
+ @param verbose: boolean |
118 |
+ @returns the hash result |
119 |
+ ''' |
120 |
+ _hash = self.hash_map[hash_] |
121 |
+ args = [_hash.cmd] |
122 |
+ args.extend(_hash.args) |
123 |
+ args.append(file_) |
124 |
+ source = Popen(args, stdout=PIPE) |
125 |
+ mylines = source.communicate()[0] |
126 |
+ mylines=mylines[0].split() |
127 |
+ result=mylines[0] |
128 |
+ if verbose: |
129 |
+ print _hash.id + " (%s) = %s" % (file_, result) |
130 |
+ return result |
131 |
+ |
132 |
+ |
133 |
+ def calc_hash2(self, file_, hash_type, verbose=False): |
134 |
+ ''' |
135 |
+ Calculate the hash for "file_" |
136 |
+ |
137 |
+ @param file_: the file to generate the hash for |
138 |
+ @param hash_: the hash algorythm to use |
139 |
+ @param verbose: boolean |
140 |
+ @returns the hash result |
141 |
+ ''' |
142 |
+ _hash = self.hash_map[hash_type] |
143 |
+ args = [_hash.cmd] |
144 |
+ args.extend(_hash.args) |
145 |
+ args.append(file_) |
146 |
+ #print("DEBUG: calc_hash2; args =", args) |
147 |
+ source = Popen(args, stdout=PIPE) |
148 |
+ output = source.communicate() |
149 |
+ lines = output[0].split('\n') |
150 |
+ #print("DEBUG: calc_hash2; output =", output) |
151 |
+ header = lines[0] |
152 |
+ h_f = lines[1].split() |
153 |
+ hash_result = h_f[0] |
154 |
+ short_file = os.path.split(h_f[1])[1] |
155 |
+ result = header + "\n" + hash_result + " " + short_file + "\n" |
156 |
+ if verbose: |
157 |
+ print header + " (%s) = %s" % (short_file, result) |
158 |
+ return result |
159 |
+ |
160 |
+ |
161 |
+ |
162 |
|
163 |
diff --git a/catalyst/main.py b/catalyst/main.py |
164 |
index 6b90989..7bcf2cb 100644 |
165 |
--- a/catalyst/main.py |
166 |
+++ b/catalyst/main.py |
167 |
@@ -22,7 +22,10 @@ from . import __version__ |
168 |
import catalyst.config |
169 |
import catalyst.util |
170 |
from catalyst.support import (required_build_targets, |
171 |
- valid_build_targets, CatalystError, hash_map, find_binary, LockInUse) |
172 |
+ valid_build_targets, CatalystError, find_binary, LockInUse) |
173 |
+ |
174 |
+from hash_utils import HashMap, HASH_DEFINITIONS |
175 |
+ |
176 |
|
177 |
|
178 |
conf_values={} |
179 |
@@ -345,40 +348,43 @@ def main(): |
180 |
# import configuration file and import our main module using those settings |
181 |
parse_config(myconfig) |
182 |
|
183 |
- # Start checking that digests are valid now that the hash_map was imported |
184 |
- # from catalyst.support |
185 |
+ # initialze our hash and contents generators |
186 |
+ hash_map = HashMap(HASH_DEFINITIONS) |
187 |
+ conf_values["hash_map"] = hash_map |
188 |
+ |
189 |
+ # Start checking that digests are valid now that hash_map is initialized |
190 |
if "digests" in conf_values: |
191 |
for i in conf_values["digests"].split(): |
192 |
- if i not in hash_map: |
193 |
+ if i not in HASH_DEFINITIONS: |
194 |
print |
195 |
print i+" is not a valid digest entry" |
196 |
print "Valid digest entries:" |
197 |
- print hash_map.keys() |
198 |
+ print HASH_DEFINITIONS.keys() |
199 |
print |
200 |
print "Catalyst aborting...." |
201 |
sys.exit(2) |
202 |
- if find_binary(hash_map[i][1]) == None: |
203 |
+ if find_binary(hash_map.hash_map[i].cmd) == None: |
204 |
print |
205 |
- print "digest="+i |
206 |
- print "\tThe "+hash_map[i][1]+\ |
207 |
+ print "digest=" + i |
208 |
+ print "\tThe " + hash_map.hash_map[i].cmd + \ |
209 |
" binary was not found. It needs to be in your system path" |
210 |
print |
211 |
print "Catalyst aborting...." |
212 |
sys.exit(2) |
213 |
if "hash_function" in conf_values: |
214 |
- if conf_values["hash_function"] not in hash_map: |
215 |
+ if conf_values["hash_function"] not in HASH_DEFINITIONS: |
216 |
print |
217 |
print conf_values["hash_function"]+\ |
218 |
" is not a valid hash_function entry" |
219 |
print "Valid hash_function entries:" |
220 |
- print hash_map.keys() |
221 |
+ print HASH_DEFINITIONS.keys() |
222 |
print |
223 |
print "Catalyst aborting...." |
224 |
sys.exit(2) |
225 |
- if find_binary(hash_map[conf_values["hash_function"]][1]) == None: |
226 |
+ if find_binary(hash_map.hash_map[conf_values["hash_function"]].cmd) == None: |
227 |
print |
228 |
print "hash_function="+conf_values["hash_function"] |
229 |
- print "\tThe "+hash_map[conf_values["hash_function"]][1]+\ |
230 |
+ print "\tThe "+hash_map.hash_map[conf_values["hash_function"]].cmd + \ |
231 |
" binary was not found. It needs to be in your system path" |
232 |
print |
233 |
print "Catalyst aborting...." |
234 |
|
235 |
diff --git a/catalyst/support.py b/catalyst/support.py |
236 |
index 5e7ce92..308d9c0 100644 |
237 |
--- a/catalyst/support.py |
238 |
+++ b/catalyst/support.py |
239 |
@@ -114,68 +114,6 @@ contents_map={ |
240 |
"isoinfo-f":[calc_contents,"isoinfo -f -i %(file)s"], |
241 |
} |
242 |
|
243 |
-def generate_hash(file,hash_function="crc32",verbose=False): |
244 |
- try: |
245 |
- return hash_map[hash_function][0](file,hash_map[hash_function][1],hash_map[hash_function][2],\ |
246 |
- hash_map[hash_function][3],verbose) |
247 |
- except: |
248 |
- raise CatalystError,"Error generating hash, is appropriate utility installed on your system?" |
249 |
- |
250 |
-def calc_hash(file,cmd,cmd_args,id_string="MD5",verbose=False): |
251 |
- a=os.popen(cmd+" "+cmd_args+" "+file) |
252 |
- mylines=a.readlines() |
253 |
- a.close() |
254 |
- mylines=mylines[0].split() |
255 |
- result=mylines[0] |
256 |
- if verbose: |
257 |
- print id_string+" (%s) = %s" % (file, result) |
258 |
- return result |
259 |
- |
260 |
-def calc_hash2(file,cmd,cmd_args,id_string="MD5",verbose=False): |
261 |
- a=os.popen(cmd+" "+cmd_args+" "+file) |
262 |
- header=a.readline() |
263 |
- mylines=a.readline().split() |
264 |
- hash=mylines[0] |
265 |
- short_file=os.path.split(mylines[1])[1] |
266 |
- a.close() |
267 |
- result=header+hash+" "+short_file+"\n" |
268 |
- if verbose: |
269 |
- print header+" (%s) = %s" % (short_file, result) |
270 |
- return result |
271 |
- |
272 |
-# This has map must be defined after the function calc_hash |
273 |
-# It is possible to call different functions from this but they must be defined |
274 |
-# before hash_map |
275 |
-# Key,function,cmd,cmd_args,Print string |
276 |
-hash_map={ |
277 |
- "adler32":[calc_hash2,"shash","-a ADLER32","ADLER32"],\ |
278 |
- "crc32":[calc_hash2,"shash","-a CRC32","CRC32"],\ |
279 |
- "crc32b":[calc_hash2,"shash","-a CRC32B","CRC32B"],\ |
280 |
- "gost":[calc_hash2,"shash","-a GOST","GOST"],\ |
281 |
- "haval128":[calc_hash2,"shash","-a HAVAL128","HAVAL128"],\ |
282 |
- "haval160":[calc_hash2,"shash","-a HAVAL160","HAVAL160"],\ |
283 |
- "haval192":[calc_hash2,"shash","-a HAVAL192","HAVAL192"],\ |
284 |
- "haval224":[calc_hash2,"shash","-a HAVAL224","HAVAL224"],\ |
285 |
- "haval256":[calc_hash2,"shash","-a HAVAL256","HAVAL256"],\ |
286 |
- "md2":[calc_hash2,"shash","-a MD2","MD2"],\ |
287 |
- "md4":[calc_hash2,"shash","-a MD4","MD4"],\ |
288 |
- "md5":[calc_hash2,"shash","-a MD5","MD5"],\ |
289 |
- "ripemd128":[calc_hash2,"shash","-a RIPEMD128","RIPEMD128"],\ |
290 |
- "ripemd160":[calc_hash2,"shash","-a RIPEMD160","RIPEMD160"],\ |
291 |
- "ripemd256":[calc_hash2,"shash","-a RIPEMD256","RIPEMD256"],\ |
292 |
- "ripemd320":[calc_hash2,"shash","-a RIPEMD320","RIPEMD320"],\ |
293 |
- "sha1":[calc_hash2,"shash","-a SHA1","SHA1"],\ |
294 |
- "sha224":[calc_hash2,"shash","-a SHA224","SHA224"],\ |
295 |
- "sha256":[calc_hash2,"shash","-a SHA256","SHA256"],\ |
296 |
- "sha384":[calc_hash2,"shash","-a SHA384","SHA384"],\ |
297 |
- "sha512":[calc_hash2,"shash","-a SHA512","SHA512"],\ |
298 |
- "snefru128":[calc_hash2,"shash","-a SNEFRU128","SNEFRU128"],\ |
299 |
- "snefru256":[calc_hash2,"shash","-a SNEFRU256","SNEFRU256"],\ |
300 |
- "tiger":[calc_hash2,"shash","-a TIGER","TIGER"],\ |
301 |
- "tiger128":[calc_hash2,"shash","-a TIGER128","TIGER128"],\ |
302 |
- "tiger160":[calc_hash2,"shash","-a TIGER160","TIGER160"],\ |
303 |
- "whirlpool":[calc_hash2,"shash","-a WHIRLPOOL","WHIRLPOOL"],\ |
304 |
- } |
305 |
|
306 |
def read_from_clst(file): |
307 |
line = '' |
308 |
|
309 |
diff --git a/catalyst/targets/generic_stage_target.py b/catalyst/targets/generic_stage_target.py |
310 |
index eaf2c1f..b6a6200 100644 |
311 |
--- a/catalyst/targets/generic_stage_target.py |
312 |
+++ b/catalyst/targets/generic_stage_target.py |
313 |
@@ -428,10 +428,11 @@ class generic_stage_target(generic_target): |
314 |
if os.path.isfile(self.settings["source_path"]): |
315 |
# XXX: Is this even necessary if the previous check passes? |
316 |
if os.path.exists(self.settings["source_path"]): |
317 |
- self.settings["source_path_hash"]=\ |
318 |
- generate_hash(self.settings["source_path"],\ |
319 |
- hash_function=self.settings["hash_function"],\ |
320 |
- verbose=False) |
321 |
+ self.settings["source_path_hash"] = \ |
322 |
+ self.settings["hash_map"].generate_hash( |
323 |
+ self.settings["source_path"], |
324 |
+ hash_ = self.settings["hash_function"], |
325 |
+ verbose = False) |
326 |
print "Source path set to "+self.settings["source_path"] |
327 |
if os.path.isdir(self.settings["source_path"]): |
328 |
print "\tIf this is not desired, remove this directory or turn off" |
329 |
@@ -457,18 +458,22 @@ class generic_stage_target(generic_target): |
330 |
self.settings["snapshot"] + ".tar.xz") |
331 |
|
332 |
if os.path.exists(self.settings["snapshot_path"]): |
333 |
- self.settings["snapshot_path_hash"]=\ |
334 |
- generate_hash(self.settings["snapshot_path"],\ |
335 |
- hash_function=self.settings["hash_function"],verbose=False) |
336 |
+ self.settings["snapshot_path_hash"] = \ |
337 |
+ self.settings["hash_map"].generate_hash( |
338 |
+ self.settings["snapshot_path"], |
339 |
+ hash_ = self.settings["hash_function"], |
340 |
+ verbose = False) |
341 |
else: |
342 |
self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\ |
343 |
"/snapshots/" + self.settings["snapshot_name"] + |
344 |
self.settings["snapshot"] + ".tar.bz2") |
345 |
|
346 |
if os.path.exists(self.settings["snapshot_path"]): |
347 |
- self.settings["snapshot_path_hash"]=\ |
348 |
- generate_hash(self.settings["snapshot_path"],\ |
349 |
- hash_function=self.settings["hash_function"],verbose=False) |
350 |
+ self.settings["snapshot_path_hash"] = \ |
351 |
+ self.settings["hash_map"].generate_hash( |
352 |
+ self.settings["snapshot_path"], |
353 |
+ hash_ = self.settings["hash_function"], |
354 |
+ verbose = False) |
355 |
|
356 |
def set_snapcache_path(self): |
357 |
if "SNAPCACHE" in self.settings: |
358 |
@@ -1716,6 +1721,7 @@ class generic_stage_target(generic_target): |
359 |
if os.path.exists(file+".DIGESTS"): |
360 |
os.remove(file+".DIGESTS") |
361 |
if "digests" in self.settings: |
362 |
+ hash_map = self.settings["hash_map"] |
363 |
if os.path.exists(file): |
364 |
myf=open(file+".DIGESTS","w") |
365 |
keys={} |
366 |
@@ -1726,14 +1732,14 @@ class generic_stage_target(generic_target): |
367 |
for f in [file, file+'.CONTENTS']: |
368 |
if os.path.exists(f): |
369 |
if "all" in array: |
370 |
- for k in hash_map.keys(): |
371 |
- hash=generate_hash(f,hash_function=k,verbose=\ |
372 |
- "VERBOSE" in self.settings) |
373 |
+ for k in list(hash_map.hash_map): |
374 |
+ hash = hash_map.generate_hash(f, hash_ = k, |
375 |
+ verbose = "VERBOSE" in self.settings) |
376 |
myf.write(hash) |
377 |
else: |
378 |
for j in array: |
379 |
- hash=generate_hash(f,hash_function=j,verbose=\ |
380 |
- "VERBOSE" in self.settings) |
381 |
+ hash = hash_map.generate_hash(f, hash_ = j, |
382 |
+ verbose = "VERBOSE" in self.settings) |
383 |
myf.write(hash) |
384 |
myf.close() |
385 |
|
386 |
|
387 |
diff --git a/catalyst/targets/livecd_stage2_target.py b/catalyst/targets/livecd_stage2_target.py |
388 |
index 1bfd820..e784844 100644 |
389 |
--- a/catalyst/targets/livecd_stage2_target.py |
390 |
+++ b/catalyst/targets/livecd_stage2_target.py |
391 |
@@ -35,7 +35,9 @@ class livecd_stage2_target(generic_stage_target): |
392 |
def set_source_path(self): |
393 |
self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2") |
394 |
if os.path.isfile(self.settings["source_path"]): |
395 |
- self.settings["source_path_hash"]=generate_hash(self.settings["source_path"]) |
396 |
+ self.settings["source_path_hash"] = \ |
397 |
+ self.settings["hash_map"].generate_hash( |
398 |
+ self.settings["source_path"]) |
399 |
else: |
400 |
self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/") |
401 |
if not os.path.exists(self.settings["source_path"]): |
402 |
|
403 |
diff --git a/catalyst/targets/stage2_target.py b/catalyst/targets/stage2_target.py |
404 |
index 15acdee..6377f5d 100644 |
405 |
--- a/catalyst/targets/stage2_target.py |
406 |
+++ b/catalyst/targets/stage2_target.py |
407 |
@@ -23,8 +23,11 @@ class stage2_target(generic_stage_target): |
408 |
if os.path.isfile(self.settings["source_path"]): |
409 |
if os.path.exists(self.settings["source_path"]): |
410 |
# XXX: Is this even necessary if the previous check passes? |
411 |
- self.settings["source_path_hash"]=generate_hash(self.settings["source_path"],\ |
412 |
- hash_function=self.settings["hash_function"],verbose=False) |
413 |
+ self.settings["source_path_hash"] = \ |
414 |
+ self.settings["hash_map"].generate_hash( |
415 |
+ self.settings["source_path"],\ |
416 |
+ hash_=self.settings["hash_function"], |
417 |
+ verbose=False) |
418 |
print "Source path set to "+self.settings["source_path"] |
419 |
if os.path.isdir(self.settings["source_path"]): |
420 |
print "\tIf this is not desired, remove this directory or turn of seedcache in the options of catalyst.conf" |