github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/bindings/manifests/manifests.go (about)

     1  package manifests
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  	"net/url"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"github.com/containers/image/v5/manifest"
    12  	"github.com/containers/podman/v2/libpod/image"
    13  	"github.com/containers/podman/v2/pkg/api/handlers"
    14  	"github.com/containers/podman/v2/pkg/bindings"
    15  	jsoniter "github.com/json-iterator/go"
    16  )
    17  
    18  // Create creates a manifest for the given name.  Optional images to be associated with
    19  // the new manifest can also be specified.  The all boolean specifies to add all entries
    20  // of a list if the name provided is a manifest list.  The ID of the new manifest list
    21  // is returned as a string.
    22  func Create(ctx context.Context, names, images []string, all *bool) (string, error) {
    23  	var idr handlers.IDResponse
    24  	conn, err := bindings.GetClient(ctx)
    25  	if err != nil {
    26  		return "", err
    27  	}
    28  	if len(names) < 1 {
    29  		return "", errors.New("creating a manifest requires at least one name argument")
    30  	}
    31  	params := url.Values{}
    32  	if all != nil {
    33  		params.Set("all", strconv.FormatBool(*all))
    34  	}
    35  	for _, name := range names {
    36  		params.Add("name", name)
    37  	}
    38  	for _, i := range images {
    39  		params.Add("image", i)
    40  	}
    41  
    42  	response, err := conn.DoRequest(nil, http.MethodPost, "/manifests/create", params, nil)
    43  	if err != nil {
    44  		return "", err
    45  	}
    46  	return idr.ID, response.Process(&idr)
    47  }
    48  
    49  // Inspect returns a manifest list for a given name.
    50  func Inspect(ctx context.Context, name string) (*manifest.Schema2List, error) {
    51  	var list manifest.Schema2List
    52  	conn, err := bindings.GetClient(ctx)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	response, err := conn.DoRequest(nil, http.MethodGet, "/manifests/%s/json", nil, nil, name)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	return &list, response.Process(&list)
    61  }
    62  
    63  // Add adds a manifest to a given manifest list.  Additional options for the manifest
    64  // can also be specified.  The ID of the new manifest list is returned as a string
    65  func Add(ctx context.Context, name string, options image.ManifestAddOpts) (string, error) {
    66  	var idr handlers.IDResponse
    67  	conn, err := bindings.GetClient(ctx)
    68  	if err != nil {
    69  		return "", err
    70  	}
    71  	optionsString, err := jsoniter.MarshalToString(options)
    72  	if err != nil {
    73  		return "", err
    74  	}
    75  	stringReader := strings.NewReader(optionsString)
    76  	response, err := conn.DoRequest(stringReader, http.MethodPost, "/manifests/%s/add", nil, nil, name)
    77  	if err != nil {
    78  		return "", err
    79  	}
    80  	return idr.ID, response.Process(&idr)
    81  }
    82  
    83  // Remove deletes a manifest entry from a manifest list.  Both name and the digest to be
    84  // removed are mandatory inputs.  The ID of the new manifest list is returned as a string.
    85  func Remove(ctx context.Context, name, digest string) (string, error) {
    86  	var idr handlers.IDResponse
    87  	conn, err := bindings.GetClient(ctx)
    88  	if err != nil {
    89  		return "", err
    90  	}
    91  	params := url.Values{}
    92  	params.Set("digest", digest)
    93  	response, err := conn.DoRequest(nil, http.MethodDelete, "/manifests/%s", params, nil, name)
    94  	if err != nil {
    95  		return "", err
    96  	}
    97  	return idr.ID, response.Process(&idr)
    98  }
    99  
   100  // Push takes a manifest list and pushes to a destination.  If the destination is not specified,
   101  // the name will be used instead.  If the optional all boolean is specified, all images specified
   102  // in the list will be pushed as well.
   103  func Push(ctx context.Context, name string, destination *string, all *bool) (string, error) {
   104  	var (
   105  		idr handlers.IDResponse
   106  	)
   107  	dest := name
   108  	conn, err := bindings.GetClient(ctx)
   109  	if err != nil {
   110  		return "", err
   111  	}
   112  	params := url.Values{}
   113  	params.Set("image", name)
   114  	if destination != nil {
   115  		dest = *destination
   116  	}
   117  	params.Set("destination", dest)
   118  	if all != nil {
   119  		params.Set("all", strconv.FormatBool(*all))
   120  	}
   121  	_, err = conn.DoRequest(nil, http.MethodPost, "/manifests/%s/push", params, nil, name)
   122  	if err != nil {
   123  		return "", err
   124  	}
   125  	return idr.ID, err
   126  }
   127  
   128  // There is NO annotate endpoint.  this binding could never work
   129  // Annotate updates the image configuration of a given manifest list
   130  //func Annotate(ctx context.Context, name, digest string, options image.ManifestAnnotateOpts) (string, error) {
   131  //	var idr handlers.IDResponse
   132  //	conn, err := bindings.GetClient(ctx)
   133  //	if err != nil {
   134  //		return "", err
   135  //	}
   136  //	params := url.Values{}
   137  //	params.Set("digest", digest)
   138  //	optionsString, err := jsoniter.MarshalToString(options)
   139  //	if err != nil {
   140  //		return "", err
   141  //	}
   142  //	stringReader := strings.NewReader(optionsString)
   143  //	response, err := conn.DoRequest(stringReader, http.MethodPost, "/manifests/%s/annotate", params, name)
   144  //	if err != nil {
   145  //		return "", err
   146  //	}
   147  //	return idr.ID, response.Process(&idr)
   148  //}