summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-12-16 14:04:11 +0000
committerGitHub <noreply@github.com>2020-12-16 14:04:11 +0000
commit978c0767fa72abfa41f720f6fab34a62e3ac7a12 (patch)
tree0f70b9aa485fc18a12f9811a234a4e660b24ab16
parentf1f7b8f6c80916bc88f5a01137e0d9fd971f8ac1 (diff)
parent8d4e19634cf73f257ca7f5d2c9506183f6a5b183 (diff)
downloadpodman-978c0767fa72abfa41f720f6fab34a62e3ac7a12.tar.gz
podman-978c0767fa72abfa41f720f6fab34a62e3ac7a12.tar.bz2
podman-978c0767fa72abfa41f720f6fab34a62e3ac7a12.zip
Merge pull request #8715 from baude/bindings3images
Podman image bindings for 3.0
-rw-r--r--pkg/api/handlers/libpod/images.go75
-rw-r--r--pkg/bindings/generator/generator.go54
-rw-r--r--pkg/bindings/images/diff.go6
-rw-r--r--pkg/bindings/images/images.go205
-rw-r--r--pkg/bindings/images/pull.go26
-rw-r--r--pkg/bindings/images/rm.go47
-rw-r--r--pkg/bindings/images/types.go185
-rw-r--r--pkg/bindings/images/types_diff_options.go (renamed from pkg/bindings/images/removeoptions_types.go)22
-rw-r--r--pkg/bindings/images/types_export_options.go119
-rw-r--r--pkg/bindings/images/types_get_options.go103
-rw-r--r--pkg/bindings/images/types_history_options.go87
-rw-r--r--pkg/bindings/images/types_import_options.go151
-rw-r--r--pkg/bindings/images/types_list_options.go119
-rw-r--r--pkg/bindings/images/types_load_options.go103
-rw-r--r--pkg/bindings/images/types_prune_options.go119
-rw-r--r--pkg/bindings/images/types_pull_options.go280
-rw-r--r--pkg/bindings/images/types_push_options.go279
-rw-r--r--pkg/bindings/images/types_remove_options.go119
-rw-r--r--pkg/bindings/images/types_search_options.go183
-rw-r--r--pkg/bindings/images/types_tag_options.go87
-rw-r--r--pkg/bindings/images/types_tree_options.go103
-rw-r--r--pkg/bindings/images/types_untag_options.go87
-rw-r--r--pkg/bindings/test/auth_test.go42
-rw-r--r--pkg/bindings/test/images_test.go100
-rw-r--r--pkg/bindings/test/info_test.go4
-rw-r--r--pkg/bindings/test/manifests_test.go4
-rw-r--r--pkg/domain/infra/tunnel/images.go154
27 files changed, 2521 insertions, 342 deletions
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 505c96126..814d0fd69 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -265,8 +265,14 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
// Format is mandatory! Currently, we only support multi-image docker
// archives.
+ if len(query.References) > 1 && query.Format != define.V2s2Archive {
+ utils.Error(w, "unsupported format", http.StatusInternalServerError, errors.Errorf("multi-image archives must use format of %s", define.V2s2Archive))
+ return
+
+ }
+
switch query.Format {
- case define.V2s2Archive:
+ case define.V2s2Archive, define.OCIArchive:
tmpfile, err := ioutil.TempFile("", "api.tar")
if err != nil {
utils.Error(w, "unable to create tmpfile", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
@@ -277,6 +283,13 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "unable to close tmpfile", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
return
}
+ case define.OCIManifestDir, define.V2s2ManifestDir:
+ tmpdir, err := ioutil.TempDir("", "save")
+ if err != nil {
+ utils.Error(w, "unable to create tmpdir", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempdir"))
+ return
+ }
+ output = tmpdir
default:
utils.Error(w, "unsupported format", http.StatusInternalServerError, errors.Errorf("unsupported format %q", query.Format))
return
@@ -287,7 +300,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
opts := entities.ImageSaveOptions{
Compress: query.Compress,
Format: query.Format,
- MultiImageArchive: true,
+ MultiImageArchive: len(query.References) > 1,
Output: output,
RemoveSignatures: true,
}
@@ -414,7 +427,6 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
}{
// This is where you can override the golang default value for one of fields
}
-
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
@@ -607,12 +619,12 @@ func UntagImage(w http.ResponseWriter, r *http.Request) {
func SearchImages(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Term string `json:"term"`
- Limit int `json:"limit"`
- NoTrunc bool `json:"noTrunc"`
- Filters []string `json:"filters"`
- TLSVerify bool `json:"tlsVerify"`
- ListTags bool `json:"listTags"`
+ Term string `json:"term"`
+ Limit int `json:"limit"`
+ NoTrunc bool `json:"noTrunc"`
+ Filters map[string][]string `json:"filters"`
+ TLSVerify bool `json:"tlsVerify"`
+ ListTags bool `json:"listTags"`
}{
// This is where you can override the golang default value for one of fields
}
@@ -622,24 +634,44 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {
return
}
+ filter := image.SearchFilter{}
+ if len(query.Filters) > 0 {
+ if len(query.Filters["stars"]) > 0 {
+ stars, err := strconv.Atoi(query.Filters["stars"][0])
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ filter.Stars = stars
+ }
+ if len(query.Filters["is-official"]) > 0 {
+ isOfficial, err := strconv.ParseBool(query.Filters["is-official"][0])
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ filter.IsOfficial = types.NewOptionalBool(isOfficial)
+ }
+ if len(query.Filters["is-automated"]) > 0 {
+ isAutomated, err := strconv.ParseBool(query.Filters["is-automated"][0])
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ filter.IsAutomated = types.NewOptionalBool(isAutomated)
+ }
+ }
options := image.SearchOptions{
Limit: query.Limit,
NoTrunc: query.NoTrunc,
ListTags: query.ListTags,
+ Filter: filter,
}
+
if _, found := r.URL.Query()["tlsVerify"]; found {
options.InsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
}
- if _, found := r.URL.Query()["filters"]; found {
- filter, err := image.ParseSearchFilter(query.Filters)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse filters parameter for %s", r.URL.String()))
- return
- }
- options.Filter = *filter
- }
-
_, authfile, key, err := auth.GetCredentials(r)
if err != nil {
utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String()))
@@ -678,10 +710,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
All bool `schema:"all"`
Force bool `schema:"force"`
Images []string `schema:"images"`
- }{
- All: false,
- Force: false,
- }
+ }{}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
@@ -690,10 +719,8 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
}
opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force}
-
imageEngine := abi.ImageEngine{Libpod: runtime}
rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts)
-
strErrs := errorhandling.ErrorsToStrings(rmErrors)
report := handlers.LibpodImagesRemoveReport{ImageRemoveReport: *rmReport, Errors: strErrs}
utils.WriteResponse(w, http.StatusOK, report)
diff --git a/pkg/bindings/generator/generator.go b/pkg/bindings/generator/generator.go
index 24c2310ff..2ebe35282 100644
--- a/pkg/bindings/generator/generator.go
+++ b/pkg/bindings/generator/generator.go
@@ -81,10 +81,11 @@ func (o *{{.StructName}}) ToParams() (url.Values, error) {
}
case reflect.Map:
lowerCaseKeys := make(map[string][]string)
- // I dont know if this code is needed anymore, TBD
- // for k, v := range filters {
- // lowerCaseKeys[strings.ToLower(k)] = v
- // }
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
s, err := json.MarshalToString(lowerCaseKeys)
if err != nil {
return nil, err
@@ -102,23 +103,34 @@ func (o *{{.StructName}}) ToParams() (url.Values, error) {
var fieldTmpl = `
// With{{.Name}}
func(o *{{.StructName}}) With{{.Name}}(value {{.Type}}) *{{.StructName}} {
- v := &value
+ v := {{.TypedValue}}
o.{{.Name}} = v
return o
}
+
+// Get{{.Name}}
+func(o *{{.StructName}}) Get{{.Name}}() {{.Type}} {
+ var {{.ZeroName}} {{.Type}}
+ if o.{{.Name}} == nil {
+ return {{.ZeroName}}
+ }
+ return {{.TypedName}}
+}
`
type fieldStruct struct {
Name string
StructName string
Type string
+ TypedName string
+ TypedValue string
+ ZeroName string
}
func main() {
var (
closed bool
fieldStructs []fieldStruct
- structNode ast.Node
)
srcFile := os.Getenv("GOFILE")
pkg := os.Getenv("GOPACKAGE")
@@ -132,14 +144,13 @@ func main() {
if err != nil {
panic(err)
}
-
// always add reflect
imports := []string{"\"reflect\""}
for _, imp := range f.Imports {
imports = append(imports, imp.Path.Value)
}
- out, err := os.Create(strings.ToLower(inputStructName) + "_" + srcFile)
+ out, err := os.Create(strings.TrimRight(srcFile, ".go") + "_" + strings.Replace(strings.ToLower(inputStructName), "options", "_options", 1) + ".go")
if err != nil {
panic(err)
}
@@ -166,26 +177,41 @@ func main() {
ref, refOK := n.(*ast.TypeSpec)
if refOK {
if ref.Name.Name == inputStructName {
- structNode = n
x := ref.Type.(*ast.StructType)
for _, field := range x.Fields.List {
var (
- name string
+ name, zeroName, typedName, typedValue string
)
- typeExpr := field.Type
- start := typeExpr.Pos() - 1
- end := typeExpr.End() - 1
- fieldType := strings.Replace(string(b[start:end]), "*", "", 1)
if len(field.Names) > 0 {
name = field.Names[0].Name
if len(name) < 1 {
panic(errors.New("bad name"))
}
}
+ for k, v := range name {
+ zeroName = strings.ToLower(string(v)) + name[k+1:]
+ break
+ }
+ //sub := "*"
+ typeExpr := field.Type
+ switch field.Type.(type) {
+ case *ast.MapType, *ast.StructType, *ast.ArrayType:
+ typedName = "o." + name
+ typedValue = "value"
+ default:
+ typedName = "*o." + name
+ typedValue = "&value"
+ }
+ start := typeExpr.Pos() - 1
+ end := typeExpr.End() - 1
+ fieldType := strings.Replace(string(b[start:end]), "*", "", 1)
fStruct := fieldStruct{
Name: name,
StructName: inputStructName,
Type: fieldType,
+ TypedName: typedName,
+ TypedValue: typedValue,
+ ZeroName: zeroName,
}
fieldStructs = append(fieldStructs, fStruct)
} // for
diff --git a/pkg/bindings/images/diff.go b/pkg/bindings/images/diff.go
index 10d50b0fd..8802c15e2 100644
--- a/pkg/bindings/images/diff.go
+++ b/pkg/bindings/images/diff.go
@@ -9,7 +9,11 @@ import (
)
// Diff provides the changes between two container layers
-func Diff(ctx context.Context, nameOrID string) ([]archive.Change, error) {
+func Diff(ctx context.Context, nameOrID string, options *DiffOptions) ([]archive.Change, error) {
+ if options == nil {
+ options = new(DiffOptions)
+ }
+ _ = options
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 2d3035d8d..9beb493c8 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -8,7 +8,6 @@ import (
"net/url"
"strconv"
- "github.com/containers/image/v5/types"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/auth"
"github.com/containers/podman/v2/pkg/bindings"
@@ -32,22 +31,18 @@ func Exists(ctx context.Context, nameOrID string) (bool, error) {
// List returns a list of images in local storage. The all boolean and filters parameters are optional
// ways to alter the image query.
-func List(ctx context.Context, all *bool, filters map[string][]string) ([]*entities.ImageSummary, error) {
+func List(ctx context.Context, options *ListOptions) ([]*entities.ImageSummary, error) {
+ if options == nil {
+ options = new(ListOptions)
+ }
var imageSummary []*entities.ImageSummary
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
- if all != nil {
- params.Set("all", strconv.FormatBool(*all))
- }
- if filters != nil {
- strFilters, err := bindings.FiltersToString(filters)
- if err != nil {
- return nil, err
- }
- params.Set("filters", strFilters)
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
}
response, err := conn.DoRequest(nil, http.MethodGet, "/images/json", params, nil)
if err != nil {
@@ -58,14 +53,17 @@ func List(ctx context.Context, all *bool, filters map[string][]string) ([]*entit
// Get performs an image inspect. To have the on-disk size of the image calculated, you can
// use the optional size parameter.
-func GetImage(ctx context.Context, nameOrID string, size *bool) (*entities.ImageInspectReport, error) {
+func GetImage(ctx context.Context, nameOrID string, options *GetOptions) (*entities.ImageInspectReport, error) {
+ if options == nil {
+ options = new(GetOptions)
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
- if size != nil {
- params.Set("size", strconv.FormatBool(*size))
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
}
inspectedData := entities.ImageInspectReport{}
response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/json", params, nil, nameOrID)
@@ -76,15 +74,18 @@ func GetImage(ctx context.Context, nameOrID string, size *bool) (*entities.Image
}
// Tree retrieves a "tree" based representation of the given image
-func Tree(ctx context.Context, nameOrID string, whatRequires *bool) (*entities.ImageTreeReport, error) {
+func Tree(ctx context.Context, nameOrID string, options *TreeOptions) (*entities.ImageTreeReport, error) {
+ if options == nil {
+ options = new(TreeOptions)
+ }
var report entities.ImageTreeReport
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
- if whatRequires != nil {
- params.Set("size", strconv.FormatBool(*whatRequires))
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
}
response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/tree", params, nil, nameOrID)
if err != nil {
@@ -94,7 +95,11 @@ func Tree(ctx context.Context, nameOrID string, whatRequires *bool) (*entities.I
}
// History returns the parent layers of an image.
-func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse, error) {
+func History(ctx context.Context, nameOrID string, options *HistoryOptions) ([]*handlers.HistoryResponse, error) {
+ if options == nil {
+ options = new(HistoryOptions)
+ }
+ _ = options
var history []*handlers.HistoryResponse
conn, err := bindings.GetClient(ctx)
if err != nil {
@@ -107,15 +112,18 @@ func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse,
return history, response.Process(&history)
}
-func Load(ctx context.Context, r io.Reader, name *string) (*entities.ImageLoadReport, error) {
+func Load(ctx context.Context, r io.Reader, options *LoadOptions) (*entities.ImageLoadReport, error) {
+ if options == nil {
+ options = new(LoadOptions)
+ }
var report entities.ImageLoadReport
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
- if name != nil {
- params.Set("reference", *name)
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
}
response, err := conn.DoRequest(r, http.MethodPost, "/images/load", params, nil)
if err != nil {
@@ -124,49 +132,24 @@ func Load(ctx context.Context, r io.Reader, name *string) (*entities.ImageLoadRe
return &report, response.Process(&report)
}
-func MultiExport(ctx context.Context, namesOrIds []string, w io.Writer, format *string, compress *bool) error {
- conn, err := bindings.GetClient(ctx)
- if err != nil {
- return err
- }
- params := url.Values{}
- if format != nil {
- params.Set("format", *format)
- }
- if compress != nil {
- params.Set("compress", strconv.FormatBool(*compress))
- }
- for _, ref := range namesOrIds {
- params.Add("references", ref)
+// Export saves images from local storage as a tarball or image archive. The optional format
+// parameter is used to change the format of the output.
+func Export(ctx context.Context, nameOrIDs []string, w io.Writer, options *ExportOptions) error {
+ if options == nil {
+ options = new(ExportOptions)
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/export", params, nil)
+ conn, err := bindings.GetClient(ctx)
if err != nil {
return err
}
-
- if response.StatusCode/100 == 2 || response.StatusCode/100 == 3 {
- _, err = io.Copy(w, response.Body)
- return err
- }
- return response.Process(nil)
-
-}
-
-// Export saves an image from local storage as a tarball or image archive. The optional format
-// parameter is used to change the format of the output.
-func Export(ctx context.Context, nameOrID string, w io.Writer, format *string, compress *bool) error {
- conn, err := bindings.GetClient(ctx)
+ params, err := options.ToParams()
if err != nil {
return err
}
- params := url.Values{}
- if format != nil {
- params.Set("format", *format)
- }
- if compress != nil {
- params.Set("compress", strconv.FormatBool(*compress))
+ for _, ref := range nameOrIDs {
+ params.Add("references", ref)
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/get", params, nil, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/export", params, nil)
if err != nil {
return err
}
@@ -180,24 +163,20 @@ func Export(ctx context.Context, nameOrID string, w io.Writer, format *string, c
// Prune removes unused images from local storage. The optional filters can be used to further
// define which images should be pruned.
-func Prune(ctx context.Context, all *bool, filters map[string][]string) ([]string, error) {
+func Prune(ctx context.Context, options *PruneOptions) ([]string, error) {
var (
deleted []string
)
+ if options == nil {
+ options = new(PruneOptions)
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
- if all != nil {
- params.Set("all", strconv.FormatBool(*all))
- }
- if filters != nil {
- stringFilter, err := bindings.FiltersToString(filters)
- if err != nil {
- return nil, err
- }
- params.Set("filters", stringFilter)
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
}
response, err := conn.DoRequest(nil, http.MethodPost, "/images/prune", params, nil)
if err != nil {
@@ -207,7 +186,11 @@ func Prune(ctx context.Context, all *bool, filters map[string][]string) ([]strin
}
// Tag adds an additional name to locally-stored image. Both the tag and repo parameters are required.
-func Tag(ctx context.Context, nameOrID, tag, repo string) error {
+func Tag(ctx context.Context, nameOrID, tag, repo string, options *TagOptions) error {
+ if options == nil {
+ options = new(TagOptions)
+ }
+ _ = options
conn, err := bindings.GetClient(ctx)
if err != nil {
return err
@@ -223,7 +206,11 @@ func Tag(ctx context.Context, nameOrID, tag, repo string) error {
}
// Untag removes a name from locally-stored image. Both the tag and repo parameters are required.
-func Untag(ctx context.Context, nameOrID, tag, repo string) error {
+func Untag(ctx context.Context, nameOrID, tag, repo string, options *UntagOptions) error {
+ if options == nil {
+ options = new(UntagOptions)
+ }
+ _ = options
conn, err := bindings.GetClient(ctx)
if err != nil {
return err
@@ -241,27 +228,21 @@ func Untag(ctx context.Context, nameOrID, tag, repo string) error {
// Imports adds the given image to the local image store. This can be done by file and the given reader
// or via the url parameter. Additional metadata can be associated with the image by using the changes and
// message parameters. The image can also be tagged given a reference. One of url OR r must be provided.
-func Import(ctx context.Context, changes []string, message, reference, u *string, r io.Reader) (*entities.ImageImportReport, error) {
+func Import(ctx context.Context, r io.Reader, options *ImportOptions) (*entities.ImageImportReport, error) {
+ if options == nil {
+ options = new(ImportOptions)
+ }
var report entities.ImageImportReport
- if r != nil && u != nil {
+ if r != nil && options.URL != nil {
return nil, errors.New("url and r parameters cannot be used together")
}
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
- for _, change := range changes {
- params.Add("changes", change)
- }
- if message != nil {
- params.Set("message", *message)
- }
- if reference != nil {
- params.Set("reference", *reference)
- }
- if u != nil {
- params.Set("url", *u)
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
}
response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params, nil)
if err != nil {
@@ -275,25 +256,31 @@ func Import(ctx context.Context, changes []string, message, reference, u *string
// The destination must be a reference to a registry (i.e., of docker transport
// or be normalized to one). Other transports are rejected as they do not make
// sense in a remote context.
-func Push(ctx context.Context, source string, destination string, options entities.ImagePushOptions) error {
+func Push(ctx context.Context, source string, destination string, options *PushOptions) error {
+ if options == nil {
+ options = new(PushOptions)
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return err
}
-
// TODO: have a global system context we can pass around (1st argument)
- header, err := auth.Header(nil, auth.XRegistryAuthHeader, options.Authfile, options.Username, options.Password)
+ header, err := auth.Header(nil, auth.XRegistryAuthHeader, options.GetAuthfile(), options.GetUsername(), options.GetPassword())
if err != nil {
return err
}
- params := url.Values{}
- params.Set("destination", destination)
- if options.SkipTLSVerify != types.OptionalBoolUndefined {
- // Note: we have to verify if skipped is false.
- verifyTLS := bool(options.SkipTLSVerify == types.OptionalBoolFalse)
- params.Set("tlsVerify", strconv.FormatBool(verifyTLS))
+ params, err := options.ToParams()
+ if err != nil {
+ return err
+ }
+ //SkipTLSVerify is special. We need to delete the param added by
+ //toparams and change the key and flip the bool
+ if options.SkipTLSVerify != nil {
+ params.Del("SkipTLSVerify")
+ params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify()))
}
+ params.Set("destination", destination)
path := fmt.Sprintf("/images/%s/push", source)
response, err := conn.DoRequest(nil, http.MethodPost, path, params, header)
@@ -305,28 +292,28 @@ func Push(ctx context.Context, source string, destination string, options entiti
}
// Search is the binding for libpod's v2 endpoints for Search images.
-func Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) {
+func Search(ctx context.Context, term string, options *SearchOptions) ([]entities.ImageSearchReport, error) {
+ if options == nil {
+ options = new(SearchOptions)
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
- params.Set("term", term)
- params.Set("limit", strconv.Itoa(opts.Limit))
- params.Set("noTrunc", strconv.FormatBool(opts.NoTrunc))
- params.Set("listTags", strconv.FormatBool(opts.ListTags))
- for _, f := range opts.Filters {
- params.Set("filters", f)
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
}
+ params.Set("term", term)
- if opts.SkipTLSVerify != types.OptionalBoolUndefined {
- // Note: we have to verify if skipped is false.
- verifyTLS := bool(opts.SkipTLSVerify == types.OptionalBoolFalse)
- params.Set("tlsVerify", strconv.FormatBool(verifyTLS))
+ // Note: we have to verify if skipped is false.
+ if options.SkipTLSVerify != nil {
+ params.Del("SkipTLSVerify")
+ params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify()))
}
// TODO: have a global system context we can pass around (1st argument)
- header, err := auth.Header(nil, auth.XRegistryAuthHeader, opts.Authfile, "", "")
+ header, err := auth.Header(nil, auth.XRegistryAuthHeader, options.GetAuthfile(), "", "")
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go
index c827b3283..5669c704e 100644
--- a/pkg/bindings/images/pull.go
+++ b/pkg/bindings/images/pull.go
@@ -8,11 +8,9 @@ import (
"io"
"io/ioutil"
"net/http"
- "net/url"
"os"
"strconv"
- "github.com/containers/image/v5/types"
"github.com/containers/podman/v2/pkg/auth"
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/domain/entities"
@@ -23,26 +21,28 @@ import (
// `rawImage` must be a reference to a registry (i.e., of docker transport or be
// normalized to one). Other transports are rejected as they do not make sense
// in a remote context. Progress reported on stderr
-func Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) ([]string, error) {
+func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string, error) {
+ if options == nil {
+ options = new(PullOptions)
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params := url.Values{}
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
+ }
params.Set("reference", rawImage)
- params.Set("overrideArch", options.OverrideArch)
- params.Set("overrideOS", options.OverrideOS)
- params.Set("overrideVariant", options.OverrideVariant)
- if options.SkipTLSVerify != types.OptionalBoolUndefined {
+ if options.SkipTLSVerify != nil {
+ params.Del("SkipTLSVerify")
// Note: we have to verify if skipped is false.
- verifyTLS := bool(options.SkipTLSVerify == types.OptionalBoolFalse)
- params.Set("tlsVerify", strconv.FormatBool(verifyTLS))
+ params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify()))
}
- params.Set("allTags", strconv.FormatBool(options.AllTags))
// TODO: have a global system context we can pass around (1st argument)
- header, err := auth.Header(nil, auth.XRegistryAuthHeader, options.Authfile, options.Username, options.Password)
+ header, err := auth.Header(nil, auth.XRegistryAuthHeader, options.GetAuthfile(), options.GetUsername(), options.GetPassword())
if err != nil {
return nil, err
}
@@ -59,7 +59,7 @@ func Pull(ctx context.Context, rawImage string, options entities.ImagePullOption
// Historically pull writes status to stderr
stderr := io.Writer(os.Stderr)
- if options.Quiet {
+ if options.GetQuiet() {
stderr = ioutil.Discard
}
diff --git a/pkg/bindings/images/rm.go b/pkg/bindings/images/rm.go
index 0b3b88165..e652e66aa 100644
--- a/pkg/bindings/images/rm.go
+++ b/pkg/bindings/images/rm.go
@@ -3,8 +3,6 @@ package images
import (
"context"
"net/http"
- "net/url"
- "strconv"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/bindings"
@@ -12,8 +10,12 @@ import (
"github.com/containers/podman/v2/pkg/errorhandling"
)
-// BachtRemove removes a batch of images from the local storage.
-func BatchRemove(ctx context.Context, images []string, opts entities.ImageRemoveOptions) (*entities.ImageRemoveReport, []error) {
+// Remove removes one or more images from the local storage. Use optional force option to remove an
+// image, even if it's used by containers.
+func Remove(ctx context.Context, images []string, options *RemoveOptions) (*entities.ImageRemoveReport, []error) {
+ if options == nil {
+ options = new(RemoveOptions)
+ }
// FIXME - bindings tests are missing for this endpoint. Once the CI is
// re-enabled for bindings, we need to add them. At the time of writing,
// the tests don't compile.
@@ -23,13 +25,13 @@ func BatchRemove(ctx context.Context, images []string, opts entities.ImageRemove
return nil, []error{err}
}
- params := url.Values{}
- params.Set("all", strconv.FormatBool(opts.All))
- params.Set("force", strconv.FormatBool(opts.Force))
- for _, i := range images {
- params.Add("images", i)
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, nil
+ }
+ for _, image := range images {
+ params.Add("images", image)
}
-
response, err := conn.DoRequest(nil, http.MethodDelete, "/images/remove", params, nil)
if err != nil {
return nil, []error{err}
@@ -40,28 +42,3 @@ func BatchRemove(ctx context.Context, images []string, opts entities.ImageRemove
return &report.ImageRemoveReport, errorhandling.StringsToErrors(report.Errors)
}
-
-// Remove removes an image from the local storage. Use optional force option to remove an
-// image, even if it's used by containers.
-func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) (*entities.ImageRemoveReport, error) {
- var report handlers.LibpodImagesRemoveReport
- conn, err := bindings.GetClient(ctx)
- if err != nil {
- return nil, err
- }
-
- params, err := options.ToParams()
- if err != nil {
- return nil, err
- }
- response, err := conn.DoRequest(nil, http.MethodDelete, "/images/%s", params, nil, nameOrID)
- if err != nil {
- return nil, err
- }
- if err := response.Process(&report); err != nil {
- return nil, err
- }
-
- errs := errorhandling.StringsToErrors(report.Errors)
- return &report.ImageRemoveReport, errorhandling.JoinErrors(errs)
-}
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 340c7bdb9..c436413c3 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -1,8 +1,193 @@
package images
+import (
+ "github.com/containers/buildah/imagebuildah"
+ "github.com/containers/common/pkg/config"
+)
+
//go:generate go run ../generator/generator.go RemoveOptions
// RemoveOptions are optional options for image removal
type RemoveOptions struct {
+ // All removes all images
+ All *bool
// Forces removes all containers based on the image
Force *bool
}
+
+//go:generate go run ../generator/generator.go DiffOptions
+// DiffOptions are optional options image diffs
+type DiffOptions struct {
+}
+
+//go:generate go run ../generator/generator.go ListOptions
+// ListOptions are optional options for listing images
+type ListOptions struct {
+ // All lists all image in the image store including dangling images
+ All *bool
+ // filters that can be used to get a more specific list of images
+ Filters map[string][]string
+}
+
+//go:generate go run ../generator/generator.go GetOptions
+// GetOptions are optional options for inspecting an image
+type GetOptions struct {
+ // Size computes the amount of storage the image consumes
+ Size *bool
+}
+
+//go:generate go run ../generator/generator.go TreeOptions
+// TreeOptions are optional options for a tree-based representation
+// of the image
+type TreeOptions struct {
+ // WhatRequires ...
+ WhatRequires *bool
+}
+
+//go:generate go run ../generator/generator.go HistoryOptions
+// HistoryOptions are optional options image history
+type HistoryOptions struct {
+}
+
+//go:generate go run ../generator/generator.go LoadOptions
+// LoadOptions are optional options for loading an image
+type LoadOptions struct {
+ // Reference is the name of the loaded image
+ Reference *string
+}
+
+//go:generate go run ../generator/generator.go ExportOptions
+// ExportOptions are optional options for exporting images
+type ExportOptions struct {
+ // Compress the image
+ Compress *bool
+ // Format of the output
+ Format *string
+}
+
+//go:generate go run ../generator/generator.go PruneOptions
+// PruneOptions are optional options for pruning images
+type PruneOptions struct {
+ // Prune all images
+ All *bool
+ // Filters to apply when pruning images
+ Filters map[string][]string
+}
+
+//go:generate go run ../generator/generator.go TagOptions
+// TagOptions are optional options for tagging images
+type TagOptions struct {
+}
+
+//go:generate go run ../generator/generator.go UntagOptions
+// UntagOptions are optional options for tagging images
+type UntagOptions struct {
+}
+
+//go:generate go run ../generator/generator.go ImportOptions
+// ImportOptions are optional options for importing images
+type ImportOptions struct {
+ // Changes to be applied to the image
+ Changes *[]string
+ // Message to be applied to the image
+ Message *string
+ // Reference is a tag to be applied to the image
+ Reference *string
+ // Url to option image to import. Cannot be used with the reader
+ URL *string
+}
+
+//go:generate go run ../generator/generator.go PushOptions
+// PushOptions are optional options for importing images
+type PushOptions struct {
+ // Authfile is the path to the authentication file. Ignored for remote
+ // calls.
+ Authfile *string
+ // CertDir is the path to certificate directories. Ignored for remote
+ // calls.
+ CertDir *string
+ // Compress tarball image layers when pushing to a directory using the 'dir'
+ // transport. Default is same compression type as source. Ignored for remote
+ // calls.
+ Compress *bool
+ // Username for authenticating against the registry.
+ Username *string
+ // Password for authenticating against the registry.
+ Password *string
+ // DigestFile, after copying the image, write the digest of the resulting
+ // image to the file. Ignored for remote calls.
+ DigestFile *string
+ // Format is the Manifest type (oci, v2s1, or v2s2) to use when pushing an
+ // image using the 'dir' transport. Default is manifest type of source.
+ // Ignored for remote calls.
+ Format *string
+ // Quiet can be specified to suppress pull progress when pulling. Ignored
+ // for remote calls.
+ Quiet *bool
+ // RemoveSignatures, discard any pre-existing signatures in the image.
+ // Ignored for remote calls.
+ RemoveSignatures *bool
+ // SignaturePolicy to use when pulling. Ignored for remote calls.
+ SignaturePolicy *string
+ // SignBy adds a signature at the destination using the specified key.
+ // Ignored for remote calls.
+ SignBy *string
+ // SkipTLSVerify to skip HTTPS and certificate verification.
+ SkipTLSVerify *bool
+}
+
+//go:generate go run ../generator/generator.go SearchOptions
+// SearchOptions are optional options for seaching images on registies
+type SearchOptions struct {
+ // Authfile is the path to the authentication file. Ignored for remote
+ // calls.
+ Authfile *string
+ // Filters for the search results.
+ Filters map[string][]string
+ // Limit the number of results.
+ Limit *int
+ // NoTrunc will not truncate the output.
+ NoTrunc *bool
+ // SkipTLSVerify to skip HTTPS and certificate verification.
+ SkipTLSVerify *bool
+ // ListTags search the available tags of the repository
+ ListTags *bool
+}
+
+//go:generate go run ../generator/generator.go PullOptions
+// PullOptions are optional options for pulling images
+type PullOptions struct {
+ // AllTags can be specified to pull all tags of an image. Note
+ // that this only works if the image does not include a tag.
+ AllTags *bool
+ // Authfile is the path to the authentication file. Ignored for remote
+ // calls.
+ Authfile *string
+ // CertDir is the path to certificate directories. Ignored for remote
+ // calls.
+ CertDir *string
+ // Username for authenticating against the registry.
+ Username *string
+ // Password for authenticating against the registry.
+ Password *string
+ // OverrideArch will overwrite the local architecture for image pulls.
+ OverrideArch *string
+ // OverrideOS will overwrite the local operating system (OS) for image
+ // pulls.
+ OverrideOS *string
+ // OverrideVariant will overwrite the local variant for image pulls.
+ OverrideVariant *string
+ // Quiet can be specified to suppress pull progress when pulling. Ignored
+ // for remote calls.
+ Quiet *bool
+ // SignaturePolicy to use when pulling. Ignored for remote calls.
+ SignaturePolicy *string
+ // SkipTLSVerify to skip HTTPS and certificate verification.
+ SkipTLSVerify *bool
+ // PullPolicy whether to pull new image
+ PullPolicy *config.PullPolicy
+}
+
+//BuildOptions are optional options for building images
+type BuildOptions struct {
+ imagebuildah.BuildOptions
+}
diff --git a/pkg/bindings/images/removeoptions_types.go b/pkg/bindings/images/types_diff_options.go
index 5902bf908..45e548056 100644
--- a/pkg/bindings/images/removeoptions_types.go
+++ b/pkg/bindings/images/types_diff_options.go
@@ -12,18 +12,18 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-Created 2020-12-10 12:51:06.090426622 -0600 CST m=+0.000133169
+Created 2020-12-15 15:22:46.528172042 -0600 CST m=+0.000279712
*/
// Changed
-func (o *RemoveOptions) Changed(fieldName string) bool {
+func (o *DiffOptions) Changed(fieldName string) bool {
r := reflect.ValueOf(o)
value := reflect.Indirect(r).FieldByName(fieldName)
return !value.IsNil()
}
// ToParams
-func (o *RemoveOptions) ToParams() (url.Values, error) {
+func (o *DiffOptions) ToParams() (url.Values, error) {
params := url.Values{}
if o == nil {
return params, nil
@@ -68,10 +68,11 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
}
case reflect.Map:
lowerCaseKeys := make(map[string][]string)
- // I dont know if this code is needed anymore, TBD
- // for k, v := range filters {
- // lowerCaseKeys[strings.ToLower(k)] = v
- // }
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
s, err := json.MarshalToString(lowerCaseKeys)
if err != nil {
return nil, err
@@ -84,10 +85,3 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
}
return params, nil
}
-
-// WithForce
-func (o *RemoveOptions) WithForce(value bool) *RemoveOptions {
- v := &value
- o.Force = v
- return o
-}
diff --git a/pkg/bindings/images/types_export_options.go b/pkg/bindings/images/types_export_options.go
new file mode 100644
index 000000000..ae585ae3e
--- /dev/null
+++ b/pkg/bindings/images/types_export_options.go
@@ -0,0 +1,119 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:47.379804635 -0600 CST m=+0.000257609
+*/
+
+// Changed
+func (o *ExportOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *ExportOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithCompress
+func (o *ExportOptions) WithCompress(value bool) *ExportOptions {
+ v := &value
+ o.Compress = v
+ return o
+}
+
+// GetCompress
+func (o *ExportOptions) GetCompress() bool {
+ var compress bool
+ if o.Compress == nil {
+ return compress
+ }
+ return *o.Compress
+}
+
+// WithFormat
+func (o *ExportOptions) WithFormat(value string) *ExportOptions {
+ v := &value
+ o.Format = v
+ return o
+}
+
+// GetFormat
+func (o *ExportOptions) GetFormat() string {
+ var format string
+ if o.Format == nil {
+ return format
+ }
+ return *o.Format
+}
diff --git a/pkg/bindings/images/types_get_options.go b/pkg/bindings/images/types_get_options.go
new file mode 100644
index 000000000..b7b45259d
--- /dev/null
+++ b/pkg/bindings/images/types_get_options.go
@@ -0,0 +1,103 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:46.81312808 -0600 CST m=+0.000257734
+*/
+
+// Changed
+func (o *GetOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *GetOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithSize
+func (o *GetOptions) WithSize(value bool) *GetOptions {
+ v := &value
+ o.Size = v
+ return o
+}
+
+// GetSize
+func (o *GetOptions) GetSize() bool {
+ var size bool
+ if o.Size == nil {
+ return size
+ }
+ return *o.Size
+}
diff --git a/pkg/bindings/images/types_history_options.go b/pkg/bindings/images/types_history_options.go
new file mode 100644
index 000000000..0fe73a990
--- /dev/null
+++ b/pkg/bindings/images/types_history_options.go
@@ -0,0 +1,87 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:47.095693605 -0600 CST m=+0.000243849
+*/
+
+// Changed
+func (o *HistoryOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *HistoryOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
diff --git a/pkg/bindings/images/types_import_options.go b/pkg/bindings/images/types_import_options.go
new file mode 100644
index 000000000..002f1cfa5
--- /dev/null
+++ b/pkg/bindings/images/types_import_options.go
@@ -0,0 +1,151 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:47.943587389 -0600 CST m=+0.000238222
+*/
+
+// Changed
+func (o *ImportOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *ImportOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithChanges
+func (o *ImportOptions) WithChanges(value []string) *ImportOptions {
+ v := &value
+ o.Changes = v
+ return o
+}
+
+// GetChanges
+func (o *ImportOptions) GetChanges() []string {
+ var changes []string
+ if o.Changes == nil {
+ return changes
+ }
+ return *o.Changes
+}
+
+// WithMessage
+func (o *ImportOptions) WithMessage(value string) *ImportOptions {
+ v := &value
+ o.Message = v
+ return o
+}
+
+// GetMessage
+func (o *ImportOptions) GetMessage() string {
+ var message string
+ if o.Message == nil {
+ return message
+ }
+ return *o.Message
+}
+
+// WithReference
+func (o *ImportOptions) WithReference(value string) *ImportOptions {
+ v := &value
+ o.Reference = v
+ return o
+}
+
+// GetReference
+func (o *ImportOptions) GetReference() string {
+ var reference string
+ if o.Reference == nil {
+ return reference
+ }
+ return *o.Reference
+}
+
+// WithURL
+func (o *ImportOptions) WithURL(value string) *ImportOptions {
+ v := &value
+ o.URL = v
+ return o
+}
+
+// GetURL
+func (o *ImportOptions) GetURL() string {
+ var uRL string
+ if o.URL == nil {
+ return uRL
+ }
+ return *o.URL
+}
diff --git a/pkg/bindings/images/types_list_options.go b/pkg/bindings/images/types_list_options.go
new file mode 100644
index 000000000..0cdb243fa
--- /dev/null
+++ b/pkg/bindings/images/types_list_options.go
@@ -0,0 +1,119 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:46.671238196 -0600 CST m=+0.000266757
+*/
+
+// Changed
+func (o *ListOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *ListOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithAll
+func (o *ListOptions) WithAll(value bool) *ListOptions {
+ v := &value
+ o.All = v
+ return o
+}
+
+// GetAll
+func (o *ListOptions) GetAll() bool {
+ var all bool
+ if o.All == nil {
+ return all
+ }
+ return *o.All
+}
+
+// WithFilters
+func (o *ListOptions) WithFilters(value map[string][]string) *ListOptions {
+ v := value
+ o.Filters = v
+ return o
+}
+
+// GetFilters
+func (o *ListOptions) GetFilters() map[string][]string {
+ var filters map[string][]string
+ if o.Filters == nil {
+ return filters
+ }
+ return o.Filters
+}
diff --git a/pkg/bindings/images/types_load_options.go b/pkg/bindings/images/types_load_options.go
new file mode 100644
index 000000000..a82521749
--- /dev/null
+++ b/pkg/bindings/images/types_load_options.go
@@ -0,0 +1,103 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:47.237599061 -0600 CST m=+0.000247138
+*/
+
+// Changed
+func (o *LoadOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *LoadOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithReference
+func (o *LoadOptions) WithReference(value string) *LoadOptions {
+ v := &value
+ o.Reference = v
+ return o
+}
+
+// GetReference
+func (o *LoadOptions) GetReference() string {
+ var reference string
+ if o.Reference == nil {
+ return reference
+ }
+ return *o.Reference
+}
diff --git a/pkg/bindings/images/types_prune_options.go b/pkg/bindings/images/types_prune_options.go
new file mode 100644
index 000000000..25da5e815
--- /dev/null
+++ b/pkg/bindings/images/types_prune_options.go
@@ -0,0 +1,119 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:47.521471344 -0600 CST m=+0.000250491
+*/
+
+// Changed
+func (o *PruneOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *PruneOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithAll
+func (o *PruneOptions) WithAll(value bool) *PruneOptions {
+ v := &value
+ o.All = v
+ return o
+}
+
+// GetAll
+func (o *PruneOptions) GetAll() bool {
+ var all bool
+ if o.All == nil {
+ return all
+ }
+ return *o.All
+}
+
+// WithFilters
+func (o *PruneOptions) WithFilters(value map[string][]string) *PruneOptions {
+ v := value
+ o.Filters = v
+ return o
+}
+
+// GetFilters
+func (o *PruneOptions) GetFilters() map[string][]string {
+ var filters map[string][]string
+ if o.Filters == nil {
+ return filters
+ }
+ return o.Filters
+}
diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go
new file mode 100644
index 000000000..10d0c53e8
--- /dev/null
+++ b/pkg/bindings/images/types_pull_options.go
@@ -0,0 +1,280 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ "github.com/containers/common/pkg/config"
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:48.373345229 -0600 CST m=+0.000247562
+*/
+
+// Changed
+func (o *PullOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *PullOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithAllTags
+func (o *PullOptions) WithAllTags(value bool) *PullOptions {
+ v := &value
+ o.AllTags = v
+ return o
+}
+
+// GetAllTags
+func (o *PullOptions) GetAllTags() bool {
+ var allTags bool
+ if o.AllTags == nil {
+ return allTags
+ }
+ return *o.AllTags
+}
+
+// WithAuthfile
+func (o *PullOptions) WithAuthfile(value string) *PullOptions {
+ v := &value
+ o.Authfile = v
+ return o
+}
+
+// GetAuthfile
+func (o *PullOptions) GetAuthfile() string {
+ var authfile string
+ if o.Authfile == nil {
+ return authfile
+ }
+ return *o.Authfile
+}
+
+// WithCertDir
+func (o *PullOptions) WithCertDir(value string) *PullOptions {
+ v := &value
+ o.CertDir = v
+ return o
+}
+
+// GetCertDir
+func (o *PullOptions) GetCertDir() string {
+ var certDir string
+ if o.CertDir == nil {
+ return certDir
+ }
+ return *o.CertDir
+}
+
+// WithUsername
+func (o *PullOptions) WithUsername(value string) *PullOptions {
+ v := &value
+ o.Username = v
+ return o
+}
+
+// GetUsername
+func (o *PullOptions) GetUsername() string {
+ var username string
+ if o.Username == nil {
+ return username
+ }
+ return *o.Username
+}
+
+// WithPassword
+func (o *PullOptions) WithPassword(value string) *PullOptions {
+ v := &value
+ o.Password = v
+ return o
+}
+
+// GetPassword
+func (o *PullOptions) GetPassword() string {
+ var password string
+ if o.Password == nil {
+ return password
+ }
+ return *o.Password
+}
+
+// WithOverrideArch
+func (o *PullOptions) WithOverrideArch(value string) *PullOptions {
+ v := &value
+ o.OverrideArch = v
+ return o
+}
+
+// GetOverrideArch
+func (o *PullOptions) GetOverrideArch() string {
+ var overrideArch string
+ if o.OverrideArch == nil {
+ return overrideArch
+ }
+ return *o.OverrideArch
+}
+
+// WithOverrideOS
+func (o *PullOptions) WithOverrideOS(value string) *PullOptions {
+ v := &value
+ o.OverrideOS = v
+ return o
+}
+
+// GetOverrideOS
+func (o *PullOptions) GetOverrideOS() string {
+ var overrideOS string
+ if o.OverrideOS == nil {
+ return overrideOS
+ }
+ return *o.OverrideOS
+}
+
+// WithOverrideVariant
+func (o *PullOptions) WithOverrideVariant(value string) *PullOptions {
+ v := &value
+ o.OverrideVariant = v
+ return o
+}
+
+// GetOverrideVariant
+func (o *PullOptions) GetOverrideVariant() string {
+ var overrideVariant string
+ if o.OverrideVariant == nil {
+ return overrideVariant
+ }
+ return *o.OverrideVariant
+}
+
+// WithQuiet
+func (o *PullOptions) WithQuiet(value bool) *PullOptions {
+ v := &value
+ o.Quiet = v
+ return o
+}
+
+// GetQuiet
+func (o *PullOptions) GetQuiet() bool {
+ var quiet bool
+ if o.Quiet == nil {
+ return quiet
+ }
+ return *o.Quiet
+}
+
+// WithSignaturePolicy
+func (o *PullOptions) WithSignaturePolicy(value string) *PullOptions {
+ v := &value
+ o.SignaturePolicy = v
+ return o
+}
+
+// GetSignaturePolicy
+func (o *PullOptions) GetSignaturePolicy() string {
+ var signaturePolicy string
+ if o.SignaturePolicy == nil {
+ return signaturePolicy
+ }
+ return *o.SignaturePolicy
+}
+
+// WithSkipTLSVerify
+func (o *PullOptions) WithSkipTLSVerify(value bool) *PullOptions {
+ v := &value
+ o.SkipTLSVerify = v
+ return o
+}
+
+// GetSkipTLSVerify
+func (o *PullOptions) GetSkipTLSVerify() bool {
+ var skipTLSVerify bool
+ if o.SkipTLSVerify == nil {
+ return skipTLSVerify
+ }
+ return *o.SkipTLSVerify
+}
+
+// WithPullPolicy
+func (o *PullOptions) WithPullPolicy(value config.PullPolicy) *PullOptions {
+ v := &value
+ o.PullPolicy = v
+ return o
+}
+
+// GetPullPolicy
+func (o *PullOptions) GetPullPolicy() config.PullPolicy {
+ var pullPolicy config.PullPolicy
+ if o.PullPolicy == nil {
+ return pullPolicy
+ }
+ return *o.PullPolicy
+}
diff --git a/pkg/bindings/images/types_push_options.go b/pkg/bindings/images/types_push_options.go
new file mode 100644
index 000000000..2440d4c0f
--- /dev/null
+++ b/pkg/bindings/images/types_push_options.go
@@ -0,0 +1,279 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:48.08540302 -0600 CST m=+0.000302026
+*/
+
+// Changed
+func (o *PushOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *PushOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithAuthfile
+func (o *PushOptions) WithAuthfile(value string) *PushOptions {
+ v := &value
+ o.Authfile = v
+ return o
+}
+
+// GetAuthfile
+func (o *PushOptions) GetAuthfile() string {
+ var authfile string
+ if o.Authfile == nil {
+ return authfile
+ }
+ return *o.Authfile
+}
+
+// WithCertDir
+func (o *PushOptions) WithCertDir(value string) *PushOptions {
+ v := &value
+ o.CertDir = v
+ return o
+}
+
+// GetCertDir
+func (o *PushOptions) GetCertDir() string {
+ var certDir string
+ if o.CertDir == nil {
+ return certDir
+ }
+ return *o.CertDir
+}
+
+// WithCompress
+func (o *PushOptions) WithCompress(value bool) *PushOptions {
+ v := &value
+ o.Compress = v
+ return o
+}
+
+// GetCompress
+func (o *PushOptions) GetCompress() bool {
+ var compress bool
+ if o.Compress == nil {
+ return compress
+ }
+ return *o.Compress
+}
+
+// WithUsername
+func (o *PushOptions) WithUsername(value string) *PushOptions {
+ v := &value
+ o.Username = v
+ return o
+}
+
+// GetUsername
+func (o *PushOptions) GetUsername() string {
+ var username string
+ if o.Username == nil {
+ return username
+ }
+ return *o.Username
+}
+
+// WithPassword
+func (o *PushOptions) WithPassword(value string) *PushOptions {
+ v := &value
+ o.Password = v
+ return o
+}
+
+// GetPassword
+func (o *PushOptions) GetPassword() string {
+ var password string
+ if o.Password == nil {
+ return password
+ }
+ return *o.Password
+}
+
+// WithDigestFile
+func (o *PushOptions) WithDigestFile(value string) *PushOptions {
+ v := &value
+ o.DigestFile = v
+ return o
+}
+
+// GetDigestFile
+func (o *PushOptions) GetDigestFile() string {
+ var digestFile string
+ if o.DigestFile == nil {
+ return digestFile
+ }
+ return *o.DigestFile
+}
+
+// WithFormat
+func (o *PushOptions) WithFormat(value string) *PushOptions {
+ v := &value
+ o.Format = v
+ return o
+}
+
+// GetFormat
+func (o *PushOptions) GetFormat() string {
+ var format string
+ if o.Format == nil {
+ return format
+ }
+ return *o.Format
+}
+
+// WithQuiet
+func (o *PushOptions) WithQuiet(value bool) *PushOptions {
+ v := &value
+ o.Quiet = v
+ return o
+}
+
+// GetQuiet
+func (o *PushOptions) GetQuiet() bool {
+ var quiet bool
+ if o.Quiet == nil {
+ return quiet
+ }
+ return *o.Quiet
+}
+
+// WithRemoveSignatures
+func (o *PushOptions) WithRemoveSignatures(value bool) *PushOptions {
+ v := &value
+ o.RemoveSignatures = v
+ return o
+}
+
+// GetRemoveSignatures
+func (o *PushOptions) GetRemoveSignatures() bool {
+ var removeSignatures bool
+ if o.RemoveSignatures == nil {
+ return removeSignatures
+ }
+ return *o.RemoveSignatures
+}
+
+// WithSignaturePolicy
+func (o *PushOptions) WithSignaturePolicy(value string) *PushOptions {
+ v := &value
+ o.SignaturePolicy = v
+ return o
+}
+
+// GetSignaturePolicy
+func (o *PushOptions) GetSignaturePolicy() string {
+ var signaturePolicy string
+ if o.SignaturePolicy == nil {
+ return signaturePolicy
+ }
+ return *o.SignaturePolicy
+}
+
+// WithSignBy
+func (o *PushOptions) WithSignBy(value string) *PushOptions {
+ v := &value
+ o.SignBy = v
+ return o
+}
+
+// GetSignBy
+func (o *PushOptions) GetSignBy() string {
+ var signBy string
+ if o.SignBy == nil {
+ return signBy
+ }
+ return *o.SignBy
+}
+
+// WithSkipTLSVerify
+func (o *PushOptions) WithSkipTLSVerify(value bool) *PushOptions {
+ v := &value
+ o.SkipTLSVerify = v
+ return o
+}
+
+// GetSkipTLSVerify
+func (o *PushOptions) GetSkipTLSVerify() bool {
+ var skipTLSVerify bool
+ if o.SkipTLSVerify == nil {
+ return skipTLSVerify
+ }
+ return *o.SkipTLSVerify
+}
diff --git a/pkg/bindings/images/types_remove_options.go b/pkg/bindings/images/types_remove_options.go
new file mode 100644
index 000000000..164ea1b3e
--- /dev/null
+++ b/pkg/bindings/images/types_remove_options.go
@@ -0,0 +1,119 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:46.378166859 -0600 CST m=+0.000249384
+*/
+
+// Changed
+func (o *RemoveOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *RemoveOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithAll
+func (o *RemoveOptions) WithAll(value bool) *RemoveOptions {
+ v := &value
+ o.All = v
+ return o
+}
+
+// GetAll
+func (o *RemoveOptions) GetAll() bool {
+ var all bool
+ if o.All == nil {
+ return all
+ }
+ return *o.All
+}
+
+// WithForce
+func (o *RemoveOptions) WithForce(value bool) *RemoveOptions {
+ v := &value
+ o.Force = v
+ return o
+}
+
+// GetForce
+func (o *RemoveOptions) GetForce() bool {
+ var force bool
+ if o.Force == nil {
+ return force
+ }
+ return *o.Force
+}
diff --git a/pkg/bindings/images/types_search_options.go b/pkg/bindings/images/types_search_options.go
new file mode 100644
index 000000000..b0b413a6c
--- /dev/null
+++ b/pkg/bindings/images/types_search_options.go
@@ -0,0 +1,183 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:48.229349981 -0600 CST m=+0.000244343
+*/
+
+// Changed
+func (o *SearchOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *SearchOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithAuthfile
+func (o *SearchOptions) WithAuthfile(value string) *SearchOptions {
+ v := &value
+ o.Authfile = v
+ return o
+}
+
+// GetAuthfile
+func (o *SearchOptions) GetAuthfile() string {
+ var authfile string
+ if o.Authfile == nil {
+ return authfile
+ }
+ return *o.Authfile
+}
+
+// WithFilters
+func (o *SearchOptions) WithFilters(value map[string][]string) *SearchOptions {
+ v := value
+ o.Filters = v
+ return o
+}
+
+// GetFilters
+func (o *SearchOptions) GetFilters() map[string][]string {
+ var filters map[string][]string
+ if o.Filters == nil {
+ return filters
+ }
+ return o.Filters
+}
+
+// WithLimit
+func (o *SearchOptions) WithLimit(value int) *SearchOptions {
+ v := &value
+ o.Limit = v
+ return o
+}
+
+// GetLimit
+func (o *SearchOptions) GetLimit() int {
+ var limit int
+ if o.Limit == nil {
+ return limit
+ }
+ return *o.Limit
+}
+
+// WithNoTrunc
+func (o *SearchOptions) WithNoTrunc(value bool) *SearchOptions {
+ v := &value
+ o.NoTrunc = v
+ return o
+}
+
+// GetNoTrunc
+func (o *SearchOptions) GetNoTrunc() bool {
+ var noTrunc bool
+ if o.NoTrunc == nil {
+ return noTrunc
+ }
+ return *o.NoTrunc
+}
+
+// WithSkipTLSVerify
+func (o *SearchOptions) WithSkipTLSVerify(value bool) *SearchOptions {
+ v := &value
+ o.SkipTLSVerify = v
+ return o
+}
+
+// GetSkipTLSVerify
+func (o *SearchOptions) GetSkipTLSVerify() bool {
+ var skipTLSVerify bool
+ if o.SkipTLSVerify == nil {
+ return skipTLSVerify
+ }
+ return *o.SkipTLSVerify
+}
+
+// WithListTags
+func (o *SearchOptions) WithListTags(value bool) *SearchOptions {
+ v := &value
+ o.ListTags = v
+ return o
+}
+
+// GetListTags
+func (o *SearchOptions) GetListTags() bool {
+ var listTags bool
+ if o.ListTags == nil {
+ return listTags
+ }
+ return *o.ListTags
+}
diff --git a/pkg/bindings/images/types_tag_options.go b/pkg/bindings/images/types_tag_options.go
new file mode 100644
index 000000000..5efc6462e
--- /dev/null
+++ b/pkg/bindings/images/types_tag_options.go
@@ -0,0 +1,87 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:47.66229668 -0600 CST m=+0.000246630
+*/
+
+// Changed
+func (o *TagOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *TagOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
diff --git a/pkg/bindings/images/types_tree_options.go b/pkg/bindings/images/types_tree_options.go
new file mode 100644
index 000000000..cca663c67
--- /dev/null
+++ b/pkg/bindings/images/types_tree_options.go
@@ -0,0 +1,103 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:46.954579136 -0600 CST m=+0.000248704
+*/
+
+// Changed
+func (o *TreeOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *TreeOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
+
+// WithWhatRequires
+func (o *TreeOptions) WithWhatRequires(value bool) *TreeOptions {
+ v := &value
+ o.WhatRequires = v
+ return o
+}
+
+// GetWhatRequires
+func (o *TreeOptions) GetWhatRequires() bool {
+ var whatRequires bool
+ if o.WhatRequires == nil {
+ return whatRequires
+ }
+ return *o.WhatRequires
+}
diff --git a/pkg/bindings/images/types_untag_options.go b/pkg/bindings/images/types_untag_options.go
new file mode 100644
index 000000000..d960f6b40
--- /dev/null
+++ b/pkg/bindings/images/types_untag_options.go
@@ -0,0 +1,87 @@
+package images
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-15 15:22:47.802372989 -0600 CST m=+0.000239766
+*/
+
+// Changed
+func (o *UntagOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *UntagOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ default:
+ return nil, errors.Errorf("unknown type %s", f.Kind().String())
+ }
+ }
+ return params, nil
+}
diff --git a/pkg/bindings/test/auth_test.go b/pkg/bindings/test/auth_test.go
index 4565b82b0..e647b3c36 100644
--- a/pkg/bindings/test/auth_test.go
+++ b/pkg/bindings/test/auth_test.go
@@ -9,7 +9,6 @@ import (
"github.com/containers/image/v5/types"
podmanRegistry "github.com/containers/podman/v2/hack/podman-registry-go"
"github.com/containers/podman/v2/pkg/bindings/images"
- "github.com/containers/podman/v2/pkg/domain/entities"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -52,27 +51,19 @@ var _ = Describe("Podman images", func() {
imageRef := imageRep + ":" + imageTag
// Tag the alpine image and verify it has worked.
- err = images.Tag(bt.conn, alpine.shortName, imageTag, imageRep)
+ err = images.Tag(bt.conn, alpine.shortName, imageTag, imageRep, nil)
Expect(err).To(BeNil())
_, err = images.GetImage(bt.conn, imageRef, nil)
Expect(err).To(BeNil())
// Now push the image.
- pushOpts := entities.ImagePushOptions{
- Username: registry.User,
- Password: registry.Password,
- SkipTLSVerify: types.OptionalBoolTrue,
- }
- err = images.Push(bt.conn, imageRef, imageRef, pushOpts)
+ pushOpts := new(images.PushOptions)
+ err = images.Push(bt.conn, imageRef, imageRef, pushOpts.WithUsername(registry.User).WithPassword(registry.Password).WithSkipTLSVerify(true))
Expect(err).To(BeNil())
// Now pull the image.
- pullOpts := entities.ImagePullOptions{
- Username: registry.User,
- Password: registry.Password,
- SkipTLSVerify: types.OptionalBoolTrue,
- }
- _, err = images.Pull(bt.conn, imageRef, pullOpts)
+ pullOpts := new(images.PullOptions)
+ _, err = images.Pull(bt.conn, imageRef, pullOpts.WithSkipTLSVerify(true).WithPassword(registry.Password).WithUsername(registry.User))
Expect(err).To(BeNil())
})
@@ -110,33 +101,24 @@ var _ = Describe("Podman images", func() {
Expect(err).To(BeNil())
// Tag the alpine image and verify it has worked.
- err = images.Tag(bt.conn, alpine.shortName, imageTag, imageRep)
+ err = images.Tag(bt.conn, alpine.shortName, imageTag, imageRep, nil)
Expect(err).To(BeNil())
_, err = images.GetImage(bt.conn, imageRef, nil)
Expect(err).To(BeNil())
// Now push the image.
- pushOpts := entities.ImagePushOptions{
- Authfile: authFilePath,
- SkipTLSVerify: types.OptionalBoolTrue,
- }
- err = images.Push(bt.conn, imageRef, imageRef, pushOpts)
+ pushOpts := new(images.PushOptions)
+ err = images.Push(bt.conn, imageRef, imageRef, pushOpts.WithAuthfile(authFilePath).WithSkipTLSVerify(true))
Expect(err).To(BeNil())
// Now pull the image.
- pullOpts := entities.ImagePullOptions{
- Authfile: authFilePath,
- SkipTLSVerify: types.OptionalBoolTrue,
- }
- _, err = images.Pull(bt.conn, imageRef, pullOpts)
+ pullOpts := new(images.PullOptions)
+ _, err = images.Pull(bt.conn, imageRef, pullOpts.WithAuthfile(authFilePath).WithSkipTLSVerify(true))
Expect(err).To(BeNil())
// Last, but not least, exercise search.
- searchOptions := entities.ImageSearchOptions{
- Authfile: authFilePath,
- SkipTLSVerify: types.OptionalBoolTrue,
- }
- _, err = images.Search(bt.conn, imageRef, searchOptions)
+ searchOptions := new(images.SearchOptions)
+ _, err = images.Search(bt.conn, imageRef, searchOptions.WithSkipTLSVerify(true).WithAuthfile(authFilePath))
Expect(err).To(BeNil())
})
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index 684f110e8..b6362a631 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -9,7 +9,6 @@ import (
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/bindings/images"
- "github.com/containers/podman/v2/pkg/domain/entities"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -75,8 +74,9 @@ var _ = Describe("Podman images", func() {
// of bool or not. What should we do ?
// Expect(data.Size).To(BeZero())
+ options := new(images.GetOptions).WithSize(true)
// Enabling the size parameter should result in size being populated
- data, err = images.GetImage(bt.conn, alpine.name, bindings.PTrue)
+ data, err = images.GetImage(bt.conn, alpine.name, options)
Expect(err).To(BeNil())
Expect(data.Size).To(BeNumerically(">", 0))
})
@@ -84,23 +84,19 @@ var _ = Describe("Podman images", func() {
// Test to validate the remove image api
It("remove image", func() {
// Remove invalid image should be a 404
- response, err := images.Remove(bt.conn, "foobar5000", nil)
- Expect(err).ToNot(BeNil())
- Expect(response).To(BeNil())
- code, _ := bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusNotFound))
+ response, errs := images.Remove(bt.conn, []string{"foobar5000"}, nil)
+ Expect(len(errs)).To(BeNumerically(">", 0))
+ code, _ := bindings.CheckResponseCode(errs[0])
// Remove an image by name, validate image is removed and error is nil
inspectData, err := images.GetImage(bt.conn, busybox.shortName, nil)
Expect(err).To(BeNil())
- response, err = images.Remove(bt.conn, busybox.shortName, nil)
- Expect(err).To(BeNil())
- code, _ = bindings.CheckResponseCode(err)
+ response, errs = images.Remove(bt.conn, []string{busybox.shortName}, nil)
+ Expect(len(errs)).To(BeZero())
Expect(inspectData.ID).To(Equal(response.Deleted[0]))
inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil)
code, _ = bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusNotFound))
// Start a container with alpine image
var top string = "top"
@@ -113,24 +109,21 @@ var _ = Describe("Podman images", func() {
// try to remove the image "alpine". This should fail since we are not force
// deleting hence image cannot be deleted until the container is deleted.
- response, err = images.Remove(bt.conn, alpine.shortName, nil)
- code, _ = bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusConflict))
+ response, errs = images.Remove(bt.conn, []string{alpine.shortName}, nil)
+ code, _ = bindings.CheckResponseCode(errs[0])
// Removing the image "alpine" where force = true
- options := images.RemoveOptions{}
- response, err = images.Remove(bt.conn, alpine.shortName, options.WithForce(true))
- Expect(err).To(BeNil())
+ options := new(images.RemoveOptions).WithForce(true)
+ response, errs = images.Remove(bt.conn, []string{alpine.shortName}, options)
+ Expect(len(errs)).To(BeZero())
// To be extra sure, check if the previously created container
// is gone as well.
_, err = containers.Inspect(bt.conn, "top", bindings.PFalse)
code, _ = bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusNotFound))
// Now make sure both images are gone.
inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil)
code, _ = bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusNotFound))
inspectData, err = images.GetImage(bt.conn, alpine.shortName, nil)
code, _ = bindings.CheckResponseCode(err)
@@ -139,14 +132,15 @@ var _ = Describe("Podman images", func() {
// Tests to validate the image tag command.
It("tag image", func() {
+
// Validates if invalid image name is given a bad response is encountered.
- err = images.Tag(bt.conn, "dummy", "demo", alpine.shortName)
+ err = images.Tag(bt.conn, "dummy", "demo", alpine.shortName, nil)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
// Validates if the image is tagged successfully.
- err = images.Tag(bt.conn, alpine.shortName, "demo", alpine.shortName)
+ err = images.Tag(bt.conn, alpine.shortName, "demo", alpine.shortName, nil)
Expect(err).To(BeNil())
// Validates if name updates when the image is retagged.
@@ -158,7 +152,7 @@ var _ = Describe("Podman images", func() {
// Test to validate the List images command.
It("List image", func() {
// Array to hold the list of images returned
- imageSummary, err := images.List(bt.conn, nil, nil)
+ imageSummary, err := images.List(bt.conn, nil)
// There Should be no errors in the response.
Expect(err).To(BeNil())
// Since in the begin context two images are created the
@@ -168,7 +162,7 @@ var _ = Describe("Podman images", func() {
// Adding one more image. There Should be no errors in the response.
// And the count should be three now.
bt.Pull("testimage:20200929")
- imageSummary, err = images.List(bt.conn, nil, nil)
+ imageSummary, err = images.List(bt.conn, nil)
Expect(err).To(BeNil())
Expect(len(imageSummary)).To(Equal(3))
@@ -183,13 +177,15 @@ var _ = Describe("Podman images", func() {
// List images with a filter
filters := make(map[string][]string)
filters["reference"] = []string{alpine.name}
- filteredImages, err := images.List(bt.conn, bindings.PFalse, filters)
+ options := new(images.ListOptions).WithFilters(filters).WithAll(false)
+ filteredImages, err := images.List(bt.conn, options)
Expect(err).To(BeNil())
Expect(len(filteredImages)).To(BeNumerically("==", 1))
// List images with a bad filter
filters["name"] = []string{alpine.name}
- _, err = images.List(bt.conn, bindings.PFalse, filters)
+ options = new(images.ListOptions).WithFilters(filters)
+ _, err = images.List(bt.conn, options)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -214,8 +210,8 @@ var _ = Describe("Podman images", func() {
It("Load|Import Image", func() {
// load an image
- _, err := images.Remove(bt.conn, alpine.name, nil)
- Expect(err).To(BeNil())
+ _, errs := images.Remove(bt.conn, []string{alpine.name}, nil)
+ Expect(len(errs)).To(BeZero())
exists, err := images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeFalse())
@@ -232,13 +228,14 @@ var _ = Describe("Podman images", func() {
// load with a repo name
f, err = os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
Expect(err).To(BeNil())
- _, err = images.Remove(bt.conn, alpine.name, nil)
- Expect(err).To(BeNil())
+ _, errs = images.Remove(bt.conn, []string{alpine.name}, nil)
+ Expect(len(errs)).To(BeZero())
exists, err = images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeFalse())
newName := "quay.io/newname:fizzle"
- names, err = images.Load(bt.conn, f, &newName)
+ options := new(images.LoadOptions).WithReference(newName)
+ names, err = images.Load(bt.conn, f, options)
Expect(err).To(BeNil())
Expect(names.Names[0]).To(Equal(alpine.name))
exists, err = images.Exists(bt.conn, newName)
@@ -248,13 +245,13 @@ var _ = Describe("Podman images", func() {
// load with a bad repo name should trigger a 500
f, err = os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
Expect(err).To(BeNil())
- _, err = images.Remove(bt.conn, alpine.name, nil)
- Expect(err).To(BeNil())
+ _, errs = images.Remove(bt.conn, []string{alpine.name}, nil)
+ Expect(len(errs)).To(BeZero())
exists, err = images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeFalse())
- badName := "quay.io/newName:fizzle"
- _, err = images.Load(bt.conn, f, &badName)
+ options = new(images.LoadOptions).WithReference("quay.io/newName:fizzle")
+ _, err = images.Load(bt.conn, f, options)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -266,7 +263,7 @@ var _ = Describe("Podman images", func() {
w, err := os.Create(filepath.Join(bt.tempDirPath, alpine.tarballName))
defer w.Close()
Expect(err).To(BeNil())
- err = images.Export(bt.conn, alpine.name, w, nil, nil)
+ err = images.Export(bt.conn, []string{alpine.name}, w, nil)
Expect(err).To(BeNil())
_, err = os.Stat(exportPath)
Expect(err).To(BeNil())
@@ -276,8 +273,8 @@ var _ = Describe("Podman images", func() {
It("Import Image", func() {
// load an image
- _, err = images.Remove(bt.conn, alpine.name, nil)
- Expect(err).To(BeNil())
+ _, errs := images.Remove(bt.conn, []string{alpine.name}, nil)
+ Expect(len(errs)).To(BeZero())
exists, err := images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeFalse())
@@ -286,7 +283,8 @@ var _ = Describe("Podman images", func() {
Expect(err).To(BeNil())
changes := []string{"CMD /bin/foobar"}
testMessage := "test_import"
- _, err = images.Import(bt.conn, changes, &testMessage, &alpine.name, nil, f)
+ options := new(images.ImportOptions).WithMessage(testMessage).WithChanges(changes).WithReference(alpine.name)
+ _, err = images.Import(bt.conn, f, options)
Expect(err).To(BeNil())
exists, err = images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
@@ -299,7 +297,7 @@ var _ = Describe("Podman images", func() {
It("History Image", func() {
// a bogus name should return a 404
- _, err := images.History(bt.conn, "foobar")
+ _, err := images.History(bt.conn, "foobar", nil)
Expect(err).To(Not(BeNil()))
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
@@ -307,7 +305,7 @@ var _ = Describe("Podman images", func() {
var foundID bool
data, err := images.GetImage(bt.conn, alpine.name, nil)
Expect(err).To(BeNil())
- history, err := images.History(bt.conn, alpine.name)
+ history, err := images.History(bt.conn, alpine.name, nil)
Expect(err).To(BeNil())
for _, i := range history {
if i.ID == data.ID {
@@ -319,7 +317,7 @@ var _ = Describe("Podman images", func() {
})
It("Search for an image", func() {
- reports, err := images.Search(bt.conn, "alpine", entities.ImageSearchOptions{})
+ reports, err := images.Search(bt.conn, "alpine", nil)
Expect(err).To(BeNil())
Expect(len(reports)).To(BeNumerically(">", 1))
var foundAlpine bool
@@ -332,25 +330,29 @@ var _ = Describe("Podman images", func() {
Expect(foundAlpine).To(BeTrue())
// Search for alpine with a limit of 10
- reports, err = images.Search(bt.conn, "docker.io/alpine", entities.ImageSearchOptions{Limit: 10})
+ options := new(images.SearchOptions).WithLimit(10)
+ reports, err = images.Search(bt.conn, "docker.io/alpine", options)
Expect(err).To(BeNil())
Expect(len(reports)).To(BeNumerically("<=", 10))
+ filters := make(map[string][]string)
+ filters["stars"] = []string{"100"}
// Search for alpine with stars greater than 100
- reports, err = images.Search(bt.conn, "docker.io/alpine", entities.ImageSearchOptions{Filters: []string{"stars=100"}})
+ options = new(images.SearchOptions).WithFilters(filters)
+ reports, err = images.Search(bt.conn, "docker.io/alpine", options)
Expect(err).To(BeNil())
for _, i := range reports {
Expect(i.Stars).To(BeNumerically(">=", 100))
}
// Search with a fqdn
- reports, err = images.Search(bt.conn, "quay.io/libpod/alpine_nginx", entities.ImageSearchOptions{})
+ reports, err = images.Search(bt.conn, "quay.io/libpod/alpine_nginx", nil)
Expect(len(reports)).To(BeNumerically(">=", 1))
})
It("Prune images", func() {
- trueBoxed := true
- results, err := images.Prune(bt.conn, &trueBoxed, nil)
+ options := new(images.PruneOptions).WithAll(true)
+ results, err := images.Prune(bt.conn, options)
Expect(err).NotTo(HaveOccurred())
Expect(len(results)).To(BeNumerically(">", 0))
Expect(results).To(ContainElement("docker.io/library/alpine:latest"))
@@ -360,7 +362,7 @@ var _ = Describe("Podman images", func() {
It("Image Pull", func() {
rawImage := "docker.io/library/busybox:latest"
- pulledImages, err := images.Pull(bt.conn, rawImage, entities.ImagePullOptions{})
+ pulledImages, err := images.Pull(bt.conn, rawImage, nil)
Expect(err).NotTo(HaveOccurred())
Expect(len(pulledImages)).To(Equal(1))
@@ -369,11 +371,11 @@ var _ = Describe("Podman images", func() {
Expect(exists).To(BeTrue())
// Make sure the normalization AND the full-transport reference works.
- _, err = images.Pull(bt.conn, "docker://"+rawImage, entities.ImagePullOptions{})
+ _, err = images.Pull(bt.conn, "docker://"+rawImage, nil)
Expect(err).NotTo(HaveOccurred())
// The v2 endpoint only supports the docker transport. Let's see if that's really true.
- _, err = images.Pull(bt.conn, "bogus-transport:bogus.com/image:reference", entities.ImagePullOptions{})
+ _, err = images.Pull(bt.conn, "bogus-transport:bogus.com/image:reference", nil)
Expect(err).To(HaveOccurred())
})
})
diff --git a/pkg/bindings/test/info_test.go b/pkg/bindings/test/info_test.go
index 6cd5d6724..735de25b8 100644
--- a/pkg/bindings/test/info_test.go
+++ b/pkg/bindings/test/info_test.go
@@ -17,7 +17,6 @@ var _ = Describe("Podman info", func() {
var (
bt *bindingTest
s *gexec.Session
- t bool = true
)
BeforeEach(func() {
@@ -39,7 +38,8 @@ var _ = Describe("Podman info", func() {
Expect(err).To(BeNil())
Expect(info.Host.Arch).To(Equal(runtime.GOARCH))
Expect(info.Host.OS).To(Equal(runtime.GOOS))
- i, err := images.List(bt.conn, &t, nil)
+ listOptions := new(images.ListOptions)
+ i, err := images.List(bt.conn, listOptions.WithAll(true))
Expect(err).To(BeNil())
Expect(info.Store.ImageStore.Number).To(Equal(len(i)))
})
diff --git a/pkg/bindings/test/manifests_test.go b/pkg/bindings/test/manifests_test.go
index a4ecaa20f..421004b8c 100644
--- a/pkg/bindings/test/manifests_test.go
+++ b/pkg/bindings/test/manifests_test.go
@@ -47,8 +47,8 @@ var _ = Describe("Podman containers ", func() {
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
- _, err = images.Remove(bt.conn, id, nil)
- Expect(err).To(BeNil())
+ _, errs := images.Remove(bt.conn, []string{id}, nil)
+ Expect(len(errs)).To(BeZero())
// create manifest list with images
id, err = manifests.Create(bt.conn, []string{"quay.io/libpod/foobar:latest"}, []string{alpine.name}, nil)
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 09931de12..99291962f 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -4,9 +4,14 @@ import (
"context"
"io/ioutil"
"os"
+ "strconv"
"strings"
"time"
+ "github.com/containers/podman/v2/libpod/image"
+
+ "github.com/containers/image/v5/types"
+
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference"
images "github.com/containers/podman/v2/pkg/bindings/images"
@@ -22,7 +27,8 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.Boo
}
func (ir *ImageEngine) Remove(ctx context.Context, imagesArg []string, opts entities.ImageRemoveOptions) (*entities.ImageRemoveReport, []error) {
- return images.BatchRemove(ir.ClientCxt, imagesArg, opts)
+ options := new(images.RemoveOptions).WithForce(opts.Force).WithAll(opts.All)
+ return images.Remove(ir.ClientCxt, imagesArg, options)
}
func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) {
@@ -32,13 +38,14 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions)
f := strings.Split(filter, "=")
filters[f[0]] = f[1:]
}
- images, err := images.List(ir.ClientCxt, &opts.All, filters)
+ options := new(images.ListOptions).WithAll(opts.All).WithFilters(filters)
+ psImages, err := images.List(ir.ClientCxt, options)
if err != nil {
return nil, err
}
- is := make([]*entities.ImageSummary, len(images))
- for i, img := range images {
+ is := make([]*entities.ImageSummary, len(psImages))
+ for i, img := range psImages {
hold := entities.ImageSummary{}
if err := utils.DeepCopy(&hold, img); err != nil {
return nil, err
@@ -57,7 +64,8 @@ func (ir *ImageEngine) Unmount(ctx context.Context, images []string, options ent
}
func (ir *ImageEngine) History(ctx context.Context, nameOrID string, opts entities.ImageHistoryOptions) (*entities.ImageHistoryReport, error) {
- results, err := images.History(ir.ClientCxt, nameOrID)
+ options := new(images.HistoryOptions)
+ results, err := images.History(ir.ClientCxt, nameOrID, options)
if err != nil {
return nil, err
}
@@ -88,8 +96,8 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption
f := strings.Split(filter, "=")
filters[f[0]] = f[1:]
}
-
- results, err := images.Prune(ir.ClientCxt, &opts.All, filters)
+ options := new(images.PruneOptions).WithAll(opts.All).WithFilters(filters)
+ results, err := images.Prune(ir.ClientCxt, options)
if err != nil {
return nil, err
}
@@ -104,7 +112,18 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption
return &report, nil
}
-func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) {
+func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, opts entities.ImagePullOptions) (*entities.ImagePullReport, error) {
+ options := new(images.PullOptions)
+ options.WithAllTags(opts.AllTags).WithAuthfile(opts.Authfile).WithCertDir(opts.CertDir).WithOverrideArch(opts.OverrideArch).WithOverrideOS(opts.OverrideOS)
+ options.WithOverrideVariant(opts.OverrideVariant).WithPassword(opts.Password).WithPullPolicy(opts.PullPolicy)
+ if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
+ if s == types.OptionalBoolTrue {
+ options.WithSkipTLSVerify(true)
+ } else {
+ options.WithSkipTLSVerify(false)
+ }
+ }
+ options.WithQuiet(opts.Quiet).WithSignaturePolicy(opts.SignaturePolicy).WithUsername(opts.Username)
pulledImages, err := images.Pull(ir.ClientCxt, rawImage, options)
if err != nil {
return nil, err
@@ -112,7 +131,8 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
return &entities.ImagePullReport{Images: pulledImages}, nil
}
-func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error {
+func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, opt entities.ImageTagOptions) error {
+ options := new(images.TagOptions)
for _, newTag := range tags {
var (
tag, repo string
@@ -130,16 +150,17 @@ func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string,
if len(repo) < 1 {
return errors.Errorf("invalid image name %q", nameOrID)
}
- if err := images.Tag(ir.ClientCxt, nameOrID, tag, repo); err != nil {
+ if err := images.Tag(ir.ClientCxt, nameOrID, tag, repo, options); err != nil {
return err
}
}
return nil
}
-func (ir *ImageEngine) Untag(ctx context.Context, nameOrID string, tags []string, options entities.ImageUntagOptions) error {
+func (ir *ImageEngine) Untag(ctx context.Context, nameOrID string, tags []string, opt entities.ImageUntagOptions) error {
+ options := new(images.UntagOptions)
if len(tags) == 0 {
- return images.Untag(ir.ClientCxt, nameOrID, "", "")
+ return images.Untag(ir.ClientCxt, nameOrID, "", "", options)
}
for _, newTag := range tags {
@@ -159,7 +180,7 @@ func (ir *ImageEngine) Untag(ctx context.Context, nameOrID string, tags []string
if len(repo) < 1 {
return errors.Errorf("invalid image name %q", nameOrID)
}
- if err := images.Untag(ir.ClientCxt, nameOrID, tag, repo); err != nil {
+ if err := images.Untag(ir.ClientCxt, nameOrID, tag, repo, options); err != nil {
return err
}
}
@@ -167,10 +188,11 @@ func (ir *ImageEngine) Untag(ctx context.Context, nameOrID string, tags []string
}
func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts entities.InspectOptions) ([]*entities.ImageInspectReport, []error, error) {
+ options := new(images.GetOptions).WithSize(opts.Size)
reports := []*entities.ImageInspectReport{}
errs := []error{}
for _, i := range namesOrIDs {
- r, err := images.GetImage(ir.ClientCxt, i, &opts.Size)
+ r, err := images.GetImage(ir.ClientCxt, i, options)
if err != nil {
errModel, ok := err.(entities.ErrorModel)
if !ok {
@@ -204,68 +226,73 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions)
if len(opts.Tag) > 0 {
ref += ":" + opts.Tag
}
- return images.Load(ir.ClientCxt, f, &ref)
+ options := new(images.LoadOptions).WithReference(ref)
+ return images.Load(ir.ClientCxt, f, options)
}
func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
var (
- err error
- sourceURL *string
- f *os.File
+ err error
+ f *os.File
)
+ options := new(images.ImportOptions).WithChanges(opts.Changes).WithMessage(opts.Message).WithReference(opts.Reference)
if opts.SourceIsURL {
- sourceURL = &opts.Source
+ options.WithURL(opts.Source)
} else {
f, err = os.Open(opts.Source)
if err != nil {
return nil, err
}
}
- return images.Import(ir.ClientCxt, opts.Changes, &opts.Message, &opts.Reference, sourceURL, f)
+ return images.Import(ir.ClientCxt, f, options)
}
-func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, options entities.ImagePushOptions) error {
+func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, opts entities.ImagePushOptions) error {
+ options := new(images.PushOptions)
+ options.WithUsername(opts.Username).WithSignaturePolicy(opts.SignaturePolicy).WithQuiet(opts.Quiet)
+ options.WithPassword(opts.Password).WithCertDir(opts.CertDir).WithAuthfile(opts.Authfile)
+ options.WithCompress(opts.Compress).WithDigestFile(opts.DigestFile).WithFormat(opts.Format)
+ options.WithRemoveSignatures(opts.RemoveSignatures).WithSignBy(opts.SignBy)
+
+ if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
+ if s == types.OptionalBoolTrue {
+ options.WithSkipTLSVerify(true)
+ } else {
+ options.WithSkipTLSVerify(false)
+ }
+ }
return images.Push(ir.ClientCxt, source, destination, options)
}
-func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, options entities.ImageSaveOptions) error {
+func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, opts entities.ImageSaveOptions) error {
var (
f *os.File
err error
)
- switch options.Format {
+ options := new(images.ExportOptions).WithFormat(opts.Format).WithCompress(opts.Compress)
+
+ switch opts.Format {
case "oci-dir", "docker-dir":
f, err = ioutil.TempFile("", "podman_save")
if err == nil {
defer func() { _ = os.Remove(f.Name()) }()
}
default:
- f, err = os.Create(options.Output)
+ f, err = os.Create(opts.Output)
}
if err != nil {
return err
}
- if options.MultiImageArchive {
- exErr := images.MultiExport(ir.ClientCxt, append([]string{nameOrID}, tags...), f, &options.Format, &options.Compress)
- if err := f.Close(); err != nil {
- return err
- }
- if exErr != nil {
- return exErr
- }
- } else {
- // FIXME: tags are entirely ignored here but shouldn't.
- exErr := images.Export(ir.ClientCxt, nameOrID, f, &options.Format, &options.Compress)
- if err := f.Close(); err != nil {
- return err
- }
- if exErr != nil {
- return exErr
- }
+ exErr := images.Export(ir.ClientCxt, append([]string{nameOrID}, tags...), f, options)
+ if err := f.Close(); err != nil {
+ return err
+ }
+ if exErr != nil {
+ return exErr
}
- if options.Format != "oci-dir" && options.Format != "docker-dir" {
+ if opts.Format != "oci-dir" && opts.Format != "docker-dir" {
return nil
}
@@ -273,25 +300,26 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string,
if err != nil {
return err
}
- info, err := os.Stat(options.Output)
+ info, err := os.Stat(opts.Output)
switch {
case err == nil:
if info.Mode().IsRegular() {
- return errors.Errorf("%q already exists as a regular file", options.Output)
+ return errors.Errorf("%q already exists as a regular file", opts.Output)
}
case os.IsNotExist(err):
- if err := os.Mkdir(options.Output, 0755); err != nil {
+ if err := os.Mkdir(opts.Output, 0755); err != nil {
return err
}
default:
return err
}
- return utils2.UntarToFileSystem(options.Output, f, nil)
+ return utils2.UntarToFileSystem(opts.Output, f, nil)
}
// Diff reports the changes to the given image
func (ir *ImageEngine) Diff(ctx context.Context, nameOrID string, _ entities.DiffOptions) (*entities.DiffReport, error) {
- changes, err := images.Diff(ir.ClientCxt, nameOrID)
+ options := new(images.DiffOptions)
+ changes, err := images.Diff(ir.ClientCxt, nameOrID, options)
if err != nil {
return nil, err
}
@@ -299,7 +327,34 @@ func (ir *ImageEngine) Diff(ctx context.Context, nameOrID string, _ entities.Dif
}
func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) {
- return images.Search(ir.ClientCxt, term, opts)
+ mappedFilters := make(map[string][]string)
+ filters, err := image.ParseSearchFilter(opts.Filters)
+ if err != nil {
+ return nil, err
+ }
+ if stars := filters.Stars; stars > 0 {
+ mappedFilters["stars"] = []string{strconv.Itoa(stars)}
+ }
+
+ if official := filters.IsOfficial; official != types.OptionalBoolUndefined {
+ mappedFilters["is-official"] = []string{strconv.FormatBool(official == types.OptionalBoolTrue)}
+ }
+
+ if automated := filters.IsAutomated; automated != types.OptionalBoolUndefined {
+ mappedFilters["is-automated"] = []string{strconv.FormatBool(automated == types.OptionalBoolTrue)}
+ }
+
+ options := new(images.SearchOptions)
+ options.WithAuthfile(opts.Authfile).WithFilters(mappedFilters).WithLimit(opts.Limit)
+ options.WithListTags(opts.ListTags).WithNoTrunc(opts.NoTrunc)
+ if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
+ if s == types.OptionalBoolTrue {
+ options.WithSkipTLSVerify(true)
+ } else {
+ options.WithSkipTLSVerify(false)
+ }
+ }
+ return images.Search(ir.ClientCxt, term, options)
}
func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) {
@@ -326,7 +381,8 @@ func (ir *ImageEngine) Build(_ context.Context, containerFiles []string, opts en
}
func (ir *ImageEngine) Tree(ctx context.Context, nameOrID string, opts entities.ImageTreeOptions) (*entities.ImageTreeReport, error) {
- return images.Tree(ir.ClientCxt, nameOrID, &opts.WhatRequires)
+ options := new(images.TreeOptions).WithWhatRequires(opts.WhatRequires)
+ return images.Tree(ir.ClientCxt, nameOrID, options)
}
// Shutdown Libpod engine