launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/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 "launchpad.net/juju-core/environs/simplestreams" 11 "launchpad.net/juju-core/utils/set" 12 ) 13 14 const ( 15 ProductMetadataPath = "streams/v1/com.ubuntu.cloud:released:imagemetadata.json" 16 ImageContentId = "com.ubuntu.cloud:custom" 17 ) 18 19 // MarshalImageMetadataJSON marshals image metadata to index and products JSON. 20 // 21 // updated is the time at which the JSON file was updated. 22 func MarshalImageMetadataJSON(metadata []*ImageMetadata, cloudSpec []simplestreams.CloudSpec, 23 updated time.Time) (index, products []byte, err error) { 24 25 if index, err = MarshalImageMetadataIndexJSON(metadata, cloudSpec, updated); err != nil { 26 return nil, nil, err 27 } 28 if products, err = MarshalImageMetadataProductsJSON(metadata, updated); err != nil { 29 return nil, nil, err 30 } 31 return index, products, err 32 } 33 34 // MarshalImageMetadataIndexJSON marshals image metadata to index JSON. 35 // 36 // updated is the time at which the JSON file was updated. 37 func MarshalImageMetadataIndexJSON(metadata []*ImageMetadata, cloudSpec []simplestreams.CloudSpec, 38 updated time.Time) (out []byte, err error) { 39 40 productIds := make([]string, len(metadata)) 41 for i, t := range metadata { 42 productIds[i] = t.productId() 43 } 44 var indices simplestreams.Indices 45 indices.Updated = updated.Format(time.RFC1123Z) 46 indices.Format = "index:1.0" 47 indices.Indexes = map[string]*simplestreams.IndexMetadata{ 48 ImageContentId: &simplestreams.IndexMetadata{ 49 CloudName: "custom", 50 Updated: indices.Updated, 51 Format: "products:1.0", 52 DataType: "image-ids", 53 ProductsFilePath: ProductMetadataPath, 54 ProductIds: set.NewStrings(productIds...).SortedValues(), 55 Clouds: cloudSpec, 56 }, 57 } 58 return json.MarshalIndent(&indices, "", " ") 59 } 60 61 // MarshalImageMetadataProductsJSON marshals image metadata to products JSON. 62 // 63 // updated is the time at which the JSON file was updated. 64 func MarshalImageMetadataProductsJSON(metadata []*ImageMetadata, updated time.Time) (out []byte, err error) { 65 var cloud simplestreams.CloudMetadata 66 cloud.Updated = updated.Format(time.RFC1123Z) 67 cloud.Format = "products:1.0" 68 cloud.ContentId = ImageContentId 69 cloud.Products = make(map[string]simplestreams.MetadataCatalog) 70 itemsversion := updated.Format("20060201") // YYYYMMDD 71 for _, t := range metadata { 72 toWrite := &ImageMetadata{ 73 Id: t.Id, 74 RegionName: t.RegionName, 75 Endpoint: t.Endpoint, 76 } 77 if catalog, ok := cloud.Products[t.productId()]; ok { 78 catalog.Items[itemsversion].Items[t.Id] = toWrite 79 } else { 80 catalog = simplestreams.MetadataCatalog{ 81 Arch: t.Arch, 82 Version: t.Version, 83 Items: map[string]*simplestreams.ItemCollection{ 84 itemsversion: &simplestreams.ItemCollection{ 85 Items: map[string]interface{}{t.Id: toWrite}, 86 }, 87 }, 88 } 89 cloud.Products[t.productId()] = catalog 90 } 91 } 92 return json.MarshalIndent(&cloud, "", " ") 93 }