def update(errataidlist, cache_only=None): packagelist = [] if type(errataidlist) not in [type([]), type(())]: errataidlist = [ errataidlist ] for errataid in errataidlist: tmpList = __getErrataInfo(errataid) packagelist = packagelist + tmpList current_packages_with_arch = {} current_packages ={} for p in rpmUtils.getInstalledPackageList(getArch=1): current_packages_with_arch[p['name']+p['arch']] = p current_packages[p['name']] = p u = {} # only update packages that are currently installed # since an "applicable errata" may only contain some packages # that actually apply. aka kernel. Fun fun fun. if len(packagelist[0]) > 4: # Newer sats send down arch, filter using name+arch for p in packagelist: if current_packages_with_arch.has_key(p[0]+p[4]): u[p[0]+p[4]] = p elif current_packages_with_arch.has_key(p[0]+"noarch"): u[p[0]+p[4]] = p elif p[4] == "noarch" and current_packages.has_key(p[0]): u[p[0]] = p else: # 5.2 and older sats + hosted dont send arch for p in packagelist: if current_packages.has_key(p[0]): u[p[0]] = p # XXX: Fix me - once we keep all errata packages around, # this is the WRONG thing to do - we want to keep the specific versions # that the user has asked for. packagelist = map(lambda a: u[a], u.keys()) if packagelist == []: data = {} data['version'] = "0" data['name'] = "errata.update.no_packages" data['erratas'] = errataidlist return (39, "No packages from that errata are available", data) return packages.update(packagelist, cache_only)
def old_update(errataidlist, cache_only=None): # XXX: this method is the one used by yum systems, but it is # deprecated and error prone on zypper systems because patches are # supposed to be installed by themselves, rather than installing the # component packages packagelist = [] for errataid in errataidlist: tmpList = __getErrataInfo(errataid) packagelist = packagelist + tmpList current_packages_with_arch = {} current_packages ={} for p in rpmUtils.getInstalledPackageList(getArch=1): current_packages_with_arch[p['name']+p['arch']] = p current_packages[p['name']] = p u = {} # only update packages that are currently installed # since an "applicable errata" may only contain some packages # that actually apply. aka kernel. Fun fun fun. if len(packagelist[0]) > 4: # Newer sats send down arch, filter using name+arch for p in packagelist: if current_packages_with_arch.has_key(p[0]+p[4]): u[p[0]+p[4]] = p elif current_packages_with_arch.has_key(p[0]+"noarch"): u[p[0]+p[4]] = p elif p[4] == "noarch" and current_packages.has_key(p[0]): u[p[0]] = p else: # 5.2 and older sats + hosted dont send arch for p in packagelist: if current_packages.has_key(p[0]): u[p[0]] = p # XXX: Fix me - once we keep all errata packages around, # this is the WRONG thing to do - we want to keep the specific versions # that the user has asked for. packagelist = map(lambda a: u[a], u.keys()) if packagelist == []: data = {} data['version'] = "0" data['name'] = "errata.update.no_packages" data['erratas'] = errataidlist return (39, "No packages from that errata are available", data) return packages.update(packagelist, cache_only)
def old_update(errataidlist, cache_only=None): # XXX: this method is the one used by yum systems, but it is # deprecated and error prone on zypper systems because patches are # supposed to be installed by themselves, rather than installing the # component packages packagelist = [] for errataid in errataidlist: tmpList = __getErrataInfo(errataid) packagelist = packagelist + tmpList current_packages_with_arch = {} current_packages = {} for p in rpmUtils.getInstalledPackageList(getArch=1): current_packages_with_arch[p['name'] + p['arch']] = p current_packages[p['name']] = p u = {} # only update packages that are currently installed # since an "applicable errata" may only contain some packages # that actually apply. aka kernel. Fun fun fun. if len(packagelist[0]) > 4: # Newer sats send down arch, filter using name+arch for p in packagelist: if current_packages_with_arch.has_key(p[0] + p[4]): u[p[0] + p[4]] = p elif current_packages_with_arch.has_key(p[0] + "noarch"): u[p[0] + p[4]] = p elif p[4] == "noarch" and current_packages.has_key(p[0]): u[p[0]] = p else: # 5.2 and older sats + hosted dont send arch for p in packagelist: if current_packages.has_key(p[0]): u[p[0]] = p # XXX: Fix me - once we keep all errata packages around, # this is the WRONG thing to do - we want to keep the specific versions # that the user has asked for. packagelist = map(lambda a: u[a], u.keys()) if packagelist == []: data = {} data['version'] = "0" data['name'] = "errata.update.no_packages" data['erratas'] = errataidlist return (39, "No packages from that errata are available", data) return packages.update(packagelist, cache_only)
def main(self): if self.options.serverUrl: rhnreg.cfg.set("serverURL", self.options.serverUrl) if self.options.sslCACert: rhnreg.cfg.set("sslCACert", self.options.sslCACert) if not (self.options.activationkey or (self.options.username and self.options.password)): print _("A username and password are required "\ "to register a system.") sys.exit(-1) if rhnreg.registered() and not self.options.force: print _("This system is already registered. Use --force to override") sys.exit(-1) rhnreg.getCaps() if not self.options.nopackages: getArch = 0 if rhnreg.cfg['supportsExtendedPackageProfile']: getArch = 1 packageList = rpmUtils.getInstalledPackageList(getArch=getArch) else: packageList = [] hardwareList = hardware.Hardware() if self.options.profilename: profilename = self.options.profilename else: profilename = RegisterKsCli.__generateProfileName(hardwareList) other = {} if self.options.systemorgid: other['org_id'] = self.options.systemorgid # Try to get the virt uuid and put it in "other". (virt_uuid, virt_type) = rhnreg.get_virt_info() if not virt_uuid is None: other['virt_uuid'] = virt_uuid other['virt_type'] = virt_type # If specified, send up the EUS channel label for subscription. if self.options.use_eus_channel: if self.options.activationkey: print _("Usage of --use-eus-channel option with --activationkey is not supported. Please use username and password instead.") sys.exit(-1) if not rhnreg.server_supports_eus(): print _("The server you are registering against does not support EUS.") sys.exit(-1) channels = rhnreg.getAvailableChannels(self.options.username, self.options.password) other['channel'] = channels['default_channel'] try: if self.options.activationkey: systemId = rhnreg.registerSystem(token = self.options.activationkey, profileName = profilename, other = other) else: systemId = rhnreg.registerSystem(self.options.username, self.options.password, profilename, other = other) except (up2dateErrors.AuthenticationTicketError, up2dateErrors.RhnUuidUniquenessError, up2dateErrors.CommunicationError, up2dateErrors.AuthenticationOrAccountCreationError), e: print "%s" % e.errmsg sys.exit(1)
def solveDep(self, unknowns, availList, msgCallback=None, progressCallback=None, refreshCallback=None): self.cfg = config.initUp2dateConfig() self.log = up2dateLog.initLog() self.log.log_me("solving dep for: %s" % unknowns) self.refreshCallback = refreshCallback self.progressCallback = progressCallback self.msgCallback = msgCallback self.availList = availList availList.sort() self.availListHash = {} for p in self.availList: if self.availListHash.has_key(tuple(p[:4])): self.availListHash[tuple(p[:4])].append(p) else: self.availListHash[tuple(p[:4])] = [p] self.retDict = {} self.getSolutions(unknowns, progressCallback=self.progressCallback, msgCallback=self.msgCallback) reslist = [] self.depToPkg = DictOfLists() self.depsNotAvailable = DictOfLists() # self.depToPkg = {} #FIXME: this should be cached, I dont really need to query the db # for this everytime self.installedPkgList = rpmUtils.getInstalledPackageList(getArch=1) self.installedPkgHash = {} for pkg in self.installedPkgList: if self.installedPkgHash.has_key(pkg[0]): self.installedPkgHash[pkg[0]].append(pkg) else: self.installedPkgHash[pkg[0]] = [pkg] # we didnt get any results, bow out... if not len(self.retDict): return (reslist, self.depToPkg) newList = [] availListNVRE = map(lambda p: p[:4], self.availList) failedDeps = [] solutionPkgs = [] pkgs = [] for dep in self.retDict.keys(): # skip the rest if we didnt get a result if len(self.retDict[dep]) == 0: continue solutions = self.retDict[dep] # fixme, grab the first package that satisfies the dep # but make sure we match nvre against the list of avail packages # so we grab the right version of the package # if we only get one soltution, use it. No point in jumping # though other hoops if len(solutions) == 1: for solution in solutions: pkgs.append(solution) # we've got more than one possible solution, do some work # to figure out if I want one, some, or all of them elif len(solutions) > 1: # try to install the new version of whatever arch is # installed solutionsInstalled = self.__getSolutionsInstalled(solutions) found = 0 if len(solutionsInstalled): for p in solutionsInstalled: pkgs.append(p) self.depToPkg[dep] = p found = 1 if found: break # we dont have any of possible solutions installed, pick one else: # this is where we could do all sort of heuristics to pick # best one. For now, grab the first one in the list thats # available #FIXME: we need to arch score here for multilib/kernel # packages that dont have a version installed # This tends to happen a lot when isntalling into # empty chroots (aka, pick which of the kernels to # install). # ie, this is the pure heuristic approach... shortest = solutions[0] for solution in solutions: if len(shortest[0]) > len(solution[0]): shortest = solution # if we get this far, its still possible that we have package # that is multilib and we need to install both versions of # this is a check for that... if self.installedPkgHash.has_key(shortest[0]): iList = self.installedPkgHash[shortest[0]] for iPkg in iList: if self.availListHash.has_key(tuple(shortest[:4])): for i in self.availListHash[tuple( shortest[:4])]: if self.cfg['forcedArch']: arches = self.cfg['forcedArch'] if i[4] in arches: pkgs.append(i) self.depToPkg[dep] = i break else: # its not the same package we have installed if iPkg[:5] != i[:5]: # this arch matches the arch of a package # installed if iPkg[4] == i[4]: pkgs.append(i) self.depToPkg[dep] = i break # you may be asking yourself, wtf is that madness that follows? # well, good question... # its basically a series of kluges to work around packaging problems # in RHEL-3 (depends who you ask... But basically, its packages doing # stuff that was determined to be "unsupported" at the time of the # initial multilib support, but packages did it later anyway # Basically, what we are trying to do is pick the best arch of # a package to solve a dep. Easy enough. The tricky part is # what happens when we discover the best arch is already in # transation and is _not_ solving the dep, so we need to look # at the next best arch. So we check to see if we added it to # the list of selected packges already, and if so, add the # next best arch to the set. To make it uglier, the second best # arch might not be valid at all, so in that case, dont use it # (which will cause an unsolved dep, but they happen...) if self.availListHash.has_key(tuple(shortest[:4])): avail = self.availListHash[tuple(shortest[:4])] bestArchP = None useNextBestArch = None bestArchP2 = None # a saner approach might be to find the applicable arches, # sort them, and walk over them in order # remove the items with archscore <= 0 app_avail = filter(lambda a: rpm.archscore(a[4]), avail) # sort the items by archscore, most approriate first app_avail.sort(lambda a, b: cmp( rpm.archscore(a[4]), rpm.archscore(b[4]))) # so, whats wrong with this bit? well, if say "libgnutls.so(64bit)" doesn't # find a dep, we'll try to solve it with gnutls.i386 # its because "gnutls" and "libgnutls.so(64bit)" are in the same set of # deps. Since gnutls.x86_64 is added for the "gnutls" dep, its in the # list of already selected for for i in app_avail: if i in self.selectedPkgs: continue pkgs.append(i) self.depToPkg[dep] = i # we found something, stop iterating over available break # we found something for this dep, stop iterating continue else: # FIXME: in an ideal world, I could raise an exception here, but that will break the current gui pkgs.append(p) self.depToPkg[dep] = p # raise UnsolvedDependencyError("Packages %s provide dep %s but are not available for install based on client config" % (pkgs,dep), dep, pkgs ) for pkg in pkgs: self.selectedPkgs.append(pkg) if pkg[:4] in availListNVRE: newList.append(pkg) else: newList.append(pkg) reslist = newList # FIXME: we need to return the list of stuff that was skipped # because it wasn't on the available list and present it to the # user something like: # blippy-1.0-1 requires barpy-2.0-1 but barpy-3.0-1 is already isntalled #print "\n\nself.depsNotAvailable" #pprint.pprint(self.depsNotAvailable) #pprint.pprint(self.depToPkg) return (reslist, self.depToPkg)
def solveDep(self, unknowns, availList, msgCallback = None, progressCallback = None, refreshCallback = None): self.cfg = config.initUp2dateConfig() self.log = up2dateLog.initLog() self.log.log_me("solving dep for: %s" % unknowns) self.refreshCallback = refreshCallback self.progressCallback = progressCallback self.msgCallback = msgCallback self.availList = availList availList.sort() self.availListHash = {} for p in self.availList: if self.availListHash.has_key(tuple(p[:4])): self.availListHash[tuple(p[:4])].append(p) else: self.availListHash[tuple(p[:4])] = [p] self.retDict = {} self.getSolutions(unknowns, progressCallback = self.progressCallback, msgCallback = self.msgCallback) reslist = [] self.depToPkg = DictOfLists() self.depsNotAvailable = DictOfLists() # self.depToPkg = {} #FIXME: this should be cached, I dont really need to query the db # for this everytime self.installedPkgList = rpmUtils.getInstalledPackageList(getArch=1) self.installedPkgHash = {} for pkg in self.installedPkgList: if self.installedPkgHash.has_key(pkg[0]): self.installedPkgHash[pkg[0]].append(pkg) else: self.installedPkgHash[pkg[0]] = [pkg] # we didnt get any results, bow out... if not len(self.retDict): return (reslist, self.depToPkg) newList = [] availListNVRE = map(lambda p: p[:4], self.availList) failedDeps = [] solutionPkgs = [] pkgs = [] for dep in self.retDict.keys(): # skip the rest if we didnt get a result if len(self.retDict[dep]) == 0: continue solutions = self.retDict[dep] # fixme, grab the first package that satisfies the dep # but make sure we match nvre against the list of avail packages # so we grab the right version of the package # if we only get one soltution, use it. No point in jumping # though other hoops if len(solutions) == 1: for solution in solutions: pkgs.append(solution) # we've got more than one possible solution, do some work # to figure out if I want one, some, or all of them elif len(solutions) > 1: # try to install the new version of whatever arch is # installed solutionsInstalled = self.__getSolutionsInstalled(solutions) found = 0 if len(solutionsInstalled): for p in solutionsInstalled: pkgs.append(p) self.depToPkg[dep] = p found = 1 if found: break # we dont have any of possible solutions installed, pick one else: # this is where we could do all sort of heuristics to pick # best one. For now, grab the first one in the list thats # available #FIXME: we need to arch score here for multilib/kernel # packages that dont have a version installed # This tends to happen a lot when isntalling into # empty chroots (aka, pick which of the kernels to # install). # ie, this is the pure heuristic approach... shortest = solutions[0] for solution in solutions: if len(shortest[0]) > len(solution[0]): shortest = solution # if we get this far, its still possible that we have package # that is multilib and we need to install both versions of # this is a check for that... if self.installedPkgHash.has_key(shortest[0]): iList = self.installedPkgHash[shortest[0]] for iPkg in iList: if self.availListHash.has_key(tuple(shortest[:4])): for i in self.availListHash[tuple(shortest[:4])]: if self.cfg['forcedArch']: arches = self.cfg['forcedArch'] if i[4] in arches: pkgs.append(i) self.depToPkg[dep] = i break else: # its not the same package we have installed if iPkg[:5] != i[:5]: # this arch matches the arch of a package # installed if iPkg[4] == i[4]: pkgs.append(i) self.depToPkg[dep] = i break # you may be asking yourself, wtf is that madness that follows? # well, good question... # its basically a series of kluges to work around packaging problems # in RHEL-3 (depends who you ask... But basically, its packages doing # stuff that was determined to be "unsupported" at the time of the # initial multilib support, but packages did it later anyway # Basically, what we are trying to do is pick the best arch of # a package to solve a dep. Easy enough. The tricky part is # what happens when we discover the best arch is already in # transation and is _not_ solving the dep, so we need to look # at the next best arch. So we check to see if we added it to # the list of selected packges already, and if so, add the # next best arch to the set. To make it uglier, the second best # arch might not be valid at all, so in that case, dont use it # (which will cause an unsolved dep, but they happen...) if self.availListHash.has_key(tuple(shortest[:4])): avail = self.availListHash[tuple(shortest[:4])] bestArchP = None useNextBestArch = None bestArchP2 = None # a saner approach might be to find the applicable arches, # sort them, and walk over them in order # remove the items with archscore <= 0 app_avail = filter(lambda a: rpm.archscore(a[4]), avail) # sort the items by archscore, most approriate first app_avail.sort(lambda a,b: cmp(rpm.archscore(a[4]),rpm.archscore(b[4]))) # so, whats wrong with this bit? well, if say "libgnutls.so(64bit)" doesn't # find a dep, we'll try to solve it with gnutls.i386 # its because "gnutls" and "libgnutls.so(64bit)" are in the same set of # deps. Since gnutls.x86_64 is added for the "gnutls" dep, its in the # list of already selected for for i in app_avail: if i in self.selectedPkgs: continue pkgs.append(i) self.depToPkg[dep] = i # we found something, stop iterating over available break # we found something for this dep, stop iterating continue else: # FIXME: in an ideal world, I could raise an exception here, but that will break the current gui pkgs.append(p) self.depToPkg[dep] = p # raise UnsolvedDependencyError("Packages %s provide dep %s but are not available for install based on client config" % (pkgs,dep), dep, pkgs ) for pkg in pkgs: self.selectedPkgs.append(pkg) if pkg[:4] in availListNVRE: newList.append(pkg) else: newList.append(pkg) reslist = newList # FIXME: we need to return the list of stuff that was skipped # because it wasn't on the available list and present it to the # user something like: # blippy-1.0-1 requires barpy-2.0-1 but barpy-3.0-1 is already isntalled #print "\n\nself.depsNotAvailable" #pprint.pprint(self.depsNotAvailable) #pprint.pprint(self.depToPkg) return (reslist, self.depToPkg)