Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(52)

Unified Diff: provider/ec2/httpstorage/httpstorage.go

Issue 13725043: Upload tools uses simplestreams (Closed)
Patch Set: Upload tools uses simplestreams Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: provider/ec2/httpstorage/httpstorage.go
=== added file 'provider/ec2/httpstorage/httpstorage.go'
--- provider/ec2/httpstorage/httpstorage.go 1970-01-01 00:00:00 +0000
+++ provider/ec2/httpstorage/httpstorage.go 2013-09-16 04:44:39 +0000
@@ -0,0 +1,108 @@
+// Copyright 2013 Canonical Ltd.
+// Licensed under the AGPLv3, see LICENCE file for details.
+
+package httpstorage
+
+import (
+ "encoding/xml"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "sort"
+ "strings"
+ "time"
+
+ "launchpad.net/juju-core/environs"
+ "launchpad.net/juju-core/errors"
+ "launchpad.net/juju-core/utils"
+)
+
+var storageAttempt = utils.AttemptStrategy{
+ Total: 5 * time.Second,
+ Delay: 200 * time.Millisecond,
+}
+
+// httpStorageReader implements the environs.StorageReader interface
+// to access an EC2 storage via HTTP.
+
+type httpStorageReader struct {
+ url string
+}
+
+// NewHTTPStorageReader creates a storage reader for the HTTP
+// access to an EC2 storage like the juju-dist storage.
+func NewHTTPStorageReader(url string) environs.StorageReader {
+ return &httpStorageReader{url}
+}
+
+// Get implements environs.StorageReader.Get.
+func (h *httpStorageReader) Get(name string) (io.ReadCloser, error) {
+ nameURL, err := h.URL(name)
+ if err != nil {
+ return nil, err
+ }
+ resp, err := http.Get(nameURL)
+ if err != nil || resp.StatusCode == http.StatusNotFound {
+ return nil, errors.NewNotFoundError(err, "")
+ }
+ return resp.Body, nil
+}
+
+// List implements environs.StorageReader.List.
+func (h *httpStorageReader) List(prefix string) ([]string, error) {
+ lbr, err := h.getListResult()
+ if err != nil {
+ return nil, err
+ }
+ var names []string
+ for _, c := range lbr.Contents {
+ if strings.HasPrefix(c.Key, prefix) {
+ names = append(names, c.Key)
+ }
+ }
+ sort.Strings(names)
+ return names, nil
+}
+
+// URL implements environs.StorageReader.URL.
+func (h *httpStorageReader) URL(name string) (string, error) {
+ if strings.HasSuffix(h.url, "/") {
+ return h.url + name, nil
+ }
+ return h.url + "/" + name, nil
+}
+
+// ConsistencyStrategy is specified in the StorageReader interface.
+func (s *httpStorageReader) ConsistencyStrategy() utils.AttemptStrategy {
+ return storageAttempt
+}
+
+// getListResult retrieves the index of the storage,
+func (h *httpStorageReader) getListResult() (*listResult, error) {
+ resp, err := http.Get(h.url)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+ var lbr listResult
+ err = xml.Unmarshal(buf, &lbr)
+ if err != nil {
+ return nil, err
+ }
+ return &lbr, nil
+}
+
+// listResult is the top level XML element of the storage index.
+// We only need the contents.
+type listResult struct {
+ Contents []*contents
+}
+
+// contents describes one entry of the storage index.
+type contents struct {
+ Key string
+}

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b