github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/environs/tools/storage.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package tools
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"github.com/juju/juju/environs/storage"
    13  	"github.com/juju/juju/juju/arch"
    14  	coretools "github.com/juju/juju/tools"
    15  	"github.com/juju/juju/version"
    16  )
    17  
    18  var ErrNoTools = errors.New("no tools available")
    19  
    20  const (
    21  	toolPrefix = "tools/%s/juju-"
    22  	toolSuffix = ".tgz"
    23  )
    24  
    25  // StorageName returns the name that is used to store and retrieve the
    26  // given version of the juju tools.
    27  func StorageName(vers version.Binary, stream string) string {
    28  	return storagePrefix(stream) + vers.String() + toolSuffix
    29  }
    30  
    31  func storagePrefix(stream string) string {
    32  	return fmt.Sprintf(toolPrefix, stream)
    33  }
    34  
    35  // ReadList returns a List of the tools in store with the given major.minor version.
    36  // If minorVersion = -1, then only majorVersion is considered.
    37  // If store contains no such tools, it returns ErrNoMatches.
    38  func ReadList(stor storage.StorageReader, toolsDir string, majorVersion, minorVersion int) (coretools.List, error) {
    39  	if minorVersion >= 0 {
    40  		logger.Debugf("reading v%d.%d tools", majorVersion, minorVersion)
    41  	} else {
    42  		logger.Debugf("reading v%d.* tools", majorVersion)
    43  	}
    44  	storagePrefix := storagePrefix(toolsDir)
    45  	names, err := storage.List(stor, storagePrefix)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	var list coretools.List
    50  	var foundAnyTools bool
    51  	for _, name := range names {
    52  		name = filepath.ToSlash(name)
    53  		if !strings.HasPrefix(name, storagePrefix) || !strings.HasSuffix(name, toolSuffix) {
    54  			continue
    55  		}
    56  		var t coretools.Tools
    57  		vers := name[len(storagePrefix) : len(name)-len(toolSuffix)]
    58  		if t.Version, err = version.ParseBinary(vers); err != nil {
    59  			logger.Debugf("failed to parse version %q: %v", vers, err)
    60  			continue
    61  		}
    62  		foundAnyTools = true
    63  		// Major version must match specified value.
    64  		if t.Version.Major != majorVersion {
    65  			continue
    66  		}
    67  		// If specified minor version value supplied, minor version must match.
    68  		if minorVersion >= 0 && t.Version.Minor != minorVersion {
    69  			continue
    70  		}
    71  		logger.Debugf("found %s", vers)
    72  		if t.URL, err = stor.URL(name); err != nil {
    73  			return nil, err
    74  		}
    75  		list = append(list, &t)
    76  		// Older versions of Juju only know about ppc64, so add metadata for that arch.
    77  		if t.Version.Arch == arch.PPC64EL {
    78  			legacyPPC64Tools := t
    79  			legacyPPC64Tools.Version.Arch = arch.LEGACY_PPC64
    80  			list = append(list, &legacyPPC64Tools)
    81  		}
    82  	}
    83  	if len(list) == 0 {
    84  		if foundAnyTools {
    85  			return nil, coretools.ErrNoMatches
    86  		}
    87  		return nil, ErrNoTools
    88  	}
    89  	return list, nil
    90  }