Package pulp :: Package server :: Module util
[hide private]
[frames] | no frames]

Source Code for Module pulp.server.util

  1  #!/usr/bin/python 
  2  # 
  3  # Copyright (c) 2010 Red Hat, Inc. 
  4  # 
  5  # 
  6  # This software is licensed to you under the GNU General Public License, 
  7  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  8  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  9  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
 10  # along with this software; if not, see 
 11  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 12  # 
 13  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 14  # granted to use or replicate Red Hat trademarks that are incorporated 
 15  # in this software or its documentation. 
 16  # 
 17   
 18  import hashlib # 3rd party on RHEL 5 
 19  import logging 
 20  import os 
 21  import random 
 22  import string 
 23  import time 
 24   
 25  import rpm 
 26  import yum 
 27   
 28  from pulp.server.pexceptions import PulpException 
 29   
 30   
 31  log = logging.getLogger(__name__) 
 32   
 33   
34 -def get_rpm_information(rpm_path):
35 """ 36 Get metadata about an RPM. 37 38 @param rpm_path: Full path to the RPM to inspect 39 """ 40 log.debug("rpm_path: %s" % rpm_path) 41 ts = rpm.ts() 42 ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) 43 file_descriptor_number = os.open(rpm_path, os.O_RDONLY) 44 rpm_info = ts.hdrFromFdno(file_descriptor_number); 45 os.close(file_descriptor_number) 46 return rpm_info
47 48
49 -def random_string():
50 ''' 51 Generates a random string suitable for using as a password. 52 ''' 53 chars = string.ascii_letters + string.digits 54 return "".join(random.choice(chars) for x in range(random.randint(8, 16)))
55 56
57 -def chunks(l, n):
58 """ 59 Split an array into n# of chunks. Taken from : http://tinyurl.com/y8v5q2j 60 """ 61 return [l[i:i+n] for i in range(0, len(l), n)]
62 63
64 -def get_file_checksum(hashtype="sha", filename=None, fd=None, file=None, buffer_size=None):
65 """ 66 Compute a file's checksum. 67 """ 68 if hashtype in ['sha', 'SHA']: 69 hashtype = 'sha1' 70 71 if buffer_size is None: 72 buffer_size = 65536 73 74 if filename is None and fd is None and file is None: 75 raise Exception("no file specified") 76 if file: 77 f = file 78 elif fd is not None: 79 f = os.fdopen(os.dup(fd), "r") 80 else: 81 f = open(filename, "r") 82 # Rewind it 83 f.seek(0, 0) 84 m = hashlib.new(hashtype) 85 while 1: 86 buffer = f.read(buffer_size) 87 if not buffer: 88 break 89 m.update(buffer) 90 91 # cleanup time 92 if file is not None: 93 file.seek(0, 0) 94 else: 95 f.close() 96 return m.hexdigest()
97 98
99 -def get_string_checksum(hashtype, data):
100 """ 101 Return checksum of a string 102 @param hashtype: hashtype, example "sha256" 103 @param data: string to get checksum 104 @return: checksum 105 """ 106 m = hashlib.new(hashtype) 107 m.update(data) 108 return m.hexdigest()
109 110
111 -def get_file_timestamp(filename):
112 """ 113 Returns a timestamp 114 @param filename: filename path to file 115 @return: filename's timestamp 116 """ 117 return int(os.stat(filename).st_mtime)
118 119
120 -def get_repomd_filetypes(repomd_path):
121 """ 122 @param repomd_path: path to repomd.xml 123 @return: List of available metadata types 124 """ 125 rmd = yum.repoMDObject.RepoMD("temp_pulp", repomd_path) 126 if rmd: 127 return rmd.fileTypes()
128 129
130 -def _get_yum_repomd(path):
131 """ 132 @param path: path to repo 133 @return yum.yumRepo.YumRepository object initialized for querying repodata 134 """ 135 r = yum.yumRepo.YumRepository("temp_repo-%s" % (time.time())) 136 r.baseurl = "file://%s" % (path.encode("ascii", "ignore")) 137 r.basecachedir = path.encode("ascii", "ignore") 138 r.baseurlSetup() 139 return r
140 141
142 -def get_repo_package(repo_path, package_filename):
143 """ 144 @param repo_path: The file system path to the repository you wish to fetch 145 the package metadata from 146 @param package_filename: the filename of the package you want the metadata for 147 """ 148 repoPackages = get_repo_packages(repo_path) 149 found = None 150 for p in repoPackages: 151 if (p.relativepath == package_filename): 152 found = p 153 if found is None: 154 raise PulpException("No package with file name: %s found in repository: %s" 155 % (package_filename, repo_path)) 156 return found
157 158
159 -def get_repo_packages(path):
160 """ 161 @param path: path to repo's base (not the repodatadir, this api 162 expects a path/repodata underneath this path) 163 @return: List of available packages objects in the repo. 164 """ 165 r = _get_yum_repomd(path) 166 if not r: 167 return [] 168 r.sack.populate(r, 'metadata', None, 0) 169 return r.getPackageSack().returnPackages()
170 171
172 -def get_repomd_filetype_path(path, filetype):
173 """ 174 @param path: path to repo 175 @param filetype: metadata type to query, example "group", "primary", etc 176 @return: Path for filetype, or None 177 """ 178 rmd = yum.repoMDObject.RepoMD("temp_pulp", path) 179 if rmd: 180 data = rmd.getData(filetype) 181 return data.location[1] 182 return None
183 184
185 -def listdir(directory):
186 """ 187 List the packages in the given directory. 188 @type directory: str 189 @param directory: name of the directory 190 @return: list of 'directory/package name' 191 """ 192 directory = os.path.abspath(os.path.normpath(directory)) 193 if not os.access(directory, os.R_OK | os.X_OK): 194 raise Exception("Cannot read from directory %s" % directory) 195 if not os.path.isdir(directory): 196 raise Exception("%s not a directory" % directory) 197 # Build the package list 198 packagesList = [] 199 for f in os.listdir(directory): 200 packagesList.append("%s/%s" % (directory, f)) 201 return packagesList
202 203
204 -def compare_packages(pkgA, pkgB):
205 """ 206 return 1: pkgA is newer than pkgB 207 return 0: pkgA equals pkgB 208 return -1: pkgB is newer than pkgA 209 """ 210 def build_evr(pkg): 211 evr = [pkg["epoch"], pkg["version"], pkg["release"]] 212 evr = map(str, evr) 213 if evr[0] == "": 214 evr[0] = None 215 return evr
216 217 evrA, evrB = (build_evr(pkgA), build_evr(pkgB)) 218 return rpm.labelCompare(evrA, evrB) 219
220 -def check_package_exists(pkg_path, hashsum, hashtype="sha", force=0):
221 if not os.path.exists(pkg_path): 222 return False 223 # File exists, same hash? 224 curr_hash = get_file_checksum(hashtype, pkg_path) 225 if curr_hash == hashsum and not force: 226 return True 227 if force: 228 return False 229 return False
230
231 -class Singleton(type):
232 """ 233 Singleton metaclass. To make a class instance a singleton, use this class 234 as your class's metaclass as follows: 235 236 class MyClass(object): 237 __metaclass__ = Singleton 238 239 Singletons are created by passing the exact same arguments to the 240 constructor. For example: 241 242 class T(): 243 __metaclass__ = Singleton 244 245 def __init__(self, value=None): 246 self.value = value 247 248 t1 = T() 249 t2 = T() 250 t1 is t2 251 True 252 t3 = T(5) 253 t4 = T(5) 254 t3 is t4 255 True 256 t1 is t3 257 False 258 """
259 - def __init__(self, name, bases, ns):
260 super(Singleton, self).__init__(name, bases, ns) 261 self.instances = {}
262
263 - def __call__(self, *args, **kwargs):
264 key = (tuple(args), tuple(sorted(kwargs.items()))) 265 return self.instances.setdefault(key, super(Singleton, self).__call__(*args, **kwargs))
266