github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/environs/imagemetadata/marshal.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package imagemetadata 5 6 import ( 7 "encoding/json" 8 "time" 9 10 "github.com/juju/utils/set" 11 12 "github.com/juju/juju/environs/simplestreams" 13 ) 14 15 const ( 16 ProductMetadataPath = "streams/v1/com.ubuntu.cloud-released-imagemetadata.json" 17 ImageContentId = "com.ubuntu.cloud:custom" 18 ) 19 20 // MarshalImageMetadataJSON marshals image metadata to index and products JSON. 21 // 22 // updated is the time at which the JSON file was updated. 23 func MarshalImageMetadataJSON(metadata []*ImageMetadata, cloudSpec []simplestreams.CloudSpec, 24 updated time.Time) (index, products []byte, err error) { 25 26 if index, err = MarshalImageMetadataIndexJSON(metadata, cloudSpec, updated); err != nil { 27 return nil, nil, err 28 } 29 if products, err = MarshalImageMetadataProductsJSON(metadata, updated); err != nil { 30 return nil, nil, err 31 } 32 return index, products, err 33 } 34 35 // MarshalImageMetadataIndexJSON marshals image metadata to index JSON. 36 // 37 // updated is the time at which the JSON file was updated. 38 func MarshalImageMetadataIndexJSON(metadata []*ImageMetadata, cloudSpec []simplestreams.CloudSpec, 39 updated time.Time) (out []byte, err error) { 40 41 productIds := make([]string, len(metadata)) 42 for i, t := range metadata { 43 productIds[i] = t.productId() 44 } 45 var indices simplestreams.Indices 46 indices.Updated = updated.Format(time.RFC1123Z) 47 indices.Format = simplestreams.IndexFormat 48 indices.Indexes = map[string]*simplestreams.IndexMetadata{ 49 ImageContentId: { 50 CloudName: "custom", 51 Updated: indices.Updated, 52 Format: simplestreams.ProductFormat, 53 DataType: "image-ids", 54 ProductsFilePath: ProductMetadataPath, 55 ProductIds: set.NewStrings(productIds...).SortedValues(), 56 Clouds: cloudSpec, 57 }, 58 } 59 return json.MarshalIndent(&indices, "", " ") 60 } 61 62 // MarshalImageMetadataProductsJSON marshals image metadata to products JSON. 63 // 64 // updated is the time at which the JSON file was updated. 65 func MarshalImageMetadataProductsJSON(metadata []*ImageMetadata, updated time.Time) (out []byte, err error) { 66 var cloud simplestreams.CloudMetadata 67 cloud.Updated = updated.Format(time.RFC1123Z) 68 cloud.Format = simplestreams.ProductFormat 69 cloud.ContentId = ImageContentId 70 cloud.Products = make(map[string]simplestreams.MetadataCatalog) 71 itemsversion := updated.Format("20060102") // YYYYMMDD 72 for _, t := range metadata { 73 toWrite := *t 74 // These fields are not required in the individual 75 // record values - they are recorded at the top level. 76 toWrite.RegionAlias = "" 77 toWrite.Version = "" 78 toWrite.Arch = "" 79 if catalog, ok := cloud.Products[t.productId()]; ok { 80 catalog.Items[itemsversion].Items[t.Id] = toWrite 81 } else { 82 catalog = simplestreams.MetadataCatalog{ 83 Arch: t.Arch, 84 Version: t.Version, 85 Items: map[string]*simplestreams.ItemCollection{ 86 itemsversion: { 87 Items: map[string]interface{}{t.Id: toWrite}, 88 }, 89 }, 90 } 91 cloud.Products[t.productId()] = catalog 92 } 93 } 94 return json.MarshalIndent(&cloud, "", " ") 95 }