mirror of https://github.com/containers/podman.git
				
				
				
			Add os, arch, and ismanifest to libpod image list
when listing images through the restful service, consumers want to know if the image they are listing is a manifest or not because the libpod endpoint returns both images and manifest lists. in addition, we now add `arch` and `os` as fields in the libpod endpoint for image listing as well. Fixes: #22184 Fixes: #22185 Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
		
							parent
							
								
									0b0335259e
								
							
						
					
					
						commit
						08a49389c8
					
				|  | @ -52,7 +52,7 @@ my $Format_Exceptions = <<'END_EXCEPTIONS'; | ||||||
| # Deep internal structs; pretty sure these are permanent exceptions | # Deep internal structs; pretty sure these are permanent exceptions | ||||||
| events       .Details | events       .Details | ||||||
| history      .ImageHistoryLayer | history      .ImageHistoryLayer | ||||||
| images       .ImageSummary | images       .Arch .ImageSummary .Os .IsManifestList | ||||||
| network-ls   .Network | network-ls   .Network | ||||||
| 
 | 
 | ||||||
| # FIXME: this one, maybe? But someone needs to write the text | # FIXME: this one, maybe? But someone needs to write the text | ||||||
|  |  | ||||||
|  | @ -483,7 +483,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { | ||||||
| 
 | 
 | ||||||
| 	imageEngine := abi.ImageEngine{Libpod: runtime} | 	imageEngine := abi.ImageEngine{Libpod: runtime} | ||||||
| 
 | 
 | ||||||
| 	listOptions := entities.ImageListOptions{All: query.All, Filter: filterList} | 	listOptions := entities.ImageListOptions{All: query.All, Filter: filterList, ExtendedAttributes: utils.IsLibpodRequest(r)} | ||||||
| 	summaries, err := imageEngine.List(r.Context(), listOptions) | 	summaries, err := imageEngine.List(r.Context(), listOptions) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		utils.Error(w, http.StatusInternalServerError, err) | 		utils.Error(w, http.StatusInternalServerError, err) | ||||||
|  |  | ||||||
|  | @ -242,8 +242,11 @@ type ImageSearchReport = entitiesTypes.ImageSearchReport | ||||||
| 
 | 
 | ||||||
| // Image List Options
 | // Image List Options
 | ||||||
| type ImageListOptions struct { | type ImageListOptions struct { | ||||||
| 	All    bool     `json:"all" schema:"all"` | 	All bool | ||||||
| 	Filter []string `json:"Filter,omitempty"` | 	// ExtendedAttributes is used by the libpod endpoint only to deliver extra information
 | ||||||
|  | 	// that the compat endpoint does not
 | ||||||
|  | 	ExtendedAttributes bool | ||||||
|  | 	Filter             []string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ImagePruneOptions struct { | type ImagePruneOptions struct { | ||||||
|  |  | ||||||
|  | @ -23,9 +23,15 @@ type ImageSummary struct { | ||||||
| 	Dangling    bool `json:",omitempty"` | 	Dangling    bool `json:",omitempty"` | ||||||
| 
 | 
 | ||||||
| 	// Podman extensions
 | 	// Podman extensions
 | ||||||
| 	Names   []string `json:",omitempty"` | 	Arch    string   `json:",omitempty"` | ||||||
| 	Digest  string   `json:",omitempty"` | 	Digest  string   `json:",omitempty"` | ||||||
| 	History []string `json:",omitempty"` | 	History []string `json:",omitempty"` | ||||||
|  | 	// IsManifestList is a ptr so we can distinguish between a true
 | ||||||
|  | 	// json empty response and false.  the docker compat side needs to return
 | ||||||
|  | 	// empty; where as the libpod side needs a value of true or false
 | ||||||
|  | 	IsManifestList *bool    `json:",omitempty"` | ||||||
|  | 	Names          []string `json:",omitempty"` | ||||||
|  | 	Os             string   `json:",omitempty"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (i *ImageSummary) Id() string { //nolint:revive,stylecheck
 | func (i *ImageSummary) Id() string { //nolint:revive,stylecheck
 | ||||||
|  |  | ||||||
|  | @ -57,6 +57,21 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) | ||||||
| 				RepoTags:    img.Names(), // may include tags and digests
 | 				RepoTags:    img.Names(), // may include tags and digests
 | ||||||
| 				ParentId:    parentID, | 				ParentId:    parentID, | ||||||
| 			} | 			} | ||||||
|  | 			if opts.ExtendedAttributes { | ||||||
|  | 				iml, err := img.IsManifestList(ctx) | ||||||
|  | 				if err != nil { | ||||||
|  | 					return nil, err | ||||||
|  | 				} | ||||||
|  | 				s.IsManifestList = &iml | ||||||
|  | 				if !iml { | ||||||
|  | 					imgData, err := img.Inspect(ctx, nil) | ||||||
|  | 					if err != nil { | ||||||
|  | 						return nil, err | ||||||
|  | 					} | ||||||
|  | 					s.Arch = imgData.Architecture | ||||||
|  | 					s.Os = imgData.Os | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 			s.Labels, err = img.Labels(ctx) | 			s.Labels, err = img.Labels(ctx) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, fmt.Errorf("retrieving label for image %q: you may need to remove the image to resolve the error: %w", img.ID(), err) | 				return nil, fmt.Errorf("retrieving label for image %q: you may need to remove the image to resolve the error: %w", img.ID(), err) | ||||||
|  |  | ||||||
|  | @ -90,3 +90,41 @@ t DELETE libpod/images/$IMAGE 200 \ | ||||||
| podman system connection rm $conn | podman system connection rm $conn | ||||||
| 
 | 
 | ||||||
| stop_registry | stop_registry | ||||||
|  | 
 | ||||||
|  | # if an image is a manifest list, it should not have | ||||||
|  | # anything for arch or os | ||||||
|  | podman manifest create foobar | ||||||
|  | t GET libpod/images/json 200  \ .[0].IsManifestList=true \ | ||||||
|  |                                 .[0].Arch=null \ | ||||||
|  |                                 .[0].Os=null | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # list images through the libpod endpoint should return | ||||||
|  | # IsManifestList (bool), Arch (string), and Os (string) | ||||||
|  | podman pull -q $IMAGE | ||||||
|  | t GET libpod/images/json 200  \ .[0].IsManifestList=true\ | ||||||
|  |                                 .[0].Arch=null \ | ||||||
|  |                                 .[0].Os=null \ | ||||||
|  |                                 '.[0].RepoDigests | length=1' \ | ||||||
|  |                                 .[1].IsManifestList=false \ | ||||||
|  |                                 .[1].Arch=amd64 \ | ||||||
|  |                                 .[1].Os=linux | ||||||
|  | 
 | ||||||
|  | # if a manifest list and an image are returned with libpod images | ||||||
|  | # endpoint, then one should be a manifest with IsManifest only; and | ||||||
|  | # the other image should have IsManifestList, Arch, and Os. | ||||||
|  | podman manifest add --arch amd64 foobar $IMAGE | ||||||
|  | t GET libpod/images/json 200    .[0].IsManifestList=true\ | ||||||
|  |                                 .[0].Arch=null \ | ||||||
|  |                                 .[0].Os=null \ | ||||||
|  |                                 '.[0].RepoDigests | length=2' \ | ||||||
|  |                                 .[1].IsManifestList=false \ | ||||||
|  |                                 .[1].Arch=amd64 \ | ||||||
|  |                                 .[1].Os=linux | ||||||
|  | 
 | ||||||
|  | t GET images/json 200    .[0].IsManifestList=null \ | ||||||
|  |                                 .[0].Arch=null \ | ||||||
|  |                                 .[0].Os=null \ | ||||||
|  |                                 .[1].IsManifestList=null \ | ||||||
|  |                                 .[1].Arch=null \ | ||||||
|  |                                 .[1].Os=null \ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue