1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-26 22:56:15 +01:00

import new request handling from branch:

- New generic "request" command:
  - new "delete" request
  - new "change_devel" request
  - Multiple actions in one request is not yet supported by osc
This commit is contained in:
Adrian Schröter 2009-06-02 13:14:46 +00:00
parent 0158d5e377
commit 46d726133c
4 changed files with 454 additions and 207 deletions

5
NEWS
View File

@ -1,4 +1,9 @@
0.118:
- Obsolete "submitreq" command
- New generic "request" command:
- new "delete" request
- new "change_devel" request
- Multiple actions in one request is not yet supported by osc
- support of added .changes in commit message template
- make submit request listing fast by server side filtering
- allow pulling of conflicting changes via "osc repairlink"

74
TODO
View File

@ -58,85 +58,11 @@ MINOR:
[1]
http://api.opensuse.org/result/Apache/SUSE_Linux_10.0/apache2/result
15:06 <darix> kurz zeit ueber 1-2 osc feature request zu reden die ich grade bekommen habe?
15:06 <DuDE_> ja
15:06 <darix> ok
15:06 <darix> das 1. ist
15:06 <darix> osc listpackages [<project>]
15:06 <DuDE_> als Alias?
15:07 <darix> osc listpackages [<project>] [<package>]
15:07 <darix> es soll die gebauten sachen listen
15:07 <DuDE_> ach so, rpms
15:07 <darix> quasi alle rpms/debs die da sind
15:07 <darix> und dann
15:07 <DuDE_> mit Pfad/URL?
15:07 <DuDE_> also praktisch den Link auf software.opesuse.org?
15:07 <darix> osc getpackage [<project>] [<package>] [<rpm>]+
15:07 <darix> nein
15:07 <darix> im zweifel ueber API saugen
15:08 <DuDE_> hm, waere noetig, falls ein Projekt noch nicht durchgebaut hat
15:08 <darix> jau
15:08 <darix> richi wuerde sich wirklich drueber freuen
15:08 <darix> ich weiss dass es ueber die api vom backend geht
15:09 <darix> ich weiss nur nicht ob api alles durchreicht
15:09 <darix> und leider hab ich schon ein paar sachen im api code gefunden
15:09 <darix> der falsch mit dem backend spricht :/
15:09 <DuDE_> ja, macht osc build auch so, eigentlich, allerdings weiss es dann die noetigen Datein aus dem buildinfo (version, release)
15:09 <darix> man kann auf dem backend alle rpms listen lassen
[3]
19:08 < Beineri> DuDE: can you add an option to "up" which moves instead overwriting a file if it has changed in the repository?
19:08 < darix> Beineri: moves?
19:08 < darix> oO
19:08 < darix> Beineri: use case?
19:09 < Beineri> darix: I want to see what changed when updating (we miss notification and history if you didn't notice). so I want to run "diff foo.myversion foo"
19:09 < darix> Beineri: we have a history?
19:09 < darix> Beineri: you should rtfm the api docs before claiming stuff!:p
19:10 < Beineri> darix: trying to turn around my words?
19:10 < darix> Beineri: no
19:10 < darix> just correcting wrong statements.
19:10 < DuDE> Beineri: doesn't sound too useful
19:10 < Beineri> darix: what's wrong with "we miss history"?
19:10 < DuDE> it's deviating too much from the normal usecase
19:10 < DuDE> which is, merging upstream changes in
19:10 < DuDE> Beineri: but I have a better idea, I think
19:11 < DuDE> Beineri: something that I miss in svn very much
19:11 < Beineri> DuDE: it still shall merge, but make a copy of my version before :-)
19:11 < darix> GET http://api.opensuse.org/source/<project>/<package>/<filename>
19:11 < DuDE> Beineri: you mean, keep a fool.mine file in any case?
19:11 < darix> GET http://api.opensuse.org/source/<project>/<package>/<filename>?rev=1234
19:11 < DuDE> Beineri: what I miss badly, is a command to see upstream changes
19:11 < DuDE> Beineri: such as the good old cvs status
19:12 < DuDE> Beineri: which showed the status of the files on the server
19:12 < Beineri> DuDE: status is not enough, I want to see what changed :-)
19:12 < DuDE> Beineri: I mostly want to know what I have to expect, before up'ping and merging
19:12 < DuDE> Beineri: yes, I also want to see that
19:12 < DuDE> Beineri: some kind of osc updiff
19:13 < DuDE> Beineri: would that help?
19:13 < darix> .oO( i smell nice race conditions^^ )o
19:13 < DuDE> Beineri: sorry, I just recognize that you asked for an option
19:13 < DuDE> Beineri: that's of course always an option
19:14 < DuDE> Beineri: surely
19:14 < Beineri> DuDE: that would help, yes. "my" stuff I could for now do with a wrapper :-)
19:15 < Beineri> darix: and that's how useful without osc/web-frontend support?
15:16 < DuDE> mt: Projekte anlegen geht nur, wenn es ein Subprojekt ist von einem Projekt wo Du Schreibrechte hast
15:16 < mt> DuDE: wofür?
15:16 < DuDE> mt: dass jeder einfach so top-level-Projekte anlegen kann, war einmal. Chaos-Reduzierung
15:17 < DuDE> mt: ueblich ist heutzutage ein Request auf opensuse-buildservice@
15:18 < DuDE> mt: kannst Du das gleiche mal eben mit osc -H probieren? Mich wuerde mal interessieren, ob da eine sinnvollere Meldung im Body mitkommt
15:19 < DuDE> mt: mit -H muesste osc den Response-Body anzeigen. Meist ist der unerwuenscht, weil er typischerweise dank iChain hauptsaechlich Javascript-Schlonz enthaelt.
15:19 < mt> DuDE: reply: 'HTTP/1.1 403 Forbidden\r\n'
15:20 < DuDE> mt: das ist gut, dann sollte osc kein "try again" anbieten, sondern die Meldung rueberbringen

