Merge lp:~ursinha/uci-engine/private-lp-mthood into lp:uci-engine/mthood

Proposed by Ursula Junque
Status: Merged
Approved by: Ursula Junque
Approved revision: 442
Merged at revision: 412
Proposed branch: lp:~ursinha/uci-engine/private-lp-mthood
Merge into: lp:uci-engine/mthood
Diff against target: 587 lines (+228/-117)
14 files modified
branch-source-builder/bsbuilder/upload_package.py (+19/-0)
branch-source-builder/cupstream2distro/launchpadmanager.py (+21/-29)
branch-source-builder/cupstream2distro/packagemanager.py (+1/-1)
branch-source-builder/cupstream2distro/settings.py (+1/-5)
branch-source-builder/watch_ppa.py (+5/-5)
ci-utils/ci_utils/launchpad.py (+30/-2)
create_private_lp_creds.py (+57/-0)
image-builder/imagebuilder/cloud_image.py (+2/-4)
image-builder/imagebuilder/tests/test_modify_cloud_image.py (+1/-1)
juju-deployer/configs/unit_config.yaml.tmpl (+6/-2)
juju-deployer/deploy.py (+17/-1)
ppa-assigner/ppa_assigner/launchpad.py (+62/-61)
ppa-assigner/ppa_assigner/models.py (+3/-3)
ppa-assigner/ppa_assigner/settings.py (+3/-3)
To merge this branch: bzr merge lp:~ursinha/uci-engine/private-lp-mthood
Reviewer Review Type Date Requested Status
Francis Ginther Approve
Andy Doan (community) Approve
Review via email: mp+218538@code.launchpad.net

Commit message

This branch contains all changes required for mthood to access a private lp instance.

Description of the change

This branch contains all changes required for mthood to access a private lp instance.

The original lp:~ursinha/uci-engine/private-lp branch was created from lp:uci-engine, not lp:uci-engine/mthood, contanining a bit more changes than only private lp related ones. In this branch I applied only relevant changes on top of the mthood branch.

To post a comment you must log in.
Revision history for this message
Andy Doan (doanac) wrote :

> === modified file 'branch-source-builder/cupstream2distro/launchpadmanager.py'

> +sys.path.append(os.path.join(os.path.dirname(__file__), '../ci-utils'))

I don't think we need sys.path.append stuff in our code anymore.

> === modified file 'branch-source-builder/cupstream2distro/packagemanager.py'

> - cmd = ["dput", ppa,
> + cmd = ["dput", "-u", "-c", "/tmp/dput.cf", ppa,
> "{}_{}_source.changes".format(source, version_for_source_file)]

I'm being a little over-protective, but as per: "/tmp/dput.cf" - Seems
like we should either make a constant for that, or (and I don't know the
code structure/flow, have pass this value down to the function via
upload_package.py

> === modified file 'branch-source-builder/cupstream2distro/settings.py'

> +PRIVATE_LAUNCHPAD = _cfg.get('private_launchpad', None)

This is beyond the scope of this MP, but a tip: We now have a
unit_config module: ci_utils.unit_config that was written to handle this
stuff for all our services.

> === modified file 'branch-source-builder/watch_ppa.py'

def get_launchpad_log(url):
> '''Retrieves the build log from launchpad (thanks to celso).'''
> if not url:
> return None
> - api_url = url.replace('/launchpad.net/','/api.launchpad.net/devel/')
> - lp = launchpadmanager.get_launchpad()
> + api_url = launchpad.get_lp_api_url(api_version="devel")
> + lp = launchpad.lp_login()
> return lp._browser.get(api_url)

looks like the "url" parameter to this function is now ignored. Should
we remove it and refactor the caller of it?

> === added file 'create_private_lp_creds.py'

> +sys.path.insert(0, os.path.join(os.path.dirname(__file__), './ci-utils'))

again - don't think you need to alter sys.path anymore.

> +web_root ="https://mthoodapi.lacinonac.com/"

I don't understand the details well enough, but should this value come
from our unit_config rather than being hard-coded? Actually it looks
like deploy.py might be setting this in the unit_config?

Revision history for this message
Francis Ginther (fginther) wrote :

Approve, let's get this in!

review: Approve
Revision history for this message
Francis Ginther (fginther) wrote :

Oops, I see failure in my tarmac.sh run. Let me dig into it first.

Revision history for this message
Francis Ginther (fginther) wrote :

I found the failure:
======================================================================
FAIL: test_pep8_conformance (ci_utils.tests.test_style.TestPep8)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/tmp.YUCsZ3kgPK/local/lib/python2.7/site-packages/ucitests-0.1.2-py2.7.egg/ucitests/styles.py", line 84, in test_pep8_conformance
    '\n'.join(self.report._msgs))
AssertionError: /tmp/engine/private-lp-mthood/ci-utils/ci_utils/launchpad.py:49:80: E501 line too long (81 > 79 characters)

Can you fix this pep8 error before we merge this please?

review: Needs Information
440. By Ursula Junque

Fixed pep8 error on launchpad.py

Revision history for this message
Ursula Junque (ursinha) wrote :

Thanks for reviewing, Andy.

> > === modified file 'branch-source-
> builder/cupstream2distro/launchpadmanager.py'
>
> > +sys.path.append(os.path.join(os.path.dirname(__file__), '../ci-utils'))
>
> I don't think we need sys.path.append stuff in our code anymore.

This branch is on top of mthood one, that is a tad far from lp:uci-engine/trunk. Are these things you mention available since when? I think this should be changed in case we're merging this with trunk, otherwise I'm not sure it's going to work? (same apply for other comments regarding things we have now and didn't have when this was created).

