Hello community,
here is the log from the commit of package openSUSE-release-tools for
openSUSE:Factory checked in at 2018-11-10 17:01:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openSUSE-release-tools (Old)
and /work/SRC/openSUSE:Factory/.openSUSE-release-tools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openSUSE-release-tools"
Sat Nov 10 17:01:41 2018 rev:143 rq:647511 version:20181109.3aae284
Changes:
--------
---
/work/SRC/openSUSE:Factory/openSUSE-release-tools/openSUSE-release-tools.changes
2018-11-09 07:56:33.207564789 +0100
+++
/work/SRC/openSUSE:Factory/.openSUSE-release-tools.new/openSUSE-release-tools.changes
2018-11-10 17:02:34.779518898 +0100
@@ -1,0 +2,35 @@
+Fri Nov 09 07:56:04 UTC 2018 - [email protected]
+
+- Update to version 20181109.3aae284:
+ * adi: Fix format for untracked requests
+
+-------------------------------------------------------------------
+Thu Nov 08 22:33:55 UTC 2018 - [email protected]
+
+- Update to version 20181108.f4371f4:
+ * dist/spec: provide obs-operator subpackage.
+ * userscript/staging-move-drag-n-drop: rework to utilize OBS Operator server.
+ * obs_operator: provide initial version of server.
+ * userscript/staging-move-drag-n-drop: provide option to click to start.
+ * userscript/staging-move-drag-n-drop: move browser compatability check to
init.
+
+-------------------------------------------------------------------
+Thu Nov 08 17:21:30 UTC 2018 - [email protected]
+
+- Update to version 20181108.09fd2ba:
+ * Remove map_ring_package_to_subject - it always return project
+ * No longer build disable on selecting non-ring packages to letter prjs
+
+-------------------------------------------------------------------
+Thu Nov 08 17:08:51 UTC 2018 - [email protected]
+
+- Update to version 20181108.e8daf87:
+ * new bugowner tool
+
+-------------------------------------------------------------------
+Thu Nov 08 16:58:35 UTC 2018 - [email protected]
+
+- Update to version 20181108.151a4fe:
+ * [ARM] Skip build number comparison
+
+-------------------------------------------------------------------
Old:
----
openSUSE-release-tools-20181108.4293b6b.obscpio
New:
----
openSUSE-release-tools-20181109.3aae284.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ openSUSE-release-tools.spec ++++++
--- /var/tmp/diff_new_pack.CHPZQc/_old 2018-11-10 17:02:35.551517956 +0100
+++ /var/tmp/diff_new_pack.CHPZQc/_new 2018-11-10 17:02:35.551517956 +0100
@@ -20,7 +20,7 @@
%define source_dir openSUSE-release-tools
%define announcer_filename factory-package-news
Name: openSUSE-release-tools
-Version: 20181108.4293b6b
+Version: 20181109.3aae284
Release: 0
Summary: Tools to aid in staging and release work for openSUSE/SUSE
License: GPL-2.0-or-later AND MIT
@@ -199,6 +199,17 @@
Requires: perl-XML-Simple
Requires(pre): shadow
+%package obs-operator
+Summary: Server used to perform staging operations
+Group: Development/Tools/Other
+BuildArch: noarch
+Requires: osc-plugin-staging = %{version}
+Requires(pre): shadow
+
+%description obs-operator
+Server used to perform staging operations as a service instead of requiring
+the osc staging plugin to be utilized directly.
+
%description repo-checker
Repository checker service that inspects built RPMs from stagings.
@@ -367,6 +378,17 @@
/usr/bin/systemctl try-restart --no-block grafana-server
fi
+%pre obs-operator
+getent passwd osrt-obs-operator > /dev/null || \
+ useradd -r -m -s /sbin/nologin -c "user for
openSUSE-release-tools-obs-operator" osrt-obs-operator
+exit 0
+
+%postun obs-operator
+%systemd_postun
+if [ -x /usr/bin/systemctl ] && /usr/bin/systemctl is-enabled
osrt-obs-operator ; then
+ /usr/bin/systemctl try-restart --no-block osrt-obs-operator
+fi
+
%pre repo-checker
getent passwd osrt-repo-checker > /dev/null || \
useradd -r -m -s /sbin/nologin -c "user for
openSUSE-release-tools-repo-checker" osrt-repo-checker
@@ -413,6 +435,7 @@
%doc README.md
%{_bindir}/osrt-biarchtool
%{_bindir}/osrt-bs_mirrorfull
+%{_bindir}/osrt-bugowner
%{_bindir}/osrt-build-fail-reminder
%{_bindir}/osrt-checknewer
%{_bindir}/osrt-check_source_in_factory
@@ -544,6 +567,10 @@
%{_unitdir}/osrt-metrics-access.service
%{_unitdir}/osrt-metrics-access.timer
+%files obs-operator
+%{_bindir}/osrt-obs_operator
+%{_unitdir}/osrt-obs-operator.service
+
%files repo-checker
%defattr(-,root,root,-)
%{_bindir}/osrt-repo_checker
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.CHPZQc/_old 2018-11-10 17:02:35.591517907 +0100
+++ /var/tmp/diff_new_pack.CHPZQc/_new 2018-11-10 17:02:35.591517907 +0100
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/openSUSE/openSUSE-release-tools.git</param>
- <param
name="changesrevision">824fab13fdeaac4f14ed10409c8ff7844eb3e07c</param>
+ <param
name="changesrevision">3aae284ff2c32b4c4f0ed528aed4355b312a3a2a</param>
</service>
</servicedata>
++++++ openSUSE-release-tools-20181108.4293b6b.obscpio ->
openSUSE-release-tools-20181109.3aae284.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/openSUSE-release-tools-20181108.4293b6b/bugowner.py
new/openSUSE-release-tools-20181109.3aae284/bugowner.py
--- old/openSUSE-release-tools-20181108.4293b6b/bugowner.py 1970-01-01
01:00:00.000000000 +0100
+++ new/openSUSE-release-tools-20181109.3aae284/bugowner.py 2018-11-09
08:50:52.000000000 +0100
@@ -0,0 +1,253 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018 SUSE LLC
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from ConfigParser import ConfigParser
+from xdg.BaseDirectory import load_first_config
+from lxml import etree as ET
+from collections import namedtuple
+
+import sys
+import cmdln
+import logging
+import urllib2
+import osc.core
+import yaml
+import os
+import ldap
+
+import ToolBase
+
+logger = logging.getLogger()
+
+FACTORY = "openSUSE:Factory"
+
+Owner = namedtuple('Owner', ('kind', 'name'))
+Person = namedtuple('Person', ('login', 'email', 'realname'))
+
+class BugownerTool(ToolBase.ToolBase):
+
+ def __init__(self):
+ ToolBase.ToolBase.__init__(self)
+ self.project = None
+ self.reference_projects = None
+ self.package_metas = dict()
+ self.release_managers = None
+ self.persons = {}
+
+ def resolve_person(self, name):
+ if name in self.persons:
+ return self.persons[name]
+
+ url = self.makeurl(['person', name])
+ root = ET.fromstring(self.cached_GET(url))
+
+ person = Person(*[ root.find('./{}'.format(field)).text for field in
Person._fields ])
+ self.persons[name] = person
+
+ return person
+
+ def find_packages_with_missing_bugowner(self):
+ url = self.makeurl(['search', 'missing_owner'], { 'project':
self.project, 'filter': 'bugowner'})
+ root = ET.fromstring(self.cached_GET(url))
+
+ missing = []
+ for node in root.findall('missing_owner'):
+ missing.append(node.get('package'))
+
+ return missing
+
+ def find_owner(self, package, role = 'bugowner'):
+ # XXX: not actually looking for package but binary
+ # https://github.com/openSUSE/open-build-service/issues/4359
+ url = self.makeurl(['search', 'owner'], { 'binary': package})
+ root = ET.fromstring(self.cached_GET(url))
+ ret = []
+ for node in root.findall('./owner/person[@role="{}"]'.format(role)):
+ ret.append(Owner('person', node.get('name')))
+ for node in root.findall('./owner/group[@role="{}"]'.format(role)):
+ ret.append(Owner('group', node.get('name')))
+
+ return ret
+
+ def add_bugowner(self, package, owner):
+ url = self.makeurl(['source', self.project, package, '_meta'])
+ root = ET.fromstring(self.cached_GET(url))
+ idname = 'userid' if owner.kind == 'person' else 'groupid'
+ # XXX: can't use 'and' here to filter for bugowner too
+ exists = root.findall('./{}[@{}="{}"]'.format(owner.kind, idname,
owner.name))
+ for node in exists:
+ if node.get('role') == 'bugowner':
+ logger.debug("%s/%s already has %s %s", self.project, package,
owner.kind, owner.name)
+ return
+
+ node = ET.SubElement(root, owner.kind)
+ node.set(idname, owner.name)
+ node.set('role', 'bugowner')
+
+ data = ET.tostring(root)
+ logger.debug(data)
+ self.http_PUT(url, data=data)
+
+ def package_get_last_committer(self, package):
+ project = self.project
+ srcrev = osc.core.get_source_rev(self.apiurl, project, package)
+
+ if 'requestid' in srcrev:
+ r = osc.core.get_request(self.apiurl, srcrev['requestid'])
+ user = r.statehistory[0].who
+ else:
+ user = srcrev['user']
+
+ if self.is_release_manager(user):
+ logging.debug("%s was last touched by %s, ignored."%(package,
user))
+ return None
+
+ return [ Owner('person', user) ]
+
+ def is_release_manager(self, name):
+ if self.release_managers is None:
+ self.release_managers = set()
+ url = self.makeurl(['group', 'sle-release-managers'])
+ root = ET.fromstring(self.cached_GET(url))
+ for node in root.findall('.//person[@userid]'):
+ self.release_managers.add(node.get('userid'))
+ # XXX: hardcoded bot
+ self.release_managers.add('leaper')
+ logger.debug("release managers %s", self.release_managers)
+
+ return name in self.release_managers
+
+
+class CommandLineInterface(ToolBase.CommandLineInterface):
+
+ def __init__(self, *args, **kwargs):
+ ToolBase.CommandLineInterface.__init__(self, args, kwargs)
+
+ def get_optparser(self):
+ parser = ToolBase.CommandLineInterface.get_optparser(self)
+ parser.add_option('-p', '--project', dest='project', metavar='PROJECT',
+ help='project to process (default: %s)' % FACTORY,
+ default = FACTORY)
+ parser.add_option('--reference-project', metavar='PROJECT',
+ action='append', help='reference project')
+ return parser
+
+ def setup_tool(self):
+ tool = BugownerTool()
+ tool.project = self.options.project
+ return tool
+
+ def do_missing(self, subcmd, opts):
+ """${cmd_name}: find packages with missing bugowner
+
+ Beware of https://github.com/openSUSE/open-build-service/issues/4172
+ when using this with SLE service packs or update projects
+
+ ${cmd_usage}
+ ${cmd_option_list}
+ """
+
+ pkgs = self.tool.find_packages_with_missing_bugowner()
+ for p in pkgs:
+ print(p)
+
+ @cmdln.option('-r', '--role', metavar='ROLE', help='role to look up',
default="bugowner")
+ @cmdln.option('-s', '--set', action='store_true', help='set bugowner in
specified project')
+ @cmdln.option('--request', action='store_true', help='print osc request
lines')
+ @cmdln.option('--employee', action='store_true', help='only filter
employees')
+ def do_owner(self, subcmd, opts, *package):
+ """${cmd_name}: find owners of the given pacakge
+
+ ${cmd_usage}
+ ${cmd_option_list}
+ """
+
+ l = ldap.initialize("ldap://pan.suse.de")
+ l.simple_bind_s()
+
+ for p in package:
+ owners = self.tool.find_owner(p, opts.role)
+ if not owners:
+ logger.info("%s does not have owners", p)
+ continue
+ for o in owners:
+ logger.info("%s -> %s %s", p, o.kind, o.name)
+ if opts.set:
+ self.tool.add_bugowner(p, o)
+ elif opts.request:
+ name = o.name
+ if o.kind == 'group':
+ name = 'group:' + name
+ print("osc -A {} reqbs -r bugowner -m 'copy bug owner from
previous codestream' {} {} {}".format(self.tool.apiurl, self.tool.project, p,
name))
+ elif opts.employee:
+ if o.kind != 'person':
+ logger.debug('%s not a person', o.name)
+ continue
+ person = self.tool.resolve_person(o.name)
+ if person.email.endswith('@suse.com'):
+ print p, o.name
+ else:
+ logger.debug('%s skipped', o.name)
+
+ def do_addbugowner(self, subcmd, opts, package, *persons):
+ """${cmd_name}: add person as bugowner unless already set
+
+ ${cmd_usage}
+ ${cmd_option_list}
+ """
+
+ for p in persons:
+ o = Owner('person', p)
+ logger.info("%s -> %s %s", package, o.kind, o.name)
+ self.tool.add_bugowner(p, o)
+
+ @cmdln.option('--set', action='store_true',
+ help='request bugowner')
+ @cmdln.option('--request', action='store_true', help='print osc request
lines')
+ def do_lastsubmitter(self, subcmd, opts, *packages):
+ """${cmd_name}: show last committer for packages
+
+ excludes release managers
+
+ ${cmd_name} PROJECT PACKAGE...
+
+ ${cmd_option_list}
+ """
+
+ for p in packages:
+ owners = self.tool.package_get_last_committer(p)
+ if not owners:
+ logger.info("%s does not have owners", p)
+ continue
+ for o in owners:
+ logger.info("%s -> %s %s", p, o.kind, o.name)
+ if opts.set:
+ self.tool.add_bugowner(p, o)
+ if opts.request:
+ name = o.name
+ if o.kind == 'group':
+ name = 'group:' + name
+ print("osc -A {} reqbs -r bugowner -m 'add last submitter
as bug owner' {} {} {}".format(self.tool.apiurl, self.tool.project, p, name))
+
+if __name__ == "__main__":
+ app = CommandLineInterface()
+ sys.exit(app.main())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20181108.4293b6b/dist/package/openSUSE-release-tools.spec
new/openSUSE-release-tools-20181109.3aae284/dist/package/openSUSE-release-tools.spec
---
old/openSUSE-release-tools-20181108.4293b6b/dist/package/openSUSE-release-tools.spec
2018-11-08 17:10:04.000000000 +0100
+++
new/openSUSE-release-tools-20181109.3aae284/dist/package/openSUSE-release-tools.spec
2018-11-09 08:50:52.000000000 +0100
@@ -199,6 +199,17 @@
Requires: perl-XML-Simple
Requires(pre): shadow
+%package obs-operator
+Summary: Server used to perform staging operations
+Group: Development/Tools/Other
+BuildArch: noarch
+Requires: osc-plugin-staging = %{version}
+Requires(pre): shadow
+
+%description obs-operator
+Server used to perform staging operations as a service instead of requiring
+the osc staging plugin to be utilized directly.
+
%description repo-checker
Repository checker service that inspects built RPMs from stagings.
@@ -367,6 +378,17 @@
/usr/bin/systemctl try-restart --no-block grafana-server
fi
+%pre obs-operator
+getent passwd osrt-obs-operator > /dev/null || \
+ useradd -r -m -s /sbin/nologin -c "user for
openSUSE-release-tools-obs-operator" osrt-obs-operator
+exit 0
+
+%postun obs-operator
+%systemd_postun
+if [ -x /usr/bin/systemctl ] && /usr/bin/systemctl is-enabled
osrt-obs-operator ; then
+ /usr/bin/systemctl try-restart --no-block osrt-obs-operator
+fi
+
%pre repo-checker
getent passwd osrt-repo-checker > /dev/null || \
useradd -r -m -s /sbin/nologin -c "user for
openSUSE-release-tools-repo-checker" osrt-repo-checker
@@ -413,6 +435,7 @@
%doc README.md
%{_bindir}/osrt-biarchtool
%{_bindir}/osrt-bs_mirrorfull
+%{_bindir}/osrt-bugowner
%{_bindir}/osrt-build-fail-reminder
%{_bindir}/osrt-checknewer
%{_bindir}/osrt-check_source_in_factory
@@ -544,6 +567,10 @@
%{_unitdir}/osrt-metrics-access.service
%{_unitdir}/osrt-metrics-access.timer
+%files obs-operator
+%{_bindir}/osrt-obs_operator
+%{_unitdir}/osrt-obs-operator.service
+
%files repo-checker
%defattr(-,root,root,-)
%{_bindir}/osrt-repo_checker
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20181108.4293b6b/obs_operator.py
new/openSUSE-release-tools-20181109.3aae284/obs_operator.py
--- old/openSUSE-release-tools-20181108.4293b6b/obs_operator.py 1970-01-01
01:00:00.000000000 +0100
+++ new/openSUSE-release-tools-20181109.3aae284/obs_operator.py 2018-11-09
08:50:52.000000000 +0100
@@ -0,0 +1,194 @@
+#!/usr/bin/python3
+
+import argparse
+from http.cookies import SimpleCookie
+from http.cookiejar import Cookie, LWPCookieJar
+from http.server import BaseHTTPRequestHandler, HTTPServer
+from socketserver import ThreadingMixIn
+import json
+import tempfile
+import os
+from osclib import common
+import subprocess
+import sys
+import time
+from urllib.parse import urlparse
+
+# Available in python 3.7.
+class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
+ pass
+
+class RequestHandler(BaseHTTPRequestHandler):
+ COOKIE_NAME = 'openSUSE_session' # Both OBS and IBS.
+ POST_ACTIONS = ['select']
+
+ def do_GET(self):
+ if self.path != '/':
+ self.send_response(404)
+ self.end_headers()
+ return
+
+ self.send_response(200)
+ self.send_header('Content-type', 'text/plain')
+ self.end_headers()
+
+ self.write_string('namespace: {}\n'.format(common.NAME))
+ self.write_string('name: {}\n'.format('OBS Operator'))
+ self.write_string('version: {}\n'.format(common.VERSION))
+
+ def do_POST(self):
+ action = self.path.lstrip('/')
+ if action not in self.POST_ACTIONS:
+ self.send_response(404)
+ self.end_headers()
+ return
+
+ data = self.data_parse()
+ user = data.get('user')
+ apiurl = self.apiurl_get()
+ if not data or not user or not apiurl:
+ self.send_response(400)
+ self.end_headers()
+ return
+ if self.debug:
+ print('data: {}'.format(data))
+ print('apiurl: {}'.format(apiurl))
+
+ session = self.session_get()
+ if not session:
+ self.send_response(401)
+ self.end_headers()
+ return
+ if self.debug:
+ print('session: {}'.format(session))
+
+ self.send_response(200)
+ self.send_header('Content-type', 'text/plain')
+ self.send_header('Access-Control-Allow-Credentials', 'true')
+ self.send_header('Access-Control-Allow-Origin',
self.headers.get('Origin'))
+ self.end_headers()
+
+ with tempfile.NamedTemporaryFile() as cookiejar_file:
+ with tempfile.NamedTemporaryFile() as oscrc_file:
+ self.oscrc_create(oscrc_file, apiurl, cookiejar_file, user)
+ self.cookiejar_create(cookiejar_file, session)
+
+ func = getattr(self, 'handle_{}'.format(action))
+ commands = func(data)
+ for command in commands:
+ self.write_string('$ {}\n'.format(' '.join(command)))
+ if not self.execute(oscrc_file, command):
+ self.write_string('failed')
+ break
+
+ def data_parse(self):
+ data = self.rfile.read(int(self.headers['Content-Length']))
+ return json.loads(data.decode('utf-8'))
+
+ def apiurl_get(self):
+ if self.apiurl:
+ return self.apiurl
+
+ origin = self.headers.get('Origin')
+ if not origin:
+ return None
+
+ # Strip port if present.
+ domain = urlparse(origin).netloc.split(':', 2)[0]
+ if '.' not in domain:
+ return None
+
+ # Remove first subdomain and replace with api subdomain.
+ domain_parent = '.'.join(domain.split('.')[1:])
+ return 'https://api.{}'.format(domain_parent)
+
+ def session_get(self):
+ if self.session:
+ return self.session
+ else:
+ cookie = self.headers.get('Cookie')
+ if cookie:
+ cookie = SimpleCookie(cookie)
+ if self.COOKIE_NAME in cookie:
+ return cookie[self.COOKIE_NAME].value
+
+ return None
+
+ def oscrc_create(self, oscrc_file, apiurl, cookiejar_file, user):
+ oscrc_file.write('\n'.join([
+ '[general]',
+ 'apiurl = {}'.format(apiurl),
+ 'cookiejar = {}'.format(cookiejar_file.name),
+ 'staging.color = 0',
+ '[{}]'.format(apiurl),
+ 'user = {}'.format(user),
+ 'pass = invalid',
+ '',
+ ]).encode('utf-8'))
+ oscrc_file.flush()
+
+ # In order to avoid osc clearing the cookie file the modified time of
+ # the oscrc file must be set further into the past.
+ # if int(round(config_mtime)) > int(os.stat(cookie_file).st_mtime):
+ recent_past = time.time() - 3600
+ os.utime(oscrc_file.name, (recent_past, recent_past))
+
+ def cookiejar_create(self, cookiejar_file, session):
+ cookie_jar = LWPCookieJar(cookiejar_file.name)
+ cookie_jar.set_cookie(Cookie(0, self.COOKIE_NAME, session,
+ None, False,
+ '', False, True,
+ '/', True,
+ True,
+ None, None, None, None, {}))
+ cookie_jar.save()
+ cookiejar_file.flush()
+
+ def execute(self, oscrc_file, command):
+ env = os.environ
+ env['OSC_CONFIG'] = oscrc_file.name
+
+ # Would be preferrable to stream incremental output, but python http
+ # server does not seem to support this easily.
+ result = subprocess.run(command, env=env, stdout=self.wfile,
stderr=self.wfile)
+ return result.returncode == 0
+
+ def write_string(self, string):
+ self.wfile.write(string.encode('utf-8'))
+
+ def staging_command(self, project, subcommand):
+ return ['osc', 'staging', '-p', project, subcommand]
+
+ def handle_select(self, data):
+ for staging, requests in data['selection'].items():
+ command = self.staging_command(data['project'], 'select')
+ if 'move' in data and data['move']:
+ command.append('--move')
+ command.append(staging)
+ command.extend(requests)
+ yield command
+
+def main(args):
+ RequestHandler.apiurl = args.apiurl
+ RequestHandler.session = args.session
+ RequestHandler.debug = args.debug
+
+ with ThreadedHTTPServer((args.host, args.port), RequestHandler) as httpd:
+ print('listening on {}:{}'.format(args.host, args.port))
+ httpd.serve_forever()
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='OBS Operator server used to
perform staging operations.')
+ parser.set_defaults(func=main)
+
+ parser.add_argument('--host', default='', help='host name to which to
bind')
+ parser.add_argument('--port', type=int, default=8080, help='port number to
which to bind')
+ parser.add_argument('-A', '--apiurl',
+ help='OBS instance API URL to use instead of basing from request
origin')
+ parser.add_argument('--session',
+ help='session cookie value to use instead of any passed cookie')
+ parser.add_argument('-d', '--debug', action='store_true',
+ help='print debugging information')
+
+ args = parser.parse_args()
+ sys.exit(args.func(args))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20181108.4293b6b/osclib/adi_command.py
new/openSUSE-release-tools-20181109.3aae284/osclib/adi_command.py
--- old/openSUSE-release-tools-20181108.4293b6b/osclib/adi_command.py
2018-11-08 17:10:04.000000000 +0100
+++ new/openSUSE-release-tools-20181109.3aae284/osclib/adi_command.py
2018-11-09 08:50:52.000000000 +0100
@@ -35,7 +35,7 @@
return
if len(info['untracked_requests']):
print(query_project + " " + Fore.YELLOW + 'untracked: ' + ',
'.join(['{}[{}]'.format(
- Fore.CYAN + req['package'] + Fore.RESET + " " +
req['number']) for req in info['untracked_requests']]))
+ Fore.CYAN + req['package'] + Fore.RESET, req['number'])
for req in info['untracked_requests']]))
return
if len(info['obsolete_requests']):
print(query_project + " " + Fore.YELLOW + 'obsolete: ' + ',
'.join(['{}[{}]'.format(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20181108.4293b6b/osclib/stagingapi.py
new/openSUSE-release-tools-20181109.3aae284/osclib/stagingapi.py
--- old/openSUSE-release-tools-20181108.4293b6b/osclib/stagingapi.py
2018-11-08 17:10:04.000000000 +0100
+++ new/openSUSE-release-tools-20181109.3aae284/osclib/stagingapi.py
2018-11-09 08:50:52.000000000 +0100
@@ -836,12 +836,11 @@
orig_project = project
self._remove_package_from_prj_pseudometa(project, package)
- project = self.map_ring_package_to_subject(project, package)
if self._supersede:
self.is_package_disabled(project, package, store=True)
for sub_prj, sub_pkg in self.get_sub_packages(package, project):
- sub_prj = self.map_ring_package_to_subject(project, sub_pkg)
+ sub_prj = project
if self._supersede:
self.is_package_disabled(sub_prj, sub_pkg, store=True)
# Skip inner-project links for letter staging
@@ -1090,21 +1089,6 @@
return True
- def map_ring_package_to_subject(self, project, pkg):
- """
- Returns the subproject (if any) to use for the pkg depending on the
ring
- the package is in
- :param project the staging prj
- :param pkg the package to add
- """
- # it's actually a pretty stupid algorithm, but it might become more
complex later
-
- # assuming it is in adi staging, workaround for
https://progress.opensuse.org/issues/9646
- if self.is_adi_project(project):
- return project
-
- return project
-
def get_sub_packages(self, package, project):
"""
Returns a list of packages that need to be linked to main package.
@@ -1164,11 +1148,10 @@
"""
tar_pkg = act.tgt_package
- project = self.map_ring_package_to_subject(project, tar_pkg)
self.create_and_wipe_package(project, tar_pkg)
for sub_prj, sub_pkg in self.get_sub_packages(tar_pkg, project):
- sub_prj = self.map_ring_package_to_subject(project, sub_pkg)
+ sub_prj = project
self.create_and_wipe_package(sub_prj, sub_pkg)
# create a link so unselect can find it
@@ -1178,13 +1161,11 @@
return tar_pkg
- def submit_to_prj(self, act, project, force_enable_build=False):
+ def submit_to_prj(self, act, project):
"""
Links sources from request to project
:param act: action for submit request
:param project: project to link into
- :param force_enable_build: overwrite the ring criteria to enable
- or disable the build
"""
src_prj = act.src_project
@@ -1192,21 +1173,7 @@
src_pkg = act.src_package
tar_pkg = act.tgt_package
- disable_build = False
- # The force_enable_build will avoid the
- # map_ring_package_to_subproject
- if not force_enable_build:
- if self.crings and not self.ring_packages.get(tar_pkg) and not
self.is_adi_project(project):
- disable_build = True
- logging.warning("{}/{} not in ring, build
disabled".format(project, tar_pkg))
- else:
- project = self.map_ring_package_to_subject(project, tar_pkg)
-
- if self._supersede:
- disable_build = self._package_disabled.get('/'.join([project,
tar_pkg]), disable_build)
-
- self.create_package_container(project, tar_pkg,
- disable_build=disable_build)
+ self.create_package_container(project, tar_pkg)
# expand the revision to a md5
url = self.makeurl(['source', src_prj, src_pkg],
@@ -1233,7 +1200,7 @@
baselibs = True
for sub_prj, sub_pkg in self.get_sub_packages(tar_pkg, project):
- sub_prj = self.map_ring_package_to_subject(project, sub_pkg)
+ sub_prj = project
# Skip inner-project links for letter staging
if not self.is_adi_project(project) and sub_prj == project:
continue
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20181108.4293b6b/systemd/osrt-obs-operator.service
new/openSUSE-release-tools-20181109.3aae284/systemd/osrt-obs-operator.service
---
old/openSUSE-release-tools-20181108.4293b6b/systemd/osrt-obs-operator.service
1970-01-01 01:00:00.000000000 +0100
+++
new/openSUSE-release-tools-20181109.3aae284/systemd/osrt-obs-operator.service
2018-11-09 08:50:52.000000000 +0100
@@ -0,0 +1,10 @@
+[Unit]
+Description=openSUSE Release Tools: OBS Operator
+
+[Service]
+User=osrt-obs-operator
+ExecStart=/usr/bin/osrt-obs_operator --debug
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20181108.4293b6b/totest-manager.py
new/openSUSE-release-tools-20181109.3aae284/totest-manager.py
--- old/openSUSE-release-tools-20181108.4293b6b/totest-manager.py
2018-11-08 17:10:04.000000000 +0100
+++ new/openSUSE-release-tools-20181109.3aae284/totest-manager.py
2018-11-09 08:50:52.000000000 +0100
@@ -817,7 +817,7 @@
return self.iso_build_version(self.project + ':ToTest',
self.main_products[0])
-class ToTest151ARM(ToTestBaseNew):
+class ToTest151ARM(ToTest151):
main_products = [
'000product:openSUSE-cd-mini-aarch64',
'000product:openSUSE-dvd5-dvd-aarch64',
@@ -832,9 +832,8 @@
# Leap 15.1 ARM still need to update snapshot
set_snapshot_number = True
-
- # product_repo openqa_group jobs_num values are specific to aarch64
- # TODO: How to handle the other entries of main_products ?
+ # JeOS doesn't follow build numbers of main isos
+ need_same_build_number = False
def openqa_group(self):
return 'openSUSE Leap 15 AArch64'
@@ -842,9 +841,6 @@
def jobs_num(self):
return 10
- def get_current_snapshot(self):
- return self.iso_build_version(self.project + ':ToTest',
self.main_products[0])
-
class ToTest150Ports(ToTestBaseNew):
main_products = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20181108.4293b6b/userscript/staging-move-drag-n-drop.user.js
new/openSUSE-release-tools-20181109.3aae284/userscript/staging-move-drag-n-drop.user.js
---
old/openSUSE-release-tools-20181108.4293b6b/userscript/staging-move-drag-n-drop.user.js
2018-11-08 17:10:04.000000000 +0100
+++
new/openSUSE-release-tools-20181109.3aae284/userscript/staging-move-drag-n-drop.user.js
2018-11-09 08:50:52.000000000 +0100
@@ -1,7 +1,7 @@
// ==UserScript==
// @name OSRT Staging Move Drag-n-Drop
// @namespace openSUSE/openSUSE-release-tools
-// @version 0.1.0
+// @version 0.2.0
// @description Provide staging request moving interface on staging dashboard.
// @author Jimmy Berry
// @match */project/staging_projects/*
@@ -16,10 +16,25 @@
(function()
{
+ // Exclude not usable browsers.
+ if (!document.querySelectorAll || !('draggable' in
document.createElement('span'))) {
+ return;
+ }
+
+ // Ensure user is logged in.
+ if (!document.querySelector('#link-to-user-home')) {
+ return;
+ }
+
// Add explanation of trigger shortcut to legend box.
var explanation = document.createElement('div');
explanation.id = 'osrt-explanation';
- explanation.innerText = 'press ctrl+m to move requests';
+ explanation.innerText = 'enter move mode';
+ explanation.setAttribute('title', 'ctrl + m');
+ explanation.onclick = function() {
+ initMoveInterface();
+ this.onclick = null;
+ };
document.querySelector('#legends').appendChild(explanation);
window.onkeyup = function(e) {
@@ -35,6 +50,12 @@
padding: 10px;
background-color: #d9b200;
color: white;
+ cursor: pointer;
+}
+
+#osrt-explanation.osrt-active
+{
+ cursor: default;
}
#osrt-summary
@@ -43,13 +64,55 @@
z-index: 10000;
bottom: 0;
left: 0;
- width: 95%;
- height: 100px;
- padding: 10px;
- background-color: black;
- color: #18f018;
- white-space: pre;
- overflow: scroll;
+ width: 100%%;
+ height: 2em;
+ padding-top: 0.7em;
+ text-align: center;
+ background-color: white;
+}
+
+#osrt-summary button
+{
+ margin-left: 10px;
+}
+
+#osrt-summary progress
+{
+ display: none;
+}
+
+#osrt-summary.osrt-progress progress
+{
+ display: inline;
+}
+
+#osrt-summary.osrt-progress span,
+#osrt-summary.osrt-progress button,
+#osrt-summary.osrt-success button
+{
+ display: none;
+}
+
+#osrt-summary.osrt-failed
+{
+ background-color: red;
+ color: white;
+}
+
+#osrt-summary.osrt-failed span
+{
+ display: inline;
+}
+
+#osrt-summary.osrt-failed progress
+{
+ display: none;
+}
+
+#osrt-summary.osrt-success
+{
+ background-color: green;
+ color: white;
}
/* drop target state */
@@ -91,19 +154,7 @@
})();
-var initMoveInterface = function(){
- //exclude older browsers by the features we need them to support
- //and legacy opera explicitly so we don't waste time on a dead browser
- if
- (
- !document.querySelectorAll
- ||
- !('draggable' in document.createElement('span'))
- ||
- window.opera
- )
- { return; }
-
+var initMoveInterface = function() {
// Update explanation text and add new legend entries.
function addLegend(type)
{
@@ -118,7 +169,10 @@
addLegend('Moved');
addLegend('Selected');
- document.querySelector('#osrt-explanation').innerText = 'move mode
activated: drag box around requests or ctrl/shift+click requests to select and
drag a request to another staging.';
+ var explanation = document.querySelector('#osrt-explanation');
+ explanation.innerText = 'drag box around requests or ctrl/shift + click
requests to select and drag a request to another staging.';
+ explanation.setAttribute('title', 'move mode activated');
+ explanation.classList.add('osrt-active');
// @resource will not work since served without proper MIME type.
$.get('https://raw.githubusercontent.com/p34eu/selectables/master/selectables.css',
function(data, status) {
@@ -143,7 +197,7 @@
e.osrtContinue = (e.target.getAttribute('data-draggable') !=
'item' &&
e.target.tagName != 'A' &&
e.target.tagName != 'LABEL' &&
- e.target.id != 'osrt-summary');
+ !e.target.id.startsWith('osrt-'));
},
// Abuse key option by setting the value in start callback whic is run
// first and the value determines if drag selection is started.
@@ -171,38 +225,96 @@
return parent.querySelector('div.letter a').innerText;
}
+ var summary = {};
function updateSummary()
{
var summaryElement = document.querySelector('div#osrt-summary');
if (!summaryElement) {
summaryElement = document.createElement('div');
summaryElement.id = 'osrt-summary';
+ summaryElement.appendChild(document.createElement('span'))
+
+ var button = document.createElement('button');
+ button.innerText = 'Apply';
+ button.onclick = applyChanges;
+ summaryElement.appendChild(button);
+
+ summaryElement.appendChild(document.createElement('progress'))
document.body.appendChild(summaryElement);
}
var elements = document.querySelectorAll('.osrt-moved');
- var summary = {};
+ summary = {};
var staging;
for (var i = 0; i < elements.length; i++) {
staging = getStaging(elements[i]);
+ if (!isNaN(staging)) {
+ staging = 'adi:' + staging;
+ }
if (!(staging in summary)) {
summary[staging] = [];
}
summary[staging].push(elements[i].children[0].innerText.trim());
}
- var summaryText = '';
+ summaryElement.children[0].innerText = elements.length + ' request(s)
to move affecting ' + Object.keys(summary).length + ' stagings(s)';
+ summaryElement.children[2].setAttribute('max', elements.length);
+ }
+
+ function applyChanges()
+ {
+ var summaryElement = document.querySelector('div#osrt-summary');
+ summaryElement.classList.add('osrt-progress');
+
+ var user =
document.querySelector('#link-to-user-home').innerText.trim();
var pathParts = window.location.pathname.split('/');
var project = pathParts[pathParts.length - 1];
- for (var key in summary) {
- staging = key;
- if (!isNaN(key)) {
- staging = 'adi:' + key;
- }
- summaryText += 'osc staging -p ' + project + ' select --move ' +
staging + ' ' + summary[key].join(' ') + "\n";
+
+ var data = JSON.stringify({'user': user, 'project': project, 'move':
true, 'selection': summary});
+ var domain_parent =
window.location.hostname.split('.').splice(1).join('.');
+ var subdomain = domain_parent.endsWith('suse.de') ? 'tortuga' :
'operator';
+ var url = 'https://' + subdomain + '.' + domain_parent + '/select';
+ $.post({url: url, data: data, crossDomain: true, xhrFields:
{withCredentials: true},
+ success: applyChangesSuccess}).fail(applyChangesFailed);
+ }
+
+ function applyChangesSuccess(data)
+ {
+ // Could provide link to this in UI.
+ console.log(data);
+
+ var summaryElement = document.querySelector('div#osrt-summary');
+ summaryElement.classList.add('osrt-complete');
+ if (data.trim().endsWith('failed')) {
+ applyChangesFailed();
+ return;
+ }
+
+ var expected = summaryElement.children[2].getAttribute('max');
+ if ((data.match(/\(\d+\/\d+\)/g) || []).length == expected) {
+ summaryElement.children[0].innerText = 'Moved ' + expected + '
request(s).';
+ summaryElement.children[2].setAttribute('value', expected);
+ summaryElement.classList.add('osrt-success');
+ summaryElement.classList.remove('osrt-progress');
+
+ // Could reset UI in a more elegant way.
+ reloadShortly();
+ return;
}
- summaryElement.innerText = summaryText;
+ applyChangesFailed();
+ }
+
+ function applyChangesFailed()
+ {
+ var summaryElement = document.querySelector('div#osrt-summary');
+ summaryElement.children[0].innerText = 'Failed to move requests.';
+ summaryElement.classList.add('osrt-failed');
+ }
+
+ function reloadShortly()
+ {
+ setTimeout(function() { window.location.reload(); }, 3000);
}
//get the collection of draggable targets and add their draggable attribute
++++++ openSUSE-release-tools.obsinfo ++++++
--- /var/tmp/diff_new_pack.CHPZQc/_old 2018-11-10 17:02:36.135517244 +0100
+++ /var/tmp/diff_new_pack.CHPZQc/_new 2018-11-10 17:02:36.135517244 +0100
@@ -1,5 +1,5 @@
name: openSUSE-release-tools
-version: 20181108.4293b6b
-mtime: 1541693404
-commit: 4293b6bce15bd3c6c0356d90ae80360a08d9b059
+version: 20181109.3aae284
+mtime: 1541749852
+commit: 3aae284ff2c32b4c4f0ed528aed4355b312a3a2a