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