github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/cmd/plugins/juju-metadata/toolsmetadata.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "fmt" 8 9 "github.com/juju/loggo" 10 "launchpad.net/gnuflag" 11 12 "launchpad.net/juju-core/cmd" 13 "launchpad.net/juju-core/environs/filestorage" 14 "launchpad.net/juju-core/environs/simplestreams" 15 "launchpad.net/juju-core/environs/storage" 16 envtools "launchpad.net/juju-core/environs/tools" 17 "launchpad.net/juju-core/juju/osenv" 18 coretools "launchpad.net/juju-core/tools" 19 "launchpad.net/juju-core/version" 20 ) 21 22 // ToolsMetadataCommand is used to generate simplestreams metadata for juju tools. 23 type ToolsMetadataCommand struct { 24 cmd.EnvCommandBase 25 fetch bool 26 metadataDir string 27 public bool 28 } 29 30 func (c *ToolsMetadataCommand) Info() *cmd.Info { 31 return &cmd.Info{ 32 Name: "generate-tools", 33 Purpose: "generate simplestreams tools metadata", 34 } 35 } 36 37 func (c *ToolsMetadataCommand) SetFlags(f *gnuflag.FlagSet) { 38 c.EnvCommandBase.SetFlags(f) 39 f.StringVar(&c.metadataDir, "d", "", "local directory in which to store metadata") 40 f.BoolVar(&c.public, "public", false, "tools are for a public cloud, so generate mirrors information") 41 } 42 43 func (c *ToolsMetadataCommand) Run(context *cmd.Context) error { 44 loggo.RegisterWriter("toolsmetadata", cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO) 45 defer loggo.RemoveWriter("toolsmetadata") 46 if c.metadataDir == "" { 47 c.metadataDir = osenv.JujuHome() 48 } else { 49 c.metadataDir = context.AbsPath(c.metadataDir) 50 } 51 52 sourceStorage, err := filestorage.NewFileStorageReader(c.metadataDir) 53 if err != nil { 54 return err 55 } 56 fmt.Fprintf(context.Stdout, "Finding tools in %s\n", c.metadataDir) 57 const minorVersion = -1 58 toolsList, err := envtools.ReadList(sourceStorage, version.Current.Major, minorVersion) 59 if err == envtools.ErrNoTools { 60 var source string 61 source, err = envtools.ToolsURL(envtools.DefaultBaseURL) 62 if err != nil { 63 return err 64 } 65 sourceDataSource := simplestreams.NewURLDataSource("local source", source, simplestreams.VerifySSLHostnames) 66 toolsList, err = envtools.FindToolsForCloud( 67 []simplestreams.DataSource{sourceDataSource}, simplestreams.CloudSpec{}, 68 version.Current.Major, minorVersion, coretools.Filter{}) 69 } 70 if err != nil { 71 return err 72 } 73 74 targetStorage, err := filestorage.NewFileStorageWriter(c.metadataDir) 75 if err != nil { 76 return err 77 } 78 writeMirrors := envtools.DoNotWriteMirrors 79 if c.public { 80 writeMirrors = envtools.WriteMirrors 81 } 82 return mergeAndWriteMetadata(targetStorage, toolsList, writeMirrors) 83 } 84 85 // This is essentially the same as tools.MergeAndWriteMetadata, but also 86 // resolves metadata for existing tools by fetching them and computing 87 // size/sha256 locally. 88 func mergeAndWriteMetadata(stor storage.Storage, toolsList coretools.List, writeMirrors envtools.ShouldWriteMirrors) error { 89 existing, err := envtools.ReadMetadata(stor) 90 if err != nil { 91 return err 92 } 93 metadata := envtools.MetadataFromTools(toolsList) 94 if metadata, err = envtools.MergeMetadata(metadata, existing); err != nil { 95 return err 96 } 97 if err = envtools.ResolveMetadata(stor, metadata); err != nil { 98 return err 99 } 100 return envtools.WriteMetadata(stor, metadata, writeMirrors) 101 }