@@ -15,6 +15,8 @@ import (
1515 "github.com/containers/common/libimage"
1616 "github.com/containers/common/pkg/ssh"
1717 "github.com/containers/image/v5/manifest"
18+ "github.com/containers/image/v5/pkg/shortnames"
19+ "github.com/containers/image/v5/types"
1820 "github.com/containers/podman/v4/libpod"
1921 "github.com/containers/podman/v4/libpod/define"
2022 "github.com/containers/podman/v4/pkg/api/handlers"
@@ -720,3 +722,36 @@ func ImageScp(w http.ResponseWriter, r *http.Request) {
720722
721723 utils .WriteResponse (w , http .StatusOK , & reports.ScpReport {Id : rep .Names [0 ]})
722724}
725+
726+ // Resolve the passed (short) name to one more candidates it may resolve to.
727+ // See https://www.redhat.com/sysadmin/container-image-short-names.
728+ //
729+ // One user of this endpoint is Podman Desktop which needs to figure out where
730+ // an image may resolve to.
731+ func ImageResolve (w http.ResponseWriter , r * http.Request ) {
732+ runtime := r .Context ().Value (api .RuntimeKey ).(* libpod.Runtime )
733+ name := utils .GetName (r )
734+
735+ mode := types .ShortNameModeDisabled
736+ sys := runtime .SystemContext ()
737+ sys .ShortNameMode = & mode
738+
739+ resolved , err := shortnames .Resolve (sys , name )
740+ if err != nil {
741+ utils .Error (w , http .StatusBadRequest , fmt .Errorf ("resolving %q: %w" , name , err ))
742+ return
743+ }
744+
745+ if len (resolved .PullCandidates ) == 0 { // Should never happen but let's be defensive.
746+ utils .Error (w , http .StatusInternalServerError , fmt .Errorf ("name %q did not resolve to any candidate" , name ))
747+ return
748+ }
749+
750+ names := make ([]string , 0 , len (resolved .PullCandidates ))
751+ for _ , candidate := range resolved .PullCandidates {
752+ names = append (names , candidate .Value .String ())
753+ }
754+
755+ report := handlers.LibpodImagesResolveReport {Names : names }
756+ utils .WriteResponse (w , http .StatusOK , report )
757+ }
0 commit comments