diff --git a/mpcdf_refresh_aggregates.py b/mpcdf_refresh_aggregates.py new file mode 100644 index 0000000000000000000000000000000000000000..0952e28ef2e26deb952909288fbb7f59e54e76bb --- /dev/null +++ b/mpcdf_refresh_aggregates.py @@ -0,0 +1,135 @@ +#!/usr/bin/python2 +from __future__ import print_function + +import os +import osc +import osc.conf +import osc.core +import osc.cmdln + +import mpcdf_common + +from osc.util.helper import decode_it +from xml.etree import ElementTree + + +def do_mpcdf_refresh_aggregates(self, subcmd, opts, *args): + """${cmd_name}: Recreates the aggregate packages in software:dist + + Use this only if you know what this means + + Usage: + osc ${cmd_name} + + ${cmd_option_list} + + """ + + if len(args) != 0: + raise osc.oscerr.WrongArgs("Too many arguments") + + if osc.core.store_read_project(os.curdir) != "software:dist" or \ + osc.core.is_package_dir(os.curdir): + raise osc.oscerr.WrongArgs("You must be in the project checkout of software:dist") + + dist = osc.core.Project(".", False) + + apiurl = self.get_api_url() + + def refresh_aggregate(aggregatename, project, source, target): + if not os.path.exists(aggregatename): + package = osc.core.Package.init_package(apiurl, "software:dist", aggregatename, aggregatename) + dist.addPackage(aggregatename) + else: + package = dist.get_pacobj(aggregatename) + + with open(aggregatename + "/_aggregate", "w") as fd: + print('<aggregatelist>', file=fd) + print(' <aggregate project="{project}">'.format(project=project), file=fd) + print(' <nosources/>', file=fd) + print(' <repository target="{target}" source="{source}" />'.format(target=target, source=source), file=fd) + print(' </aggregate>', file=fd) + print('</aggregatelist>', file=fd) + + if package.status("_aggregate") == "?": + package.addfile("_aggregate") + + if package.status("_aggregate") in ("A", "M"): + dist.commit((aggregatename,), msg="Refresh aggregate", verbose=True) + + pkg_meta = osc.core.show_package_meta(apiurl, "software:dist", aggregatename) + root = ElementTree.fromstringlist(pkg_meta) + pkg_meta = ElementTree.tostring(root, encoding=osc.core.ET_ENCODING) + + build = root.find("./build") + if build is None: + build = ElementTree.SubElement(root, "build") + + for enable in build.findall("./enable"): + build.remove(enable) + + node = ElementTree.Element("enable") + node.set("repository", target) + node.tail = "\n " + build.insert(0, node) + + new_pkg_meta = ElementTree.tostring(root, encoding=osc.core.ET_ENCODING) + if pkg_meta != new_pkg_meta: + osc.core.edit_meta("pkg", ("software:dist", aggregatename), + data=new_pkg_meta) + + projects = [p for p in osc.core.meta_get_project_list(apiurl) + if p.startswith("software") and not (p == "software:dist" or p == "software:images")] + + macros = {} + for project in projects: + repos = osc.core.get_repositories_of_project(apiurl, project) + if project == "software": + # Stupid special case + target = "SLE_12_SP3-sandybridge" + else: + target = project[len("software:"):].replace(":", "-") + + macros[target] = [] + for attribute in mpcdf_common.config_attributes + mpcdf_common.default_attributes: + _, name = attribute.split(":") + values = mpcdf_common.get_attribute_values(apiurl, project, None, attribute) + macros[target].append("%available_{0} {1}".format(name, ",".join(sorted(values)))) + + for repo in repos: + aggregatename = "zz_aggregate_" + project.replace(":", "-") + "_" + repo + refresh_aggregate(aggregatename, project, repo, target) + + prjconf = list(map(decode_it, osc.core.show_project_conf(apiurl, "software:dist"))) + start_marker = "# Autogenerated by osc mpcdf_refresh_aggregates, do not edit till end of section\n" + end_marker = "# End of autogenerated section\n" + + try: + start = prjconf.index(start_marker) + end = prjconf.index(end_marker) + except ValueError: + start = None + end = len(prjconf) + + prjconf_head = "".join(prjconf[:start]) + prjconf_tail = "".join(prjconf[end + 1:]) + prjconf = [start_marker] + + distributions = osc.core.get_repositories_of_project(apiurl, "distributions") + for swdistrepo in osc.core.get_repositories_of_project(apiurl, "software:dist"): + for distrepo in distributions: + if swdistrepo.startswith(distrepo): + refresh_aggregate("zz_aggregate_" + swdistrepo + "_distributions", "distributions", distrepo, swdistrepo) + break + distrepo = None + prjconf.append('%if "%_repository" == "{0}"'.format(swdistrepo)) + prjconf.append("Macros:") + prjconf.extend(macros[swdistrepo]) + prjconf.append("%distribution {0}".format(distrepo)) + prjconf.append(":Macros") + prjconf.append("%endif") + prjconf.append("") + + prjconf.append(end_marker) + prjconf = prjconf_head + "\n".join(prjconf) + prjconf_tail + osc.core.edit_meta("prjconf", "software:dist", data=prjconf)