Package rpmUtils :: Module arch
[hide private]
[frames] | no frames]

Source Code for Module rpmUtils.arch

  1  #!/usr/bin/python 
  2  # 
  3   
  4  import os 
  5   
  6  # dict mapping arch -> ( multicompat, best personality, biarch personality ) 
  7  multilibArches = { "x86_64":  ( "athlon", "x86_64", "athlon" ), 
  8                     "sparc64v": ( "sparc", "sparcv9v", "sparc64v" ), 
  9                     "sparc64": ( "sparc", "sparcv9", "sparc64" ), 
 10                     "ppc64":   ( "ppc", "ppc", "ppc64" ), 
 11                     "s390x":   ( "s390", "s390x", "s390" ), 
 12                     } 
 13   
 14  arches = { 
 15      # ia32 
 16      "athlon": "i686", 
 17      "i686": "i586", 
 18      "geode": "i586", 
 19      "i586": "i486", 
 20      "i486": "i386", 
 21      "i386": "noarch", 
 22       
 23      # amd64 
 24      "x86_64": "athlon", 
 25      "amd64": "x86_64", 
 26      "ia32e": "x86_64", 
 27       
 28      # ppc 
 29      "ppc64pseries": "ppc64", 
 30      "ppc64iseries": "ppc64",     
 31      "ppc64": "ppc", 
 32      "ppc": "noarch", 
 33       
 34      # s390{,x} 
 35      "s390x": "s390", 
 36      "s390": "noarch", 
 37       
 38      # sparc 
 39      "sparc64v": "sparc64", 
 40      "sparc64v": "sparcv9v", 
 41      "sparc64": "sparcv9", 
 42      "sparcv9v": "sparcv9", 
 43      "sparcv9": "sparcv8", 
 44      "sparcv8": "sparc", 
 45      "sparc": "noarch", 
 46   
 47      # alpha 
 48      "alphaev7":   "alphaev68", 
 49      "alphaev68":  "alphaev67", 
 50      "alphaev67":  "alphaev6", 
 51      "alphaev6":   "alphapca56", 
 52      "alphapca56": "alphaev56", 
 53      "alphaev56":  "alphaev5", 
 54      "alphaev5":   "alphaev45", 
 55      "alphaev45":  "alphaev4", 
 56      "alphaev4":   "alpha", 
 57      "alpha":      "noarch", 
 58   
 59      # arm 
 60      "armv7l": "armv6l", 
 61      "armv6l": "armv5tejl", 
 62      "armv5tejl": "armv5tel", 
 63      "armv5tel": "noarch", 
 64   
 65      # super-h  
 66      "sh4a": "sh4", 
 67      "sh4": "noarch", 
 68      "sh3": "noarch", 
 69       
 70      #itanium 
 71      "ia64": "noarch", 
 72      } 
 73   
