From 6055034754c3e099951e5f24f154fd2fbeab2a90 Mon Sep 17 00:00:00 2001 From: Will Woods Date: Fri, 18 Sep 2009 17:26:21 -0400 Subject: Initial attempt at library for israwhidebroken clients --- clientlib.py | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 clientlib.py diff --git a/clientlib.py b/clientlib.py new file mode 100644 index 0000000..c6f1b04 --- /dev/null +++ b/clientlib.py @@ -0,0 +1,106 @@ +#!/usr/bin/python +# uses the fedora.client library to talk to israwhidebroken + +from fedora.client import BaseClient, AppError, ServerError +import os, sys + +# A couple of useful helper methods +def todays_compose_id(serial=1): + import datetime + '''Return the default compose_id for today''' + return int(datetime.datetime.today().strftime('%Y%m%d') + '%02u' % serial) + +def treedata_from_url(url): + import urllib2, ConfigParser + import xml.etree.cElementTree as ElementTree + '''Given the URL of a rawhide tree, return a dict of tree data''' + treedata = dict() + # this one's a gimme + treedata['compose_id'] = todays_compose_id() + try: + # fetch treeinfo + treeinfo = ConfigParser.SafeConfigParser() + treeinfo.readfp(urllib2.urlopen(url+'/.treeinfo')) + treedata['arch'] = treeinfo.get('general','arch') + treedata['tree_time'] = int(float(treeinfo.get('general','timestamp'))) + except: + pass + try: + # fetch repomd.xml + repomd = urllib2.urlopen(url+'/repodata/repomd.xml') + repomdtree = ElementTree.parse(repomd) + ns = '{http://linux.duke.edu/metadata/repo}' + revision = repomdtree.getroot().find(ns+'revision') + treedata['repodata_time'] = int(revision.text) + except: + pass + return treedata + +class IRBClient(BaseClient): + def get_tests(self): + '''Return the list of known tests''' + r = self.send_request('/get_tests') + if 'tests' in r: + return r['tests'] + else: + pass # FIXME raise an exception or something + + def get_trees(self, *args, **kw): + '''Get a list of trees that match all the given parameters: + id, compose_id, arch, tree_time, repodata_time''' + r = self.send_request('/get_trees', req_params=kw) + if 'trees' in r: + return r['trees'] + else: + pass # FIXME raise an exception or something + + def add_tree(self, *args, **kw): + '''Add a new tree to israwhidebroken. + Required arguments: arch, compose_id + Optional: tree_time, repodata_time''' + for field in ('arch', 'compose_id', 'tree_time', 'repodata_time'): + if field not in kw: + raise ValueError, "Missing required arg %s" % field + if type(kw['arch']) is not str: + raise ValueError, 'arch must be str' + r = self.send_request('/add_tree', auth=True, req_params=kw) + if 'tree' in r: + return r['tree'] + else: + pass # FIXME raise an exception or something + + def add_result(self, treeid, testid, result, detail_url=None): + '''Add a test result to the database''' + params = {'treeid':treeid, 'testid':testid, 'result': result} + if detail_url: + params['detail_url'] = detail_url + self.send_request('/add_result', auth=True, req_params=params) + + def report_result(self, testid, tree_data, result, add_tree=False): + '''Convenience method that will look up the tree using tree_data and + then add the given result for the given testid. + + tree_data should be a dict containing enough data to look up exactly + one tree. Typically that means either specifying the exact treeid if + it's already known (e.g. {'id':treeid}) or a dict with 'arch' and one or + more of (compose_id, tree_time, repodata_time) + + If add_tree is True and tree_data does not match any known tree, a new + tree will be added.''' + treelist = self.get_trees(**tree_data) + if not treelist: + if not add_tree: + print 'Could not find a matching tree' + return None + tree = self.add_tree(**tree_data) + # FIXME else check for error + elif len(treelist) > 1: + print 'Ambiguous tree data - too many matching trees' + return False + else: + tree = treelist.pop() + r = self.add_result(treeid=tree['id'], testid=testid, result=result) + if 'id' in r: + return r['id'] + else: + pass # FIXME raise an exception or something -- cgit