home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2000 July / CD 3 / redhat-6.2.iso / RedHat / instimage / usr / lib / anaconda / comps.py < prev    next >
Encoding:
Python Source  |  2000-03-08  |  8.5 KB  |  327 lines

  1. import sys
  2. import rpm
  3. import os
  4. from string import *
  5. import types
  6. import iutil
  7. import urllib
  8.  
  9. XFreeServerPackages = { 'XFree86-3DLabs' : 1,     'XFree86-8514' : 1,
  10.             'XFree86-AGX' : 1,     'XFree86-I128' : 1,
  11.             'XFree86-Mach32' : 1,     'XFree86-Mach64' : 1,
  12.             'XFree86-Mach8' : 1,     'XFree86-Mono' : 1,
  13.             'XFree86-P9000' : 1,     'XFree86-S3' : 1,
  14.             'XFree86-S3V' : 1,     'XFree86-SVGA' : 1,
  15.             'XFree86-W32' : 1,    'XFree86-Sun' : 1,
  16.             'XFree86-SunMono' : 1,    'XFree86-Sun24' : 1 }
  17.  
  18. class Package:
  19.     def __getitem__(self, item):
  20.     return self.h[item]
  21.  
  22.     def __repr__(self):
  23.     return self.name
  24.  
  25.     def __init__(self, header):
  26.     self.h = header
  27.     self.name = header[rpm.RPMTAG_NAME]
  28.     self.selected = 0
  29.  
  30. class HeaderList:
  31.     def selected(self):
  32.     l = []
  33.      keys = self.packages.keys()
  34.     keys.sort()
  35.     for name in keys:
  36.         if self.packages[name].selected: l.append(self.packages[name])
  37.     return l
  38.  
  39.     def has_key(self, item):
  40.     return self.packages.has_key(item)
  41.  
  42.     def keys(self):
  43.         return self.packages.keys()
  44.  
  45.     def __getitem__(self, item):
  46.     return self.packages[item]
  47.  
  48.     def __init__(self, hdlist):
  49.         self.hdlist = hdlist
  50.     self.packages = {}
  51.     for h in hdlist:
  52.         name = h[rpm.RPMTAG_NAME]
  53.         score1 = rpm.archscore(h['arch'])
  54.         if (score1):
  55.         if self.packages.has_key(name):
  56.             score2 = rpm.archscore(self.packages[name].h['arch'])
  57.             if (score1 < score2):
  58.             self.packages[name] = Package(h)
  59.         else:
  60.             self.packages[name] = Package(h)
  61.  
  62. class HeaderListFromFile (HeaderList):
  63.  
  64.     def __init__(self, path):
  65.     hdlist = rpm.readHeaderListFromFile(path)
  66.     HeaderList.__init__(self, hdlist)
  67.  
  68. class HeaderListFD (HeaderList):
  69.     def __init__(self, fd):
  70.     hdlist = rpm.readHeaderListFromFD (fd)
  71.     HeaderList.__init__(self, hdlist)
  72.  
  73. class Component:
  74.     def __len__(self):
  75.     return len(self.items)
  76.  
  77.     def __getitem__(self, key):
  78.     return self.items[key]
  79.  
  80.     def addPackage(self, package):
  81.     self.items[package] = package
  82.  
  83.     def addConditional (self, condition, package):
  84.         if self.conditional.has_key (condition):
  85.             self.conditional[condition].append (package)
  86.         else:
  87.             self.conditional[condition] = [ package ]
  88.  
  89.     def addInclude(self, component):
  90.     self.includes.append(component)
  91.     
  92.     def addRequires(self, component):
  93.     self.requires = component
  94.  
  95.     def conditionalSelect (self, key):
  96.         for pkg in self.conditional[key]:
  97.             pkg.selected = 1
  98.  
  99.     def conditionalUnselect (self, key):
  100.         for pkg in self.conditional[key]:
  101.             pkg.selected = 0
  102.  
  103.     def select(self, recurse = 1):
  104.         self.selected = 1
  105.     for pkg in self.items.keys ():
  106.         self.items[pkg].selected = 1
  107.         # turn on any conditional packages
  108.         for (condition, pkgs) in self.conditional.items ():
  109.             if condition.selected:
  110.                 for pkg in pkgs:
  111.                     pkg.selected = 1
  112.  
  113.         # components that have conditional packages keyed on this
  114.         # component AND are currently selected have those conditional
  115.         # packages turned turned on when this component is turned on.
  116.         if self.dependents:
  117.             for dep in self.dependents:
  118.                 if dep.selected:
  119.                     dep.conditionalSelect (self)
  120.                 
  121.     if recurse:
  122.         for n in self.includes:
  123.         if n.requires:
  124.             if n.requires.selected:
  125.             n.select(recurse)
  126.             else:
  127.             n.select(recurse)
  128.         if n.requires:
  129.             if n.requires.selected:
  130.             n.select(recurse)
  131.             else:
  132.             n.select(recurse)
  133.  
  134.     def unselect(self, recurse = 1):
  135.         self.selected = 0
  136.     for n in self.items.keys ():
  137.         self.items[n].selected = 0
  138.  
  139.         # always turn off conditional packages, regardless
  140.         # if the condition is met or not.
  141.         for (condition, pkgs) in self.conditional.items ():
  142.             for pkg in pkgs:
  143.                 pkg.selected = 0
  144.  
  145.         # now we must turn off conditional packages in components that
  146.         # are keyed on this package
  147.         if self.dependents:
  148.             for dep in self.dependents:
  149.                 dep.conditionalUnselect (self)
  150.  
  151.     if recurse:
  152.         for n in self.includes:
  153.         n.unselect(recurse)
  154.  
  155.     def __init__(self, name, selected, hidden = 0):
  156.     self.name = name
  157.     self.hidden = hidden
  158.     self.selected = selected
  159.     self.items = {}
  160.         self.conditional = {}
  161.         self.dependents = []
  162.     self.requires = None
  163.     self.includes = []
  164.  
  165. class ComponentSet:
  166.     def __len__(self):
  167.     return len(self.comps)
  168.  
  169.     def __getitem__(self, key):
  170.     if (type(key) == types.IntType):
  171.         return self.comps[key]
  172.     return self.compsDict[key]
  173.  
  174.     def keys(self):
  175.     return self.compsDict.keys()
  176.  
  177.     def exprMatch(self, expr, arch1, arch2):
  178.     if os.environ.has_key('LANG'):
  179.         lang = os.environ['LANG']
  180.     else:
  181.         lang = None
  182.  
  183.     if expr[0] != '(':
  184.         raise ValueError, "leading ( expected"
  185.     expr = expr[1:]
  186.     if expr[len(expr) - 1] != ')':
  187.         raise ValueError, "bad kickstart file [missing )]"
  188.     expr = expr[:len(expr) - 1]
  189.  
  190.     exprList = split(expr, 'and')
  191.     truth = 1
  192.     for expr in exprList:
  193.         l = split(expr)
  194.  
  195.         if l[0] == "lang":
  196.         if len(l) != 2:
  197.             raise ValueError, "too many arguments for lang"
  198.         if l[1] != lang:
  199.             newTruth = 0
  200.         else:
  201.             newTruth = 1
  202.         elif l[0] == "arch":
  203.         if len(l) != 2:
  204.             raise ValueError, "too many arguments for arch"
  205.         newTruth = self.archMatch(l[1], arch1, arch2)
  206.         else:
  207.         s = "unknown condition type %s" % (l[0],)
  208.         raise ValueError, s
  209.  
  210.         truth = truth and newTruth
  211.  
  212.     return truth
  213.  
  214.     # this checks to see if "item" is one of the archs
  215.     def archMatch(self, item, arch1, arch2):
  216.     if item == arch1 or (arch2 and item == arch2): 
  217.         return 1
  218.     return 0
  219.  
  220.     def readCompsFile(self, filename, packages):
  221.     arch = iutil.getArch()
  222.     arch2 = None
  223.     if arch == "sparc" and os.uname ()[4] == "sparc64":
  224.         arch2 = "sparc64"
  225.     file = urllib.urlopen(filename)
  226.     lines = file.readlines()
  227.  
  228.     file.close()
  229.     top = lines[0]
  230.     lines = lines[1:]
  231.     if (top != "3\n" and top != "4\n"):
  232.         raise TypeError, "comp file version 3 or 4 expected"
  233.     
  234.     comp = None
  235.         conditional = None
  236.     self.comps = []
  237.     self.compsDict = {}
  238.     for l in lines:
  239.         l = strip (l)
  240.         if (not l): continue
  241.  
  242.         if (find(l, ":") > -1):
  243.         (archList, l) = split(l, ":", 1)
  244.         if archList[0] == '(':
  245.             l = strip(l)
  246.             if not self.exprMatch(archList, arch, arch2):
  247.             continue
  248.         else:
  249.             while (l[0] == " "): l = l[1:]
  250.  
  251.             skipIfFound = 0
  252.             if (archList[0] == '!'):
  253.             skipIfFound = 1
  254.             archList = archList[1:]
  255.             archList = split(archList)
  256.             found = 0
  257.             for n in archList:
  258.             if self.archMatch(n, arch, arch2):    
  259.                 found = 1
  260.                 break
  261.             if ((found and skipIfFound) or 
  262.             (not found and not skipIfFound)):
  263.             continue
  264.  
  265.         if (find(l, "?") > -1):
  266.                 (trash, cond) = split (l, '?', 1)
  267.                 (cond, trash) = split (cond, '{', 1)
  268.                 conditional = self.compsDict[strip (cond)]
  269.                 continue
  270.  
  271.         if (comp == None):
  272.         (default, l) = split(l, None, 1)
  273.         hidden = 0
  274.         if (l[0:6] == "--hide"):
  275.             hidden = 1
  276.             (foo, l) = split(l, None, 1)
  277.                 (l, trash) = split(l, '{', 1)
  278.                 l = strip (l)
  279.                 if l == "Base":
  280.                     hidden = 1
  281.         comp = Component(l, default == '1', hidden)
  282.         elif (l == "}"):
  283.                 if conditional:
  284.             if comp.conditional.has_key (conditional):
  285.             conditional.dependents.append (comp)
  286.                     conditional = None
  287.                 else:
  288.                     self.comps.append(comp)
  289.                     self.compsDict[comp.name] = comp
  290.                     comp = None
  291.         else:
  292.         if (l[0] == "@"):
  293.             (at, l) = split(l, None, 1)
  294.             comp.addInclude(self.compsDict[l])
  295.         else:
  296.                     if conditional:
  297.                         comp.addConditional (conditional, packages[l])
  298.                     else:
  299.                         comp.addPackage(packages[l])
  300.                     
  301.         everything = Component("Everything", 0, 0)
  302.         for package in packages.keys ():
  303.         if (packages[package]['name'] != 'kernel' and
  304.                 packages[package]['name'] != 'kernel-BOOT' and
  305.                 packages[package]['name'] != 'kernel-smp' and
  306.           not XFreeServerPackages.has_key(packages[package]['name'])):
  307.         everything.addPackage (packages[package])
  308.         self.comps.append (everything)
  309.         self.compsDict["Everything"] = everything
  310.         
  311.     def __repr__(self):
  312.     s = ""
  313.     for n in self.comps:
  314.         s = s + "{ " + n.name + " [";
  315.         for include in n.includes:
  316.         s = s + " @" + include.name
  317.         
  318.         for package in n:
  319.         s = s + " " + package
  320.         s = s + " ] } "
  321.  
  322.     return s
  323.  
  324.     def __init__(self, file, hdlist):
  325.     self.packages = hdlist
  326.     self.readCompsFile(file, self.packages)
  327.