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)
|
(page, version) = packages.checkSourceExists(package, release)
|
||||||
|
|
||||||
# Get the component the package is in.
|
# Get the component the package is in.
|
||||||
component = packages.packageComponent(package, release)
|
component = lp_functions.packageComponent(package, release)
|
||||||
|
|
||||||
# Output details.
|
# Output details.
|
||||||
print "The source version for '%s' in %s (%s) is at %s." % (package,
|
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)
|
# Operations that are remaining may only be done by Ubuntu developers (retry)
|
||||||
# or buildd admins (rescore). Check if the proper permissions are in place.
|
# 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 op == "retry":
|
||||||
if component in ("main", "restricted"):
|
necessaryPrivs = lp_functions.canUploadPackage(package, release)
|
||||||
teamNeeded = "ubuntu-core-dev"
|
|
||||||
else:
|
|
||||||
teamNeeded = "ubuntu-dev"
|
|
||||||
|
|
||||||
necessaryPrivs = lp_functions.isLPTeamMember(teamNeeded)
|
|
||||||
|
|
||||||
if not necessaryPrivs:
|
if not necessaryPrivs:
|
||||||
print >> sys.stderr, "You cannot perform the %s operation on a %s package " \
|
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
|
- Delete the directory just after creating it if the package
|
||||||
doesn't exist.
|
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
|
ubuntu-dev-tools (0.73) karmic; urgency=low
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
.SH NAME
|
.SH NAME
|
||||||
requestsync \- helper to file sync requests for Ubuntu
|
requestsync \- helper to file sync requests for Ubuntu
|
||||||
.SH SYNOPSIS
|
.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
|
.br
|
||||||
.B requestsync \-\-lp\fR [\fB\-nse\fR] <\fBsource package\fR> <\fBtarget release\fR> [\fIbase version\fR]
|
.B requestsync \-\-lp\fR [\fB\-nse\fR] <\fBsource package\fR> <\fBtarget release\fR> [\fIbase version\fR]
|
||||||
.br
|
.br
|
||||||
|
60
requestsync
60
requestsync
@ -40,12 +40,13 @@ import ubuntutools.lp.cookie as lp_cookie
|
|||||||
import ubuntutools.lp.functions as lp_functions
|
import ubuntutools.lp.functions as lp_functions
|
||||||
import ubuntutools.lp.libsupport as lp_libsupport
|
import ubuntutools.lp.libsupport as lp_libsupport
|
||||||
import ubuntutools.lp.urlopener as lp_urlopener
|
import ubuntutools.lp.urlopener as lp_urlopener
|
||||||
|
import ubuntutools.lp.udtexceptions as udtexceptions
|
||||||
# https_proxy fix
|
# https_proxy fix
|
||||||
import ubuntutools.common
|
import ubuntutools.common
|
||||||
|
|
||||||
launchpad_cookiefile = lp_cookie.prepareLaunchpadCookie()
|
launchpad_cookiefile = lp_cookie.prepareLaunchpadCookie()
|
||||||
|
|
||||||
def checkNeedsSponsorship(component):
|
def checkNeedsSponsorship(srcpkg):
|
||||||
"""
|
"""
|
||||||
Check that the user has the appropriate permissions by checking what
|
Check that the user has the appropriate permissions by checking what
|
||||||
Launchpad returns while authenticating with their cookie.
|
Launchpad returns while authenticating with their cookie.
|
||||||
@ -59,25 +60,14 @@ def checkNeedsSponsorship(component):
|
|||||||
The prepareLaunchpadCookie function above shall ensure that a cookie
|
The prepareLaunchpadCookie function above shall ensure that a cookie
|
||||||
file exists first.
|
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']:
|
if component in ['main', 'restricted']:
|
||||||
team = "ubuntu-core-dev"
|
team = "ubuntu-core-dev"
|
||||||
sponsor = "ubuntu-main-sponsors"
|
sponsor = "ubuntu-main-sponsors"
|
||||||
else:
|
else:
|
||||||
team = "ubuntu-dev"
|
team = "motu"
|
||||||
sponsor = "ubuntu-universe-sponsors"
|
sponsor = "ubuntu-universe-sponsors"
|
||||||
|
|
||||||
# Check if they are a member of the team.
|
if not lp_functions.canUploadPackage(srcpkg):
|
||||||
teamMember = lp_functions.isLPTeamMember(team)
|
|
||||||
|
|
||||||
if not teamMember:
|
|
||||||
|
|
||||||
# Check if they have a per-package upload permission.
|
# Check if they have a per-package upload permission.
|
||||||
if lp_functions.isPerPackageUploader(args[0]):
|
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
|
"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 " \
|
print "This must be done before it can be processed by a member of " \
|
||||||
"the Ubuntu Archive team."
|
"the Ubuntu Archive team."
|
||||||
print "If the above is correct please press Enter, otherwise please " \
|
print "If the above is correct please press Enter."
|
||||||
"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."
|
|
||||||
raw_input_exit_on_ctrlc() # Abort if necessary.
|
raw_input_exit_on_ctrlc() # Abort if necessary.
|
||||||
return True # Sponsorship required.
|
return True # Sponsorship required.
|
||||||
|
|
||||||
@ -150,21 +136,17 @@ def checkExistingReports(package):
|
|||||||
raw_input_exit_on_ctrlc()
|
raw_input_exit_on_ctrlc()
|
||||||
|
|
||||||
def cur_version_component(sourcepkg, release):
|
def cur_version_component(sourcepkg, release):
|
||||||
'''Determine current package version in ubuntu.'''
|
|
||||||
madison = subprocess.Popen(['rmadison', '-u', 'ubuntu', '-a', 'source', \
|
try:
|
||||||
'-s', release, sourcepkg], stdout=subprocess.PIPE)
|
version = lp_functions.packageVersion(sourcepkg, release)
|
||||||
out = madison.communicate()[0]
|
component = lp_functions.packageComponent(sourcepkg, release)
|
||||||
assert (madison.returncode == 0)
|
|
||||||
|
|
||||||
for l in out.splitlines():
|
return (version, component)
|
||||||
(pkg, version, rel, builds) = l.split('|')
|
|
||||||
component = 'main'
|
except udtexceptions.PackageNotFoundException:
|
||||||
if rel.find('/') != -1:
|
|
||||||
component = rel.split('/')[1]
|
print "%s doesn't appear to exist in %s, specify -n for a package not in Ubuntu." % (sourcepkg, release)
|
||||||
return (version.strip(), component.strip())
|
sys.exit(1)
|
||||||
|
|
||||||
print "%s doesn't appear to exist in %s, specify -n for a package not in Ubuntu." % (sourcepkg, release)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def cur_deb_version(sourcepkg, distro):
|
def cur_deb_version(sourcepkg, distro):
|
||||||
'''Return the current debian version of a package in a Debian distro.'''
|
'''Return the current debian version of a package in a Debian distro.'''
|
||||||
@ -505,15 +487,17 @@ if __name__ == '__main__':
|
|||||||
distro = options.dist
|
distro = options.dist
|
||||||
ffe = options.ffe
|
ffe = options.ffe
|
||||||
|
|
||||||
if len(args) not in (2, 3):
|
if len(args) not in (2, 3): # no release specified, assume development release
|
||||||
optParser.error("Source package / target release missing - please " \
|
release = lp_functions.ubuntuDevelopmentSeries()
|
||||||
"specify.")
|
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():
|
if not use_lp_bugs and not get_email_address():
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
srcpkg = args[0]
|
srcpkg = args[0]
|
||||||
release = args[1]
|
|
||||||
force_base_ver = None
|
force_base_ver = None
|
||||||
|
|
||||||
# Base version specified.
|
# Base version specified.
|
||||||
@ -534,7 +518,7 @@ if __name__ == '__main__':
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# -s flag not specified - check if we do need sponsorship.
|
# -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.
|
# Check for existing package reports.
|
||||||
if not newsource and use_lp_bugs: checkExistingReports(srcpkg)
|
if not newsource and use_lp_bugs: checkExistingReports(srcpkg)
|
||||||
|
@ -22,45 +22,148 @@ import cookie
|
|||||||
import urlopener as lp_urlopener
|
import urlopener as lp_urlopener
|
||||||
import urllib2
|
import urllib2
|
||||||
import sys
|
import sys
|
||||||
|
from udtexceptions import PackageNotFoundException, TeamNotFoundException, SeriesNotFoundException
|
||||||
import libsupport as lp_libsupport
|
import libsupport as lp_libsupport
|
||||||
import launchpadlib
|
import launchpadlib
|
||||||
from re import findall
|
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):
|
def isLPTeamMember(team):
|
||||||
""" Checks if the user is a member of a certain team on Launchpad.
|
""" 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
|
Uses the LP API.
|
||||||
text "You are not a member of this team" is present using the
|
|
||||||
user's cookie file for authentication.
|
|
||||||
|
|
||||||
If the user is a member of the team: return True.
|
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 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:
|
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.
|
lpteam = launchpad.people[team]
|
||||||
if ("You are not a member of this team") in lpTeamPage:
|
|
||||||
return False
|
if not lpteam.is_team:
|
||||||
|
raise KeyError
|
||||||
return True
|
|
||||||
|
return _findMember(lpteam, launchpad.me)
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
|
||||||
|
raise TeamNotFoundException("The team %s does not exist on Launchpad" %
|
||||||
|
team)
|
||||||
|
|
||||||
def isPerPackageUploader(package):
|
def isPerPackageUploader(package):
|
||||||
# Checks if the user has upload privileges for a certain 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]
|
me = findall('~(\S+)', '%s' % launchpad.me)[0]
|
||||||
main_archive = launchpad.distributions["ubuntu"].main_archive
|
main_archive = launchpad.distributions["ubuntu"].main_archive
|
||||||
try:
|
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