>
> > === modified file 'branch-source-builder/cupstream2distro/packagemanager.py'
>
> > - cmd = ["dput", ppa,
> > + cmd = ["dput", "-u", "-c", "/tmp/dput.cf", ppa,
> > "{}_{}_source.changes".format(source, version_for_source_file)]
>
> I'm being a little over-protective, but as per: "/tmp/dput.cf" - Seems
> like we should either make a constant for that, or (and I don't know the
> code structure/flow, have pass this value down to the function via
> upload_package.py

I'll leave this for Francis to comment, he implemented that part and knows the constraints better than I do.

>
> > === modified file 'branch-source-builder/cupstream2distro/settings.py'
>
> > +PRIVATE_LAUNCHPAD = _cfg.get('private_launchpad', None)
>
> This is beyond the scope of this MP, but a tip: We now have a
> unit_config module: ci_utils.unit_config that was written to handle this
> stuff for all our services.
>
> > === modified file 'branch-source-builder/watch_ppa.py'
>
> def get_launchpad_log(url):
> > '''Retrieves the build log from launchpad (thanks to celso).'''
> > if not url:
> > return None
> > - api_url = url.replace('/launchpad.net/','/api.launchpad.net/devel/')
> > - lp = launchpadmanager.get_launchpad()
> > + api_url = launchpad.get_lp_api_url(api_version="devel")
> > + lp = launchpad.lp_login()
> > return lp._browser.get(api_url)
>
> looks like the "url" parameter to this function is now ignored. Should
> we remove it and refactor the caller of it?
>
> > === added file 'create_private_lp_creds.py'
>
> > +sys.path.insert(0, os.path.join(os.path.dirname(__file__), './ci-utils'))
>
> again - don't think you need to alter sys.path anymore.
>
> > +web_root ="https://mthoodapi.lacinonac.com/"
>
> I don't understand the details well enough, but should this value come
> from our unit_config rather than being hard-coded? Actually it looks
> like deploy.py might be setting this in the unit_config?

This script is only a helper to create the credentials to the private lp instance, I think in trunk the original create_lp_creds.py doesn't even exist anymore. I agree this could be done using values on unit_config, but as this is something that should go away soon I didn't bother much.

Revision history for this message
Andy Doan (doanac) wrote :

On 05/07/2014 12:12 PM, Ursula Junque wrote:
> Thanks for reviewing, Andy.
>
>>> === modified file 'branch-source-
>> builder/cupstream2distro/launchpadmanager.py'
>>
>>> +sys.path.append(os.path.join(os.path.dirname(__file__), '../ci-utils'))
>>
>> I don't think we need sys.path.append stuff in our code anymore.
>
> This branch is on top of mthood one, that is a tad far from lp:uci-engine/trunk. Are these things you mention available since when? I think this should be changed in case we're merging this with trunk, otherwise I'm not sure it's going to work? (same apply for other comments regarding things we have now and didn't have when this was created).

yes. it was added here:

<http://bazaar.launchpad.net/~canonical-ci-engineering/uci-engine/mthood/revision/320>

>>> +web_root ="https://mthoodapi.lacinonac.com/"
>>
>> I don't understand the details well enough, but should this value come
>> from our unit_config rather than being hard-coded? Actually it looks
>> like deploy.py might be setting this in the unit_config?
>
> This script is only a helper to create the credentials to the private lp instance, I think in trunk the original create_lp_creds.py doesn't even exist anymore. I agree this could be done using values on unit_config, but as this is something that should go away soon I didn't bother much.

ah - okay. makes sense then.

Revision history for this message
Ursula Junque (ursinha) wrote :

Oops, I missed this.

>
> > === modified file 'branch-source-builder/watch_ppa.py'
>
> def get_launchpad_log(url):
> > '''Retrieves the build log from launchpad (thanks to celso).'''
> > if not url:
> > return None
> > - api_url = url.replace('/launchpad.net/','/api.launchpad.net/devel/')
> > - lp = launchpadmanager.get_launchpad()
> > + api_url = launchpad.get_lp_api_url(api_version="devel")
> > + lp = launchpad.lp_login()
> > return lp._browser.get(api_url)
>
> looks like the "url" parameter to this function is now ignored. Should
> we remove it and refactor the caller of it?

You are not only right, I think you found a bug. :) I'm fixing it right now.

>
> > === added file 'create_private_lp_creds.py'
>
> > +sys.path.insert(0, os.path.join(os.path.dirname(__file__), './ci-utils'))
>
> again - don't think you need to alter sys.path anymore.
>
> > +web_root ="https://mthoodapi.lacinonac.com/"
>
> I don't understand the details well enough, but should this value come
> from our unit_config rather than being hard-coded? Actually it looks
> like deploy.py might be setting this in the unit_config?

441. By Ursula Junque

Fixing bug spotted by andy during review (thanks andy), build log correct url is used now

442. By Ursula Junque

