Merge lp:~cjohnston/ubuntu-ci-services-itself/push-img-swift into lp:ubuntu-ci-services-itself

Proposed by Chris Johnston
Status: Merged
Approved by: Chris Johnston
Approved revision: 389
Merged at revision: 399
Proposed branch: lp:~cjohnston/ubuntu-ci-services-itself/push-img-swift
Merge into: lp:ubuntu-ci-services-itself
Diff against target: 95 lines (+27/-13)
3 files modified
ci-utils/ci_utils/amqp_worker.py (+8/-5)
image-builder/imagebuilder/cloud_image.py (+12/-6)
image-builder/imagebuilder/run_worker.py (+7/-2)
To merge this branch: bzr merge lp:~cjohnston/ubuntu-ci-services-itself/push-img-swift
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Andy Doan (community) Approve
Chris Johnston (community) Needs Resubmitting
Francis Ginther Needs Fixing
Review via email: mp+211142@code.launchpad.net

Commit message

Push build images to swift storage for later retrieval

Description of the change

This is the first part of a multi-part MP to enable a user to download the built image files via the CLI.

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

is there a reason to not use the create_datatore implemention:

 http://bazaar.launchpad.net/~canonical-ci-engineering/ubuntu-ci-services-itself/trunk/view/head:/ci-utils/ci_utils/amqp_worker.py#L110

instead of creating one in cloud_image.py?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:386
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/430/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/430/rebuild

review: Approve (continuous-integration)
387. By Chris Johnston

Update per review

Revision history for this message
Chris Johnston (cjohnston) :
review: Needs Resubmitting
Revision history for this message
Francis Ginther (fginther) wrote :

76 + ds = _create_data_store(ticket_id)
77 + ds.change_visibility()
53 + with open(converted_image_path, 'r') as fp:
54 + location = ds.put_file(upload_filename, fp)

I believe public/private is a setting for the container. So doesn't this just set the container to private until the next component comes along and changes visibility back to public? Perhaps I missing something.

review: Needs Fixing
Revision history for this message
Chris Johnston (cjohnston) wrote :

On Fri, Mar 14, 2014 at 6:13 PM, Francis Ginther <
<email address hidden>> wrote:

> Review: Needs Fixing
>
> 76 + ds = _create_data_store(ticket_id)
> 77 + ds.change_visibility()
> 53 + with open(converted_image_path, 'r') as fp:
> 54 + location = ds.put_file(upload_filename, fp)
>
> I believe public/private is a setting for the container. So doesn't this
> just set the container to private until the next component comes along and
> changes visibility back to public? Perhaps I missing something.
>

 67+ ds_name = params['ticket_id'] + '-image' 68+ ds =
self._create_data_store(ds_name)
Here you will see that we are creating a separate data store called
ticket-<id>-image... So, nothing else should be setting this container to
public.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:387
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/433/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/433/rebuild

review: Approve (continuous-integration)
Revision history for this message
Evan (ev) wrote :

17 + def _create_artifact(self, name, url, retval, type='LOGS'):

This could use a docstring.

54 + location = ds.put_file(upload_filename, fp)

Shouldn't we catch and handle DataStoreException here?

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

On 03/14/2014 06:55 PM, Evan Dandrea wrote:
> 54 + location = ds.put_file(upload_filename, fp)
>
> Shouldn't we catch and handle DataStoreException here?

Good idea. If this fails, the ticket should be able to continue. eg, all
is not lost.

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

> On Fri, Mar 14, 2014 at 6:13 PM, Francis Ginther <
> <email address hidden>> wrote:
>
> > Review: Needs Fixing
> >
> > 76 + ds = _create_data_store(ticket_id)
> > 77 + ds.change_visibility()
> > 53 + with open(converted_image_path, 'r') as fp:
> > 54 + location = ds.put_file(upload_filename, fp)
> >
> > I believe public/private is a setting for the container. So doesn't this
> > just set the container to private until the next component comes along and
> > changes visibility back to public? Perhaps I missing something.
> >
>
> 67+ ds_name = params['ticket_id'] + '-image' 68+ ds =
> self._create_data_store(ds_name)
> Here you will see that we are creating a separate data store called
> ticket-<id>-image... So, nothing else should be setting this container to
> public.

I swear I was looking for something like this, just in the wrong place. Thanks for clearing up.

388. By Chris Johnston

Catch exception per review

