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 }