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 }