View File

@ -486,58 +486,25 @@ class Osc(cmdln.Cmdln):
help='only show requests created by yourself')
@cmdln.alias("sr")
@cmdln.alias("submitrequest")
@cmdln.hide(1)
def do_submitreq(self, subcmd, opts, *args):
"""${cmd_name}: Handle requests to submit a package into another project
[See http://en.opensuse.org/Build_Service/Collaboration for information
on this topic.]
For "create", there are two ways to use it. Either with a working copy
or without. If called with no arguments, osc will guess what to submit
where. If you don't have a working copy, you can give the respective
arguments on the command line (see below for an example).
Then, the DESTPAC name is optional; the source packages' name will be
used if DESTPAC is omitted.
With --message, a message can be attached.
With --revision, a revision MD5 of a package can be specified which is
to be submitted. The default is to request submission of the currently
checked in revision.
"list" lists open requests attached to a project or package.
"log" will show the history of the given ID
"show" will show the request itself, and generate a diff for review, if
used with the --diff option.
"decline" will change the request state to "declined" and append a
message that you specify with the --message option.
"delete" will permanently delete a request and append a
message that you specify with the --message option.
"revoke" will set the request state to "revoked" and append a
message that you specify with the --message option.
"accept" will change the request state to "accepted" and will trigger
the actual submit process. That would normally be a server-side copy of
the source package to the target package.
usage:
osc submitreq create [-m TEXT]
osc submitreq create [-m TEXT] DESTPRJ [DESTPKG]
osc submitreq create [-m TEXT] SOURCEPRJ SOURCEPKG DESTPRJ [DESTPKG]
osc submitreq list [-M] [PRJ [PKG]]
osc submitreq log ID
osc submitreq show [-d] [-b] ID
osc submitreq accept [-m TEXT] ID
osc submitreq decline [-m TEXT] ID
osc submitreq delete [-m TEXT] ID
osc submitreq revoke [-m TEXT] ID
${cmd_option_list}
*************************************************************************
WARNING: the "submitreq" command is about to become obsolete. Please use
the "request" command instead !
*************************************************************************
"""
print """
*************************************************************************
WARNING: the "submitreq" command is about to become obsolete. Please use
the "request" command instead !
*************************************************************************
"""
args = slash_split(args)
cmds = ['create', 'list', 'log', 'show', 'decline', 'accept', 'delete', 'revoke']
@ -639,23 +606,25 @@ of the package %s primarily takes place.
Please submit there instead, or use --nodevelproject to force direct submission.""" \
% (devloc, dst_package)
sys.exit(1)
reqs = get_submit_request_list(apiurl, dst_project, dst_package)
reqs = get_request_list(apiurl, dst_project, dst_package)
user = conf.get_apiurl_usr(apiurl)
myreqs = [ i for i in reqs if i.state.who == user ]
repl = ''
if len(myreqs) > 0:
print 'You already created the following submitrequests: %s.' % \
print 'You already created the following requests: %s.' % \
', '.join([str(i.reqid) for i in myreqs ])
repl = raw_input('Revoke the old requests? (y/N) ')
# since we have no support in the cli to specify different action types yet
# the default is a submit action
result = create_submit_request(apiurl,
src_project, src_package,
dst_project, dst_package,
opts.message, orev=opts.revision)
src_project, src_package,
dst_project, dst_package,
opts.message, orev=opts.revision)
if repl == 'y':
for req in myreqs:
change_submit_request_state(apiurl, str(req.reqid), 'revoked',
'superseded by %s' % result)
change_request_state(apiurl, str(req.reqid), 'revoked',
'superseded by %s' % result)
print 'created request id', result
@ -667,8 +636,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if opts.mine:
who = conf.get_apiurl_usr(apiurl)
results = get_submit_request_list(apiurl,
project, package, who, state_list)
results = get_request_list(apiurl,
project, package, who, state_list)
results.sort(reverse=True)
@ -676,13 +645,13 @@ Please submit there instead, or use --nodevelproject to force direct submission.
print result.list_view()
elif cmd == 'log':
for l in get_submit_request_log(conf.config['apiurl'], reqid):
for l in get_request_log(conf.config['apiurl'], reqid):
print l
# show
elif cmd == 'show':
r = get_submit_request(conf.config['apiurl'], reqid)
r = get_request(conf.config['apiurl'], reqid)
if opts.brief:
print r.list_view()
else:
@ -691,8 +660,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if opts.diff:
try:
print server_diff(conf.config['apiurl'],
r.dst_project, r.dst_package, None,
r.src_project, r.src_package, r.src_rev, opts.unified)
r.actions[0].dst_project, r.actions[0].dst_package, None,
r.actions[0].src_project, r.actions[0].src_package, r.actions[0].src_rev, opts.unified)
except urllib2.HTTPError, e:
e.osc_msg = 'Diff not possible'
raise
@ -700,23 +669,300 @@ Please submit there instead, or use --nodevelproject to force direct submission.
# decline
elif cmd == 'decline':
r = change_submit_request_state(conf.config['apiurl'],
r = change_request_state(conf.config['apiurl'],
reqid, 'declined', opts.message or '')
print r
# accept
elif cmd == 'accept':
r = change_submit_request_state(conf.config['apiurl'],
r = change_request_state(conf.config['apiurl'],
reqid, 'accepted', opts.message or '')
print r
# delete
elif cmd == 'delete':
r = change_submit_request_state(conf.config['apiurl'],
r = change_request_state(conf.config['apiurl'],
reqid, 'deleted', opts.message or '')
print r
# revoke
elif cmd == 'revoke':
r = change_submit_request_state(conf.config['apiurl'],
r = change_request_state(conf.config['apiurl'],
reqid, 'revoked', opts.message or '')
print r
@cmdln.option('-d', '--diff', action='store_true',
help='generate a diff')
@cmdln.option('-u', '--unified', action='store_true',
help='output the diff in the unified diff format')
@cmdln.option('-m', '--message', metavar='TEXT',
help='specify message TEXT')
@cmdln.option('-r', '--revision', metavar='REV',
help='for "create", specify a certain source revision ID (the md5 sum)')
@cmdln.option('--nodevelproject', action='store_true',
help='do not follow a defined devel project ' \
'(primary project where a package is developed)')
@cmdln.option('-s', '--state', default='new',
help='only list requests in one of the comma separated given states [default=new]')
@cmdln.option('-b', '--brief', action='store_true', default=False,
help='print output in list view as list subcommand')
@cmdln.option('-M', '--mine', action='store_true',
help='only show requests created by yourself')
@cmdln.alias("rq")
def do_request(self, subcmd, opts, *args):
"""${cmd_name}: Handle requests to another project
[See http://en.opensuse.org/Build_Service/Collaboration for information
on this topic.]
For "submit", there are two ways to use it. Either with a working copy
or without. If called with no arguments, osc will guess what to submit
where. If you don't have a working copy, you can give the respective
arguments on the command line (see below for an example).
Then, the DESTPAC name is optional; the source packages' name will be
used if DESTPAC is omitted.
With --message, a message can be attached.
With --revision, a revision MD5 of a package can be specified which is
to be submitted. The default is to request submission of the currently
checked in revision.
"list" lists open requests attached to a project or package.
"log" will show the history of the given ID
"show" will show the request itself, and generate a diff for review, if
used with the --diff option.
"decline" will change the request state to "declined" and append a
message that you specify with the --message option.
"delete" will permanently delete a request and append a
message that you specify with the --message option.
"revoke" will set the request state to "revoked" and append a
message that you specify with the --message option.
"accept" will change the request state to "accepted" and will trigger
the actual submit process. That would normally be a server-side copy of
the source package to the target package.
usage:
osc request submit [-m TEXT]
osc request submit [-m TEXT] DESTPRJ [DESTPKG]
osc request submit [-m TEXT] SOURCEPRJ SOURCEPKG DESTPRJ [DESTPKG]
osc request list [-M] [PRJ [PKG]]
osc request log ID
osc request show [-d] [-b] ID
osc request accept [-m TEXT] ID
osc request decline [-m TEXT] ID
osc request revoke [-m TEXT] ID
osc request delete [-m TEXT] DESTPRJ [DESTPKG]
osc request change_devel [-m TEXT] PROJECT PACKAGE DEVEL_PROJECT [DEVEL_PACKAGE]
${cmd_option_list}
"""
args = slash_split(args)
cmds = ['submit', 'list', 'log', 'show', 'decline', 'accept', 'delete', 'revoke', 'change_devel']
if not args or args[0] not in cmds:
raise oscerr.WrongArgs('Unknown request action. Choose one of %s.' \
% ', '.join(cmds))
cmd = args[0]
del args[0]
if cmd in ['submit']:
min_args, max_args = 0, 4
elif cmd in ['delete']:
min_args, max_args = 1, 2
elif cmd in ['change_devel']:
min_args, max_args = 3, 4
elif cmd in ['list']:
min_args, max_args = 0, 2
else:
min_args, max_args = 1, 1
if len(args) < min_args:
raise oscerr.WrongArgs('Too few arguments.')
if len(args) > max_args:
raise oscerr.WrongArgs('Too many arguments.')
apiurl = conf.config['apiurl']
# collect specific arguments
if cmd == 'submit':
if len(args) <= 2:
# try using the working copy at hand
p = findpacs(os.curdir)[0]
src_project = p.prjname
src_package = p.name
if len(args) == 0 and p.islink():
dst_project = p.linkinfo.project
dst_package = p.linkinfo.package
apiurl = p.apiurl
elif len(args) > 0:
dst_project = args[0]
if len(args) == 2:
dst_package = args[1]
else:
dst_package = src_package
else:
sys.exit('Package \'%s\' is not a source link, so I cannot guess the submit target.\n'
'Please provide it the target via commandline arguments.' % p.name)
modified = [i for i in p.filenamelist if p.status(i) != ' ' and p.status(i) != '?']
if len(modified) > 0:
print 'Your working copy has local modifications.'
repl = raw_input('Proceed without committing the local changes? (y|N) ')
if repl != 'y':
sys.exit(1)
elif len(args) >= 3:
# get the arguments from the commandline
src_project, src_package, dst_project = args[0:3]
if len(args) == 4:
dst_package = args[3]
else:
dst_package = src_package
else:
raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \
+ self.get_cmd_help('request'))
elif cmd == 'list':
package = None
project = None
if len(args) > 0:
project = args[0]
elif not opts.mine:
project = store_read_project(os.curdir)
apiurl = store_read_apiurl(os.curdir)
try:
package = store_read_package(os.curdir)
except oscerr.NoWorkingCopy:
pass
if len(args) > 1:
package = args[1]
elif cmd in ['log', 'show', 'decline', 'accept', 'delete', 'revoke']:
reqid = args[0]
# create submit request
if cmd == 'submit':
if not opts.nodevelproject:
devloc = None
try:
devloc = show_develproject(apiurl, dst_project, dst_package)
except urllib2.HTTPError:
print >>sys.stderr, """\
Warning: failed to fetch meta data for '%s' package '%s' (new package?) """ \
% (dst_project, dst_package)
pass
if devloc \
and dst_project != devloc \
and src_project != devloc:
print """\
Sorry, but a different project, %s, is defined as the place where development
of the package %s primarily takes place.
Please submit there instead, or use --nodevelproject to force direct submission.""" \
% (devloc, dst_package)
sys.exit(1)
reqs = get_request_list(apiurl, dst_project, dst_package)
user = conf.get_apiurl_usr(apiurl)
myreqs = [ i for i in reqs if i.state.who == user ]
repl = ''
if len(myreqs) > 0:
print 'You already created the following submit request: %s.' % \
', '.join([str(i.reqid) for i in myreqs ])
repl = raw_input('Revoke the old requests? (y/N) ')
# since we have no support in the cli to specify different action types yet
# the default is a submit action
result = create_submit_request(apiurl,
src_project, src_package,
dst_project, dst_package,
opts.message, orev=opts.revision)
if repl == 'y':
for req in myreqs:
change_request_state(apiurl, str(req.reqid), 'revoked',
'superseded by %s' % result)
print 'created request id', result
# create delete request
elif cmd == 'delete':
project = args[0]
package = None
if len(args) > 1:
package = args[1]
result = create_delete_request(apiurl, project, package, opts.message)
print result
# request to change devel project
elif cmd == 'change_devel':
devel_project = args[2]
project = args[0]
package = args[1]
devel_package = package
if len(args) > 3:
devel_package = args[3]
result = create_change_devel_request(apiurl,
devel_project, devel_package,
project, package,
opts.message)
print result
# list
elif cmd == 'list':
state_list = opts.state.split(',')
who = ''
if opts.mine:
who = conf.get_apiurl_usr(apiurl)
results = get_request_list(apiurl,
project, package, who, state_list)
results.sort(reverse=True)
for result in results:
print result.list_view()
elif cmd == 'log':
for l in get_request_log(conf.config['apiurl'], reqid):
print l
# show
elif cmd == 'show':
r = get_request(conf.config['apiurl'], reqid)
if opts.brief:
print r.list_view()
else:
print r
# fixme: will inevitably fail if the given target doesn't exist
if opts.diff:
try:
print server_diff(conf.config['apiurl'],
r.actions[0].dst_project, r.actions[0].dst_package, None,
r.actions[0].src_project, r.actions[0].src_package, r.actions[0].src_rev, opts.unified)
except urllib2.HTTPError, e:
e.osc_msg = 'Diff not possible'
raise
# decline
elif cmd == 'decline':
r = change_request_state(conf.config['apiurl'],
reqid, 'declined', opts.message or '')
print r
# accept
elif cmd == 'accept':
r = change_request_state(conf.config['apiurl'],
reqid, 'accepted', opts.message or '')
print r
# revoke
elif cmd == 'revoke':
r = change_request_state(conf.config['apiurl'],
reqid, 'revoked', opts.message or '')
print r
@ -727,6 +973,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
@cmdln.alias("createpac")
@cmdln.alias("edituser")
@cmdln.alias("usermeta")
@cmdln.hide(1)
def do_editmeta(self, subcmd, opts, *args):
"""${cmd_name}:

View File

@ -1231,9 +1231,18 @@ class RequestState:
self.when = when
self.comment = comment
class Action:
"""represents an action"""
def __init__(self, type, src_project, src_package, src_rev, dst_project, dst_package):
self.type = type
self.src_project = src_project
self.src_package = src_package
self.src_rev = src_rev
self.dst_project = dst_project
self.dst_package = dst_package
class SubmitReq:
"""represent a submit request and holds its metadata
class Request:
"""represent a request and holds its metadata
it has methods to read in metadata from xml,
different views, ..."""
def __init__(self):
@ -1242,26 +1251,30 @@ class SubmitReq:
self.who = None
self.when = None
self.last_author = None
self.src_project = None
self.src_package = None
self.src_rev = None
self.dst_project = None
self.dst_package = None
self.descr = None
self.actions = []
self.statehistory = []
def read(self, root):
self.reqid = int(root.get('id'))
actions = root.findall('action')
if len(actions) == 0:
actions = [ root.find('submit') ] # for old style requests
n = root.find('submit').find('source')
self.src_project = n.get('project')
self.src_package = n.get('package')
try: self.src_rev = n.get('rev')
except: pass
n = root.find('submit').find('target')
self.dst_project = n.get('project')
self.dst_package = n.get('package')
for action in actions:
type = action.get('type', 'submit')
try:
n = action.find('source')
src_prj = n.get('project')
src_pkg = n.get('package')
src_rev = n.get('rev', None)
n = action.find('target')
dst_prj = n.get('project')
dst_pkg = n.get('package')
self.add_action(type, src_prj, src_pkg, src_rev, dst_prj, dst_pkg)
except:
msg = 'invalid request format:\n%s' % ET.tostring(root)
raise oscerr.APIError(msg)
# read the state
n = root.find('state')
@ -1292,11 +1305,15 @@ class SubmitReq:
except:
pass
def add_action(self, type, src_prj, src_pkg, src_rev, dst_prj, dst_pkg):
self.actions.append(Action(type, src_prj, src_pkg, src_rev,
dst_prj, dst_pkg)
)
def list_view(self):
dst = "%s/%s" % (self.dst_project, self.dst_package)
if self.src_package == self.dst_package:
dst = self.dst_project
dst = "%s/%s" % (self.actions[0].dst_project, self.actions[0].dst_package)
if self.actions[0].src_package == self.actions[0].dst_package:
dst = self.actions[0].dst_project
desc = ""
if self.descr:
@ -1305,15 +1322,16 @@ class SubmitReq:
return '%6d %-7s %-12s %-50s -> %-20s %s' % \
(self.reqid,
self.state.name, "(%s)" % self.state.who,
"%s/%s" % (self.src_project, self.src_package),
"%s/%s" % (self.actions[0].src_project, self.actions[0].src_package),
dst, desc)
def __cmp__(self, other):
return cmp(self.reqid, other.reqid)
def __str__(self):
# XXX: only prints out the first action element
s = """\
Request to submit (sri%d):
Request to %s (sri%s):
%s/%s -> %s/%s
@ -1325,12 +1343,13 @@ Message:
State: %-10s %s %s
Comment: %s
""" % (self.reqid,
self.src_project,
self.src_package,
self.dst_project,
self.dst_package,
self.src_rev or 'not given',
""" % (self.actions[0].type,
self.reqid,
self.actions[0].src_project,
self.actions[0].src_package,
self.actions[0].dst_project,
self.actions[0].dst_package,
self.actions[0].src_rev or 'not given',
self.descr,
self.state.name,
self.state.when, self.state.who, self.state.comment)
@ -2022,21 +2041,68 @@ def edit_message(footer='', template=''):
pass
def create_delete_request(apiurl, project, package, message):
import cgi
if package:
package = """package="%s" """ % (package)
else:
package = ""
xml = """\
<request>
<action type="delete">
<target project="%s" %s/>
</action>
<state name="new"/>
<description>%s</description>
</request>
""" % (project, package,
cgi.escape(message or ''))
u = makeurl(apiurl, ['request'], query='cmd=create')
f = http_POST(u, data=xml)
root = ET.parse(f).getroot()
return root.get('id')
def create_change_devel_request(apiurl,
devel_project, devel_package,
project, package,
message):
import cgi
xml = """\
<request>
<action type="change_devel">
<source project="%s" package="%s" />
<target project="%s" package="%s" />
</action>
<state name="new"/>
<description>%s</description>
</request>
""" % (devel_project,
devel_package,
project,
package,
cgi.escape(message or ''))
u = makeurl(apiurl, ['request'], query='cmd=create')
f = http_POST(u, data=xml)
root = ET.parse(f).getroot()
return root.get('id')
def create_submit_request(apiurl,
src_project, src_package,
dst_project, dst_package,
message, orev=None):
import cgi
r = SubmitReq()
r.src_project = src_project
r.src_package = src_package
r.src_rev = orev or show_upstream_rev(apiurl, src_project, src_package)
r.dst_project = dst_project
r.dst_package = dst_package
r.descr = cgi.escape(message or '')
# XXX: keep the old template for now in order to work with old obs instances
xml = """\
<request type="submit">
<submit>
@ -2046,12 +2112,12 @@ def create_submit_request(apiurl,
<state name="new"/>
<description>%s</description>
</request>
""" % (r.src_project,
r.src_package,
r.src_rev,
r.dst_project,
r.dst_package,
r.descr)
""" % (src_project,
src_package,
orev or show_upstream_rev(apiurl, src_project, src_package),
dst_project,
dst_package,
cgi.escape(message or ''))
u = makeurl(apiurl, ['request'], query='cmd=create')
f = http_POST(u, data=xml)
@ -2060,17 +2126,17 @@ def create_submit_request(apiurl,
return root.get('id')
def get_submit_request(apiurl, reqid):
def get_request(apiurl, reqid):
u = makeurl(apiurl, ['request', reqid])
f = http_GET(u)
root = ET.parse(f).getroot()
r = SubmitReq()
r = Request()
r.read(root)
return r
def change_submit_request_state(apiurl, reqid, newstate, message=''):
def change_request_state(apiurl, reqid, newstate, message=''):
u = makeurl(apiurl,
['request', reqid],
query={'cmd': 'changestate', 'newstate': newstate})
@ -2078,40 +2144,43 @@ def change_submit_request_state(apiurl, reqid, newstate, message=''):
return f.read()
def get_submit_request_list(apiurl, project, package, req_who='', req_state=('new',) ):
match = ''
if project:
if len(match): match += '%20and%20'
match += 'submit/target/@project=\'%s\'' % quote_plus(project)
if package:
if len(match): match += '%20and%20'
match += 'submit/target/@package=\'%s\'' % quote_plus(package)
for state in req_state:
if len(match): match += '%20and%20'
match += 'state/@name=\'%s\'' % quote_plus(state)
if req_who:
if len(match): match += '%20and%20'
match += 'state/@who=\'%s\'' % quote_plus(req_who)
u = makeurl(apiurl, ['search', 'request'], ['match=%s' % match])
f = http_GET(u)
collection = ET.parse(f).getroot()
def get_request_list(apiurl, project, package, req_who='', req_state=('new',) ):
requests = []
for root in collection.findall('request'):
r = SubmitReq()
r.read(root)
if (r.state.name in req_state) or not len(req_state):
requests.append(r)
# XXX: we cannot use the '|' in the xpath expression because it is not supported
# in the backend
for what in ['action', 'submit']:
match = ''
if project:
if len(match): match += '%20and%20'
match += '%s/target/@project=\'%s\'' % (what, quote_plus(project))
if package:
if len(match): match += '%20and%20'
match += '%s/target/@package=\'%s\'' % (what, quote_plus(package))
for state in req_state:
if len(match): match += '%20and%20'
match += 'state/@name=\'%s\'' % quote_plus(state)
if req_who:
if len(match): match += '%20and%20'
match += 'state/@who=\'%s\'' % quote_plus(req_who)
u = makeurl(apiurl, ['search', 'request'], ['match=%s' % match])
f = http_GET(u)
collection = ET.parse(f).getroot()
for root in collection.findall('request'):
r = Request()
r.read(root)
if (r.state.name in req_state) or not len(req_state):
requests.append(r)
return requests
def get_submit_request_log(apiurl, reqid):
r = get_submit_request(conf.config['apiurl'], reqid)
def get_request_log(apiurl, reqid):
r = get_request(conf.config['apiurl'], reqid)
data = []
frmt = '-' * 76 + '\n%s | %s | %s\n\n%s'
# the description of the submitrequest is used for the initial log entry
# the description of the request is used for the initial log entry
# otherwise its comment attribute would contain None
if len(r.statehistory) >= 1:
r.statehistory[-1].comment = r.descr