Removing sys.path changes as per andy's review, it's not required anymore

Revision history for this message
Ursula Junque (ursinha) wrote :

> I found the failure:
> ======================================================================
> FAIL: test_pep8_conformance (ci_utils.tests.test_style.TestPep8)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
> File "/tmp/tmp.YUCsZ3kgPK/local/lib/python2.7/site-
> packages/ucitests-0.1.2-py2.7.egg/ucitests/styles.py", line 84, in
> test_pep8_conformance
> '\n'.join(self.report._msgs))
> AssertionError: /tmp/engine/private-lp-mthood/ci-
> utils/ci_utils/launchpad.py:49:80: E501 line too long (81 > 79 characters)
>
> Can you fix this pep8 error before we merge this please?

Fixed in 440.

Revision history for this message
Ursula Junque (ursinha) wrote :

> On 05/07/2014 12:12 PM, Ursula Junque wrote:
> > Thanks for reviewing, Andy.
> >
> >>> === modified file 'branch-source-
> >> builder/cupstream2distro/launchpadmanager.py'
> >>
> >>> +sys.path.append(os.path.join(os.path.dirname(__file__), '../ci-utils'))
> >>
> >> I don't think we need sys.path.append stuff in our code anymore.
> >
> > This branch is on top of mthood one, that is a tad far from lp:uci-
> engine/trunk. Are these things you mention available since when? I think this
> should be changed in case we're merging this with trunk, otherwise I'm not
> sure it's going to work? (same apply for other comments regarding things we
> have now and didn't have when this was created).
>
> yes. it was added here:
>
> <http://bazaar.launchpad.net/~canonical-ci-engineering/uci-
> engine/mthood/revision/320>

Fixed in 442.

Revision history for this message
Ursula Junque (ursinha) wrote :

> > > === modified file 'branch-source-builder/watch_ppa.py'
> >
> > def get_launchpad_log(url):
> > > '''Retrieves the build log from launchpad (thanks to celso).'''
> > > if not url:
> > > return None
> > > - api_url = url.replace('/launchpad.net/','/api.launchpad.net/devel/')
> > > - lp = launchpadmanager.get_launchpad()
> > > + api_url = launchpad.get_lp_api_url(api_version="devel")
> > > + lp = launchpad.lp_login()
> > > return lp._browser.get(api_url)
> >
> > looks like the "url" parameter to this function is now ignored. Should
> > we remove it and refactor the caller of it?
>
> You are not only right, I think you found a bug. :) I'm fixing it right now.

Fixed in 441.

Revision history for this message
Francis Ginther (fginther) wrote :

