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 }