From: Brian Dolbec <dolsen@gentoo.org>
To: gentoo-catalyst@lists.gentoo.org
Subject: [gentoo-catalyst] [PATCH] Initial separation and creation of a hash_utils.py module
Date: Wed, 2 Apr 2014 16:46:35 -0700 [thread overview]
Message-ID: <1396482395-10188-2-git-send-email-dolsen@gentoo.org> (raw)
In-Reply-To: <1396482395-10188-1-git-send-email-dolsen@gentoo.org>
---
catalyst/hash_utils.py | 137 +++++++++++++++++++++++++++++++
catalyst/main.py | 30 ++++---
catalyst/support.py | 62 --------------
catalyst/targets/generic_stage_target.py | 36 ++++----
catalyst/targets/livecd_stage2_target.py | 4 +-
catalyst/targets/stage2_target.py | 7 +-
6 files changed, 184 insertions(+), 92 deletions(-)
create mode 100644 catalyst/hash_utils.py
diff --git a/catalyst/hash_utils.py b/catalyst/hash_utils.py
new file mode 100644
index 0000000..b575ace
--- /dev/null
+++ b/catalyst/hash_utils.py
@@ -0,0 +1,137 @@
+
+import os
+from collections import namedtuple
+from subprocess import Popen, PIPE
+
+from support import CatalystError
+
+
+# Use HashMap.fields for the value legend
+# fields = ["func", "cmd", "args", "id"]
+HASH_DEFINITIONS = {
+ "adler32" :["calc_hash2", "shash", ["-a", "ADLER32"], "ADLER32"],
+ "crc32" :["calc_hash2", "shash", ["-a", "CRC32"], "CRC32"],
+ "crc32b" :["calc_hash2", "shash", ["-a", "CRC32B"], "CRC32B"],
+ "gost" :["calc_hash2", "shash", ["-a", "GOST"], "GOST"],
+ "haval128" :["calc_hash2", "shash", ["-a", "HAVAL128"], "HAVAL128"],
+ "haval160" :["calc_hash2", "shash", ["-a", "HAVAL160"], "HAVAL160"],
+ "haval192" :["calc_hash2", "shash", ["-a", "HAVAL192"], "HAVAL192"],
+ "haval224" :["calc_hash2", "shash", ["-a", "HAVAL224"], "HAVAL224"],
+ "haval256" :["calc_hash2", "shash", ["-a", "HAVAL256"], "HAVAL256"],
+ "md2" :["calc_hash2", "shash", ["-a", "MD2"], "MD2"],
+ "md4" :["calc_hash2", "shash", ["-a", "MD4"], "MD4"],
+ "md5" :["calc_hash2", "shash", ["-a", "MD5"], "MD5"],
+ "ripemd128":["calc_hash2", "shash", ["-a", "RIPEMD128"], "RIPEMD128"],
+ "ripemd160":["calc_hash2", "shash", ["-a", "RIPEMD160"], "RIPEMD160"],
+ "ripemd256":["calc_hash2", "shash", ["-a", "RIPEMD256"], "RIPEMD256"],
+ "ripemd320":["calc_hash2", "shash", ["-a", "RIPEMD320"], "RIPEMD320"],
+ "sha1" :["calc_hash2", "shash", ["-a", "SHA1"], "SHA1"],
+ "sha224" :["calc_hash2", "shash", ["-a", "SHA224"], "SHA224"],
+ "sha256" :["calc_hash2", "shash", ["-a", "SHA256"], "SHA256"],
+ "sha384" :["calc_hash2", "shash", ["-a", "SHA384"], "SHA384"],
+ "sha512" :["calc_hash2", "shash", ["-a", "SHA512"], "SHA512"],
+ "snefru128":["calc_hash2", "shash", ["-a", "SNEFRU128"], "SNEFRU128"],
+ "snefru256":["calc_hash2", "shash", ["-a", "SNEFRU256"], "SNEFRU256"],
+ "tiger" :["calc_hash2", "shash", ["-a", "TIGER"], "TIGER"],
+ "tiger128" :["calc_hash2", "shash", ["-a", "TIGER128"], "TIGER128"],
+ "tiger160" :["calc_hash2", "shash", ["-a", "TIGER160"], "TIGER160"],
+ "whirlpool":["calc_hash2", "shash", ["-a", "WHIRLPOOL"], "WHIRLPOOL"],
+ }
+
+
+class HashMap(object):
+ '''Class for handling
+ Catalyst's hash generation'''
+
+ fields = ["func", "cmd", "args", "id"]
+
+
+ def __init__(self, hashes=None):
+ '''Class init
+
+ @param hashes: dictionary of Key:[function, cmd, cmd_args, Print string]
+ @param fields: list of ordered field names for the hashes
+ eg: ["func", "cmd", "args", "id"]
+ '''
+ if hashes is None:
+ hashes = {}
+ self.hash_map = {}
+
+ # create the hash definition namedtuple classes
+ for name in list(hashes):
+ obj = namedtuple(name, self.fields)
+ obj.__slots__ = ()
+ self.hash_map[name] = obj._make(hashes[name])
+ del obj
+
+
+ def generate_hash(self, file_, hash_="crc32", verbose=False):
+ '''Prefered method of generating a hash for the passed in file_
+
+ @param file_: the file to generate the hash for
+ @param hash_: the hash algorythm to use
+ @param verbose: boolean
+ @returns the hash result
+ '''
+ try:
+ return getattr(self, self.hash_map[hash_].func)(
+ file_,
+ hash_,
+ verbose
+ )
+ except:
+ raise CatalystError,"Error generating hash, is appropriate " + \
+ "utility installed on your system?"
+
+
+ def calc_hash(self, file_, hash_, verbose=False):
+ '''
+ Calculate the hash for "file_"
+
+ @param file_: the file to generate the hash for
+ @param hash_: the hash algorythm to use
+ @param verbose: boolean
+ @returns the hash result
+ '''
+ _hash = self.hash_map[hash_]
+ args = [_hash.cmd]
+ args.extend(_hash.args)
+ args.append(file_)
+ source = Popen(args, stdout=PIPE)
+ mylines = source.communicate()[0]
+ mylines=mylines[0].split()
+ result=mylines[0]
+ if verbose:
+ print _hash.id + " (%s) = %s" % (file_, result)
+ return result
+
+
+ def calc_hash2(self, file_, hash_type, verbose=False):
+ '''
+ Calculate the hash for "file_"
+
+ @param file_: the file to generate the hash for
+ @param hash_: the hash algorythm to use
+ @param verbose: boolean
+ @returns the hash result
+ '''
+ _hash = self.hash_map[hash_type]
+ args = [_hash.cmd]
+ args.extend(_hash.args)
+ args.append(file_)
+ #print("DEBUG: calc_hash2; args =", args)
+ source = Popen(args, stdout=PIPE)
+ output = source.communicate()
+ lines = output[0].split('\n')
+ #print("DEBUG: calc_hash2; output =", output)
+ header = lines[0]
+ h_f = lines[1].split()
+ hash_result = h_f[0]
+ short_file = os.path.split(h_f[1])[1]
+ result = header + "\n" + hash_result + " " + short_file + "\n"
+ if verbose:
+ print header + " (%s) = %s" % (short_file, result)
+ return result
+
+
+
diff --git a/catalyst/main.py b/catalyst/main.py
index 6b90989..7bcf2cb 100644
--- a/catalyst/main.py
+++ b/catalyst/main.py
@@ -22,7 +22,10 @@ from . import __version__
import catalyst.config
import catalyst.util
from catalyst.support import (required_build_targets,
- valid_build_targets, CatalystError, hash_map, find_binary, LockInUse)
+ valid_build_targets, CatalystError, find_binary, LockInUse)
+
+from hash_utils import HashMap, HASH_DEFINITIONS
+
conf_values={}
@@ -345,40 +348,43 @@ def main():
# import configuration file and import our main module using those settings
parse_config(myconfig)
- # Start checking that digests are valid now that the hash_map was imported
- # from catalyst.support
+ # initialze our hash and contents generators
+ hash_map = HashMap(HASH_DEFINITIONS)
+ conf_values["hash_map"] = hash_map
+
+ # Start checking that digests are valid now that hash_map is initialized
if "digests" in conf_values:
for i in conf_values["digests"].split():
- if i not in hash_map:
+ if i not in HASH_DEFINITIONS:
print
print i+" is not a valid digest entry"
print "Valid digest entries:"
- print hash_map.keys()
+ print HASH_DEFINITIONS.keys()
print
print "Catalyst aborting...."
sys.exit(2)
- if find_binary(hash_map[i][1]) == None:
+ if find_binary(hash_map.hash_map[i].cmd) == None:
print
- print "digest="+i
- print "\tThe "+hash_map[i][1]+\
+ print "digest=" + i
+ print "\tThe " + hash_map.hash_map[i].cmd + \
" binary was not found. It needs to be in your system path"
print
print "Catalyst aborting...."
sys.exit(2)
if "hash_function" in conf_values:
- if conf_values["hash_function"] not in hash_map:
+ if conf_values["hash_function"] not in HASH_DEFINITIONS:
print
print conf_values["hash_function"]+\
" is not a valid hash_function entry"
print "Valid hash_function entries:"
- print hash_map.keys()
+ print HASH_DEFINITIONS.keys()
print
print "Catalyst aborting...."
sys.exit(2)
- if find_binary(hash_map[conf_values["hash_function"]][1]) == None:
+ if find_binary(hash_map.hash_map[conf_values["hash_function"]].cmd) == None:
print
print "hash_function="+conf_values["hash_function"]
- print "\tThe "+hash_map[conf_values["hash_function"]][1]+\
+ print "\tThe "+hash_map.hash_map[conf_values["hash_function"]].cmd + \
" binary was not found. It needs to be in your system path"
print
print "Catalyst aborting...."
diff --git a/catalyst/support.py b/catalyst/support.py
index 5e7ce92..308d9c0 100644
--- a/catalyst/support.py
+++ b/catalyst/support.py
@@ -114,68 +114,6 @@ contents_map={
"isoinfo-f":[calc_contents,"isoinfo -f -i %(file)s"],
}
-def generate_hash(file,hash_function="crc32",verbose=False):
- try:
- return hash_map[hash_function][0](file,hash_map[hash_function][1],hash_map[hash_function][2],\
- hash_map[hash_function][3],verbose)
- except:
- raise CatalystError,"Error generating hash, is appropriate utility installed on your system?"
-
-def calc_hash(file,cmd,cmd_args,id_string="MD5",verbose=False):
- a=os.popen(cmd+" "+cmd_args+" "+file)
- mylines=a.readlines()
- a.close()
- mylines=mylines[0].split()
- result=mylines[0]
- if verbose:
- print id_string+" (%s) = %s" % (file, result)
- return result
-
-def calc_hash2(file,cmd,cmd_args,id_string="MD5",verbose=False):
- a=os.popen(cmd+" "+cmd_args+" "+file)
- header=a.readline()
- mylines=a.readline().split()
- hash=mylines[0]
- short_file=os.path.split(mylines[1])[1]
- a.close()
- result=header+hash+" "+short_file+"\n"
- if verbose:
- print header+" (%s) = %s" % (short_file, result)
- return result
-
-# This has map must be defined after the function calc_hash
-# It is possible to call different functions from this but they must be defined
-# before hash_map
-# Key,function,cmd,cmd_args,Print string
-hash_map={
- "adler32":[calc_hash2,"shash","-a ADLER32","ADLER32"],\
- "crc32":[calc_hash2,"shash","-a CRC32","CRC32"],\
- "crc32b":[calc_hash2,"shash","-a CRC32B","CRC32B"],\
- "gost":[calc_hash2,"shash","-a GOST","GOST"],\
- "haval128":[calc_hash2,"shash","-a HAVAL128","HAVAL128"],\
- "haval160":[calc_hash2,"shash","-a HAVAL160","HAVAL160"],\
- "haval192":[calc_hash2,"shash","-a HAVAL192","HAVAL192"],\
- "haval224":[calc_hash2,"shash","-a HAVAL224","HAVAL224"],\
- "haval256":[calc_hash2,"shash","-a HAVAL256","HAVAL256"],\
- "md2":[calc_hash2,"shash","-a MD2","MD2"],\
- "md4":[calc_hash2,"shash","-a MD4","MD4"],\
- "md5":[calc_hash2,"shash","-a MD5","MD5"],\
- "ripemd128":[calc_hash2,"shash","-a RIPEMD128","RIPEMD128"],\
- "ripemd160":[calc_hash2,"shash","-a RIPEMD160","RIPEMD160"],\
- "ripemd256":[calc_hash2,"shash","-a RIPEMD256","RIPEMD256"],\
- "ripemd320":[calc_hash2,"shash","-a RIPEMD320","RIPEMD320"],\
- "sha1":[calc_hash2,"shash","-a SHA1","SHA1"],\
- "sha224":[calc_hash2,"shash","-a SHA224","SHA224"],\
- "sha256":[calc_hash2,"shash","-a SHA256","SHA256"],\
- "sha384":[calc_hash2,"shash","-a SHA384","SHA384"],\
- "sha512":[calc_hash2,"shash","-a SHA512","SHA512"],\
- "snefru128":[calc_hash2,"shash","-a SNEFRU128","SNEFRU128"],\
- "snefru256":[calc_hash2,"shash","-a SNEFRU256","SNEFRU256"],\
- "tiger":[calc_hash2,"shash","-a TIGER","TIGER"],\
- "tiger128":[calc_hash2,"shash","-a TIGER128","TIGER128"],\
- "tiger160":[calc_hash2,"shash","-a TIGER160","TIGER160"],\
- "whirlpool":[calc_hash2,"shash","-a WHIRLPOOL","WHIRLPOOL"],\
- }
def read_from_clst(file):
line = ''
diff --git a/catalyst/targets/generic_stage_target.py b/catalyst/targets/generic_stage_target.py
index eaf2c1f..b6a6200 100644
--- a/catalyst/targets/generic_stage_target.py
+++ b/catalyst/targets/generic_stage_target.py
@@ -428,10 +428,11 @@ class generic_stage_target(generic_target):
if os.path.isfile(self.settings["source_path"]):
# XXX: Is this even necessary if the previous check passes?
if os.path.exists(self.settings["source_path"]):
- self.settings["source_path_hash"]=\
- generate_hash(self.settings["source_path"],\
- hash_function=self.settings["hash_function"],\
- verbose=False)
+ self.settings["source_path_hash"] = \
+ self.settings["hash_map"].generate_hash(
+ self.settings["source_path"],
+ hash_ = self.settings["hash_function"],
+ verbose = False)
print "Source path set to "+self.settings["source_path"]
if os.path.isdir(self.settings["source_path"]):
print "\tIf this is not desired, remove this directory or turn off"
@@ -457,18 +458,22 @@ class generic_stage_target(generic_target):
self.settings["snapshot"] + ".tar.xz")
if os.path.exists(self.settings["snapshot_path"]):
- self.settings["snapshot_path_hash"]=\
- generate_hash(self.settings["snapshot_path"],\
- hash_function=self.settings["hash_function"],verbose=False)
+ self.settings["snapshot_path_hash"] = \
+ self.settings["hash_map"].generate_hash(
+ self.settings["snapshot_path"],
+ hash_ = self.settings["hash_function"],
+ verbose = False)
else:
self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\
"/snapshots/" + self.settings["snapshot_name"] +
self.settings["snapshot"] + ".tar.bz2")
if os.path.exists(self.settings["snapshot_path"]):
- self.settings["snapshot_path_hash"]=\
- generate_hash(self.settings["snapshot_path"],\
- hash_function=self.settings["hash_function"],verbose=False)
+ self.settings["snapshot_path_hash"] = \
+ self.settings["hash_map"].generate_hash(
+ self.settings["snapshot_path"],
+ hash_ = self.settings["hash_function"],
+ verbose = False)
def set_snapcache_path(self):
if "SNAPCACHE" in self.settings:
@@ -1716,6 +1721,7 @@ class generic_stage_target(generic_target):
if os.path.exists(file+".DIGESTS"):
os.remove(file+".DIGESTS")
if "digests" in self.settings:
+ hash_map = self.settings["hash_map"]
if os.path.exists(file):
myf=open(file+".DIGESTS","w")
keys={}
@@ -1726,14 +1732,14 @@ class generic_stage_target(generic_target):
for f in [file, file+'.CONTENTS']:
if os.path.exists(f):
if "all" in array:
- for k in hash_map.keys():
- hash=generate_hash(f,hash_function=k,verbose=\
- "VERBOSE" in self.settings)
+ for k in list(hash_map.hash_map):
+ hash = hash_map.generate_hash(f, hash_ = k,
+ verbose = "VERBOSE" in self.settings)
myf.write(hash)
else:
for j in array:
- hash=generate_hash(f,hash_function=j,verbose=\
- "VERBOSE" in self.settings)
+ hash = hash_map.generate_hash(f, hash_ = j,
+ verbose = "VERBOSE" in self.settings)
myf.write(hash)
myf.close()
diff --git a/catalyst/targets/livecd_stage2_target.py b/catalyst/targets/livecd_stage2_target.py
index 1bfd820..e784844 100644
--- a/catalyst/targets/livecd_stage2_target.py
+++ b/catalyst/targets/livecd_stage2_target.py
@@ -35,7 +35,9 @@ class livecd_stage2_target(generic_stage_target):
def set_source_path(self):
self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2")
if os.path.isfile(self.settings["source_path"]):
- self.settings["source_path_hash"]=generate_hash(self.settings["source_path"])
+ self.settings["source_path_hash"] = \
+ self.settings["hash_map"].generate_hash(
+ self.settings["source_path"])
else:
self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/")
if not os.path.exists(self.settings["source_path"]):
diff --git a/catalyst/targets/stage2_target.py b/catalyst/targets/stage2_target.py
index 15acdee..6377f5d 100644
--- a/catalyst/targets/stage2_target.py
+++ b/catalyst/targets/stage2_target.py
@@ -23,8 +23,11 @@ class stage2_target(generic_stage_target):
if os.path.isfile(self.settings["source_path"]):
if os.path.exists(self.settings["source_path"]):
# XXX: Is this even necessary if the previous check passes?
- self.settings["source_path_hash"]=generate_hash(self.settings["source_path"],\
- hash_function=self.settings["hash_function"],verbose=False)
+ self.settings["source_path_hash"] = \
+ self.settings["hash_map"].generate_hash(
+ self.settings["source_path"],\
+ hash_=self.settings["hash_function"],
+ verbose=False)
print "Source path set to "+self.settings["source_path"]
if os.path.isdir(self.settings["source_path"]):
print "\tIf this is not desired, remove this directory or turn of seedcache in the options of catalyst.conf"
--
1.8.5.3
next prev parent reply other threads:[~2014-04-02 23:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-02 23:46 [gentoo-catalyst] Patch 0/8 Remaining patches in pending Brian Dolbec
2014-04-02 23:46 ` Brian Dolbec [this message]
2014-05-05 19:20 ` Brian Dolbec
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1396482395-10188-2-git-send-email-dolsen@gentoo.org \
--to=dolsen@gentoo.org \
--cc=gentoo-catalyst@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox