Hello community, here is the log from the commit of package openSUSE-release-tools for openSUSE:Factory checked in at 2017-11-27 22:18:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openSUSE-release-tools (Old) and /work/SRC/openSUSE:Factory/.openSUSE-release-tools.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "openSUSE-release-tools" Mon Nov 27 22:18:42 2017 rev:23 rq:545982 version:20171127.3368dd5 Changes: -------- --- /work/SRC/openSUSE:Factory/openSUSE-release-tools/openSUSE-release-tools.changes 2017-11-23 09:44:34.144174879 +0100 +++ /work/SRC/openSUSE:Factory/.openSUSE-release-tools.new/openSUSE-release-tools.changes 2017-11-27 22:18:44.257923680 +0100 @@ -1,0 +2,15 @@ +Mon Nov 27 12:23:21 UTC 2017 - opensuse-releaseteam@opensuse.org + +- Update to version 20171127.3368dd5: + * Implement namespace callback for locales + * pkglistgen: Optionally include suggested packages too + * fcc_submitter: update to Leap 15.0 + * ttm: Add support for SLE 15 + +------------------------------------------------------------------- +Wed Nov 22 15:32:45 UTC 2017 - opensuse-releaseteam@opensuse.org + +- Update to version 20171122.ea9f948: + * Split EDITOR environment variable to handle flags in prefix. + +------------------------------------------------------------------- Old: ---- openSUSE-release-tools-20171122.b428ed3.obscpio New: ---- openSUSE-release-tools-20171127.3368dd5.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openSUSE-release-tools.spec ++++++ --- /var/tmp/diff_new_pack.rj5wDc/_old 2017-11-27 22:18:45.097893194 +0100 +++ /var/tmp/diff_new_pack.rj5wDc/_new 2017-11-27 22:18:45.101893049 +0100 @@ -20,7 +20,7 @@ %define source_dir osc-plugin-factory %define announcer_filename factory-package-news Name: openSUSE-release-tools -Version: 20171122.b428ed3 +Version: 20171127.3368dd5 Release: 0 Summary: Tools to aid in staging and release work for openSUSE/SUSE License: GPL-2.0+ and MIT ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.rj5wDc/_old 2017-11-27 22:18:45.145891452 +0100 +++ /var/tmp/diff_new_pack.rj5wDc/_new 2017-11-27 22:18:45.145891452 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/openSUSE/osc-plugin-factory.git</param> - <param name="changesrevision">4838dbec828febf522d3d23ac1945207aed5c01a</param> + <param name="changesrevision">3368dd555d8cb1953738675345fcb10461de65a9</param> </service> </servicedata> ++++++ openSUSE-release-tools-20171122.b428ed3.obscpio -> openSUSE-release-tools-20171127.3368dd5.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20171122.b428ed3/fcc_submitter.py new/openSUSE-release-tools-20171127.3368dd5/fcc_submitter.py --- old/openSUSE-release-tools-20171122.b428ed3/fcc_submitter.py 2017-11-22 14:00:16.000000000 +0100 +++ new/openSUSE-release-tools-20171127.3368dd5/fcc_submitter.py 2017-11-27 13:23:10.000000000 +0100 @@ -34,8 +34,8 @@ from osc import oscerr from osclib.memoize import memoize -OPENSUSE = 'openSUSE:Leap:42.3' -OPENSUSE_PREVERSION = 'openSUSE:Leap:42.2' +OPENSUSE = 'openSUSE:Leap:15.0' +OPENSUSE_PREVERSION = 'openSUSE:Leap:42.3' FCC = 'openSUSE:42:Factory-Candidates-Check' makeurl = osc.core.makeurl @@ -70,7 +70,7 @@ logging.debug("Processing %s" % (package)) # If the package is an internal one (e.g _product) - if package.startswith('_') or package.startswith('Test-DVD'): + if package.startswith('_') or package.startswith('Test-DVD') or package.startswith('000'): return None for linked in si.findall('linked'): @@ -140,6 +140,9 @@ self.apiurl = osc.conf.config['apiurl'] self.debug = osc.conf.config['debug'] self.sle_base_prjs = [ + 'SUSE:SLE-15:GA', + 'SUSE:SLE-12-SP3:Update', + 'SUSE:SLE-12-SP3:GA', 'SUSE:SLE-12-SP2:Update', 'SUSE:SLE-12-SP2:GA', 'SUSE:SLE-12-SP1:Update', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20171122.b428ed3/issue-diff.py new/openSUSE-release-tools-20171127.3368dd5/issue-diff.py --- old/openSUSE-release-tools-20171122.b428ed3/issue-diff.py 2017-11-22 14:00:16.000000000 +0100 +++ new/openSUSE-release-tools-20171127.3368dd5/issue-diff.py 2017-11-27 13:23:10.000000000 +0100 @@ -131,7 +131,7 @@ editor = os.getenv('EDITOR') if not editor: editor = 'xdg-open' - subprocess.call([editor, temp.name]) + subprocess.call(editor.split(' ') + [temp.name]) changes_after = yaml.safe_load(open(temp.name).read()) if changes_after is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20171122.b428ed3/osc-staging.py new/openSUSE-release-tools-20171127.3368dd5/osc-staging.py --- old/openSUSE-release-tools-20171122.b428ed3/osc-staging.py 2017-11-22 14:00:16.000000000 +0100 +++ new/openSUSE-release-tools-20171127.3368dd5/osc-staging.py 2017-11-27 13:23:10.000000000 +0100 @@ -599,7 +599,7 @@ editor = os.getenv('EDITOR') if not editor: editor = 'xdg-open' - return_code = subprocess.call([editor, temp.name]) + return_code = subprocess.call(editor.split(' ') + [temp.name]) proposal = yaml.safe_load(open(temp.name).read()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20171122.b428ed3/pkglistgen.py new/openSUSE-release-tools-20171127.3368dd5/pkglistgen.py --- old/openSUSE-release-tools-20171122.b428ed3/pkglistgen.py 2017-11-22 14:00:16.000000000 +0100 +++ new/openSUSE-release-tools-20171127.3368dd5/pkglistgen.py 2017-11-27 13:23:10.000000000 +0100 @@ -70,7 +70,11 @@ self.develpkgs = [] self.silents = set() self.ignored = set() - self.recommended = set() + # special feature for SLE. Patterns are marked for expansion + # of recommended packages, all others aren't. Only works + # with recommends on actual package names, not virtual + # provides. + self.expand_recommended = set() pkglist.groups[self.safe_name] = self @@ -100,7 +104,7 @@ elif rel == 'silent': self.silents.add(name) elif rel == 'recommended': - self.recommended.add(name) + self.expand_recommended.add(name) else: arch = rel @@ -116,7 +120,7 @@ self.locked.update(group.locked) self.silents.update(group.silents) - self.recommended.update(group.recommended) + self.expand_recommended.update(group.expand_recommended) # do not repeat packages def ignore(self, without): @@ -135,7 +139,7 @@ self.ignore(g) self.ignored.add(without) - def solve(self, ignore_recommended=False): + def solve(self, ignore_recommended=False, include_suggested = False): """ base: list of base groups or None """ if self.solved: @@ -147,27 +151,30 @@ self.srcpkgs = set() self.recommends = dict() + self.suggested = dict() for arch in self.architectures: pool = self.pkglist._prepare_pool(arch) # pool.set_debuglevel(10) + suggested = [] - tosolv = self.packages[arch] - while tosolv: - n, group = tosolv.pop(0) + # packages resulting from explicit recommended expansion + extra = [] + + def solve_one_package(n, group): jobs = list(self.pkglist.lockjobs[arch]) sel = pool.select(str(n), solv.Selection.SELECTION_NAME) if sel.isempty(): logger.debug('{}.{}: package {} not found'.format(self.name, arch, n)) self.not_found.setdefault(n, set()).add(arch) - continue + return else: - if n in self.recommended: + if n in self.expand_recommended: for s in sel.solvables(): for dep in s.lookup_deparray(solv.SOLVABLE_RECOMMENDS): # only add recommends that exist as packages rec = pool.select(dep.str(), solv.Selection.SELECTION_NAME) if not rec.isempty(): - tosolv.append([dep.str(), group + ":recommended:" + n]) + extra.append([dep.str(), group + ":recommended:" + n]) jobs += sel.jobs(solv.Job.SOLVER_INSTALL) @@ -200,23 +207,24 @@ else: logger.debug(msg) self.unresolvable[arch][n] = str(problem) - continue - - trans = solver.transaction() - if trans.isempty(): - logger.error('%s.%s: nothing to do', self.name, arch) - continue + return - if 'get_recommended' in dir(solver): + if hasattr(solver, 'get_recommended'): for s in solver.get_recommended(): if s.name in locked: continue self.recommends.setdefault(s.name, group + ':' + n) for s in solver.get_suggested(): - self.recommends.setdefault(s.name, group + ':' + n) + suggested.append([s.name, group + ':suggested:' + n]) + self.suggested.setdefault(s.name, group + ':' + n) else: logger.warn('newer libsolv needed for recommends!') + trans = solver.transaction() + if trans.isempty(): + logger.error('%s.%s: nothing to do', self.name, arch) + return + for s in trans.newsolvables(): solved[arch].setdefault(s.name, group + ':' + n) reason, rule = solver.describe_decision(s) @@ -229,6 +237,18 @@ src = s.lookup_str(solv.SOLVABLE_SOURCENAME) self.srcpkgs.add(src) + for n, group in self.packages[arch]: + solve_one_package(n, group) + + if include_suggested: + seen = set() + while suggested: + n, group = suggested.pop() + if n in seen: + continue + seen.add(n) + solve_one_package(n, group) + common = None # compute common packages across all architectures for arch in self.architectures: @@ -292,17 +312,19 @@ if not already_present: self.develpkgs.append(p) - def filter_duplicated_recommends(self, modules): - recommends = self.recommends + def _filter_already_selected(self, modules, pkgdict): # erase our own - so we don't filter our own - self.recommends = dict() - for p in recommends: + for p in pkgdict.keys(): already_present = False for m in modules: for arch in ['*'] + self.architectures: already_present = already_present or (p in m.solved_packages[arch]) - if not already_present: - self.recommends[p] = recommends[p] + if already_present: + del pkgdict[p] + + def filter_already_selected(self, modules): + self._filter_already_selected(modules, self.recommends) + self._filter_already_selected(modules, self.suggested) def toxml(self, arch, ignore_broken = False): packages = self.solved_packages[arch] @@ -356,11 +378,18 @@ c = ET.Comment("\nDevelopment packages:\n - " + "\n - ".join(sorted(self.develpkgs)) + "\n") root.append(c) if arch == '*' and self.recommends: - comment = "\nRecommended and suggested packages:\n" + comment = "\nRecommended packages:\n" for p in sorted(self.recommends.keys()): comment += " - {} # {}\n".format(p, self.recommends[p]) c = ET.Comment(comment) root.append(c) + if arch == '*' and self.suggested: + comment = "\nSuggested packages:\n" + for p in sorted(self.suggested.keys()): + comment += " - {} # {}\n".format(p, self.suggested[p]) + c = ET.Comment(comment) + root.append(c) + return root @@ -389,8 +418,10 @@ self.lockjobs = dict() self.ignore_broken = False self.ignore_recommended = False + self.include_suggested = False self.unwanted = set() self.output = None + self.locales = set() def _dump_supportstatus(self): for name in self.packages.keys(): @@ -483,7 +514,7 @@ g = self.groups[groupname] for i in includes: g.inherit(self.groups[i]) - g.solve(self.ignore_recommended) + g.solve(self.ignore_recommended, self.include_suggested) for e in excludes: g.ignore(self.groups[e]) @@ -517,6 +548,26 @@ self.lockjobs[arch] = [] solvables = set() + + def cb(name, evr): + ret = 0 + if name == solv.NAMESPACE_MODALIAS: + ret = 1 + elif name == solv.NAMESPACE_FILESYSTEM: + ret = 1 + elif name == solv.NAMESPACE_LANGUAGE: + if pool.id2str(evr) in self.locales: + ret = 1 + else: + logger.warning('unhandled "{} {}"'.format(pool.id2str(name), pool.id2str(evr))) + + return ret + + if hasattr(pool, 'set_namespacecallback'): + pool.set_namespacecallback(cb) + else: + logger.warn('libsolv missing namespace callback') + for prp in self.repos: project, reponame = prp.split('/') repo = pool.add_repo(project) @@ -680,6 +731,9 @@ @cmdln.option('--ignore-unresolvable', action='store_true', help='ignore unresolvable and missing packges') @cmdln.option('--ignore-recommended', action='store_true', help='do not include recommended packages automatically') + @cmdln.option('--include-suggested', action='store_true', help='include suggested packges also') + @cmdln.option('--locale', action='append', help='locales to inclues') + @cmdln.option('--locales-from', metavar='FILE', help='get supported locales from product file FILE') def do_solve(self, subcmd, opts): """${cmd_name}: Solve groups @@ -696,6 +750,18 @@ self.tool.ignore_broken = True if opts.ignore_recommended: self.tool.ignore_recommended = True + if opts.include_suggested: + if opts.ignore_recommended: + raise cmdln.CmdlnUserError("--ignore-recommended and --include-suggested don't work together") + self.tool.include_suggested = True + if opts.locale: + for l in opts.locale: + self.tool.locales |= set(l.split(',')) + if opts.locales_from: + with open(os.path.join(self.tool.input_dir, opts.locales_from), 'r') as fh: + root = ET.parse(fh).getroot() + self.tool.locales |= set([ lang.text for lang in root.findall(".//linguas/language") ]) + modules = [] # the yml parser makes an array out of everything, so @@ -713,7 +779,7 @@ for module in modules: module.check_dups(modules) module.collect_devel_packages(modules) - module.filter_duplicated_recommends(modules) + module.filter_already_selected(modules) self.tool._collect_unsorted_packages(modules) self.tool._write_all_groups() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20171122.b428ed3/pkglistgen.sh new/openSUSE-release-tools-20171127.3368dd5/pkglistgen.sh --- old/openSUSE-release-tools-20171122.b428ed3/pkglistgen.sh 2017-11-22 14:00:16.000000000 +0100 +++ new/openSUSE-release-tools-20171127.3368dd5/pkglistgen.sh 2017-11-27 13:23:10.000000000 +0100 @@ -17,6 +17,17 @@ cachedir=${XDG_CACHE_HOME:-~/.cache}/opensuse-packagelists/$api/$project todo=("$product" "$groups") +solveargs=() + +if [ -n "$IGNORE_RECOMMENDED" ]; then + solveargs+=('--ignore-recommended') +fi +if [ -n "$INCLUDE_SUGGESTED" ]; then + solveargs+=('--include-suggested') +fi +if [ -n "$LOCALES_FROM" ]; then + solveargs+=('--locales-from', "$LOCALES_FROM") +fi _osc=`type -p osc` osc() @@ -83,8 +94,10 @@ for i in *.spec.in; do mv -v $i "${i%.in}" done -${self%.sh}.py -i "$cachedir/$groups" -r $repos -o . -a x86_64 update -${self%.sh}.py -i "$cachedir/$groups" -r $repos -o . -a x86_64 solve +if ! ${self%.sh}.py -i "$cachedir/$groups" -r $repos -o . -a x86_64 update; then + echo "no change in packages" +fi +${self%.sh}.py -i "$cachedir/$groups" -r $repos -o . -a x86_64 solve "${solveargs[@]}" for i in $delete_products; do rm -vf -- "$i" done diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20171122.b428ed3/totest-manager.py new/openSUSE-release-tools-20171127.3368dd5/totest-manager.py --- old/openSUSE-release-tools-20171122.b428ed3/totest-manager.py 2017-11-22 14:00:16.000000000 +0100 +++ new/openSUSE-release-tools-20171127.3368dd5/totest-manager.py 2017-11-27 13:23:10.000000000 +0100 @@ -5,6 +5,7 @@ # (C) 2014 tchvatal@suse.cz, openSUSE.org # (C) 2014 aplanas@suse.de, openSUSE.org # (C) 2014 coolo@suse.de, openSUSE.org +# (C) 2017 okurz@suse.de, openSUSE.org # Distribute under GPLv2 or GPLv3 import cmdln @@ -45,18 +46,24 @@ """Base class to store the basic interface""" - def __init__(self, project, dryrun=False): + def __init__(self, project, dryrun=False, api_url=None, openqa_server='https://openqa.opensuse.org', test_subproject=None): self.project = project self.dryrun = dryrun - self.api = StagingAPI( - osc.conf.config['apiurl'], project='openSUSE:%s' % project) - self.openqa = OpenQA_Client(server='https://openqa.opensuse.org') + if not api_url: + api_url = osc.conf.config['apiurl'] + self.api = StagingAPI(api_url, project=project) + self.openqa_server = openqa_server + if not test_subproject: + test_subproject = 'ToTest' + self.test_project = '%s:%s' % (self.project, test_subproject) + self.openqa = OpenQA_Client(server=openqa_server) self.issues_to_ignore = [] self.issuefile = "{}_{}".format(self.project, ISSUE_FILE) if os.path.isfile(self.issuefile): with open(self.issuefile, 'r') as f: for line in f.readlines(): self.issues_to_ignore.append(line.strip()) + self.project_base = project.split(':')[0] def openqa_group(self): return self.project @@ -85,34 +92,37 @@ return ret def get_current_snapshot(self): - """Return the current snapshot in :ToTest""" + """Return the current snapshot in the test project""" - # for now we hardcode all kind of things - for binary in self.binaries_of_product('openSUSE:%s:ToTest' % self.project, '_product:openSUSE-cd-mini-%s' % self.arch()): - result = re.match(r'openSUSE-%s-NET-.*-Snapshot(.*)-Media.iso' % self.iso_prefix(), + for binary in self.binaries_of_product(self.test_project, '_product:%s-cd-mini-%s' % (self.project_base, self.arch())): + result = re.match(r'%s-%s-NET-.*-Snapshot(.*)-Media.iso' % (self.project_base, self.iso_prefix()), binary) if result: return result.group(1) return None - def ftp_build_version(self, project, tree): - for binary in self.binaries_of_product('openSUSE:%s' % project, tree): - result = re.match(r'openSUSE.*Build(.*)-Media1.report', binary) + def ftp_build_version(self, project, tree, base=None): + if not base: + base = self.project_base + for binary in self.binaries_of_product(project, tree): + result = re.match(r'%s.*Build(.*)-Media1.report' % base, binary) if result: return result.group(1) raise NotFoundException("can't find %s ftp version" % project) - def iso_build_version(self, project, tree): - for binary in self.binaries_of_product('openSUSE:%s' % project, tree): - result = re.match(r'openSUSE.*Build(.*)-Media.iso', binary) + def iso_build_version(self, project, tree, base=None): + if not base: + base = self.project_base + for binary in self.binaries_of_product(project, tree): + result = re.match(r'%s.*Build(.*)-Media(.*).iso' % base, binary) if result: return result.group(1) raise NotFoundException("can't find %s iso version" % project) def release_version(self): - url = self.api.makeurl(['build', 'openSUSE:%s' % self.project, 'standard', self.arch(), - '_product:openSUSE-release']) + url = self.api.makeurl(['build', self.project, 'standard', self.arch(), + '_product:%s-release' % self.project_base]) f = self.api.retried_GET(url) root = ET.parse(f).getroot() for binary in root.findall('binary'): @@ -129,7 +139,7 @@ """ - url = makeurl('https://openqa.opensuse.org', + url = makeurl(self.openqa_server, ['api', 'v1', 'jobs'], {'group': self.openqa_group(), 'build': snapshot, 'latest': 1}) f = self.api.retried_GET(url) jobs = [] @@ -161,7 +171,7 @@ (module['name'], module['result'], module['flags'])) def update_ignored_issues(self): - url = makeurl('https://openqa.opensuse.org', + url = makeurl(self.openqa_server, ['api', 'v1', 'job_groups']) f = self.api.retried_GET(url) job_groups = json.load(f) @@ -176,7 +186,7 @@ issues = ' , '.join(self.issues_to_ignore) msg = "pinned-description: Ignored issues\r\n\r\n{}".format(issues) data = {'text': msg} - url = makeurl('https://openqa.opensuse.org', + url = makeurl(self.openqa_server, ['api', 'v1', 'groups', str(group_id), 'comments']) f = self.api.retried_GET(url) comments = json.load(f) @@ -210,10 +220,10 @@ update_pinned_descr = False for job in jobs: # print json.dumps(job, sort_keys=True, indent=4) - if job['result'] in ('failed', 'incomplete', 'skipped', 'user_cancelled', 'obsoleted'): + if job['result'] in ('failed', 'incomplete', 'skipped', 'user_cancelled', 'obsoleted', 'parallel_failed'): jobname = job['name'] # print json.dumps(job, sort_keys=True, indent=4), jobname - url = makeurl('https://openqa.opensuse.org', + url = makeurl(self.openqa_server, ['api', 'v1', 'jobs', str(job['id']), 'comments']) f = self.api.retried_GET(url) comments = json.load(f) @@ -253,7 +263,7 @@ if ignored: logger.info("job %s failed, but was ignored", jobname) else: - joburl = 'https://openqa.opensuse.org/tests/%s' % job['id'] + joburl = '%s/tests/%s' % (self.openqa_server, job['id']) logger.info("job %s failed, see %s", jobname, joburl) elif job['result'] == 'passed' or job['result'] == 'softfailed': @@ -321,13 +331,13 @@ if re.match(r'livecd-.*', package): return 999999999 # a GB stick - if re.match(r'.*-dvd9-dvd-.*', package): + if re.match(r'.*-(dvd9-dvd|cd-DVD)-.*', package): return 8539996159 - if ':openSUSE-ftp-ftp-' in package: + if re.match(r'.*-ftp-(ftp|POOL)-', package): return None - if ':openSUSE-Addon-NonOss-ftp-ftp' in package: + if ':%s-Addon-NonOss-ftp-ftp' % self.base in package: return None raise Exception('No maxsize for {}'.format(package)) @@ -372,21 +382,21 @@ """ - if not self.all_repos_done('openSUSE:%s' % self.project): + if not self.all_repos_done(self.project): return False for product in self.ftp_products + self.main_products: - if not self.package_ok('openSUSE:%s' % self.project, product, 'images', 'local'): + if not self.package_ok(self.project, product, 'images', 'local'): return False if len(self.livecd_products): - if not self.all_repos_done('openSUSE:%s:Live' % self.project): + if not self.all_repos_done('%s:Live' % self.project): return False for arch in ['i586', 'x86_64']: for product in self.livecd_products: - if not self.package_ok('openSUSE:%s:Live' % self.project, product, 'images', arch): + if not self.package_ok('%s:Live' % self.project, product, 'images', arch): return False return True @@ -412,36 +422,34 @@ def _release(self, set_release=None): for product in self.ftp_products: - self._release_package('openSUSE:%s' % self.project, product) + self._release_package(self.project, product) for cd in self.livecd_products: - self._release_package('openSUSE:%s:Live' % + self._release_package('%s:Live' % self.project, cd, set_release=set_release) for cd in self.main_products: - self._release_package('openSUSE:%s' % - self.project, cd, set_release=set_release) + self._release_package(self.project, cd, set_release=set_release) def update_totest(self, snapshot=None): release = 'Snapshot%s' % snapshot if snapshot else None logger.info('Updating snapshot %s' % snapshot) if not self.dryrun: - self.api.switch_flag_in_prj( - 'openSUSE:%s:ToTest' % self.project, flag='publish', state='disable') + self.api.switch_flag_in_prj(self.test_project, flag='publish', state='disable') self._release(set_release=release) def publish_factory_totest(self): - logger.info('Publish ToTest') + logger.info('Publish test project content') if not self.dryrun: self.api.switch_flag_in_prj( - 'openSUSE:%s:ToTest' % self.project, flag='publish', state='enable') + self.test_project, flag='publish', state='enable') def totest_is_publishing(self): """Find out if the publishing flag is set in totest's _meta""" url = self.api.makeurl( - ['source', 'openSUSE:%s:ToTest' % self.project, '_meta']) + ['source', self.test_project, '_meta']) f = self.api.retried_GET(url) root = ET.parse(f).getroot() if not root.find('publish'): # default true @@ -458,7 +466,7 @@ try: current_snapshot = self.get_current_snapshot() except NotFoundException as e: - # nothing in :ToTest (yet) + # nothing in test project (yet) logger.warn(e) current_snapshot = None new_snapshot = self.current_version() @@ -479,7 +487,7 @@ if new_snapshot == current_snapshot: logger.debug("no change in snapshot version") can_release = False - elif not self.all_repos_done('openSUSE:%s:ToTest' % self.project): + elif not self.all_repos_done(self.test_project): logger.debug("not all repos done, can't release") # the repos have to be done, otherwise we better not touch them # with a new release @@ -499,9 +507,9 @@ can_release = False # we have to wait else: # We reached a very bad status: openQA testing is 'done', but not of the same version - # currently in :ToTest. This can happen when 'releasing' the + # currently in test project. This can happen when 'releasing' the # product failed - raise Exception("Publishing stopped: tested version (%s) does not match :ToTest version (%s)" + raise Exception("Publishing stopped: tested version (%s) does not match version in test project (%s)" % (current_qa_version, current_snapshot)) if can_release: @@ -515,7 +523,7 @@ def write_version_to_dashboard(self, target, version): if not self.dryrun: url = self.api.makeurl( - ['source', 'openSUSE:%s:Staging' % self.project, 'dashboard', 'version_%s' % target]) + ['source', '%s:Staging' % self.project, 'dashboard', 'version_%s' % target]) osc.core.http_PUT(url + '?comment=Update+version', data=version) @@ -526,7 +534,7 @@ query = {'cmd': 'release'} package = '000product' - project = 'openSUSE:{}'.format(self.project) + project = self.project if set_release: query['setrelease'] = set_release @@ -541,12 +549,12 @@ # XXX still legacy for cd in self.livecd_products: - self._release_package('openSUSE:%s:Live' % + self._release_package('%s:Live' % self.project, cd, set_release=set_release) def release_version(self): - url = self.api.makeurl(['build', 'openSUSE:%s' % self.project, 'standard', self.arch(), - '000product:openSUSE-release']) + url = self.api.makeurl(['build', self.project, 'standard', self.arch(), + '000product:%s-release' % self.project_base]) f = self.api.retried_GET(url) root = ET.parse(f).getroot() for binary in root.findall('binary'): @@ -557,6 +565,30 @@ raise NotFoundException("can't find %s release version" % self.project) + def current_version(self): + return self.iso_build_version(self.project, self.main_products[0]) + + def is_snapshottable(self): + ret = super(ToTestBaseNew, self).is_snapshottable() + if ret: + # make sure all medias have the same build number + builds = set() + for p in self.ftp_products: + if 'Addon-NonOss' in p: + # XXX: don't care about nonoss atm. + continue + builds.add(self.ftp_build_version(self.project, p)) + for p in self.main_products + self.livecd_products: + builds.add(self.iso_build_version(self.project, p)) + + ret = (len(builds) == 1) + + return ret + + def update_totest(self, snapshot): + # omit snapshot, we don't want to rename on release + super(ToTestBaseNew, self).update_totest() + class ToTestFactory(ToTestBase): main_products = ['_product:openSUSE-dvd5-dvd-i586', @@ -671,32 +703,41 @@ def openqa_group(self): return 'openSUSE Leap 15.0' - def current_version(self): - return self.iso_build_version(self.project, self.main_products[0]) - def get_current_snapshot(self): return self.iso_build_version(self.project + ':ToTest', self.main_products[0]) - def is_snapshottable(self): - ret = super(ToTest150, self).is_snapshottable() - if ret: - # make sure all medias have the same build number - builds = set() - for p in self.ftp_products: - if 'Addon-NonOss' in p: - # XXX: don't care about nonoss atm. - continue - builds.add(self.ftp_build_version(self.project, p)) - for p in self.main_products + self.livecd_products: - builds.add(self.iso_build_version(self.project, p)) - ret = (len(builds) == 1) +class ToTestSLE150(ToTestBaseNew): + main_products = [ + '000product:SLES-cd-DVD-aarch64', + '000product:SLES-cd-DVD-ppc64le', + '000product:SLES-cd-DVD-s390x', + '000product:SLES-cd-DVD-x86_64', + ] - return ret + ftp_products = [ + '000product:SLES-ftp-POOL-aarch64', + '000product:SLES-ftp-POOL-ppc64le', + '000product:SLES-ftp-POOL-s390x', + '000product:SLES-ftp-POOL-x86_64', + ] - def update_totest(self, snapshot): - # omit snapshot, we don't want to rename on release - super(ToTest150, self).update_totest() + livecd_products = [] + + def __init__(self, *args, **kwargs): + ToTestBaseNew.__init__(self, test_subproject='TEST', *args, **kwargs) + + def openqa_group(self): + return 'Functional' + + def get_current_snapshot(self): + return self.iso_build_version(self.project + ':TEST', self.main_products[0]) + + def ftp_build_version(self, project, tree): + return super(ToTestSLE150, self).ftp_build_version(project, tree, base='SLE') + + def iso_build_version(self, project, tree): + return super(ToTestSLE150, self).iso_build_version(project, tree, base='SLE') class CommandlineInterface(cmdln.Cmdln): @@ -705,11 +746,20 @@ cmdln.Cmdln.__init__(self, args, kwargs) self.totest_class = { - 'Factory': ToTestFactory, - 'Factory:PowerPC': ToTestFactoryPowerPC, - 'Factory:ARM': ToTestFactoryARM, - 'Factory:zSystems': ToTestFactoryzSystems, - 'Leap:15.0': ToTest150, + 'openSUSE:Factory': ToTestFactory, + 'openSUSE:Factory:PowerPC': ToTestFactoryPowerPC, + 'openSUSE:Factory:ARM': ToTestFactoryARM, + 'openSUSE:Factory:zSystems': ToTestFactoryzSystems, + 'openSUSE:Leap:15.0': ToTest150, + 'SUSE:SLE-15:GA': ToTestSLE150, + } + self.openqa_server = { + 'openSUSE': 'https://openqa.opensuse.org', + 'SLE': 'https://openqa.suse.de', + } + self.api_url = { + 'openSUSE': 'https://api.opensuse.org', + 'SLE': 'https://api.suse.de', } def get_optparser(self): @@ -719,6 +769,16 @@ parser.add_option("--verbose", action="store_true", help="verbose") parser.add_option( "--osc-debug", action="store_true", help="osc debug output") + parser.add_option( + "--project-base", help="""Select base of OBS/IBS project as well as openQA server based on distribution family, e.g. 'openSUSE' or 'SLE', default: + 'openSUSE'""") + parser.add_option( + "--openqa-server", help="""Full URL to the openQA server that should be queried, default based on '--project-base' selection, e.g. + 'https://openqa.opensuse.org' for 'openSUSE'""") + parser.add_option( + "--obs-api-url", help="""Full URL to OBS instance to be queried, default based on '--project-base' selection, e.g. + 'https://api.opensuse.org' for 'openSUSE'""") + return parser return parser def postoptparse(self): @@ -737,19 +797,28 @@ osc.conf.get_config() if (self.options.osc_debug): osc.conf.config['debug'] = True + if not self.options.project_base: + self.options.project_base = 'openSUSE' + if not self.options.openqa_server: + self.options.openqa_server = self.openqa_server[self.options.project_base] + if not self.options.obs_api_url: + self.options.obs_api_url = self.api_url[self.options.project_base] - def _setup_totest(self, project): - Config('openSUSE:%s' % project) + def _setup_totest(self, project): + fallback_project = 'openSUSE:%s' % project + if project not in self.totest_class and fallback_project in self.totest_class: + project = fallback_project + Config(project) if project not in self.totest_class: msg = 'Project %s not recognized. Possible values [%s]' % ( project, ', '.join(self.totest_class)) raise cmdln.CmdlnUserError(msg) - return self.totest_class[project](project, self.options.dry) + return self.totest_class[project](project, self.options.dry, self.options.obs_api_url, self.options.openqa_server) @cmdln.option('-n', '--interval', metavar="minutes", type="int", help="periodic interval in minutes") - def do_run(self, subcmd, opts, project='Factory'): + def do_run(self, subcmd, opts, project='openSUSE:Factory'): """${cmd_name}: run the ToTest Manager ${cmd_usage} @@ -790,7 +859,7 @@ continue break - def do_release(self, subcmd, opts, project='Factory'): + def do_release(self, subcmd, opts, project='openSUSE:Factory'): """${cmd_name}: manually release all media. Use with caution! ${cmd_usage} ++++++ openSUSE-release-tools.obsinfo ++++++ --- /var/tmp/diff_new_pack.rj5wDc/_old 2017-11-27 22:18:45.885864595 +0100 +++ /var/tmp/diff_new_pack.rj5wDc/_new 2017-11-27 22:18:45.885864595 +0100 @@ -1,5 +1,5 @@ name: openSUSE-release-tools -version: 20171122.b428ed3 -mtime: 1511355616 -commit: b428ed3a7d54c8487710bded915a590bfcd79447 +version: 20171127.3368dd5 +mtime: 1511785390 +commit: 3368dd555d8cb1953738675345fcb10461de65a9