def delta(inp_left, inp_right, **kwargs): left = input_to_nevr_dict(inp_left, **kwargs) right = input_to_nevr_dict(inp_right, **kwargs) lc = set(left.keys()) rc = set(right.keys()) removed_comps = sorted(list(lc - rc)) removed = {} for comp in removed_comps: removed[comp] = left[comp] added_comps = sorted(list(rc - lc)) added = {} for comp in added_comps: added[comp] = right[comp] common_comps = sorted(list(lc & rc)) common = {} downgrades = {} upgrades = {} # Break this one up in a more granular fashion for comp in common_comps: lnevr = left[comp] rnevr = right[comp] (ln, lv, lr, le, la) = splitFilename(lnevr) (rn, rv, rr, re, ra) = splitFilename(rnevr) rebase = False if lv != rv: rebase = True ret = labelCompare((le, lv, lr), (re, rv, rr)) if ret > 0: downgrades[comp] = {'old': lnevr, 'new': rnevr, 'rebase': rebase} elif ret < 0: upgrades[comp] = {'old': lnevr, 'new': rnevr, 'rebase': rebase} else: common[comp] = lnevr ret = {} ret['old'] = left ret['new'] = right ret['removed'] = removed ret['added'] = added ret['common'] = common ret['downgrades'] = downgrades ret['upgrades'] = upgrades return ret
def parse_list(self, this_list, ignore_packages=None): """ Take a list of containers and convert it to dictionary Dictionary key is the package name, the value is the version info Parameters: list (list): list of rpms Returns: packages: a dictionary of rpm key, value pairs """ packages = defaultdict(list) # TO-DO pass ignored and error to result # packages_ignored = () packages_error = () for item in this_list: # sanitize ignored = False if "metadata expiration" in item: continue try: nvr = utils.splitFilename(item) version = nvr[1] release = nvr[2] if ignore_packages: search_term = "{}".format(nvr[0]) for ignore in ignore_packages: if ".*" in ignore: r = re.compile(ignore) match = r.match(search_term) if match: logging.info( "Ignoring Package: {}".format(search_term)) ignored = True else: if ignore in search_term: logging.info( "Ignoring Package: {}".format(search_term)) ignored = True if not ignored: packages[nvr[0]].append((version, release)) except Exception as e: logging.error(e) logging.warning( "error found getting package name/version for {}" " OR the ignore package regex {}".format( str(item), ignore)) is_alpha = re.match('[a-zA-Z]', nvr[0]) if not is_alpha: packages_error.add(item) logging.warning("package name does not meet criteria " "for item: {}".format(item)) continue continue return packages
def tidy_nevra(nevra): (n, v, r, e, a) = splitFilename(nevra) if e != 0 and e != '' and e != '0': v = f'{e}:{v}' nevra = '-'.join([x for x in [n, v, r] if x != '']) if a: nevra = f'{nevra}.{a}' return nevra
def tag_cleaner(args): print('attempting to do tag cleanup on {0}'.format(args.brew_tag)) exclude_components = set(args.exclude.split(',')) base_tag = None for sub_tag in [ '-trunk-candidate', '-trunk-override', '-candidate', '-pending', '-override' ]: if sub_tag in args.brew_tag: base_tag = args.brew_tag[0:-len(sub_tag)] break if base_tag is None: raise Exception("brew tag must be either -candidate, -trunk-candidate," " -trunk-override, -pending, or -override otherwise " "I don't know what to do") candidate_tag = args.brew_tag container_tag = base_tag + '-container-released' bw = KojiWrapperBase(profile='brew') if args.latest: released_builds = KojiTag(session=bw, tag=candidate_tag) else: released_builds = KojiTag(session=bw, tag=base_tag) staged_builds = KojiTag(session=bw, tag=candidate_tag) released_builds.builds(inherit=False, latest=args.latest) staged_builds.builds(inherit=False, latest=False) released_containers = None dc = [] try: if not args.latest and container_tag: released_containers = KojiTag(session=bw, tag=container_tag) released_containers.builds(inherit=False) dc = released_containers.builds_by_attribute('name') except koji.GenericError: released_containers = None dc = [] lc = released_builds.builds_by_attribute('name') rc = staged_builds.builds_by_attribute('name') common = sorted(list((set(lc) & set(rc)) - exclude_components)) # NOQA new_build_components = sorted( list((set(rc) - set(lc) - set(dc)) - exclude_components)) # NOQA tagged_only_components = sorted( list((set(lc) - set(rc)) - exclude_components)) # NOQA tagged_only_containers = sorted( list((set(dc) - set(rc)) - exclude_components)) # NOQA common_containers = sorted(list((set(dc) & set(rc)) - exclude_components)) # NOQA if args.debug: print({ 'tagged_only': tagged_only_components, 'new_builds': new_build_components, 'common': common, 'common_containers': common_containers, 'tagged_only_containers': tagged_only_containers }) builds_to_untag = [] for c in common: rel_build = latest_package(released_builds, c) can_builds = builds_package(staged_builds, c) if args.debug: print('released', rel_build) print('-candidate', can_builds) if ((args.clean_all) and (rel_build in can_builds) and (rel_build == latest_package(staged_builds, c))): if args.debug: print("Latest build {0} is released".format(rel_build) + ", untagging them all") for build in can_builds: builds_to_untag.append(build) continue for build in can_builds: if build == rel_build: if not args.latest: if args.debug: print("Latest build {0} is released".format(rel_build)) builds_to_untag.append(build) else: if args.debug: print("Preserving latest build {0}".format(rel_build)) continue else: (ln, lv, lr, le, la) = splitFilename(rel_build) (rn, rv, rr, re, ra) = splitFilename(build) v = labelCompare((le, lv, lr), (re, rv, rr)) if v > 0: if args.debug: print("released is newer, untagging {0}".format(build)) builds_to_untag.append(build) elif v < 0: if args.debug: print("Skipping {0} newer than released".format(build)) else: if args.debug: print("released equal, untagging {0}".format(build)) if not args.latest: builds_to_untag.append(build) for c in common_containers: if args.debug: print('Looking at container {0}'.format(c)) rel_build = latest_package(released_containers, c) can_builds = builds_package(staged_builds, c) if args.debug: print('released', rel_build) print('-candidate', can_builds) if ((args.clean_all) and (rel_build in can_builds) and (rel_build == latest_package(staged_builds, c))): if args.debug: print("Latest build {0} is released".format(rel_build) + ", untagging them all") for build in can_builds: builds_to_untag.append(build) continue for build in can_builds: if build == rel_build: if args.debug: print("Latest build {0} is released".format(rel_build)) builds_to_untag.append(build) continue else: (ln, lv, lr, le, la) = splitFilename(rel_build) (rn, rv, rr, re, ra) = splitFilename(build) v = labelCompare((le, lv, lr), (re, rv, rr)) if v > 0: if args.debug: print("released is newer, untagging {0}".format(build)) builds_to_untag.append(build) elif v < 0: if args.debug: print("Skipping {0} newer than released".format(build)) else: if args.debug: print("released equal, untagging {0}".format(build)) builds_to_untag.append(build) # NOTE: jschlueter 2016-12-16 # for RH-OSP we have several image builds that use # brew image-build-indirection to generate the released images # rhosp-director-images ==> director-utility,director-input,minimal-input # director-utility and *-input are used to generate overcloud-full # and ironic-python-agent images. Those images are then embedded # in rhos-director-images. # This means we never release these auxiliary images and they # need to be cleaned out of the -candidate tag but we would like to leave # tagged in -candidate any auxiliary images equal or newer to the last # released overcloud-full package. # # Beginning with OSP 16.1, the multiarch name is included in the # image build name, e.g. overcloud-full-(x86_64|ppc64le) corresponds # respectively to director-input-(x86_64|ppc64le), # director-utility-(x86_64|ppc64le), minimal-input-(x86_64|ppc64le) # # add logic to handle auxiliary image builds # we want to keep corresponding -input and -utility images # matching build is: # overcloud-full-(ARCH-)<VR> # == director-input-(ARCH-)<VR> # == director-utility-(ARCH-)<VR> # == minimal-input-(ARCH-)<VR> (16.1+ only) latest_images = None # By default use the pre-16.1 naming convention oc_build_name = 'overcloud-full' aux_build_names = ['director-input', 'director-utility'] # If the multiarch overcloud-full-x86_64 build is present, use # multiarch-named builds if ('overcloud-full-x86_64' in lc): oc_build_name = 'overcloud-full-x86_64' aux_build_names = [ 'director-input-x86_64', 'director-input-ppc64le', 'director-utility-x86_64', 'director-utility-ppc64le', 'minimal-input-x86_64', 'minimal-input-ppc64le' ] if ([a for a in aux_build_names if a in rc] and oc_build_name in lc): latest_images = latest_package(released_builds, oc_build_name) if args.debug: if latest_images is not None: print('Attempting director-input/utility image cleanup') else: print( 'Skipping director-input/utility no overcloud-full found') if latest_images is not None: VR = latest_images[len(oc_build_name):] keep = [abn + VR for abn in aux_build_names] print("Trying to clean up director-input and director-utility") print("Keeping {0} for Released {1}".format(keep, latest_images)) for c in aux_build_names: for build in builds_package(staged_builds, c): if build in keep: continue (ln, lv, lr, le, la) = splitFilename(c + VR) (rn, rv, rr, re, ra) = splitFilename(build) v = labelCompare((le, lv, lr), (re, rv, rr)) if v > 0: if args.debug: print("released is newer, untagging") builds_to_untag.append(build) if len(builds_to_untag) > 0: untag_it(candidate_tag, builds_to_untag, dry_run=args.dry_run, verbose=args.debug) else: print("All Clean. nothing to do for {0}".format(candidate_tag))