CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/Utilities/ReleaseScripts/scripts/cmstc.py

Go to the documentation of this file.
00001 """CMS TagCollector Python API
00002 """
00003 
00004 __author__ = "Miguel Ojeda"
00005 __copyright__ = "Copyright 2010-2011, CERN CMS"
00006 __credits__ = ["Miguel Ojeda"]
00007 __license__ = "Unknown"
00008 __maintainer__ = "Miguel Ojeda"
00009 __email__ = "mojedasa@cern.ch"
00010 __status__ = "Staging"
00011 
00012 _tagcollector_url = 'https://cmssdt.cern.ch/tc/'
00013 
00014 import urllib
00015 import urllib2
00016 import cookielib
00017 try:
00018     import json
00019 except ImportError:
00020     import simplejson as json
00021 import getpass
00022 
00023 class TagCollector(object):
00024         """CMS TagCollector Python API"""
00025 
00026         def __init__(self):
00027                 self._url = _tagcollector_url
00028                 self._cj = cookielib.CookieJar()
00029                 self._opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self._cj))
00030                 self.login = False
00031 
00032         def __del__(self):
00033                 if self.login: self.signOut()
00034 
00035         def _open(self, page, params = None, data = None):
00036                 url = self._url + page + '?'
00037                 if params:
00038                         url += urllib.urlencode(params)
00039                 if data:
00040                         data = urllib.urlencode(data)
00041                 try:
00042                         return self._opener.open(url, data).read()
00043                 except urllib2.HTTPError, e:
00044                         raise Exception(e.read().strip())
00045 
00046         def _openjson(self, page, params = None, data = None):
00047                 return json.loads(self._open(page, params, data))
00048 
00049         def signIn(self, username, password):
00050                 """Sign in to TagCollector."""
00051                 self._open('signIn', data = {'password': password, 'user_name': username})
00052                 self.login = True
00053 
00054         def signInInteractive(self):
00055                 """Sign in to TagCollector, asking for the username and password."""
00056                 username = raw_input('Username: ')
00057                 password = getpass.getpass()
00058                 self.signIn(username, password)
00059                 return username
00060 
00061         def signOut(self):
00062                 """Sign out of TagCollector."""
00063                 self._open('signOut')
00064                 self.login = False
00065 
00066         def getPackageTags(self, package):
00067                 """Get the tags published in TagCollector for a package.
00068                 Note: TagCollector's published tags are a subset of CVS' tags."""
00069                 return self._openjson('py_getPackageTags', {'package': package})
00070 
00071         def getPackageTagDescriptionFirstLine(self, package, tag):
00072                 """Get the first line of the descriptions of a tag."""
00073                 return self._openjson('py_getPackageTagDescriptionFirstLine', {'package': package, 'tag': tag})
00074 
00075         def getPackageTagReleases(self, package, tag):
00076                 """Get the releases where a tag is."""
00077                 return self._openjson('py_getPackageTagReleases', {'package': package, 'tag': tag})
00078 
00079         def getReleasesTags(self, releases, diff = False):
00080                 """Get the tags of one or more release.
00081                 Optionally, return only the tags that differ between releases."""
00082                 releases = json.dumps(releases)
00083                 diff = json.dumps(diff)
00084                 return self._openjson('py_getReleasesTags', {'releases': releases, 'diff': diff})
00085 
00086         def getReleaseTags(self, release):
00087                 """Get the tags of one release."""
00088                 return self.getReleasesTags((release, ))
00089 
00090         def getTagsetTags(self, tagset):
00091                 """Get the tags of one tagset."""
00092                 return self._openjson('py_getTagsetTags', {'tagset': tagset})
00093 
00094         def getTagsetInformation(self, tagset):
00095                 """Get the information of one tagset."""
00096                 return self._openjson('py_getTagsetInformation', {'tagset': tagset})
00097 
00098         def getPendingApprovalTags(self, args, allow_multiple_tags = False):
00099                 """Prints Pending Approval tags of one or more releases,
00100                 one or more tagsets, or both (i.e. it joins all the tags).
00101                 Prints an error if several tags appear for a single package.
00102                 Suitable for piping to addpkg (note: at the moment,
00103                 addpkg does not read from stdin, use "-f" instead)."""
00104                 args = json.dumps(args)
00105                 allow_multiple_tags = json.dumps(allow_multiple_tags)
00106                 return self._openjson('py_getPendingApprovalTags', {'args': args, 'allow_multiple_tags': allow_multiple_tags})
00107         
00108         def getTagsetsTagsPendingSignatures(self, user_name, show_all, author_tagsets, release_names = None):
00109                 """Prints Pending Signature tags of one or more releases,
00110                 one or more tagsets, or both (i.e. it joins all the tags).
00111                 Prints an error if several tags appear for a single package.
00112                 Suitable for piping to addpkg (note: at the moment,
00113                 addpkg does not read from stdin, use "-f" instead)."""
00114                 if not release_names == None:
00115                         return self._openjson('py_getTagsetsTagsPendingSignatures', {'user_name': user_name, 'show_all': show_all, 'author_tagsets': author_tagsets, 'release_names': json.dumps(release_names)})
00116                 else:
00117                         return self._openjson('py_getTagsetsTagsPendingSignatures', {'user_name': user_name, 'show_all': show_all, 'author_tagsets': author_tagsets})
00118 
00119         def commentTagsets(self, tagset_ids, comment):
00120                 """Comment one or more tagsets.
00121                 Requirement: Signed in."""
00122                 tagset_ids = json.dumps(tagset_ids)
00123                 if len(comment) < 1:
00124                         raise Exception("Error: Expected a comment.")
00125                 self._open('commentTagsets', {'tagset_ids': tagset_ids, 'comment': comment})
00126 
00127         def signTagsets(self, tagset_ids, comment = ''):
00128                 """Sign one or more tagsets.
00129                 Requirement: Signed in as a L2."""
00130                 tagset_ids = json.dumps(tagset_ids)
00131                 self._open('signTagsets', {'tagset_ids': tagset_ids, 'comment': comment})
00132 
00133         def signTagsetsAll(self, tagset_ids, comment = ''):
00134                 """Sign all one or more tagsets.
00135                 Requirement: Signed in as a top-level admin."""
00136                 tagset_ids = json.dumps(tagset_ids)
00137                 self._open('signTagsetsAll', {'tagset_ids': tagset_ids, 'comment': comment})
00138 
00139         def rejectTagsetsPendingSignatures(self, tagset_ids, comment = ''):
00140                 """Reject one or more tagsets Pending Signatures.
00141                 Requirement: Signed in as a L2s or as a Release Manager
00142                 for the tagset's release or as the author of the tagset."""
00143                 tagset_ids = json.dumps(tagset_ids)
00144                 self._open('rejectTagsetsPendingSignatures', {'tagset_ids': tagset_ids, 'comment': comment})
00145 
00146         def approveTagsets(self, tagset_ids, comment = ''):
00147                 """Approve one or more tagsets.
00148                 Requirement: Signed in as a Release Manager for each tagset's release."""
00149                 tagset_ids = json.dumps(tagset_ids)
00150                 self._open('approveTagsets', {'tagset_ids': tagset_ids, 'comment': comment})
00151 
00152         def bypassTagsets(self, tagset_ids, comment = ''):
00153                 """Bypass one or more tagsets.
00154                 Requirement: Signed in as a Release Manager for each tagset's release."""
00155                 tagset_ids = json.dumps(tagset_ids)
00156                 self._open('bypassTagsets', {'tagset_ids': tagset_ids, 'comment': comment})
00157 
00158         def rejectTagsetsPendingApproval(self, tagset_ids, comment = ''):
00159                 """Reject one or more tagsets Pending Approval.
00160                 Requirement: Signed in as a Release Manager."""
00161                 tagset_ids = json.dumps(tagset_ids)
00162                 self._open('rejectTagsetsPendingApproval', {'tagset_ids': tagset_ids, 'comment': comment})
00163 
00164         def removeTagsets(self, tagset_ids, comment = ''):
00165                 """Remove one or more tagsets from the History (i.e. stack of the release).
00166                 Requirement: Signed in as a Release Manager."""
00167                 tagset_ids = json.dumps(tagset_ids)
00168                 self._open('removeTagsets', {'tagset_ids': tagset_ids, 'comment': comment})
00169 
00170         def getPackagesPendingApproval(self):
00171                 """Get New Package Requests which are Pending Approval."""
00172                 return self._openjson('py_getPackagesPendingApproval')
00173 
00174         def getPackageManagersRequested(self, package):
00175                 """Get the Package Managers (administrators and developers) requested in a New Package Request."""
00176                 return self._openjson('py_getPackageManagersRequested', {'package': package})
00177 
00178         def search(self, term):
00179                 """Searches for releases, packages, tagsets, users and categories.
00180                 Requirement: Signed in."""
00181                 return self._openjson('search', {'term': term})
00182 
00183         def approvePackage(self, package):
00184                 """Approve a New Package Request.
00185                 Requirement: Signed in as a Creator (i.e. people in the top-level .admin/developers file).
00186                 Warning: This does *not* create the package in CVS."""
00187                 self._open('approveNewPackageRequest', {'package_name': package})
00188 
00189         def getIBs(self, filt = '', limit = 10):
00190                 """Get the name and creation date of Integration Builds.
00191                 By default, it only returns the latest 10 IBs.
00192                 Optionally, filter by name."""
00193                 return self._openjson('py_getIBs', {'filt': filt, 'limit': limit})
00194         
00195         def createRelease(self, base_release_name, new_release_name, new_state, new_private, new_type, new_description, release_managers, copy_queues, tags):
00196                 """Create a new release.
00197                 Requirement: Signed in as a release manager."""
00198                 if self.login:
00199                     self._open('copyRelease', {'release_name': base_release_name, 'new_release_name': new_release_name, 'new_state': new_state, 'new_private': new_private, 'new_type': new_type, 'new_description': new_description, 'release_managers': release_managers, 'copy_queues': copy_queues, 'tags': tags})
00200                 else:
00201                         raise Exception("Error: Not logged in?!")
00202                 
00203         def requestCustomIB(self, release_name, architectures, tags):
00204                 """Request a CustomIB.
00205                 Requirement: Signed in."""
00206                 if self.login:
00207                     self._open('requestCustomIB', {'release_name': release_name, 'architecture_names': architectures, 'tags': tags})
00208                 else:
00209                         raise Exception("Error: Not logged in?!")
00210                 
00211         def getReleaseArchitectures(self, release, default='0'):
00212                 """Returns release architectures."""
00213                 return self._openjson('py_getReleaseArchitectures', {'release': release, 'default': default})