github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/api/handlers/utils/images.go (about)

     1  package utils
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/containers/image/v5/docker"
     8  	"github.com/containers/image/v5/storage"
     9  	"github.com/containers/image/v5/transports/alltransports"
    10  	"github.com/containers/image/v5/types"
    11  	"github.com/containers/libpod/libpod"
    12  	"github.com/containers/libpod/libpod/image"
    13  	"github.com/gorilla/schema"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // ParseDockerReference parses the specified image name to a
    18  // `types.ImageReference` and enforces it to refer to a docker-transport
    19  // reference.
    20  func ParseDockerReference(name string) (types.ImageReference, error) {
    21  	dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
    22  	imageRef, err := alltransports.ParseImageName(name)
    23  	if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
    24  		return nil, errors.Errorf("reference %q must be a docker reference", name)
    25  	} else if err != nil {
    26  		origErr := err
    27  		imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, name))
    28  		if err != nil {
    29  			return nil, errors.Wrapf(origErr, "reference %q must be a docker reference", name)
    30  		}
    31  	}
    32  	return imageRef, nil
    33  }
    34  
    35  // ParseStorageReference parses the specified image name to a
    36  // `types.ImageReference` and enforces it to refer to a
    37  // containers-storage-transport reference.
    38  func ParseStorageReference(name string) (types.ImageReference, error) {
    39  	storagePrefix := fmt.Sprintf("%s:", storage.Transport.Name())
    40  	imageRef, err := alltransports.ParseImageName(name)
    41  	if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
    42  		return nil, errors.Errorf("reference %q must be a storage reference", name)
    43  	} else if err != nil {
    44  		origErr := err
    45  		imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", storagePrefix, name))
    46  		if err != nil {
    47  			return nil, errors.Wrapf(origErr, "reference %q must be a storage reference", name)
    48  		}
    49  	}
    50  	return imageRef, nil
    51  }
    52  
    53  // GetImages is a common function used to get images for libpod and other compatibility
    54  // mechanisms
    55  func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) {
    56  	decoder := r.Context().Value("decoder").(*schema.Decoder)
    57  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    58  	query := struct {
    59  		All     bool
    60  		Filters map[string][]string `schema:"filters"`
    61  		Digests bool
    62  	}{
    63  		// This is where you can override the golang default value for one of fields
    64  	}
    65  	// TODO I think all is implemented with a filter?
    66  
    67  	if err := decoder.Decode(&query, r.URL.Query()); err != nil {
    68  		return nil, err
    69  	}
    70  	var filters = []string{}
    71  	if _, found := r.URL.Query()["digests"]; found && query.Digests {
    72  		UnSupportedParameter("digests")
    73  	}
    74  
    75  	if len(query.Filters) > 0 {
    76  		for k, v := range query.Filters {
    77  			for _, val := range v {
    78  				filters = append(filters, fmt.Sprintf("%s=%s", k, val))
    79  			}
    80  		}
    81  		return runtime.ImageRuntime().GetImagesWithFilters(filters)
    82  	} else {
    83  		return runtime.ImageRuntime().GetImages()
    84  	}
    85  
    86  }
    87  
    88  func GetImage(r *http.Request, name string) (*image.Image, error) {
    89  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    90  	return runtime.ImageRuntime().NewFromLocal(name)
    91  }