> > > === modified file 'branch-source-
> builder/cupstream2distro/packagemanager.py'
> >
> > > - cmd = ["dput", ppa,
> > > + cmd = ["dput", "-u", "-c", "/tmp/dput.cf", ppa,
> > > "{}_{}_source.changes".format(source,
> version_for_source_file)]
> >
> > I'm being a little over-protective, but as per: "/tmp/dput.cf" - Seems
> > like we should either make a constant for that, or (and I don't know the
> > code structure/flow, have pass this value down to the function via
> > upload_package.py
>
> I'll leave this for Francis to comment, he implemented that part and knows the
> constraints better than I do.

A constant is more appropriate and will make it easier if we need to relocate the file. And when thinking about the proper location, /srv/$service_name/etc/dput.cf is probably a better fit.

I'll work on a fix for this.

Revision history for this message
Andy Doan (doanac) wrote :

LGTM. i'll defer to fginther on the rest.

review: Approve
Revision history for this message
Francis Ginther (fginther) wrote :

I'd like to work on the dput.cf location and use of a constant change in a follow on MP. Approving this as all of the other comments have been addressed.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'branch-source-builder/bsbuilder/upload_package.py'
2--- branch-source-builder/bsbuilder/upload_package.py 2014-03-14 10:37:28 +0000
3+++ branch-source-builder/bsbuilder/upload_package.py 2014-05-07 18:17:44 +0000
4@@ -23,9 +23,11 @@
5 import shutil
6 import sys
7 import tempfile
8+import textwrap
9 import urllib2
10
11 from cupstream2distro import packagemanager
12+from ci_utils import unit_config
13
14
15 def parse_arguments():
16@@ -53,6 +55,22 @@
17 return directory
18
19
20+def _create_dput_config():
21+ dput_cf = '/tmp/dput.cf'
22+ if not os.path.exists(dput_cf):
23+ with open(dput_cf, 'w') as f:
24+ os.fchmod(f.fileno(), 0700)
25+ template = textwrap.dedent('''\
26+ [ppa]
27+ login = anonymous
28+ fqdn = {}
29+ method = ftp
30+ allow_unsigned_uploads = 0
31+ incoming = ~%(ppa)s/ubuntu
32+ ''')
33+ f.write(template.format(unit_config.get('launchpad_upload_url')))
34+
35+
36 def get_url_contents(url):
37 try:
38 req = urllib2.Request(url)
39@@ -121,6 +139,7 @@
40
41 def create_upload_list(subtickets):
42 '''Parses the subtickets into the upload list.'''
43+ _create_dput_config()
44 upload_list = get_source_files(subtickets)
45 parse_source_files(upload_list)
46 return upload_list
47
48=== modified file 'branch-source-builder/cupstream2distro/launchpadmanager.py'
49--- branch-source-builder/cupstream2distro/launchpadmanager.py 2014-02-19 16:34:46 +0000
50+++ branch-source-builder/cupstream2distro/launchpadmanager.py 2014-05-07 18:17:44 +0000
51@@ -23,35 +23,24 @@
52 import lazr
53 import logging
54 import os
55-launchpad = None
56-
57-from .settings import ARCHS_TO_EVENTUALLY_IGNORE, ARCHS_TO_UNCONDITIONALLY_IGNORE, VIRTUALIZED_PPA_ARCH, CRED_FILE_PATH, COMMON_LAUNCHPAD_CACHE_DIR
58+import sys
59+
60+from ci_utils import launchpad
61+
62+from .settings import (ARCHS_TO_EVENTUALLY_IGNORE,
63+ ARCHS_TO_UNCONDITIONALLY_IGNORE, VIRTUALIZED_PPA_ARCH,
64+ CRED_FILE_PATH, COMMON_LAUNCHPAD_CACHE_DIR,
65+ PRIVATE_LAUNCHPAD)
66+my_launchpad = None
67
68
69 def get_launchpad(use_staging=False, use_cred_file=os.path.expanduser(CRED_FILE_PATH)):
70 '''Get THE Launchpad'''
71- global launchpad
72- if not launchpad:
73- if use_staging:
74- server = 'staging'
75- else:
76- server = 'production'
77-
78- launchpadlib_dir = COMMON_LAUNCHPAD_CACHE_DIR
79- if not os.path.exists(launchpadlib_dir):
80- os.makdedirs(launchpadlib_dir)
81-
82- if use_cred_file:
83- launchpad = Launchpad.login_with('cupstream2distro', server, allow_access_levels=["WRITE_PRIVATE"],
84- version='devel', # devel because copyPackage is only available there
85- credentials_file=use_cred_file,
86- launchpadlib_dir=launchpadlib_dir)
87- else:
88- launchpad = Launchpad.login_with('cupstream2distro', server, allow_access_levels=["WRITE_PRIVATE"],
89- version='devel', # devel because copyPackage is only available there
90- launchpadlib_dir=launchpadlib_dir)
91-
92- return launchpad
93+ global my_launchpad
94+ if not my_launchpad:
95+ my_launchpad = launchpad.lp_login()
96+
97+ return my_launchpad
98
99
100 def get_ubuntu():
101@@ -110,14 +99,17 @@
102 def get_available_and_all_archs(series, ppa=None):
103 '''Return a set of available archs, and the all arch'''
104 available_arch = set()
105- if ppa and ppa.require_virtualized:
106+ if PRIVATE_LAUNCHPAD:
107+ # Hack to workaround having only archindep arch enabled for PPAs in
108+ # the private lp instance.
109+ archindep = series.nominatedarchindep.architecture_tag
110+ available_arch = set([archindep])
111+ arch_all_arch = archindep
112+ elif ppa and ppa.require_virtualized:
113 available_arch = set(VIRTUALIZED_PPA_ARCH)
114 arch_all_arch = VIRTUALIZED_PPA_ARCH[0]
115 else:
116 for arch in series.architectures:
117- # HACK: filters armel as it's still seen as available on raring: https://launchpad.net/bugs/1077257
118- if arch.architecture_tag == "armel":
119- continue
120 available_arch.add(arch.architecture_tag)
121 if arch.is_nominated_arch_indep:
122 arch_all_arch = arch.architecture_tag
123
124=== modified file 'branch-source-builder/cupstream2distro/packagemanager.py'
125--- branch-source-builder/cupstream2distro/packagemanager.py 2014-02-19 16:34:46 +0000
126+++ branch-source-builder/cupstream2distro/packagemanager.py 2014-05-07 18:17:44 +0000
127@@ -471,7 +471,7 @@
128 here = os.getcwd()
129 os.chdir(source_directory)
130 version_for_source_file = version.split(':')[-1]
131- cmd = ["dput", ppa,
132+ cmd = ["dput", "-u", "-c", "/tmp/dput.cf", ppa,
133 "{}_{}_source.changes".format(source, version_for_source_file)]
134 if subprocess.call(cmd) != 0:
135 if here:
136
137=== modified file 'branch-source-builder/cupstream2distro/settings.py'
138--- branch-source-builder/cupstream2distro/settings.py 2014-03-14 10:37:28 +0000
139+++ branch-source-builder/cupstream2distro/settings.py 2014-05-07 18:17:44 +0000
140@@ -50,14 +50,9 @@
141 print('Unable to use unit_config(%s), defaulting values' % path)
142 return config
143 _cfg = _unit_config()
144-LAUNCHPAD_PPA_OWNER = _cfg.get('launchpad_ppa_owner', None)
145-LAUNCHPAD_USER = _cfg.get('launchpad_user', None)
146-LAUNCHPAD_API_BASE = _cfg.get(
147- 'launchpad_api_base', 'https://api.launchpad.net/1.0')
148 OAUTH_CONSUMER_KEY = _cfg.get('oauth_consumer_key', None)
149 OAUTH_TOKEN = _cfg.get('oauth_token', None)
150 OAUTH_TOKEN_SECRET = _cfg.get('oauth_token_secret', None)
151-OAUTH_REALM = _cfg.get('oauth_realm', 'https://api.launchpad.net/')
152
153 if not os.path.exists(CRED_FILE_PATH):
154 with open(CRED_FILE_PATH, 'w') as f:
155@@ -73,6 +68,7 @@
156 BOT_KEY = "B879A3E9"
157
158 # selected arch for building arch:all packages
159+PRIVATE_LAUNCHPAD = _cfg.get('private_launchpad', None)
160 VIRTUALIZED_PPA_ARCH = ["i386", "amd64"]
161 # an arch we will ignore for publication if latest published version in dest doesn't build it
162 ARCHS_TO_EVENTUALLY_IGNORE = set(['powerpc', 'arm64', 'ppc64el'])
163
164=== modified file 'branch-source-builder/watch_ppa.py'
165--- branch-source-builder/watch_ppa.py 2014-03-14 10:37:28 +0000
166+++ branch-source-builder/watch_ppa.py 2014-05-07 18:17:44 +0000
167@@ -33,8 +33,7 @@
168 from cupstream2distro.settings import (
169 TIME_BETWEEN_PPA_CHECKS, TIME_BEFORE_STOP_LOOKING_FOR_SOURCE_PUBLISH)
170
171-sys.path.append(os.path.join(os.path.dirname(__file__), '../ci-utils'))
172-from ci_utils import dump_stack
173+from ci_utils import dump_stack, launchpad
174 from ci_utils.ticket_states import (
175 SubTicketWorkflowStep,
176 SubTicketWorkflowStepStatus
177@@ -99,9 +98,10 @@
178 '''Retrieves the build log from launchpad (thanks to celso).'''
179 if not url:
180 return None
181- api_url = url.replace('/launchpad.net/', '/api.launchpad.net/devel/')
182- lp = launchpadmanager.get_launchpad()
183- return lp._browser.get(api_url)
184+ api_url = launchpad.get_lp_api_url(api_version="devel")
185+ url = "{}/{}".format(api_url, "/".join(build.build_log_url.split("/")[3:]))
186+ lp = launchpad.lp_login()
187+ return lp._browser.get(url)
188
189
190 def get_build_logs(datastore, ppa, package):
191
192=== modified file 'ci-utils/ci_utils/launchpad.py'
193--- ci-utils/ci_utils/launchpad.py 2014-03-14 03:43:36 +0000
194+++ ci-utils/ci_utils/launchpad.py 2014-05-07 18:17:44 +0000
195@@ -44,9 +44,37 @@
196 def lp_login():
197 lib = '/tmp/launchpadlib'
198 store = _get_credential_store()
199- return Launchpad.login_with('ci-engine', 'production',
200- credential_store=store, launchpadlib_dir=lib)
201+ return Launchpad.login_with('ci-engine', service_root=get_lp_root_url(),
202+ credential_store=store, launchpadlib_dir=lib,
203+ version=unit_config.get(
204+ 'launchpad_api_version'))
205
206
207 def get_lp_user_name():
208 return unit_config.get('launchpad_user')
209+
210+
211+def get_lp_ppa_owner():
212+ return unit_config.get('launchpad_ppa_owner')
213+
214+
215+def get_lp_root_url():
216+ return unit_config.get('launchpad_api_root_url')
217+
218+
219+def get_lp_api_url(api_version=None):
220+ if not api_version:
221+ api_version = unit_config.get('launchpad_api_version')
222+ return "{}/{}/".format(get_lp_root_url(), api_version)
223+
224+
225+def get_private_ppa_sources_list_url(lp, ppa):
226+ if lp:
227+ user = lp.people[get_lp_user_name()]
228+ return user.getArchiveSubscriptionURL(archive=ppa)
229+ return None
230+
231+
232+def get_ppa_sources_list_url(team, repo_name):
233+ api_url = get_lp_root_url().replace("https", "http").replace("api", "ppa")
234+ return "{}/{}/{}/ubuntu".format(api_url, team, repo_name)
235
236=== added file 'create_private_lp_creds.py'
237--- create_private_lp_creds.py 1970-01-01 00:00:00 +0000
238+++ create_private_lp_creds.py 2014-05-07 18:17:44 +0000
239@@ -0,0 +1,57 @@
240+#!/usr/bin/env python
241+
242+import os
243+import subprocess
244+import sys
245+
246+import launchpadlib.uris
247+from launchpadlib.launchpad import Launchpad
248+from lazr.restfulclient import errors
249+sys.path.insert(0, os.path.join(os.path.dirname(__file__), './ci-utils'))
250+from ci_utils import dump_stack
251+
252+web_root = "https://mthoodapi.lacinonac.com/"
253+
254+old = launchpadlib.uris.web_root_for_service_root
255+
256+
257+def web_root_for_service_root(service_root):
258+ if service_root == 'https://mthoodapi.lacinonac.com/':
259+ return 'https://mthood.lacinonac.com/'
260+ return old(service_root)
261+
262+launchpadlib.uris.web_root_for_service_root = web_root_for_service_root
263+
264+creds_path = os.path.abspath('lp_creds.txt')
265+
266+
267+def create():
268+ try:
269+ lp = Launchpad.login_with('ci-airline', consumer_name='ci-airline',
270+ service_root=web_root, version='devel')
271+ except errors.HTTPError as e:
272+ if e.response['status'] == '403':
273+ sys.stderr.write('Ok, not creating credentials then\n')
274+ exit(1)
275+ raise
276+
277+ creds = lp.credentials
278+ creds.save_to_path(creds_path)
279+ sys.stderr.write('Credentials created in {}\n'.format(creds_path))
280+
281+ print('export CI_OAUTH_CONSUMER_KEY="{}"'.format(creds.consumer.key))
282+ print('export CI_OAUTH_TOKEN={}'.format(creds.access_token.key))
283+ print('export CI_OAUTH_TOKEN_SECRET={}'.format(creds.access_token.secret))
284+ print('export CI_LAUNCHPAD_USER={}'.format(lp.me.name))
285+ # This should be a team that owns the ppa build pool
286+ print('export CI_LAUNCHPAD_PPA_OWNER={}'.format(lp.me.name))
287+ return 0
288+
289+
290+def main(args):
291+ create()
292+
293+
294+if __name__ == '__main__':
295+ dump_stack.install_stack_dump_signal()
296+ sys.exit(main(sys.argv[1:]))
297
298=== modified file 'image-builder/imagebuilder/cloud_image.py'
299--- image-builder/imagebuilder/cloud_image.py 2014-03-17 16:08:17 +0000
300+++ image-builder/imagebuilder/cloud_image.py 2014-05-07 18:17:44 +0000
301@@ -65,11 +65,9 @@
302 ppa = lp.people[team].getPPAByName(name=repo)
303 keys[ppa.name] = ppa.signing_key_fingerprint
304 if ppa.private:
305- #lp.me won't work, you have to get yourself by person
306- user = lp.people[launchpad.get_lp_user_name()]
307- url = user.getArchiveSubscriptionURL(archive=ppa)
308+ url = launchpad.get_private_ppa_sources_list_url(lp, ppa)
309 else:
310- url = 'http://ppa.launchpad.net/{}/{}/ubuntu'.format(team, repo)
311+ url = launchpad.get_ppa_sources_list_url(team, repo)
312 aptlines.append('deb {} {} main'.format(url, series))
313 aptlines.append('deb-src {} {} main'.format(url, series))
314 return aptlines, keys
315
316=== modified file 'image-builder/imagebuilder/tests/test_modify_cloud_image.py'
317--- image-builder/imagebuilder/tests/test_modify_cloud_image.py 2014-03-15 16:46:11 +0000
318+++ image-builder/imagebuilder/tests/test_modify_cloud_image.py 2014-05-07 18:17:44 +0000
319@@ -28,6 +28,7 @@
320 @mock.patch('imagebuilder.cloud_image.launchpad')
321 def test_parse_ppas(self, launchpad):
322 launchpad.get_lp_user_name.return_value = 'foo'
323+ launchpad.get_private_ppa_sources_list_url.return_value = 'foo_url'
324
325 lp = mock.MagicMock()
326 ppa = mock.Mock()
327@@ -35,7 +36,6 @@
328 ppa.signing_key_fingerprint = 'foofp'
329 ppa.private = True
330 lp.people['foo'].getPPAByName.return_value = ppa
331- lp.people['foo'].getArchiveSubscriptionURL.return_value = 'foo_url'
332
333 series = 'precise'
334 deblines, keys = cloud_image._parse_ppas(lp, ['ppa:/foo/bar'], series)
335
336=== modified file 'juju-deployer/configs/unit_config.yaml.tmpl'
337--- juju-deployer/configs/unit_config.yaml.tmpl 2014-03-15 23:15:38 +0000
338+++ juju-deployer/configs/unit_config.yaml.tmpl 2014-05-07 18:17:44 +0000
339@@ -8,13 +8,17 @@
340 # for launchpad apis
341 # and see: https://help.launchpad.net/API/SigningRequests
342 # and see ../../create_lp_creds.py
343-launchpad_api_base: https://api.launchpad.net/1.0
344+launchpad_api_root_url: $CI_LAUNCHPAD_API_ROOT_URL
345+launchpad_api_version: $CI_LAUNCHPAD_API_VERSION
346 launchpad_user: $CI_LAUNCHPAD_USER
347 launchpad_ppa_owner: $CI_LAUNCHPAD_PPA_OWNER
348-oauth_consumer_key: $CI_OAUTH_CONSUMER_KEY
349+launchpad_upload_url: $CI_LAUNCHPAD_UPLOAD_URL
350+oauth_consumer_key: "$CI_OAUTH_CONSUMER_KEY"
351 oauth_token: $CI_OAUTH_TOKEN
352 oauth_token_secret: $CI_OAUTH_TOKEN_SECRET
353
354+private_launchpad: $CI_PRIVATE_LAUNCHPAD
355+
356 ppa_pattern: "ci-pool-\\d+"
357
358 private_ppas_only: $CI_PRIVATE_PPAS_ONLY
359
360=== modified file 'juju-deployer/deploy.py'
361--- juju-deployer/deploy.py 2014-03-14 23:53:04 +0000
362+++ juju-deployer/deploy.py 2014-05-07 18:17:44 +0000
363@@ -65,7 +65,11 @@
364 'CI_PAYLOAD_URL': 'n/a',
365 'CI_LAUNCHPAD_USER': None,
366 'CI_LAUNCHPAD_PPA_OWNER': None,
367+ 'CI_LAUNCHPAD_API_ROOT_URL': 'https://api.launchpad.net/',
368+ 'CI_LAUNCHPAD_API_VERSION': 'devel',
369+ 'CI_LAUNCHPAD_UPLOAD_URL': 'ppa.launchpad.net',
370 'CI_PRIVATE_PPAS_ONLY': '0',
371+ 'CI_PRIVATE_LAUNCHPAD': 'False',
372 'CI_OAUTH_CONSUMER_KEY': None,
373 'CI_OAUTH_TOKEN': None,
374 'CI_OAUTH_TOKEN_SECRET': None,
375@@ -345,7 +349,9 @@
376 when building packages.''')
377 parser.add_argument('specific', metavar='<config.yaml>', nargs='*',
378 help='Use a specific list of juju-deployer configs.')
379-
380+ parser.add_argument('--private-launchpad', action='store_true',
381+ help='''Sets the environment to use proper Launchpad
382+ instance.''', default=False)
383 return parser.parse_args(args)
384
385
386@@ -361,6 +367,16 @@
387 # variable value.
388 check_and_set_ppa_privacy(args.private_ppas_only)
389
390+ if args.private_launchpad:
391+ os.environ['CI_LAUNCHPAD_API_ROOT_URL'] = (
392+ 'https://mthoodapi.lacinonac.com/')
393+ os.environ['CI_LAUNCHPAD_UPLOAD_URL'] = (
394+ 'mthood.lacinonac.com')
395+ os.environ['CI_PRIVATE_LAUNCHPAD'] = 'True'
396+ print('Private Launchpad instance: ENABLED')
397+ else:
398+ print('Private Launchpad instance: DISABLED')
399+
400 check_bootstrapped()
401 check_dependencies()
402
403
404=== modified file 'ppa-assigner/ppa_assigner/launchpad.py'
405--- ppa-assigner/ppa_assigner/launchpad.py 2014-03-14 10:37:28 +0000
406+++ ppa-assigner/ppa_assigner/launchpad.py 2014-05-07 18:17:44 +0000
407@@ -22,65 +22,6 @@
408 from oauth import oauth
409
410
411-def lp_collection(url):
412- '''iterate through each item returned in an lp_collection'''
413- resp = _lp_get_authenticated(url)
414- resp = resp.read()
415- data = json.loads(resp)
416-
417- for d in data['entries']:
418- yield d
419-
420- if 'next_collection_link' in data:
421- for d in lp_collection(data['next_collection_link']):
422- yield d
423-
424-
425-def _oauth_headers():
426- '''oauth header required for a launchpad api post
427-
428- https://help.launchpad.net/API/SigningRequests
429- '''
430- values = [
431- 'OAuth realm="%s"' % settings.OAUTH_REALM,
432- 'oauth_version="1.0"',
433- 'oauth_consumer_key="%s"' % settings.OAUTH_CONSUMER_KEY,
434- 'oauth_token="%s"' % settings.OAUTH_TOKEN,
435- 'oauth_signature_method="PLAINTEXT"',
436- 'oauth_signature="%%26%s"' % settings.OAUTH_TOKEN_SECRET,
437- 'oauth_timestamp="%d"' % int(oauth.time.time()),
438- 'oauth_nonce="%s"' % oauth.generate_nonce(),
439- ]
440- return {
441- 'Authorization': ', '.join(values),
442- 'Accept': 'application/json',
443- }
444-
445-
446-def _lp_post(url, data):
447- headers = _oauth_headers()
448- headers['Content-Type'] = 'application/x-www-form-urlencoded'
449- req = urllib2.Request(url, urllib.urlencode(data), headers)
450- return urllib2.urlopen(req)
451-
452-
453-def _lp_get_authenticated(url):
454- '''An authenticated GET to obtain also private information.'''
455- req = urllib2.Request(url, headers=_oauth_headers())
456- return urllib2.urlopen(req)
457-
458-
459-def get_publishing_history(ppa):
460- '''A generator for the source and binary publish history of a ppa.'''
461- url = settings.LAUNCHPAD_API_BASE + '/~%s/+archive/%s/?ws.op='
462- url = url % (settings.LAUNCHPAD_PPA_OWNER, ppa.split('/')[-1])
463-
464- for x in lp_collection(url + 'getPublishedSources'):
465- yield x
466- for x in lp_collection(url + 'getPublishedBinaries'):
467- yield x
468-
469-
470 def request_ppa_clean(ppa):
471 '''call requestDeletion operation on ppa's source and binary pub history'''
472 for x in get_publishing_history(ppa):
473@@ -116,8 +57,9 @@
474
475 def _sync_source(ppa, source_name, version, pocket, archive):
476 '''Used for populating a PPA so we can run integration tests.'''
477- url = 'https://api.launchpad.net/1.0/~%s/+archive/%s'
478- url = url % (settings.LAUNCHPAD_PPA_OWNER, ppa.split('/')[-1])
479+ url = '{}/~{}/+archive/{}'.format(settings.LAUNCHPAD_API_URL,
480+ settings.LAUNCHPAD_PPA_OWNER,
481+ ppa.split('/')[-1])
482 data = {
483 'ws.op': 'syncSource',
484 'from_archive': archive,
485@@ -129,3 +71,62 @@
486 c = resp.getcode()
487 if c != 200:
488 raise urllib2.HTTPError(url, c, resp.read(), resp.header.headers, None)
489+
490+
491+def get_publishing_history(ppa):
492+ '''A generator for the source and binary publish history of a ppa.'''
493+ url = '{}/~{}/+archive/{}/?ws.op='.format(settings.LAUNCHPAD_API_URL,
494+ settings.LAUNCHPAD_PPA_OWNER,
495+ ppa.split('/')[-1])
496+ for x in _lp_collection(url + 'getPublishedSources'):
497+ yield x
498+ for x in _lp_collection(url + 'getPublishedBinaries'):
499+ yield x
500+
501+
502+def _lp_collection(url):
503+ '''iterate through each item returned in an lp_collection'''
504+ resp = _lp_get_authenticated(url)
505+ resp = resp.read()
506+ data = json.loads(resp)
507+
508+ for d in data['entries']:
509+ yield d
510+
511+ if 'next_collection_link' in data:
512+ for d in _lp_collection(data['next_collection_link']):
513+ yield d
514+
515+
516+def _oauth_headers():
517+ '''oauth header required for a launchpad api post
518+
519+ https://help.launchpad.net/API/SigningRequests
520+ '''
521+ values = [
522+ 'OAuth realm="%s"' % settings.OAUTH_REALM,
523+ 'oauth_version="1.0"',
524+ 'oauth_consumer_key="%s"' % settings.OAUTH_CONSUMER_KEY,
525+ 'oauth_token="%s"' % settings.OAUTH_TOKEN,
526+ 'oauth_signature_method="PLAINTEXT"',
527+ 'oauth_signature="%%26%s"' % settings.OAUTH_TOKEN_SECRET,
528+ 'oauth_timestamp="%d"' % int(oauth.time.time()),
529+ 'oauth_nonce="%s"' % oauth.generate_nonce(),
530+ ]
531+ return {
532+ 'Authorization': ', '.join(values),
533+ 'Accept': 'application/json',
534+ }
535+
536+
537+def _lp_post(url, data):
538+ headers = _oauth_headers()
539+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
540+ req = urllib2.Request(url, urllib.urlencode(data), headers)
541+ return urllib2.urlopen(req)
542+
543+
544+def _lp_get_authenticated(url):
545+ '''An authenticated GET to obtain also private information.'''
546+ req = urllib2.Request(url, headers=_oauth_headers())
547+ return urllib2.urlopen(req)
548
549=== modified file 'ppa-assigner/ppa_assigner/models.py'
550--- ppa-assigner/ppa_assigner/models.py 2014-03-14 23:53:04 +0000
551+++ ppa-assigner/ppa_assigner/models.py 2014-05-07 18:17:44 +0000
552@@ -83,13 +83,13 @@
553 @staticmethod
554 def populate_from_launchpad():
555 '''Get list of PPAs from launchpad and ensure they exist here.'''
556- url = settings.LAUNCHPAD_API_BASE + '/~%s/ppas'
557- url = url % settings.LAUNCHPAD_PPA_OWNER
558+ url = '{}/~{}/ppas'.format(settings.LAUNCHPAD_API_URL,
559+ settings.LAUNCHPAD_PPA_OWNER)
560 logging.info('populating ppa model from: %s', url)
561 try:
562 ppas = {}
563 pat = re.compile(settings.PPA_PATTERN)
564- for ppa in launchpad.lp_collection(url):
565+ for ppa in launchpad._lp_collection(url):
566 if pat.match(ppa['name']):
567 ppa_name = 'ppa:{}/{}'.format(settings.LAUNCHPAD_PPA_OWNER,
568 ppa['name'])
569
570=== modified file 'ppa-assigner/ppa_assigner/settings.py'
571--- ppa-assigner/ppa_assigner/settings.py 2014-03-14 23:53:04 +0000
572+++ ppa-assigner/ppa_assigner/settings.py 2014-05-07 18:17:44 +0000
573@@ -44,12 +44,12 @@
574
575 LAUNCHPAD_USER = _cfg.get('launchpad_user', None)
576 LAUNCHPAD_PPA_OWNER = _cfg.get('launchpad_ppa_owner', None)
577-LAUNCHPAD_API_BASE = _cfg.get(
578- 'launchpad_api_base', 'https://api.launchpad.net/1.0')
579+LAUNCHPAD_API_URL = "{}/{}".format(_cfg.get('launchpad_api_root_url', None),
580+ _cfg.get('launchpad_api_version'))
581 OAUTH_CONSUMER_KEY = _cfg.get('oauth_consumer_key', None)
582 OAUTH_TOKEN = _cfg.get('oauth_token', None)
583 OAUTH_TOKEN_SECRET = _cfg.get('oauth_token_secret', None)
584-OAUTH_REALM = _cfg.get('oauth_realm', 'https://api.launchpad.net/')
585+OAUTH_REALM = _cfg.get('launchpad_api_root_url')
586 PPA_PATTERN = _cfg.get('ppa_pattern', r'ci-pool-\d+')
587 PRIVATE_PPAS_ONLY = _cfg.get('private_ppas_only', None)
588

Subscribers

People subscribed via source and target branches