summaryrefslogtreecommitdiff
path: root/pkg/bindings/manifests/manifests.go
blob: feeb8d3f7ea9909675b559c047c81a078e5912e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package manifests

import (
	"context"
	"errors"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	"github.com/containers/image/v5/manifest"
	"github.com/containers/libpod/v2/libpod/image"
	"github.com/containers/libpod/v2/pkg/api/handlers"
	"github.com/containers/libpod/v2/pkg/bindings"
	jsoniter "github.com/json-iterator/go"
)

// Create creates a manifest for the given name.  Optional images to be associated with
// the new manifest can also be specified.  The all boolean specifies to add all entries
// of a list if the name provided is a manifest list.  The ID of the new manifest list
// is returned as a string.
func Create(ctx context.Context, names, images []string, all *bool) (string, error) {
	var idr handlers.IDResponse
	conn, err := bindings.GetClient(ctx)
	if err != nil {
		return "", err
	}
	if len(names) < 1 {
		return "", errors.New("creating a manifest requires at least one name argument")
	}
	params := url.Values{}
	if all != nil {
		params.Set("all", strconv.FormatBool(*all))
	}
	for _, name := range names {
		params.Add("name", name)
	}
	for _, i := range images {
		params.Add("image", i)
	}

	response, err := conn.DoRequest(nil, http.MethodPost, "/manifests/create", params, nil)
	if err != nil {
		return "", err
	}
	return idr.ID, response.Process(&idr)
}

// Inspect returns a manifest list for a given name.
func Inspect(ctx context.Context, name string) (*manifest.Schema2List, error) {
	var list manifest.Schema2List
	conn, err := bindings.GetClient(ctx)
	if err != nil {
		return nil, err
	}
	response, err := conn.DoRequest(nil, http.MethodGet, "/manifests/%s/json", nil, nil, name)
	if err != nil {
		return nil, err
	}
	return &list, response.Process(&list)
}

// Add adds a manifest to a given manifest list.  Additional options for the manifest
// can also be specified.  The ID of the new manifest list is returned as a string
func Add(ctx context.Context, name string, options image.ManifestAddOpts) (string, error) {
	var idr handlers.IDResponse
	conn, err := bindings.GetClient(ctx)
	if err != nil {
		return "", err
	}
	optionsString, err := jsoniter.MarshalToString(options)
	if err != nil {
		return "", err
	}
	stringReader := strings.NewReader(optionsString)
	response, err := conn.DoRequest(stringReader, http.MethodPost, "/manifests/%s/add", nil, nil, name)
	if err != nil {
		return "", err
	}
	return idr.ID, response.Process(&idr)
}

// Remove deletes a manifest entry from a manifest list.  Both name and the digest to be
// removed are mandatory inputs.  The ID of the new manifest list is returned as a string.
func Remove(ctx context.Context, name, digest string) (string, error) {
	var idr handlers.IDResponse
	conn, err := bindings.GetClient(ctx)
	if err != nil {
		return "", err
	}
	params := url.Values{}
	params.Set("digest", digest)
	response, err := conn.DoRequest(nil, http.MethodDelete, "/manifests/%s", params, nil, name)
	if err != nil {
		return "", err
	}
	return idr.ID, response.Process(&idr)
}

// Push takes a manifest list and pushes to a destination.  If the destination is not specified,
// the name will be used instead.  If the optional all boolean is specified, all images specified
// in the list will be pushed as well.
func Push(ctx context.Context, name string, destination *string, all *bool) (string, error) {
	var (
		idr handlers.IDResponse
	)
	dest := name
	conn, err := bindings.GetClient(ctx)
	if err != nil {
		return "", err
	}
	params := url.Values{}
	params.Set("image", name)
	if destination != nil {
		dest = *destination
	}
	params.Set("destination", dest)
	if all != nil {
		params.Set("all", strconv.FormatBool(*all))
	}
	_, err = conn.DoRequest(nil, http.MethodPost, "/manifests/%s/push", params, nil, name)
	if err != nil {
		return "", err
	}
	return idr.ID, err
}

// There is NO annotate endpoint.  this binding could never work
// Annotate updates the image configuration of a given manifest list
//func Annotate(ctx context.Context, name, digest string, options image.ManifestAnnotateOpts) (string, error) {
//	var idr handlers.IDResponse
//	conn, err := bindings.GetClient(ctx)
//	if err != nil {
//		return "", err
//	}
//	params := url.Values{}
//	params.Set("digest", digest)
//	optionsString, err := jsoniter.MarshalToString(options)
//	if err != nil {
//		return "", err
//	}
//	stringReader := strings.NewReader(optionsString)
//	response, err := conn.DoRequest(stringReader, http.MethodPost, "/manifests/%s/annotate", params, name)
//	if err != nil {
//		return "", err
//	}
//	return idr.ID, response.Process(&idr)
//}