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  }