1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import hashlib
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
47
48
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
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
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
92 if file is not None:
93 file.seek(0, 0)
94 else:
95 f.close()
96 return m.hexdigest()
97
98
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
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
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
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
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
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
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
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
198 packagesList = []
199 for f in os.listdir(directory):
200 packagesList.append("%s/%s" % (directory, f))
201 return packagesList
202
203
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
221 if not os.path.exists(pkg_path):
222 return False
223
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
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 """
262
264 key = (tuple(args), tuple(sorted(kwargs.items())))
265 return self.instances.setdefault(key, super(Singleton, self).__call__(*args, **kwargs))
266