~ubuntu-branches/ubuntu/precise/euca2ools/precise-proposed

« back to all changes in this revision

Viewing changes to .pc/debian-changes-2.0.0~bzr464-0ubuntu1/euca2ools/commands/euca/uploadbundle.py

  • Committer: Bazaar Package Importer
  • Author(s): Scott Moser
  • Date: 2011-08-15 11:16:29 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20110815111629-3u49jvtwabwozpb7
Tags: 2.0.0~bzr464-0ubuntu1
* new upstream snapshot of bzr revno 464. (LP: #826022)
* Note, previous upload was incorrectly named 'bzr451'.  It should have
  been named bzr461 as it was a snapshot of revision 461.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Software License Agreement (BSD License)
 
2
#
 
3
# Copyright (c) 2009-2011, Eucalyptus Systems, Inc.
 
4
# All rights reserved.
 
5
#
 
6
# Redistribution and use of this software in source and binary forms, with or
 
7
# without modification, are permitted provided that the following conditions
 
8
# are met:
 
9
#
 
10
#   Redistributions of source code must retain the above
 
11
#   copyright notice, this list of conditions and the
 
12
#   following disclaimer.
 
13
#
 
14
#   Redistributions in binary form must reproduce the above
 
15
#   copyright notice, this list of conditions and the
 
16
#   following disclaimer in the documentation and/or other
 
17
#   materials provided with the distribution.
 
18
#
 
19
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
20
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
21
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
22
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
23
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
24
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
25
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
26
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
27
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
28
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
29
# POSSIBILITY OF SUCH DAMAGE.
 
30
#
 
31
# Author: Neil Soman neil@eucalyptus.com
 
32
#         Mitch Garnaat mgarnaat@eucalyptus.com
 
33
 
 
34
import euca2ools.commands.eucacommand
 
35
from boto.roboto.param import Param
 
36
import sys
 
37
import os
 
38
from xml.dom import minidom
 
39
from boto.exception import S3ResponseError, S3CreateError
 
40
from boto.s3.key import Key
 
41
from boto.s3.connection import Location
 
42
 
 
43
class UploadBundle(euca2ools.commands.eucacommand.EucaCommand):
 
44
 
 
45
    Description = 'Upload a previously bundled image to the cloud.'
 
46
    Options = [Param(name='bucket', short_name='b', long_name='bucket',
 
47
                     optional=False, ptype='string',
 
48
                     doc='Name of the bucket to upload to.'),
 
49
               Param(name='manifest_path',
 
50
                     short_name='m', long_name='manifest',
 
51
                     optional=False, ptype='file',
 
52
                     doc='Path to the manifest file for bundled image.'),
 
53
               Param(name='canned_acl',  long_name='acl',
 
54
                     optional=True, ptype='string', default='aws-exec-read',
 
55
                     doc='Canned access policy'),
 
56
               Param(name='ec2cert_path', long_name='ec2cert',
 
57
                     optional=True, ptype='file',
 
58
                     doc="Path to the Cloud's X509 public key certificate."),
 
59
               Param(name='bundle_path',
 
60
                     short_name='d', long_name='directory',
 
61
                     optional=True, ptype='string',
 
62
                     doc="""The directory containing the bundled
 
63
                     image to upload (defaults to the manifest directory)."""),
 
64
               Param(name='part', long_name='part',
 
65
                     optional=True, ptype='integer',
 
66
                     doc='Uploads specified part and all subsequent parts.'),
 
67
               Param(name='skip_manifest', long_name='skipmanifest',
 
68
                     optional=True, ptype='boolean', default=False,
 
69
                     doc='Do not  upload the manifest.'),
 
70
               Param(name='location', long_name='location',
 
71
                     optional=True, ptype='string', default=Location.DEFAULT,
 
72
                     doc="""The location of the destination S3 bucket
 
73
                            Valid values: US|EU|us-west-1|ap-southeast-1|ap-northeast-1""")]
 
74
 
 
75
    def ensure_bucket(self, acl, location=Location.DEFAULT):
 
76
        bucket_instance = None
 
77
        s3conn = self.make_connection_cli('s3')
 
78
        try:
 
79
            print 'Checking bucket:', self.bucket
 
80
            bucket_instance = s3conn.get_bucket(self.bucket)
 
81
            if location:
 
82
                if location != bucket_instance.get_location():
 
83
                    msg = 'Supplied location does not match bucket location'
 
84
                    self.display_error_and_exit(msg)
 
85
        except S3ResponseError, s3error:
 
86
            s3error_string = '%s' % s3error
 
87
            if s3error_string.find('404') >= 0:
 
88
                try:
 
89
                    print 'Creating bucket:', self.bucket
 
90
                    bucket_instance = s3conn.create_bucket(self.bucket,
 
91
                                                           policy=acl,
 
92
                                                           location=location)
 
93
                except S3CreateError:
 
94
                    msg = 'Unable to create bucket %s' % self.bucket
 
95
                    self.display_error_and_exit(msg)
 
96
            elif s3error_string.find('403') >= 0:
 
97
                msg = 'You do not have permission to access bucket:', self.bucket
 
98
                self.display_error_and_exit(msg)
 
99
            else:
 
100
                self.display_error_and_exit(s3error_string)
 
101
        return bucket_instance
 
102
 
 
103
    def get_parts(self, manifest_filename):
 
104
        parts = []
 
105
        dom = minidom.parse(manifest_filename)
 
106
        manifest_elem = dom.getElementsByTagName('manifest')[0]
 
107
        parts_list = manifest_elem.getElementsByTagName('filename')
 
108
        for part_elem in parts_list:
 
109
            nodes = part_elem.childNodes
 
110
            for node in nodes:
 
111
                if node.nodeType == node.TEXT_NODE:
 
112
                    parts.append(node.data)
 
113
        return parts
 
114
 
 
115
    def upload_manifest(self, bucket_instance, manifest_filename,
 
116
                        canned_acl=None, upload_policy=None,
 
117
                        upload_policy_signature=None):
 
118
        print 'Uploading manifest file'
 
119
        k = Key(bucket_instance)
 
120
        k.key = self.get_relative_filename(manifest_filename)
 
121
        manifest_file = open(manifest_filename, 'rb')
 
122
        headers = {}
 
123
        if upload_policy:
 
124
            headers['S3UploadPolicy'] = upload_policy
 
125
        if upload_policy_signature:
 
126
            headers['S3UploadPolicySignature']=upload_policy_signature
 
127
 
 
128
        try:
 
129
            k.set_contents_from_file(manifest_file, policy=canned_acl,
 
130
                                     headers=headers)
 
131
        except S3ResponseError, s3error:
 
132
            s3error_string = '%s' % s3error
 
133
            if s3error_string.find('403') >= 0:
 
134
                msg = 'Permission denied while writing:', k.key
 
135
            else:
 
136
                msg = s3error_string
 
137
            self.display_error_and_exit(msg)
 
138
 
 
139
    def upload_parts(self, bucket_instance, directory, parts,
 
140
                     part_to_start_from, canned_acl=None,
 
141
                     upload_policy=None, upload_policy_signature=None):
 
142
        if part_to_start_from:
 
143
            okay_to_upload = False
 
144
        else:
 
145
            okay_to_upload = True
 
146
 
 
147
        headers = {}
 
148
        if upload_policy:
 
149
            headers['S3UploadPolicy'] = upload_policy
 
150
        if upload_policy_signature:
 
151
            headers['S3UploadPolicySignature']=upload_policy_signature
 
152
 
 
153
        for part in parts:
 
154
            if part == part_to_start_from:
 
155
                okay_to_upload = True
 
156
            if okay_to_upload:
 
157
                print 'Uploading part:', part
 
158
                k = Key(bucket_instance)
 
159
                k.key = part
 
160
                part_file = open(os.path.join(directory, part), 'rb')
 
161
                try:
 
162
                    k.set_contents_from_file(part_file, policy=canned_acl,
 
163
                                             headers=headers)
 
164
                except S3ResponseError, s3error:
 
165
                    s3error_string = '%s' % s3error
 
166
                    if s3error_string.find('403') >= 0:
 
167
                        msg = 'Permission denied while writing:', k.key
 
168
                    else:
 
169
                        msg = s3error_string
 
170
                    self.display_error_and_exit(msg)
 
171
 
 
172
    def main(self):
 
173
        bucket_instance = self.ensure_bucket(self.canned_acl, self.location)
 
174
        parts = self.get_parts(self.manifest_path)
 
175
        manifest_directory, manifest_file = os.path.split(self.manifest_path)
 
176
        if not self.bundle_path:
 
177
            self.bundle_path = manifest_directory
 
178
        if not self.skip_manifest and not self.part:
 
179
            self.upload_manifest(bucket_instance, self.manifest_path,
 
180
                                 self.canned_acl)
 
181
        self.upload_parts(bucket_instance, self.bundle_path,
 
182
                          parts, self.part, self.canned_acl)
 
183
        print 'Uploaded image as %s/%s' % (self.bucket,
 
184
                self.get_relative_filename(self.manifest_path))
 
185
 
 
186
    def main_cli(self):
 
187
        self.main()
 
188
 
 
189