def _build_matcher(self, tags): # NOTE: Matcher only looks at tags atm product = stubs.StubProduct("69", "Red Hat Enterprise Linux Server", version="6.2", provided_tags=tags) matcher = rhelproduct.RHELProductMatcher(product) return matcher
def update_removed(self, active, temp_disabled_repos=None): """remove product certs for inactive products For each installed product cert, check to see if we still have packages installed from the repo the product cert was installed from. If not, delete the product cert. With a few exceptions: 1) if the productid db does not know about the product cert, do not delete it 2) if the productid db doesn't know what repo that cert came from, do not delete it. 3) If there were errors reading the repo metadata for any of the repos that provide that cert, do not delete it. 4) If the product cert has providedtags for 'rhel*' Args: active: a set of repo name strings of the repos that installed packages were installed from Side effects: deletes certs that need to be deleted """ temp_disabled_repos = temp_disabled_repos or [] certs_to_delete = [] log.debug("Checking for product certs to remove. Active include: %s", active) for cert in self.pdir.list(): p = cert.products[0] prod_hash = p.id # FIXME: or if the productid.hs wasn't updated to reflect a new repo repos = self.db.find_repos(prod_hash) delete_product_cert = True # this is the core of a fix for rhbz #859197 # # which is a scenario where we have rhel installed, a rhel cert installed, # a rhel entitlement, a rhel enabled repo, yet no packages installed from # that rhel repo. Aka, a system anaconda installed from a cloned repo # perhaps. In that case, all the installed package think they came from # that other repo (say, 'anaconda-repo'), so it looks like the rhel repo # is not 'active'. So it ends up deleting the product cert for rhel since # it appears it is not being used. It is kind of a strange case for the # base os product cert, so we hardcode a special case here. rhel_matcher = rhelproduct.RHELProductMatcher(p) if rhel_matcher.is_rhel(): delete_product_cert = False # If productid database does not know about the the product, # ie, repo is None (basically, return from a db.content.get(), # dont delete the cert because we dont know anything about it if repos is None or repos is []: # FIXME: this can also mean we need to update the product cert # for prod_hash, since it is installed, but no longer maps to a repo delete_product_cert = False # no repos to check, go to next cert continue for repo in repos: # if we had errors with the repo or productid metadata # we could be very confused here, so do not # delete anything. see bz #736424 if repo in self.meta_data_errors: log.debug( "%s has meta-data errors. Not deleting product cert %s.", repo, prod_hash) delete_product_cert = False # do not delete a product cert if the repo[a] associated with it's prod_hash # has packages installed. if repo in active: log.debug( "%s is an active repo. Not deleting product cert %s", repo, prod_hash) delete_product_cert = False # If product id maps to a repo that we know is only temporarily # disabled, don't delete it. if repo in temp_disabled_repos: log.warn( "%s is disabled via yum cmdline. Not deleting product cert %s", repo, prod_hash) delete_product_cert = False # is the repo we find here actually active? try harder to find active? # for this prod cert/hash, we know what repo[a] it's for, but nothing # appears to be installed from the repo[s] # if delete_product_cert: certs_to_delete.append((p, cert)) # TODO: plugin hook for pre_product_id_delete for (product, cert) in certs_to_delete: log.info("None of the repos for %s are active: %s", product.id, self.db.find_repos(product.id)) log.info("product cert %s for %s is being deleted" % (product.id, product.id)) cert.delete() self.pdir.refresh() #TODO: plugin hook for post_product_id_delete # it should be safe to delete it's entry now, we either dont # know anything about it's repos, it doesnt have any, or none # of the repos are active self.db.delete(product.id) self.db.write()
def get_releases(self): # cdn base url # find the rhel product release_product = None installed_products = self.product_dir.get_installed_products() for product_hash in installed_products: product_cert = installed_products[product_hash] products = product_cert.products for product in products: rhel_matcher = rhelproduct.RHELProductMatcher(product) if rhel_matcher.is_rhel(): release_product = product if release_product is None: log.info("No products with RHEL product tags found") return [] entitlements = self.entitlement_dir.list_for_product(release_product.id) listings = [] for entitlement in entitlements: contents = entitlement.content for content in contents: # ignore content that is not enabled # see bz #820639 if not content.enabled: continue if self._is_correct_rhel(release_product.provided_tags, content.required_tags): listing_path = self._build_listing_path(content.url) listings.append(listing_path) # FIXME: not sure how to get the "base" content if we have multiple # entitlements for a product # for a entitlement, grant the corresponding entitlement cert # use it for this connection # hmm. We are really only supposed to have one product # with one content with one listing file. We shall see. releases = [] listings = sorted(set(listings)) for listing_path in listings: try: data = self.content_connection.get_versions(listing_path) except (socket.error, httplib.HTTPException, SSLError) as e: # content connection doesn't handle any exceptions # and the code that invokes this doesn't either, so # swallow them here. log.exception(e) continue # any non 200 response on fetching the release version # listing file returns a None here if not data: continue ver_listing = listing.ListingFile(data=data) # ver_listing.releases can be empty releases = releases + ver_listing.get_releases() releases_set = sorted(set(releases)) return releases_set
def get_releases(self): # cdn base url # Find the rhel products release_products = [] certificates = set() installed_products = self.product_dir.get_installed_products() for product_hash in installed_products: product_cert = installed_products[product_hash] products = product_cert.products for product in products: rhel_matcher = rhelproduct.RHELProductMatcher(product) if rhel_matcher.is_rhel(): release_products.append(product) certificates.add(product_cert) if len(release_products) == 0: log.debug("No products with RHEL product tags found") return [] elif len(release_products) > 1: raise MultipleReleaseProductsError(certificates=certificates) # Note: only release_products with one item can pass previous if-elif release_product = release_products[0] entitlements = self.entitlement_dir.list_for_product(release_product.id) listings = [] ent_cert_key_pairs = set() for entitlement in entitlements: contents = entitlement.content for content in contents: # ignore content that is not enabled # see bz #820639 if not content.enabled: continue if self._is_correct_rhel(release_product.provided_tags, content.required_tags): listing_path = self._build_listing_path(content.url) listings.append(listing_path) ent_cert_key_pairs.add((entitlement.path, entitlement.key_path())) # FIXME: not sure how to get the "base" content if we have multiple # entitlements for a product # for a entitlement, grant the corresponding entitlement cert # use it for this connection # hmm. We are really only supposed to have one product # with one content with one listing file. We shall see. releases = [] listings = sorted(set(listings)) for listing_path in listings: try: data = self.content_connection.get_versions(listing_path) except (socket.error, six.moves.http_client.HTTPException, ssl.SSLError, NoValidEntitlement) as e: # content connection doesn't handle any exceptions # and the code that invokes this doesn't either, so # swallow them here. log.exception(e) continue # any non 200 response on fetching the release version # listing file returns a None here if not data: continue ver_listing = listing.ListingFile(data=data) # ver_listing.releases can be empty releases = releases + ver_listing.get_releases() releases_set = sorted(set(releases)) return releases_set