Merge lp:~ursinha/uci-engine/private-lp-mthood into lp:uci-engine/mthood
- private-lp-mthood
- Merge into mthood
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 |
Related bugs: |
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.
Andy Doan (doanac) wrote : | # |
Francis Ginther (fginther) wrote : | # |
Approve, let's get this in!
Francis Ginther (fginther) wrote : | # |
Oops, I see failure in my tarmac.sh run. Let me dig into it first.
Francis Ginther (fginther) wrote : | # |
I found the failure:
=======
FAIL: test_pep8_
-------
Traceback (most recent call last):
File "/tmp/tmp.
'\n'
AssertionError: /tmp/engine/
Can you fix this pep8 error before we merge this please?
- 440. By Ursula Junque
-
Fixed pep8 error on launchpad.py
Ursula Junque (ursinha) wrote : | # |
Thanks for reviewing, Andy.
> > === modified file 'branch-source-
> builder/
>
> > +sys.path.
>
> 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-
>
> > - cmd = ["dput", ppa,
> > + cmd = ["dput", "-u", "-c", "/tmp/dput.cf", ppa,
> > "{}_{}_
>
> 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-
>
> > +PRIVATE_LAUNCHPAD = _cfg.get(
>
> This is beyond the scope of this MP, but a tip: We now have a
> unit_config module: ci_utils.
> stuff for all our services.
>
> > === modified file 'branch-
>
> def get_launchpad_
> > '''Retrieves the build log from launchpad (thanks to celso).'''
> > if not url:
> > return None
> > - api_url = url.replace(
> > - lp = launchpadmanage
> > + api_url = launchpad.
> > + lp = launchpad.
> > return lp._browser.
>
> looks like the "url" parameter to this function is now ignored. Should
> we remove it and refactor the caller of it?
>
> > === added file 'create_
>
> > +sys.path.insert(0, os.path.
>
> again - don't think you need to alter sys.path anymore.
>
> > +web_root ="https:/
>
> 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.
Andy Doan (doanac) wrote : | # |
On 05/07/2014 12:12 PM, Ursula Junque wrote:
> Thanks for reviewing, Andy.
>
>>> === modified file 'branch-source-
>> builder/
>>
>>> +sys.path.
>>
>> 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://
>>> +web_root ="https:/
>>
>> 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.
Ursula Junque (ursinha) wrote : | # |
Oops, I missed this.
>
> > === modified file 'branch-
>
> def get_launchpad_
> > '''Retrieves the build log from launchpad (thanks to celso).'''
> > if not url:
> > return None
> > - api_url = url.replace(
> > - lp = launchpadmanage
> > + api_url = launchpad.
> > + lp = launchpad.
> > return lp._browser.
>
> 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_
>
> > +sys.path.insert(0, os.path.
>
> again - don't think you need to alter sys.path anymore.
>
> > +web_root ="https:/
>
> 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
Ursula Junque (ursinha) wrote : | # |
> I found the failure:
> =======
> FAIL: test_pep8_
> -------
> Traceback (most recent call last):
> File "/tmp/tmp.
> packages/
> test_pep8_
> '\n'.join(
> AssertionError: /tmp/engine/
> utils/ci_
>
> Can you fix this pep8 error before we merge this please?
Fixed in 440.
Ursula Junque (ursinha) wrote : | # |
> On 05/07/2014 12:12 PM, Ursula Junque wrote:
> > Thanks for reviewing, Andy.
> >
> >>> === modified file 'branch-source-
> >> builder/
> >>
> >>> +sys.path.
> >>
> >> 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://
> engine/
Fixed in 442.
Ursula Junque (ursinha) wrote : | # |
> > > === modified file 'branch-
> >
> > def get_launchpad_
> > > '''Retrieves the build log from launchpad (thanks to celso).'''
> > > if not url:
> > > return None
> > > - api_url = url.replace(
> > > - lp = launchpadmanage
> > > + api_url = launchpad.
> > > + lp = launchpad.
> > > return lp._browser.
> >
> > 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.
Francis Ginther (fginther) wrote : | # |
> > > === modified file 'branch-source-
> builder/
> >
> > > - cmd = ["dput", ppa,
> > > + cmd = ["dput", "-u", "-c", "/tmp/dput.cf", ppa,
> > > "{}_{}_
> version_
> >
> > 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_
I'll work on a fix for this.
Andy Doan (doanac) wrote : | # |
LGTM. i'll defer to fginther on the rest.
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.
Preview Diff
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 |
> === modified file 'branch- source- builder/ cupstream2distr o/launchpadmana ger.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/ cupstream2distr o/packagemanage r.py'
> - cmd = ["dput", ppa, source. changes" .format( source, version_ for_source_ file)]
> + cmd = ["dput", "-u", "-c", "/tmp/dput.cf", ppa,
> "{}_{}_
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/ cupstream2distr o/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 that was written to handle this
unit_config module: ci_utils.
stuff for all our services.
> === modified file 'branch- source- builder/ watch_ppa. py'
def get_launchpad_ log(url) : '/launchpad. net/',' /api.launchpad. net/devel/ ') r.get_launchpad () get_lp_ api_url( api_version= "devel" ) lp_login( ) get(api_ url)
> '''Retrieves the build log from launchpad (thanks to celso).'''
> if not url:
> return None
> - api_url = url.replace(
> - lp = launchpadmanage
> + api_url = launchpad.
> + lp = launchpad.
> return lp._browser.
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?