github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/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  	"launchpad.net/juju-core/environs/simplestreams"
    15  	"launchpad.net/juju-core/utils/set"
    16  )
    17  
    18  const (
    19  	ProductMetadataPath = "streams/v1/com.ubuntu.juju:released:tools.json"
    20  	ToolsContentId      = "com.ubuntu.juju:released:tools"
    21  )
    22  
    23  // MarshalToolsMetadataJSON marshals tools metadata to index and products JSON.
    24  //
    25  // updated is the time at which the JSON file was updated.
    26  func MarshalToolsMetadataJSON(metadata []*ToolsMetadata, updated time.Time) (index, products []byte, err error) {
    27  	if index, err = MarshalToolsMetadataIndexJSON(metadata, updated); err != nil {
    28  		return nil, nil, err
    29  	}
    30  	if products, err = MarshalToolsMetadataProductsJSON(metadata, updated); err != nil {
    31  		return nil, nil, err
    32  	}
    33  	return index, products, err
    34  }
    35  
    36  // MarshalToolsMetadataIndexJSON marshals tools metadata to index JSON.
    37  //
    38  // updated is the time at which the JSON file was updated.
    39  func MarshalToolsMetadataIndexJSON(metadata []*ToolsMetadata, updated time.Time) (out []byte, err error) {
    40  	productIds := make([]string, len(metadata))
    41  	for i, t := range metadata {
    42  		productIds[i], err = t.productId()
    43  		if err != nil {
    44  			return nil, err
    45  		}
    46  	}
    47  	var indices simplestreams.Indices
    48  	indices.Updated = updated.Format(time.RFC1123Z)
    49  	indices.Format = "index:1.0"
    50  	indices.Indexes = map[string]*simplestreams.IndexMetadata{
    51  		ToolsContentId: &simplestreams.IndexMetadata{
    52  			Updated:          indices.Updated,
    53  			Format:           "products:1.0",
    54  			DataType:         "content-download",
    55  			ProductsFilePath: ProductMetadataPath,
    56  			ProductIds:       set.NewStrings(productIds...).SortedValues(),
    57  		},
    58  	}
    59  	return json.MarshalIndent(&indices, "", "    ")
    60  }
    61  
    62  // MarshalToolsMetadataProductsJSON marshals tools metadata to products JSON.
    63  //
    64  // updated is the time at which the JSON file was updated.
    65  func MarshalToolsMetadataProductsJSON(metadata []*ToolsMetadata, updated time.Time) (out []byte, err error) {
    66  	var cloud simplestreams.CloudMetadata
    67  	cloud.Updated = updated.Format(time.RFC1123Z)
    68  	cloud.Format = "products:1.0"
    69  	cloud.ContentId = ToolsContentId
    70  	cloud.Products = make(map[string]simplestreams.MetadataCatalog)
    71  	itemsversion := updated.Format("20060102") // YYYYMMDD
    72  	for _, t := range metadata {
    73  		id, err := t.productId()
    74  		if err != nil {
    75  			return nil, err
    76  		}
    77  		itemid := fmt.Sprintf("%s-%s-%s", t.Version, t.Release, t.Arch)
    78  		if catalog, ok := cloud.Products[id]; ok {
    79  			catalog.Items[itemsversion].Items[itemid] = t
    80  		} else {
    81  			catalog = simplestreams.MetadataCatalog{
    82  				Arch:    t.Arch,
    83  				Version: t.Version,
    84  				Items: map[string]*simplestreams.ItemCollection{
    85  					itemsversion: &simplestreams.ItemCollection{
    86  						Items: map[string]interface{}{itemid: t},
    87  					},
    88  				},
    89  			}
    90  			cloud.Products[id] = catalog
    91  		}
    92  	}
    93  	return json.MarshalIndent(&cloud, "", "    ")
    94  }