// APIResult2ServiceResources converts a ResourcesResult into a resource.ServiceResources. func APIResult2ServiceResources(apiResult ResourcesResult) (resource.ServiceResources, error) { var result resource.ServiceResources if apiResult.Error != nil { // TODO(ericsnow) Return the resources too? err := common.RestoreError(apiResult.Error) return resource.ServiceResources{}, errors.Trace(err) } for _, apiRes := range apiResult.Resources { res, err := API2Resource(apiRes) if err != nil { // This could happen if the server is misbehaving // or non-conforming. // TODO(ericsnow) Aggregate errors? return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } result.Resources = append(result.Resources, res) } for _, unitRes := range apiResult.UnitResources { tag, err := names.ParseUnitTag(unitRes.Tag) if err != nil { return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } resNames := map[string]bool{} unitResources := resource.UnitResources{Tag: tag} for _, apiRes := range unitRes.Resources { res, err := API2Resource(apiRes) if err != nil { return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } resNames[res.Name] = true unitResources.Resources = append(unitResources.Resources, res) } if len(unitRes.DownloadProgress) > 0 { unitResources.DownloadProgress = make(map[string]int64) for resName, progress := range unitRes.DownloadProgress { if _, ok := resNames[resName]; !ok { err := errors.Errorf("got progress from unrecognized resource %q", resName) return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } unitResources.DownloadProgress[resName] = progress } } result.UnitResources = append(result.UnitResources, unitResources) } for _, chRes := range apiResult.CharmStoreResources { res, err := API2CharmResource(chRes) if err != nil { return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } result.CharmStoreResources = append(result.CharmStoreResources, res) } return result, nil }
// ListResources returns the info for each non-pending resource of the // identified service. func (p ResourcePersistence) ListResources(serviceID string) (resource.ServiceResources, error) { logger.Tracef("listing all resources for service %q", serviceID) docs, err := p.resources(serviceID) if err != nil { return resource.ServiceResources{}, errors.Trace(err) } store := map[string]charmresource.Resource{} units := map[names.UnitTag][]resource.Resource{} downloadProgress := make(map[names.UnitTag]map[string]int64) var results resource.ServiceResources for _, doc := range docs { if doc.PendingID != "" { continue } res, err := doc2basicResource(doc) if err != nil { return resource.ServiceResources{}, errors.Trace(err) } if !doc.LastPolled.IsZero() { store[res.Name] = res.Resource continue } if doc.UnitID == "" { results.Resources = append(results.Resources, res) continue } tag := names.NewUnitTag(doc.UnitID) if doc.PendingID == "" { units[tag] = append(units[tag], res) } if doc.DownloadProgress != nil { if downloadProgress[tag] == nil { downloadProgress[tag] = make(map[string]int64) } downloadProgress[tag][doc.Name] = *doc.DownloadProgress } } for _, res := range results.Resources { storeRes := store[res.Name] results.CharmStoreResources = append(results.CharmStoreResources, storeRes) } for tag, res := range units { results.UnitResources = append(results.UnitResources, resource.UnitResources{ Tag: tag, Resources: res, DownloadProgress: downloadProgress[tag], }) } return results, nil }
func newPersistenceResources(c *gc.C, serviceID string, names ...string) (resource.ServiceResources, []resourceDoc) { var svcResources resource.ServiceResources var docs []resourceDoc for _, name := range names { res, doc := newPersistenceResource(c, serviceID, name) svcResources.Resources = append(svcResources.Resources, res.Resource) svcResources.CharmStoreResources = append(svcResources.CharmStoreResources, res.Resource.Resource) docs = append(docs, doc) csDoc := doc // a copy csDoc.DocID += "#charmstore" csDoc.Username = "" csDoc.Timestamp = coretesting.ZeroTime() csDoc.StoragePath = "" csDoc.LastPolled = coretesting.NonZeroTime().UTC() docs = append(docs, csDoc) } return svcResources, docs }
// APIResult2ServiceResources converts a ResourcesResult into a resource.ServiceResources. func APIResult2ServiceResources(apiResult ResourcesResult) (resource.ServiceResources, error) { var result resource.ServiceResources if apiResult.Error != nil { // TODO(ericsnow) Return the resources too? err, _ := common.RestoreError(apiResult.Error) return resource.ServiceResources{}, errors.Trace(err) } for _, apiRes := range apiResult.Resources { res, err := API2Resource(apiRes) if err != nil { // This could happen if the server is misbehaving // or non-conforming. // TODO(ericsnow) Aggregate errors? return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } result.Resources = append(result.Resources, res) } for _, unitRes := range apiResult.UnitResources { tag, err := names.ParseUnitTag(unitRes.Tag) if err != nil { return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } unitResources := resource.UnitResources{Tag: tag} for _, apiRes := range unitRes.Resources { res, err := API2Resource(apiRes) if err != nil { return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server") } unitResources.Resources = append(unitResources.Resources, res) } result.UnitResources = append(result.UnitResources, unitResources) } return result, nil }