Revision history for this message
Chris Johnston (cjohnston) :
review: Needs Resubmitting
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:388
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/435/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/435/rebuild

review: Approve (continuous-integration)
Revision history for this message
Andy Doan (doanac) :
review: Approve
389. By Chris Johnston

Merge trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:389
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/436/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/436/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ci-utils/ci_utils/amqp_worker.py'
2--- ci-utils/ci_utils/amqp_worker.py 2014-03-12 21:45:22 +0000
3+++ ci-utils/ci_utils/amqp_worker.py 2014-03-15 11:29:58 +0000
4@@ -128,14 +128,17 @@
5 try:
6 name = '{}.output.log'.format(logger.name)
7 url = store.put_file(name, content, 'text/plain')
8- retval.setdefault('artifacts', []).append({
9- 'name': name,
10- 'reference': url,
11- 'type': 'LOGS',
12- })
13+ self._create_artifact(name, url, retval)
14 except:
15 log.exception('unable to store worker log')
16
17+ def _create_artifact(self, name, url, retval, type='LOGS'):
18+ retval.setdefault('artifacts', []).append({
19+ 'name': name,
20+ 'reference': url,
21+ 'type': type,
22+ })
23+
24 def _handle_cancel(self, params):
25 '''provide an advisory mechansim to inform the worker to stop
26
27
28=== modified file 'image-builder/imagebuilder/cloud_image.py'
29--- image-builder/imagebuilder/cloud_image.py 2014-03-15 03:27:45 +0000
30+++ image-builder/imagebuilder/cloud_image.py 2014-03-15 11:29:58 +0000
31@@ -31,7 +31,7 @@
32
33 from imagebuilder import ImageException
34 from ci_utils.image_store import ImageStore
35-from ci_utils import dump_stack, launchpad
36+from ci_utils import dump_stack, data_store, launchpad
37
38
39 log = logging.getLogger('Imagebuilder')
40@@ -228,7 +228,7 @@
41 runcmd('qemu-nbd -d /dev/%s' % self.nbd_dev)
42
43
44-def modify_image(image, repos, series, packages, status_cb=None):
45+def modify_image(image, repos, series, packages, ds, status_cb=None):
46 '''Add packges and PPAs to a cloud image mounted in a chroot'''
47 if not status_cb:
48 status_cb = lambda x: 0 # just provide a no-op
49@@ -250,11 +250,17 @@
50 status_cb('Shrinking the converted image...')
51 runcmd('qemu-img convert -O qcow2 -c %s %s' % (
52 image_path, converted_image_path))
53- glance_filename = str(uuid.uuid1()) + '.img'
54+ upload_filename = str(uuid.uuid1()) + '.img'
55 status_cb(
56- 'Uploading converted image to glance as %s' % glance_filename)
57- glance.image_create(glance_filename, converted_image_path)
58- return glance_filename
59+ 'Uploading converted image to glance as %s' % upload_filename)
60+ glance.image_create(upload_filename, converted_image_path)
61+ try:
62+ ds.change_visibility()
63+ with open(converted_image_path, 'r') as fp:
64+ location = ds.put_file(upload_filename, fp)
65+ except data_store.DataStoreException:
66+ status_cb('ERROR: unable to upload image to swift')
67+ return upload_filename, location
68
69
70 def main():
71
72=== modified file 'image-builder/imagebuilder/run_worker.py'
73--- image-builder/imagebuilder/run_worker.py 2014-03-14 21:54:37 +0000
74+++ image-builder/imagebuilder/run_worker.py 2014-03-15 11:29:58 +0000
75@@ -29,13 +29,18 @@
76 series = params['series']
77 packages = params['package_list']
78 trigger = params['progress_trigger']
79+ ds_name = params['ticket_id'] + '-image'
80+ ds = self._create_data_store(ds_name)
81
82 def status_cb(msg):
83 log.info(msg)
84 amqp_utils.progress_update(trigger, {'message': msg})
85
86- image_id = modify_image(image, repos, series, packages, status_cb)
87- return amqp_utils.progress_completed, {'image_id': image_id}
88+ image_id, location = modify_image(image, repos, series, packages,
89+ ds, status_cb)
90+ retval = {'image_id': image_id}
91+ self._create_artifact(image_id, location, retval, type='IMAGE')
92+ return amqp_utils.progress_completed, retval
93
94
95 if __name__ == '__main__':

Subscribers

People subscribed via source and target branches