// marshalToolsMetadataIndexJSON marshals tools metadata to index JSON. // updated is the time at which the JSON file was updated. func marshalToolsMetadataIndexJSON(streamMetadata map[string][]*ToolsMetadata, updated time.Time) (out, outlegacy []byte, err error) { var indices simplestreams.Indices indices.Updated = updated.Format(time.RFC1123Z) indices.Format = simplestreams.IndexFormat indices.Indexes = make(map[string]*simplestreams.IndexMetadata, len(streamMetadata)) var indicesLegacy simplestreams.Indices indicesLegacy.Updated = updated.Format(time.RFC1123Z) indicesLegacy.Format = simplestreams.IndexFormat for stream, metadata := range streamMetadata { var productIds []string for _, t := range metadata { id, err := t.productId() if err != nil { if series.IsUnknownSeriesVersionError(err) { logger.Infof("ignoring tools metadata with unknown series %q", t.Release) continue } return nil, nil, err } productIds = append(productIds, id) } indexMetadata := &simplestreams.IndexMetadata{ Updated: indices.Updated, Format: simplestreams.ProductFormat, DataType: ContentDownload, ProductsFilePath: ProductMetadataPath(stream), ProductIds: set.NewStrings(productIds...).SortedValues(), } indices.Indexes[ToolsContentId(stream)] = indexMetadata if stream == ReleasedStream { indicesLegacy.Indexes = make(map[string]*simplestreams.IndexMetadata, 1) indicesLegacy.Indexes[ToolsContentId(stream)] = indexMetadata } } out, err = json.MarshalIndent(&indices, "", " ") if len(indicesLegacy.Indexes) == 0 { return out, nil, err } outlegacy, err = json.MarshalIndent(&indicesLegacy, "", " ") if err != nil { return nil, nil, err } return out, outlegacy, nil }
// ProductIds generates a string array representing product ids formed similarly to an ISCSI qualified name (IQN). func (tc *ToolsConstraint) ProductIds() ([]string, error) { var allIds []string for _, ser := range tc.Series { version, err := series.SeriesVersion(ser) if err != nil { if series.IsUnknownSeriesVersionError(err) { logger.Debugf("ignoring unknown series %q", ser) continue } return nil, err } ids := make([]string, len(tc.Arches)) for i, arch := range tc.Arches { ids[i] = fmt.Sprintf("com.ubuntu.juju:%s:%s", version, arch) } allIds = append(allIds, ids...) } return allIds, nil }
// MarshalToolsMetadataProductsJSON marshals tools metadata to products JSON. // updated is the time at which the JSON file was updated. func MarshalToolsMetadataProductsJSON( streamMetadata map[string][]*ToolsMetadata, updated time.Time, ) (out map[string][]byte, err error) { out = make(map[string][]byte, len(streamMetadata)) for stream, metadata := range streamMetadata { var cloud simplestreams.CloudMetadata cloud.Updated = updated.Format(time.RFC1123Z) cloud.Format = simplestreams.ProductFormat cloud.ContentId = ToolsContentId(stream) cloud.Products = make(map[string]simplestreams.MetadataCatalog) itemsversion := updated.Format("20060102") // YYYYMMDD for _, t := range metadata { id, err := t.productId() if err != nil { if series.IsUnknownSeriesVersionError(err) { continue } return nil, err } itemid := fmt.Sprintf("%s-%s-%s", t.Version, t.Release, t.Arch) if catalog, ok := cloud.Products[id]; ok { catalog.Items[itemsversion].Items[itemid] = t } else { catalog = simplestreams.MetadataCatalog{ Arch: t.Arch, Version: t.Version, Items: map[string]*simplestreams.ItemCollection{ itemsversion: { Items: map[string]interface{}{itemid: t}, }, }, } cloud.Products[id] = catalog } } if out[stream], err = json.MarshalIndent(&cloud, "", " "); err != nil { return nil, err } } return out, nil }