github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/environs/tools/marshal.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // The tools package supports locating, parsing, and filtering Ubuntu tools metadata in simplestreams format.
     5  // See http://launchpad.net/simplestreams and in particular the doc/README file in that project for more information
     6  // about the file formats.
     7  package tools
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  	"time"
    13  
    14  	"github.com/juju/utils/set"
    15  
    16  	"github.com/juju/juju/environs/simplestreams"
    17  )
    18  
    19  const (
    20  	ProductMetadataPath = "streams/v1/com.ubuntu.juju:released:tools.json"
    21  	ToolsContentId      = "com.ubuntu.juju:released:tools"
    22  )
    23  
    24  // MarshalToolsMetadataJSON marshals tools metadata to index and products JSON.
    25  //
    26  // updated is the time at which the JSON file was updated.
    27  func MarshalToolsMetadataJSON(metadata []*ToolsMetadata, updated time.Time) (index, products []byte, err error) {
    28  	if index, err = MarshalToolsMetadataIndexJSON(metadata, updated); err != nil {
    29  		return nil, nil, err
    30  	}
    31  	if products, err = MarshalToolsMetadataProductsJSON(metadata, updated); err != nil {
    32  		return nil, nil, err
    33  	}
    34  	return index, products, err
    35  }
    36  
    37  // MarshalToolsMetadataIndexJSON marshals tools metadata to index JSON.
    38  //
    39  // updated is the time at which the JSON file was updated.
    40  func MarshalToolsMetadataIndexJSON(metadata []*ToolsMetadata, updated time.Time) (out []byte, err error) {
    41  	productIds := make([]string, len(metadata))
    42  	for i, t := range metadata {
    43  		productIds[i], err = t.productId()
    44  		if err != nil {
    45  			return nil, err
    46  		}
    47  	}
    48  	var indices simplestreams.Indices
    49  	indices.Updated = updated.Format(time.RFC1123Z)
    50  	indices.Format = "index:1.0"
    51  	indices.Indexes = map[string]*simplestreams.IndexMetadata{
    52  		ToolsContentId: &simplestreams.IndexMetadata{
    53  			Updated:          indices.Updated,
    54  			Format:           "products:1.0",
    55  			DataType:         "content-download",
    56  			ProductsFilePath: ProductMetadataPath,
    57  			ProductIds:       set.NewStrings(productIds...).SortedValues(),
    58  		},
    59  	}
    60  	return json.MarshalIndent(&indices, "", "    ")
    61  }
    62  
    63  // MarshalToolsMetadataProductsJSON marshals tools metadata to products JSON.
    64  //
    65  // updated is the time at which the JSON file was updated.
    66  func MarshalToolsMetadataProductsJSON(metadata []*ToolsMetadata, updated time.Time) (out []byte, err error) {
    67  	var cloud simplestreams.CloudMetadata
    68  	cloud.Updated = updated.Format(time.RFC1123Z)
    69  	cloud.Format = "products:1.0"
    70  	cloud.ContentId = ToolsContentId
    71  	cloud.Products = make(map[string]simplestreams.MetadataCatalog)
    72  	itemsversion := updated.Format("20060102") // YYYYMMDD
    73  	for _, t := range metadata {
    74  		id, err := t.productId()
    75  		if err != nil {
    76  			return nil, err
    77  		}
    78  		itemid := fmt.Sprintf("%s-%s-%s", t.Version, t.Release, t.Arch)
    79  		if catalog, ok := cloud.Products[id]; ok {
    80  			catalog.Items[itemsversion].Items[itemid] = t
    81  		} else {
    82  			catalog = simplestreams.MetadataCatalog{
    83  				Arch:    t.Arch,
    84  				Version: t.Version,
    85  				Items: map[string]*simplestreams.ItemCollection{
    86  					itemsversion: &simplestreams.ItemCollection{
    87  						Items: map[string]interface{}{itemid: t},
    88  					},
    89  				},
    90  			}
    91  			cloud.Products[id] = catalog
    92  		}
    93  	}
    94  	return json.MarshalIndent(&cloud, "", "    ")
    95  }