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