Fix edge case with results spread over several pages

When most_recent=false, and one page contains just a single potential
result, but a following page may contain more (which needs to be
reported as an error).
This commit is contained in:
Olaf Seibert 2019-05-02 10:43:56 +02:00
parent 58f8f088e2
commit 43bb372f84
1 changed files with 16 additions and 14 deletions

View File

@ -49,6 +49,7 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag)
log.Printf("Using Image Filters %+v", s.SourceImageOpts) log.Printf("Using Image Filters %+v", s.SourceImageOpts)
image := &images.Image{} image := &images.Image{}
count := 0
err = images.List(client, s.SourceImageOpts).EachPage(func(page pagination.Page) (bool, error) { err = images.List(client, s.SourceImageOpts).EachPage(func(page pagination.Page) (bool, error) {
imgs, err := images.ExtractImages(page) imgs, err := images.ExtractImages(page)
if err != nil { if err != nil {
@ -56,9 +57,6 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag)
} }
ui.Message(fmt.Sprintf("Resulting images: %d", len(imgs))) ui.Message(fmt.Sprintf("Resulting images: %d", len(imgs)))
count := 0
first := -1
for index, img := range imgs { for index, img := range imgs {
ui.Message(fmt.Sprintf("index +%v, image %+v", index, img)) ui.Message(fmt.Sprintf("index +%v, image %+v", index, img))
ui.Message(fmt.Sprintf("Metadata %+v", img.Metadata)) ui.Message(fmt.Sprintf("Metadata %+v", img.Metadata))
@ -68,8 +66,9 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag)
if PropertiesSatisfied(&img, &s.SourceProperties) { if PropertiesSatisfied(&img, &s.SourceProperties) {
ui.Message(fmt.Sprintf("Matched properties %+v", s.SourceProperties)) ui.Message(fmt.Sprintf("Matched properties %+v", s.SourceProperties))
count++ count++
if first < 0 { if count == 1 {
first = index // Tentatively return this result.
*image = img
} }
// Don't iterate over entries we will never use. // Don't iterate over entries we will never use.
if count > 1 { if count > 1 {
@ -80,20 +79,22 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag)
} }
} }
ui.Message(fmt.Sprintf("Count = %v", count))
switch count { switch count {
case 0: case 0: // Continue looking at next page.
return true, nil return true, nil
case 1: case 1: // Maybe we're done, maybe there is another result in a later page and it is an error.
*image = imgs[first] if s.SourceMostRecent {
return false, nil return false, nil
default: }
return true, nil
default: // By now we should know if getting 2+ results is an error or not.
if s.SourceMostRecent { if s.SourceMostRecent {
*image = imgs[first]
return false, nil return false, nil
} }
return false, fmt.Errorf( return false, fmt.Errorf(
"Your query returned more than one result. Please try a more specific search, or set most_recent to true. Search filters: %+v", "Your query returned more than one result. Please try a more specific search, or set most_recent to true. Search filters: %+v properties %+v",
s.SourceImageOpts) s.SourceImageOpts, s.SourceProperties)
} }
}) })
@ -105,7 +106,8 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag)
} }
if image.ID == "" { if image.ID == "" {
err := fmt.Errorf("No image was found matching filters: %+v", s.SourceImageOpts) err := fmt.Errorf("No image was found matching filters: %+v properties %+v",
s.SourceImageOpts, s.SourceProperties)
state.Put("error", err) state.Put("error", err)
ui.Error(err.Error()) ui.Error(err.Error())
return multistep.ActionHalt return multistep.ActionHalt