diff --git a/CREDITS b/CREDITS index b51e6d78..ec200eba 100644 --- a/CREDITS +++ b/CREDITS @@ -1,5 +1,6 @@ There is a number of people who have helped: +Marcus Huewe - wipebinaries command, abortbuild command, editmeta error handling Marcus Rueckert - help and countless suggestions Christoph Thiel - patch enabling build log following. Adrian Schroeter - one-liner showing how to handle an error ;-) diff --git a/NEWS b/NEWS index ecadf409..7915b0d2 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ since 0.96: +- new wipebinaries and abortbuild commands, by courtesy of Marcus Huewe +- improved metadata error condition handling (thanks to Marcus Huewe) - build: add --userootforbuild option - build: implement -x/--extra-pkgs option (passed to backend and included in buildinfo result) - make filling out of username in templates work again diff --git a/osc/commandline.py b/osc/commandline.py index e23d1853..387a9d3c 100755 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -1208,7 +1208,7 @@ class Osc(cmdln.Cmdln): if opts.failed: code = 'failed' - print cmd_rebuild(conf.config['apiurl'], project, package, repo, arch, code) + print rebuild(conf.config['apiurl'], project, package, repo, arch, code) def do_info(self, subcmd, opts, *args): @@ -1229,6 +1229,60 @@ class Osc(cmdln.Cmdln): print p.info() + @cmdln.option('-a', '--arch', metavar='ARCH', + help='Abort builds for a specific architecture') + @cmdln.option('-r', '--repo', metavar='REPO', + help='Abort builds for a specific repository') + def do_abortbuild(self, subcmd, opts, *args): + """${cmd_name}: Aborts the build of a certain project/package + + With the optional argument you can specify a certain package + otherwise all builds in the project will be cancelled. + + usage: + osc abortbuild [OPTS] PROJECT [PACKAGE] + ${cmd_option_list} + """ + + if len(args) < 1: + print >>sys.stderr, 'Missing argument' + return 2 + + if len(args) == 2: + package = args[1] + else: + package = None + + print abortbuild(conf.config['apiurl'], args[0], package, opts.arch, opts.repo) + + + @cmdln.option('-a', '--arch', metavar='ARCH', + help='Delete all binary package for a specific architecture') + @cmdln.option('-r', '--repo', metavar='REPO', + help='Delete all binary packages for a specific repository') + def do_wipebinaries(self, subcmd, opts, *args): + """${cmd_name}: Delete all binary packages of a certain project/package + + With the optional arguement you can specify a certain package + otherwise all binary packages in the project will be deleted. + + usage: + osc wipebinaries [OPTS] PROJECT [PACKAGE] + ${cmd_option_list} + """ + + if len(args) < 1: + print >>sys.stderr, 'Missing argument' + return 2 + + if len(args) == 2: + package = args[1] + else: + package = None + + print wipebinaries(conf.config['apiurl'], args[0], package, opts.arch, opts.repo) + + if __name__ == '__main__': osc = Osc() sys.exit(osc.main()) diff --git a/osc/core.py b/osc/core.py index 5f6b9cb9..2af93c1c 100755 --- a/osc/core.py +++ b/osc/core.py @@ -844,21 +844,43 @@ class metafile: if self.change_is_required == True and os.path.getmtime(self.filename) == self.timestamp: print 'File unchanged. Not saving.' os.unlink(self.filename) + return - else: - print 'Sending meta data...', + try: + print 'Sending meta data...' http_PUT(self.url, file=self.filename) os.unlink(self.filename) print 'Done.' + return + except urllib2.HTTPError, e: + # internal server error (probably the xml file is incorrect) + if e.code == 500: + print >>sys.stderr, 'cannot save meta data - probably your xml file is incorrect' + print >>sys.stderr, e + # this may be unhelpful... because it may just print a big blob of uninteresting + # ichain html and javascript... however it could potentially be useful if the orign + # server returns an information body + #print >>sys.stderr, e.read() + return False + else: + print >> sys.stderr, 'cannot save meta data - an unexpected error occured' + return False def edit_meta(prj, pac, template=new_package_templ, change_is_required=True): f=metafile(prj, pac, template, change_is_required) editor = os.getenv('EDITOR', default='vim') - os.system('%s %s' % (editor, f.filename)) - - if change_is_required == True: - f.sync() + while 1: + os.system('%s %s' % (editor, f.filename)) + if change_is_required == True: + if not f.sync(): + input = raw_input('Try again? (yY = Yes - nN = No): ') + if input != 'y' and input != 'Y': + break + else: + break + else: + break def edit_user_meta(user, change_is_required=True): import tempfile @@ -1324,7 +1346,7 @@ def get_buildhistory(apiurl, prj, package, platform, arch): return r -def cmd_rebuild(apiurl, prj, package, repo, arch, code=None): +def rebuild(apiurl, prj, package, repo, arch, code=None): query = [] query.append('cmd=rebuild') if package: @@ -1378,3 +1400,59 @@ def store_write_apiurl(dir, apiurl): def get_osc_version(): return __version__ + +def abortbuild(apiurl, project, package=None, arch=None, repo=None): + query = [] + query.append('cmd=abortbuild') + if package: + query.append('package=%s' % quote_plus(package)) + if arch: + query.append('arch=%s' % quote_plus(arch)) + if repo: + query.append('repository=%s' % quote_plus(repo)) + u = makeurl(apiurl, ['build', project], query) + try: + f = http_POST(u) + except urllib2.HTTPError, e: + err_str = 'abortion failed for project %s' % project + if package: + err_str += ' package %s' % package + if arch: + err_str += ' arch %s' % arch + if repo: + err_str += ' repo %s' % repo + print >> sys.stderr, err_str + print >> sys.stderr, u + print >> sys.stderr, e + sys.exit(1) + root = ET.parse(f).getroot() + return root.get('code') + + +def wipebinaries(apiurl, project, package=None, arch=None, repo=None): + query = [] + query.append('cmd=wipe') + if package: + query.append('package=%s' % quote_plus(package)) + if arch: + query.append('arch=%s' % quote_plus(arch)) + if repo: + query.append('repository=%s' % quote_plus(repo)) + + u = makeurl(apiurl, ['build', project], query) + try: + f = http_POST(u) + except urllib2.HTTPError, e: + err_str = 'wipe binary rpms failed for project %s' % project + if package: + err_str += ' package %s' % package + if arch: + err_str += ' arch %s' % arch + if repo: + err_str += ' repository %s' % repo + print >> sys.stderr, err_str + print >> sys.stderr, u + print >> sys.stderr, e + sys.exit(1) + root = ET.parse(f).getroot() + return root.get('code')