~ubuntu-branches/ubuntu/saucy/juju-core/saucy-proposed

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/environs/ec2/storage.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-07-11 17:18:27 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130711171827-vjqkg40r0dlf7ys2
Tags: 1.11.2-0ubuntu1
* New upstream release.
* Make juju-core the default juju (LP: #1190634):
  - d/control: Add virtual package juju -> juju-core.
  - d/juju-core.postinst.in: Bump priority of alternatives over that of
    python juju packages.
* Enable for all architectures (LP: #1172505):
  - d/control: Version BD on golang-go to >= 2:1.1.1 to ensure CGO
    support for non-x86 archs, make juju-core Arch: any.
  - d/README.source: Dropped - no longer required.
* d/watch: Updated for new upstream tarball naming.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2012, 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
1
4
package ec2
2
5
 
3
6
import (
 
7
        "encoding/xml"
4
8
        "fmt"
5
9
        "io"
 
10
        "io/ioutil"
 
11
        "net/http"
 
12
        "sort"
 
13
        "strings"
 
14
        "sync"
 
15
        "time"
 
16
 
6
17
        "launchpad.net/goamz/s3"
7
18
        "launchpad.net/juju-core/environs"
8
 
        "sync"
9
 
        "time"
 
19
        "launchpad.net/juju-core/errors"
10
20
)
11
21
 
12
22
func NewStorage(bucket *s3.Bucket) environs.Storage {
156
166
 
157
167
func maybeNotFound(err error) error {
158
168
        if err != nil && s3ErrorStatusCode(err) == 404 {
159
 
                return &environs.NotFoundError{err}
 
169
                return &errors.NotFoundError{err, ""}
160
170
        }
161
171
        return err
162
172
}
 
173
 
 
174
// listBucketResult is the top level XML element of the storage index.
 
175
// We only need the contents.
 
176
type listBucketResult struct {
 
177
        Contents []*contents
 
178
}
 
179
 
 
180
// contents describes one entry of the storage index.
 
181
type contents struct {
 
182
        Key string
 
183
}
 
184
 
 
185
// httpStorageReader implements the environs.StorageReader interface
 
186
// to access an EC2 storage via HTTP.
 
187
type httpStorageReader struct {
 
188
        url string
 
189
}
 
190
 
 
191
// NewHTTPStorageReader creates a storage reader for the HTTP
 
192
// access to an EC2 storage like the juju-dist storage.
 
193
func NewHTTPStorageReader(url string) environs.StorageReader {
 
194
        return &httpStorageReader{url}
 
195
}
 
196
 
 
197
// Get implements environs.StorageReader.Get.
 
198
func (h *httpStorageReader) Get(name string) (io.ReadCloser, error) {
 
199
        nameURL, err := h.URL(name)
 
200
        if err != nil {
 
201
                return nil, err
 
202
        }
 
203
        resp, err := http.Get(nameURL)
 
204
        if err != nil && resp.StatusCode == http.StatusNotFound {
 
205
                return nil, &errors.NotFoundError{err, ""}
 
206
        }
 
207
        return resp.Body, nil
 
208
}
 
209
 
 
210
// List implements environs.StorageReader.List.
 
211
func (h *httpStorageReader) List(prefix string) ([]string, error) {
 
212
        lbr, err := h.getListBucketResult()
 
213
        if err != nil {
 
214
                return nil, err
 
215
        }
 
216
        var names []string
 
217
        for _, c := range lbr.Contents {
 
218
                if strings.HasPrefix(c.Key, prefix) {
 
219
                        names = append(names, c.Key)
 
220
                }
 
221
        }
 
222
        sort.Strings(names)
 
223
        return names, nil
 
224
}
 
225
 
 
226
// URL implements environs.StorageReader.URL.
 
227
func (h *httpStorageReader) URL(name string) (string, error) {
 
228
        if strings.HasSuffix(h.url, "/") {
 
229
                return h.url + name, nil
 
230
        }
 
231
        return h.url + "/" + name, nil
 
232
}
 
233
 
 
234
// getListBucketResult retrieves the index of the storage,
 
235
func (h *httpStorageReader) getListBucketResult() (*listBucketResult, error) {
 
236
        resp, err := http.Get(h.url)
 
237
        if err != nil {
 
238
                return nil, err
 
239
        }
 
240
        defer resp.Body.Close()
 
241
        buf, err := ioutil.ReadAll(resp.Body)
 
242
        if err != nil {
 
243
                return nil, err
 
244
        }
 
245
        var lbr listBucketResult
 
246
        err = xml.Unmarshal(buf, &lbr)
 
247
        if err != nil {
 
248
                return nil, err
 
249
        }
 
250
        return &lbr, nil
 
251
}