mirror of
https://git.launchpad.net/ubuntu-dev-tools
synced 2025-03-13 08:01:09 +00:00
* ubuntutools/lp/lp_functions.py,
ubuntutools/lp/udtexceptions.py: - Add new public functions that expose features from LP API - Modify isLPTeamMember to use LP API * requestsync - Use new functions to check if user can upload requested package directly instead of checking team membership - Default to current development release if no release is specified on commandline * buildd - Check if user has upload privileges instead of checking for team membership when seeing if operations are permitted
This commit is contained in:
parent
dc4750eb91
commit
b4cd975dc8
11
buildd
11
buildd
@ -116,7 +116,7 @@ packages.checkReleaseExists(release)
|
||||
(page, version) = packages.checkSourceExists(package, release)
|
||||
|
||||
# Get the component the package is in.
|
||||
component = packages.packageComponent(package, release)
|
||||
component = lp_functions.packageComponent(package, release)
|
||||
|
||||
# Output details.
|
||||
print "The source version for '%s' in %s (%s) is at %s." % (package,
|
||||
@ -156,14 +156,9 @@ if len(buildstats) == 1 and options.architecture != "i386":
|
||||
|
||||
# Operations that are remaining may only be done by Ubuntu developers (retry)
|
||||
# or buildd admins (rescore). Check if the proper permissions are in place.
|
||||
if op == "rescore": teamNeeded = "launchpad-buildd-admins"
|
||||
if op == "rescore": necessaryPrivs = lp_functions.isLPTeamMember('launchpad-buildd-admins')
|
||||
if op == "retry":
|
||||
if component in ("main", "restricted"):
|
||||
teamNeeded = "ubuntu-core-dev"
|
||||
else:
|
||||
teamNeeded = "ubuntu-dev"
|
||||
|
||||
necessaryPrivs = lp_functions.isLPTeamMember(teamNeeded)
|
||||
necessaryPrivs = lp_functions.canUploadPackage(package, release)
|
||||
|
||||
if not necessaryPrivs:
|
||||
print >> sys.stderr, "You cannot perform the %s operation on a %s package " \
|
||||
|
16
debian/changelog
vendored
16
debian/changelog
vendored
@ -13,7 +13,21 @@ ubuntu-dev-tools (0.74) UNRELEASED; urgency=low
|
||||
- Delete the directory just after creating it if the package
|
||||
doesn't exist.
|
||||
|
||||
-- Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com> Wed, 06 May 2009 23:14:33 +0200
|
||||
[ Iain Lane ]
|
||||
* ubuntutools/lp/lp_functions.py,
|
||||
ubuntutools/lp/udtexceptions.py:
|
||||
- Add new public functions that expose features from LP API
|
||||
- Modify isLPTeamMember to use LP API
|
||||
* requestsync
|
||||
- Use new functions to check if user can upload requested package directly
|
||||
instead of checking team membership
|
||||
- Default to current development release if no release is specified on
|
||||
commandline
|
||||
* buildd
|
||||
- Check if user has upload privileges instead of checking for team
|
||||
membership when seeing if operations are permitted
|
||||
|
||||
-- Iain Lane <laney@ubuntu.com> Sat, 09 May 2009 20:09:28 +0100
|
||||
|
||||
ubuntu-dev-tools (0.73) karmic; urgency=low
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
.SH NAME
|
||||
requestsync \- helper to file sync requests for Ubuntu
|
||||
.SH SYNOPSIS
|
||||
.B requestsync\fR [\fB\-d distro\fR] [\fB\-nse\fR] [\fB\-k \fIkeyid\fR] <\fBsource package\fR> <\fBtarget release\fR> [\fIbase version\fR]
|
||||
.B requestsync\fR [\fB\-d distro\fR] [\fB\-nse\fR] [\fB\-k \fIkeyid\fR] <\fBsource package\fR> [\fBtarget release\fR] [\fIbase version\fR]
|
||||
.br
|
||||
.B requestsync \-\-lp\fR [\fB\-nse\fR] <\fBsource package\fR> <\fBtarget release\fR> [\fIbase version\fR]
|
||||
.br
|
||||
|
54
requestsync
54
requestsync
@ -40,12 +40,13 @@ import ubuntutools.lp.cookie as lp_cookie
|
||||
import ubuntutools.lp.functions as lp_functions
|
||||
import ubuntutools.lp.libsupport as lp_libsupport
|
||||
import ubuntutools.lp.urlopener as lp_urlopener
|
||||
import ubuntutools.lp.udtexceptions as udtexceptions
|
||||
# https_proxy fix
|
||||
import ubuntutools.common
|
||||
|
||||
launchpad_cookiefile = lp_cookie.prepareLaunchpadCookie()
|
||||
|
||||
def checkNeedsSponsorship(component):
|
||||
def checkNeedsSponsorship(srcpkg):
|
||||
"""
|
||||
Check that the user has the appropriate permissions by checking what
|
||||
Launchpad returns while authenticating with their cookie.
|
||||
@ -59,25 +60,14 @@ def checkNeedsSponsorship(component):
|
||||
The prepareLaunchpadCookie function above shall ensure that a cookie
|
||||
file exists first.
|
||||
"""
|
||||
# TODO: use launchpadlib here
|
||||
# Once LP: #313233 has been fixed this can be implemented by either:
|
||||
# >>> me = launchpad.me
|
||||
# >>> me.inTeam(<TEAM>) #or
|
||||
# >>> me in <TEAM>
|
||||
urlopener = lp_urlopener.setupLaunchpadUrlOpener(launchpad_cookiefile)
|
||||
|
||||
# Check where the package is and assign the appropriate variables.
|
||||
if component in ['main', 'restricted']:
|
||||
team = "ubuntu-core-dev"
|
||||
sponsor = "ubuntu-main-sponsors"
|
||||
else:
|
||||
team = "ubuntu-dev"
|
||||
team = "motu"
|
||||
sponsor = "ubuntu-universe-sponsors"
|
||||
|
||||
# Check if they are a member of the team.
|
||||
teamMember = lp_functions.isLPTeamMember(team)
|
||||
|
||||
if not teamMember:
|
||||
if not lp_functions.canUploadPackage(srcpkg):
|
||||
|
||||
# Check if they have a per-package upload permission.
|
||||
if lp_functions.isPerPackageUploader(args[0]):
|
||||
@ -89,11 +79,7 @@ def checkNeedsSponsorship(component):
|
||||
"the '%s'\nteam, who shall be subscribed to this bug report." % sponsor
|
||||
print "This must be done before it can be processed by a member of " \
|
||||
"the Ubuntu Archive team."
|
||||
print "If the above is correct please press Enter, otherwise please " \
|
||||
"press Ctrl-C to stop this script now\nand check the cookie file " \
|
||||
"at:", launchpad_cookiefile
|
||||
print "Logging into Launchpad, deleting the above and rerunning this " \
|
||||
"script should be enough to generate the cookie."
|
||||
print "If the above is correct please press Enter."
|
||||
raw_input_exit_on_ctrlc() # Abort if necessary.
|
||||
return True # Sponsorship required.
|
||||
|
||||
@ -150,18 +136,14 @@ def checkExistingReports(package):
|
||||
raw_input_exit_on_ctrlc()
|
||||
|
||||
def cur_version_component(sourcepkg, release):
|
||||
'''Determine current package version in ubuntu.'''
|
||||
madison = subprocess.Popen(['rmadison', '-u', 'ubuntu', '-a', 'source', \
|
||||
'-s', release, sourcepkg], stdout=subprocess.PIPE)
|
||||
out = madison.communicate()[0]
|
||||
assert (madison.returncode == 0)
|
||||
|
||||
for l in out.splitlines():
|
||||
(pkg, version, rel, builds) = l.split('|')
|
||||
component = 'main'
|
||||
if rel.find('/') != -1:
|
||||
component = rel.split('/')[1]
|
||||
return (version.strip(), component.strip())
|
||||
try:
|
||||
version = lp_functions.packageVersion(sourcepkg, release)
|
||||
component = lp_functions.packageComponent(sourcepkg, release)
|
||||
|
||||
return (version, component)
|
||||
|
||||
except udtexceptions.PackageNotFoundException:
|
||||
|
||||
print "%s doesn't appear to exist in %s, specify -n for a package not in Ubuntu." % (sourcepkg, release)
|
||||
sys.exit(1)
|
||||
@ -505,15 +487,17 @@ if __name__ == '__main__':
|
||||
distro = options.dist
|
||||
ffe = options.ffe
|
||||
|
||||
if len(args) not in (2, 3):
|
||||
optParser.error("Source package / target release missing - please " \
|
||||
"specify.")
|
||||
if len(args) not in (2, 3): # no release specified, assume development release
|
||||
release = lp_functions.ubuntuDevelopmentSeries()
|
||||
print >> sys.stderr, ("Source package / target release missing - assuming %s " %
|
||||
release)
|
||||
else:
|
||||
release = args[1]
|
||||
|
||||
if not use_lp_bugs and not get_email_address():
|
||||
sys.exit(1)
|
||||
|
||||
srcpkg = args[0]
|
||||
release = args[1]
|
||||
force_base_ver = None
|
||||
|
||||
# Base version specified.
|
||||
@ -534,7 +518,7 @@ if __name__ == '__main__':
|
||||
sys.exit(1)
|
||||
|
||||
# -s flag not specified - check if we do need sponsorship.
|
||||
if not sponsorship: sponsorship = checkNeedsSponsorship(component)
|
||||
if not sponsorship: sponsorship = checkNeedsSponsorship(srcpkg)
|
||||
|
||||
# Check for existing package reports.
|
||||
if not newsource and use_lp_bugs: checkExistingReports(srcpkg)
|
||||
|
@ -22,45 +22,148 @@ import cookie
|
||||
import urlopener as lp_urlopener
|
||||
import urllib2
|
||||
import sys
|
||||
from udtexceptions import PackageNotFoundException, TeamNotFoundException, SeriesNotFoundException
|
||||
import libsupport as lp_libsupport
|
||||
import launchpadlib
|
||||
from re import findall
|
||||
|
||||
# Takes time to initialise - move to top level so we only pay the penalty
|
||||
# once. Should probably make this a proper class so we can instansiate
|
||||
# singleton-style (lazily).
|
||||
launchpad = lp_libsupport.get_launchpad("ubuntu-dev-tools")
|
||||
|
||||
def ubuntuDevelopmentSeries():
|
||||
""" Get the string repr of the current Ubuntu development series """
|
||||
|
||||
ubuntu = launchpad.distributions['ubuntu']
|
||||
return ubuntu.current_series.name
|
||||
|
||||
def _ubuntuSeries(name):
|
||||
""" Get the LP representation of a series
|
||||
|
||||
returns the LP API repr of a series passed by name (e.g. 'karmic')
|
||||
If the series is not found: raise SeriesNotFoundException
|
||||
"""
|
||||
|
||||
ubuntu = launchpad.distributions['ubuntu']
|
||||
try:
|
||||
|
||||
return ubuntu.getSeries(name_or_version=name)
|
||||
|
||||
except launchpadlib.errors.HTTPError:
|
||||
|
||||
raise SeriesNotFoundException('The series %s was not found' % name)
|
||||
|
||||
def _ubuntuSourcePackage(package, series):
|
||||
""" Finds an Ubuntu source package on LP
|
||||
|
||||
returns LP API repr of the source package
|
||||
If the package does not exist: raise PackageNotFoundException
|
||||
"""
|
||||
|
||||
try:
|
||||
|
||||
lpseries = _ubuntuSeries(series)
|
||||
|
||||
ubuntu = launchpad.distributions['ubuntu']
|
||||
u_archive = ubuntu.main_archive
|
||||
|
||||
component = u_archive.getPublishedSources(source_name=package, status="Published",
|
||||
exact_match=True, distro_series=lpseries)[0]
|
||||
|
||||
return component
|
||||
|
||||
except IndexError:
|
||||
|
||||
raise PackageNotFoundException("The package %s does not exist in the Ubuntu main archive" %
|
||||
package)
|
||||
|
||||
def packageVersion(package, series=ubuntuDevelopmentSeries()):
|
||||
""" Retrieves the version of a given source package in the current
|
||||
development distroseries
|
||||
|
||||
returns unicode string repr of source package version
|
||||
If the package does not exist: raise PackageNotFoundException
|
||||
"""
|
||||
|
||||
return _ubuntuSourcePackage(package, series).source_package_version
|
||||
|
||||
def packageComponent(package, series=ubuntuDevelopmentSeries()):
|
||||
""" Retrieves the component for a given source package
|
||||
|
||||
returns unicode string representation of component
|
||||
If the package does not exist: raise PackageNotFoundException
|
||||
"""
|
||||
|
||||
return _ubuntuSourcePackage(package, series).component_name
|
||||
|
||||
def canUploadPackage(package, series=ubuntuDevelopmentSeries()):
|
||||
""" Checks whether the user can upload package to Ubuntu's main archive
|
||||
|
||||
Uses LP API to do this.
|
||||
|
||||
If the user can upload the package: return True.
|
||||
If the user cannot upload the package: return False.
|
||||
If the package does not exist: raise PackageNotFoundException
|
||||
"""
|
||||
|
||||
ubuntu = launchpad.distributions['ubuntu']
|
||||
u_archive = ubuntu.main_archive
|
||||
|
||||
uploaders = u_archive.getUploadersForComponent(component_name=packageComponent(package, series))
|
||||
|
||||
for permission in uploaders:
|
||||
current_uploader = permission.person
|
||||
if _findMember(current_uploader, launchpad.me):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _findMember(haystack, needle):
|
||||
""" Find a person in a haystack. A haystack can consist of either people or teams.
|
||||
|
||||
If the needle is in the haystack: return True
|
||||
If the needle is not in the haystack: return False
|
||||
"""
|
||||
|
||||
if not haystack.is_team:
|
||||
return (str(haystack) == str(needle))
|
||||
else: # is a team
|
||||
members = haystack.members
|
||||
for m in members:
|
||||
if _findMember(m, needle):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def isLPTeamMember(team):
|
||||
""" Checks if the user is a member of a certain team on Launchpad.
|
||||
|
||||
We do this by opening the team page on Launchpad and checking if the
|
||||
text "You are not a member of this team" is present using the
|
||||
user's cookie file for authentication.
|
||||
Uses the LP API.
|
||||
|
||||
If the user is a member of the team: return True.
|
||||
If the user is not a member of the team: return False.
|
||||
|
||||
If the team is not found: raise a TeamNotFoundException.
|
||||
"""
|
||||
|
||||
# TODO: Check if launchpadlib may be a better way of doing this.
|
||||
|
||||
# Prepare cookie.
|
||||
cookieFile = cookie.prepareLaunchpadCookie()
|
||||
# Prepare URL opener.
|
||||
urlopener = lp_urlopener.setupLaunchpadUrlOpener(cookieFile)
|
||||
|
||||
# Try to open the Launchpad team page:
|
||||
try:
|
||||
lpTeamPage = urlopener.open("https://launchpad.net/~%s" % team).read()
|
||||
except urllib2.HTTPError, error:
|
||||
print >> sys.stderr, "Unable to connect to Launchpad. Received a %s." % error.code
|
||||
sys.exit(1)
|
||||
|
||||
# Check if text is present in page.
|
||||
if ("You are not a member of this team") in lpTeamPage:
|
||||
return False
|
||||
lpteam = launchpad.people[team]
|
||||
|
||||
return True
|
||||
if not lpteam.is_team:
|
||||
raise KeyError
|
||||
|
||||
return _findMember(lpteam, launchpad.me)
|
||||
|
||||
except KeyError:
|
||||
|
||||
raise TeamNotFoundException("The team %s does not exist on Launchpad" %
|
||||
team)
|
||||
|
||||
def isPerPackageUploader(package):
|
||||
# Checks if the user has upload privileges for a certain package.
|
||||
|
||||
launchpad = lp_libsupport.get_launchpad("ubuntu-dev-tools")
|
||||
me = findall('~(\S+)', '%s' % launchpad.me)[0]
|
||||
main_archive = launchpad.distributions["ubuntu"].main_archive
|
||||
try:
|
||||
|
11
ubuntutools/lp/udtexceptions.py
Normal file
11
ubuntutools/lp/udtexceptions.py
Normal file
@ -0,0 +1,11 @@
|
||||
class PackageNotFoundException(BaseException):
|
||||
""" Thrown when a package is not found """
|
||||
pass
|
||||
|
||||
class TeamNotFoundException(BaseException):
|
||||
""" Thrown when a team is not found """
|
||||
pass
|
||||
|
||||
class SeriesNotFoundException(BaseException):
|
||||
""" Thrown when a distroseries is not found """
|
||||
pass
|
Loading…
x
Reference in New Issue
Block a user