74 -def legitMultiArchesInSameLib(arch=None):
75 # this is completely crackrock - if anyone has a better way I 76 # am all ears 77 78 arch = getBestArch(arch) 79 if isMultiLibArch(arch): 80 arch = getBaseArch(myarch=arch) 81 82 results = [arch] 83 84 if arch == 'x86_64' or arch.startswith('sparcv9'): 85 for (k, v) in arches.items(): 86 if v == arch: 87 results.append(k) 88 return results
89 90
91 -def canCoinstall(arch1, arch2):
92 """Take two arches and return True if it is possible that they can be 93 installed together with the same nevr. Ex: arch1=i386 and arch2=i686 then 94 it will return False. arch1=i386 and arch2=x86_64 will return True. 95 It does not determine whether or not the arches make any sense. Just whether 96 they could possibly install w/o conflict""" 97 98 # if both are a multlibarch then we can't coinstall (x86_64, ia32e) 99 # if both are not multilibarches then we can't coinstall (i386, i686) 100 101 if 'noarch' in [arch1, arch2]: # noarch can never coinstall 102 return False 103 104 if isMultiLibArch(arch=arch1) == isMultiLibArch(arch=arch2): 105 return False 106 # this section keeps arch1=x86_64 arch2=ppc from returning True 107 if arch1 in getArchList(arch2) or arch2 in getArchList(arch1): 108 return True 109 return False
110 111 # this computes the difference between myarch and targetarch
112 -def archDifference(myarch, targetarch):
113 if myarch == targetarch: 114 return 1 115 if myarch in arches: 116 ret = archDifference(arches[myarch], targetarch) 117 if ret != 0: 118 return ret + 1 119 return 0 120 return 0
121
122 -def score(arch):
123 return archDifference(canonArch, arch)
124
125 -def isMultiLibArch(arch=None):
126 """returns true if arch is a multilib arch, false if not""" 127 if arch is None: 128 arch = canonArch 129 130 if arch not in arches: # or we could check if it is noarch 131 return 0 132 133 if arch in multilibArches: 134 return 1 135 136 if arches[arch] in multilibArches: 137 return 1 138 139 return 0
140
141 -def getBestArchFromList(archlist, myarch=None):
142 """ 143 return the best arch from the list for myarch if - myarch is not given, 144 then return the best arch from the list for the canonArch. 145 """ 146 147 if len(archlist) == 0: 148 return None 149 150 if myarch is None: 151 myarch = canonArch 152 153 mybestarch = getBestArch(myarch) 154 155 bestarch = getBestArch(myarch) 156 if bestarch != myarch: 157 bestarchchoice = getBestArchFromList(archlist, bestarch) 158 if bestarchchoice != None and bestarchchoice != "noarch": 159 return bestarchchoice 160 161 thisarch = archlist[0] 162 for arch in archlist[1:]: 163 val1 = archDifference(myarch, thisarch) 164 val2 = archDifference(myarch, arch) 165 if val1 == 0 and val2 == 0: 166 continue 167 if val1 < val2: 168 if val1 == 0: 169 thisarch = arch 170 if val2 < val1: 171 if val2 != 0: 172 thisarch = arch 173 if val1 == val2: 174 pass 175 176 # thisarch should now be our bestarch 177 # one final check to make sure we're not returning a bad arch 178 val = archDifference(myarch, thisarch) 179 if val == 0: 180 return None 181 182 return thisarch
183 184
185 -def getArchList(thisarch=None):
186 # this returns a list of archs that are compatible with arch given 187 if not thisarch: 188 thisarch = canonArch 189 190 archlist = [thisarch] 191 while thisarch in arches: 192 thisarch = arches[thisarch] 193 archlist.append(thisarch) 194 195 # hack hack hack 196 # sparc64v is also sparc64 compat 197 if archlist[0] == "sparc64v": 198 archlist.insert(1,"sparc64") 199 200 # if we're a weirdo arch - add noarch on there. 201 if len(archlist) == 1 and archlist[0] == thisarch: 202 archlist.append('noarch') 203 return archlist
204 205 206
207 -def getCanonX86Arch(arch):
208 # 209 if arch == "i586": 210 f = open("/proc/cpuinfo", "r") 211 lines = f.readlines() 212 f.close() 213 for line in lines: 214 if line.startswith("model name") and line.find("Geode(TM)") != -1: 215 return "geode" 216 return arch 217 # only athlon vs i686 isn't handled with uname currently 218 if arch != "i686": 219 return arch 220 221 # if we're i686 and AuthenticAMD, then we should be an athlon 222 f = open("/proc/cpuinfo", "r") 223 lines = f.readlines() 224 f.close() 225 for line in lines: 226 if line.startswith("vendor") and line.find("AuthenticAMD") != -1: 227 return "athlon" 228 # i686 doesn't guarantee cmov, but we depend on it 229 elif line.startswith("flags") and line.find("cmov") == -1: 230 return "i586" 231 232 return arch
233
234 -def getCanonPPCArch(arch):
235 # FIXME: should I do better handling for mac, etc? 236 if arch != "ppc64": 237 return arch 238 239 machine = None 240 f = open("/proc/cpuinfo", "r") 241 lines = f.readlines() 242 f.close() 243 for line in lines: 244 if line.find("machine") != -1: 245 machine = line.split(':')[1] 246 break 247 if machine is None: 248 return arch 249 250 if machine.find("CHRP IBM") != -1: 251 return "ppc64pseries" 252 if machine.find("iSeries") != -1: 253 return "ppc64iseries" 254 return arch
255
256 -def getCanonSPARCArch(arch):
257 # Deal with sun4v, sun4u, sun4m cases 258 SPARCtype = None 259 f = open("/proc/cpuinfo", "r") 260 lines = f.readlines() 261 f.close() 262 for line in lines: 263 if line.startswith("type"): 264 SPARCtype = line.split(':')[1] 265 break 266 if SPARCtype is None: 267 return arch 268 269 if SPARCtype.find("sun4v") != -1: 270 if arch.startswith("sparc64"): 271 return "sparc64v" 272 else: 273 return "sparcv9v" 274 if SPARCtype.find("sun4u") != -1: 275 if arch.startswith("sparc64"): 276 return "sparc64" 277 else: 278 return "sparcv9" 279 if SPARCtype.find("sun4m") != -1: 280 return "sparcv8" 281 return arch
282
283 -def getCanonX86_64Arch(arch):
284 if arch != "x86_64": 285 return arch 286 287 vendor = None 288 f = open("/proc/cpuinfo", "r") 289 lines = f.readlines() 290 f.close() 291 for line in lines: 292 if line.startswith("vendor_id"): 293 vendor = line.split(':')[1] 294 break 295 if vendor is None: 296 return arch 297 298 if vendor.find("Authentic AMD") != -1 or vendor.find("AuthenticAMD") != -1: 299 return "amd64" 300 if vendor.find("GenuineIntel") != -1: 301 return "ia32e" 302 return arch
303
304 -def getCanonArch(skipRpmPlatform = 0):
305 if not skipRpmPlatform and os.access("/etc/rpm/platform", os.R_OK): 306 try: 307 f = open("/etc/rpm/platform", "r") 308 line = f.readline() 309 f.close() 310 (arch, vendor, opersys) = line.split("-", 2) 311 return arch 312 except: 313 pass 314 315 arch = os.uname()[4] 316 317 if (len(arch) == 4 and arch[0] == "i" and arch[2:4] == "86"): 318 return getCanonX86Arch(arch) 319 320 if arch.startswith("ppc"): 321 return getCanonPPCArch(arch) 322 if arch.startswith("sparc"): 323 return getCanonSPARCArch(arch) 324 if arch == "x86_64": 325 return getCanonX86_64Arch(arch) 326 327 return arch
328 329 canonArch = getCanonArch() 330 331 # this gets you the "compat" arch of a biarch pair
332 -def getMultiArchInfo(arch = canonArch):
333 if arch in multilibArches: 334 return multilibArches[arch] 335 if arch in arches and arches[arch] != "noarch": 336 return getMultiArchInfo(arch = arches[arch]) 337 return None
338 339 # get the best usual userspace arch for the arch we're on. this is 340 # our arch unless we're on an arch that uses the secondary as its 341 # userspace (eg ppc64, sparc64)
342 -def getBestArch(myarch=None):
343 if myarch: 344 arch = myarch 345 else: 346 arch = canonArch 347 348 if arch.startswith("sparc64"): 349 arch = multilibArches[arch][1] 350 351 if arch.startswith("ppc64"): 352 arch = 'ppc' 353 354 return arch
355
356 -def getBaseArch(myarch=None):
357 """returns 'base' arch for myarch, if specified, or canonArch if not. 358 base arch is the arch before noarch in the arches dict if myarch is not 359 a key in the multilibArches.""" 360 361 if not myarch: 362 myarch = canonArch 363 364 if myarch not in arches: # this is dumb, but <shrug> 365 return myarch 366 367 if myarch.startswith("sparc64"): 368 return "sparc" 369 elif myarch.startswith("ppc64"): 370 return "ppc" 371 372 if isMultiLibArch(arch=myarch): 373 if myarch in multilibArches: 374 return myarch 375 else: 376 return arches[myarch] 377 378 if myarch in arches: 379 basearch = myarch 380 value = arches[basearch] 381 while value != 'noarch': 382 basearch = value 383 value = arches[basearch] 384 385 return basearch
386 387
388 -class ArchStorage(object):
389 """class for keeping track of what arch we have set and doing various 390 permutations based on it"""
391 - def __init__(self):
392 self.canonarch = None 393 self.basearch = None 394 self.bestarch = None 395 self.compatarches = [] 396 self.archlist = [] 397 self.multilib = False 398 self.setup_arch()
399
400 - def setup_arch(self, arch=None):
401 if arch: 402 self.canonarch = arch 403 else: 404 self.canonarch = getCanonArch() 405 406 self.basearch = getBaseArch(myarch=self.canonarch) 407 self.archlist = getArchList(thisarch=self.canonarch) 408 self.bestarch = getBestArch(myarch=self.canonarch) 409 self.compatarches = getMultiArchInfo(arch=self.canonarch) 410 self.multilib = isMultiLibArch(arch=self.canonarch) 411 self.legit_multi_arches = legitMultiArchesInSameLib(arch = self.canonarch)
412
413 - def get_best_arch_from_list(self, archlist, fromarch=None):
414 if not fromarch: 415 fromarch = self.canonarch 416 return getBestArchFromList(archlist, myarch=fromarch)
417
418 - def score(self, arch):
419 return archDifference(self.canonarch, arch)
420
421 - def get_arch_list(self, arch):
422 if not arch: 423 return self.archlist 424 return getArchList(thisarch=arch)
425