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-releaset...@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-releaset...@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 tchva...@suse.cz, openSUSE.org
 # (C) 2014 apla...@suse.de, openSUSE.org
 # (C) 2014 co...@suse.de, openSUSE.org
+# (C) 2017 ok...@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
 


Reply via email to