1
// Copyright 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
11
"github.com/juju/utils"
13
"github.com/juju/juju/environs/simplestreams"
16
// RemoveAll is a default implementation for StorageWriter.RemoveAll.
17
// Providers may have more efficient implementations, or better error handling,
18
// or safeguards against races with other users of the same storage medium.
19
// But a simple way to implement RemoveAll would be to delegate to here.
20
func RemoveAll(stor Storage) error {
21
files, err := List(stor, "")
23
return fmt.Errorf("unable to list files for deletion: %v", err)
26
// Some limited parallellism might be useful in this loop.
27
for _, file := range files {
28
err = stor.Remove(file)
36
// Get gets the named file from stor using the stor's default consistency strategy.
37
func Get(stor StorageReader, name string) (io.ReadCloser, error) {
38
return GetWithRetry(stor, name, stor.DefaultConsistencyStrategy())
41
// GetWithRetry gets the named file from stor using the specified attempt strategy.
43
// TODO(katco): 2016-08-09: lp:1611427
44
func GetWithRetry(stor StorageReader, name string, attempt utils.AttemptStrategy) (r io.ReadCloser, err error) {
45
for a := attempt.Start(); a.Next(); {
46
r, err = stor.Get(name)
47
if err == nil || !stor.ShouldRetry(err) {
54
// List lists the files matching prefix from stor using the stor's default consistency strategy.
55
func List(stor StorageReader, prefix string) ([]string, error) {
56
return ListWithRetry(stor, prefix, stor.DefaultConsistencyStrategy())
59
// ListWithRetry lists the files matching prefix from stor using the specified attempt strategy.
61
// TODO(katco): 2016-08-09: lp:1611427
62
func ListWithRetry(stor StorageReader, prefix string, attempt utils.AttemptStrategy) (list []string, err error) {
63
for a := attempt.Start(); a.Next(); {
64
list, err = stor.List(prefix)
65
if err == nil || !stor.ShouldRetry(err) {
72
// BaseToolsPath is the container where tools tarballs and metadata are found.
73
var BaseToolsPath = "tools"
75
// BaseImagesPath is the container where images metadata is found.
76
var BaseImagesPath = "images"
78
// A storageSimpleStreamsDataSource retrieves data from a StorageReader.
79
type storageSimpleStreamsDataSource struct {
88
// TestingGetAllowRetry is used in tests which need to see if allowRetry has been
89
// set on a storageSimpleStreamsDataSource.
90
func TestingGetAllowRetry(s simplestreams.DataSource) (bool, ok bool) {
91
if storageDataSource, ok := s.(*storageSimpleStreamsDataSource); ok {
92
return storageDataSource.allowRetry, ok
97
// NewStorageSimpleStreamsDataSource returns a new datasource reading from the specified storage.
98
func NewStorageSimpleStreamsDataSource(description string, storage StorageReader, basePath string, priority int, requireSigned bool) simplestreams.DataSource {
99
return &storageSimpleStreamsDataSource{description, basePath, storage, false, priority, requireSigned}
102
func (s *storageSimpleStreamsDataSource) relpath(storagePath string) string {
103
relpath := storagePath
104
if s.basePath != "" {
105
relpath = path.Join(s.basePath, relpath)
110
// Description is defined in simplestreams.DataSource.
111
func (s *storageSimpleStreamsDataSource) Description() string {
115
// Fetch is defined in simplestreams.DataSource.
116
func (s *storageSimpleStreamsDataSource) Fetch(path string) (io.ReadCloser, string, error) {
117
relpath := s.relpath(path)
119
fullURL, err := s.storage.URL(relpath)
123
// TODO(katco): 2016-08-09: lp:1611427
124
var attempt utils.AttemptStrategy
126
attempt = s.storage.DefaultConsistencyStrategy()
128
rc, err := GetWithRetry(s.storage, relpath, attempt)
130
return nil, dataURL, err
132
return rc, dataURL, nil
135
// URL is defined in simplestreams.DataSource.
136
func (s *storageSimpleStreamsDataSource) URL(path string) (string, error) {
137
return s.storage.URL(s.relpath(path))
140
// PublicSigningKey is defined in simplestreams.DataSource.
141
func (u *storageSimpleStreamsDataSource) PublicSigningKey() string {
145
// SetAllowRetry is defined in simplestreams.DataSource.
146
func (s *storageSimpleStreamsDataSource) SetAllowRetry(allow bool) {
150
// Priority is defined in simplestreams.DataSource.
151
func (s *storageSimpleStreamsDataSource) Priority() int {
155
// RequireSigned is defined in simplestreams.DataSource.
156
func (s *storageSimpleStreamsDataSource) RequireSigned() bool {
157
return s.requireSigned