diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2021-01-19 08:47:37 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-19 08:47:37 -0500 |
commit | 8c6df5e93e6941a7f50da651678751f7dfec900e (patch) | |
tree | 11c249515e428afe98e353b497d2d6abd1ae7ca3 | |
parent | 9a10f20bc1a8733f2a4025d4a1bca45aa31db0d7 (diff) | |
parent | 4ccb0729b4f0a25eb53f62c2f6ca7f8925f0fe4e (diff) | |
download | podman-8c6df5e93e6941a7f50da651678751f7dfec900e.tar.gz podman-8c6df5e93e6941a7f50da651678751f7dfec900e.tar.bz2 podman-8c6df5e93e6941a7f50da651678751f7dfec900e.zip |
Merge pull request #9004 from baude/existsoptions
Add binding options for container|pod exists
-rw-r--r-- | pkg/bindings/containers/containers.go | 8 | ||||
-rw-r--r-- | pkg/bindings/containers/types.go | 7 | ||||
-rw-r--r-- | pkg/bindings/containers/types_exists_options.go | 104 | ||||
-rw-r--r-- | pkg/bindings/images/images.go | 2 | ||||
-rw-r--r-- | pkg/bindings/images/types.go | 5 | ||||
-rw-r--r-- | pkg/bindings/images/types_exists_options.go | 88 | ||||
-rw-r--r-- | pkg/bindings/pods/pods.go | 2 | ||||
-rw-r--r-- | pkg/bindings/pods/types.go | 5 | ||||
-rw-r--r-- | pkg/bindings/pods/types_exists_options.go | 88 | ||||
-rw-r--r-- | pkg/bindings/test/containers_test.go | 12 | ||||
-rw-r--r-- | pkg/bindings/test/images_test.go | 20 | ||||
-rw-r--r-- | pkg/bindings/test/pods_test.go | 6 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/pods.go | 2 |
15 files changed, 326 insertions, 27 deletions
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go index 1081a0e61..73e4d1d3d 100644 --- a/pkg/bindings/containers/containers.go +++ b/pkg/bindings/containers/containers.go @@ -341,13 +341,15 @@ func Wait(ctx context.Context, nameOrID string, options *WaitOptions) (int32, er // Exists is a quick, light-weight way to determine if a given container // exists in local storage. The nameOrID can be a container name // or a partial/full ID. -func Exists(ctx context.Context, nameOrID string, external bool) (bool, error) { +func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, error) { conn, err := bindings.GetClient(ctx) if err != nil { return false, err } - params := url.Values{} - params.Set("external", strconv.FormatBool(external)) + params, err := options.ToParams() + if err != nil { + return false, err + } response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/exists", params, nil, nameOrID) if err != nil { return false, err diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 10f553e52..43cb58a54 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -237,3 +237,10 @@ type ExecStartAndAttachOptions struct { // If false, stdout will not be attached AttachInput *bool } + +//go:generate go run ../generator/generator.go ExistsOptions +// ExistsOptions are optional options for checking if a container exists +type ExistsOptions struct { + // External checks for containers created outside of Podman + External *bool +} diff --git a/pkg/bindings/containers/types_exists_options.go b/pkg/bindings/containers/types_exists_options.go new file mode 100644 index 000000000..f0d8885b2 --- /dev/null +++ b/pkg/bindings/containers/types_exists_options.go @@ -0,0 +1,104 @@ +package containers + +import ( + "net/url" + "reflect" + "strconv" + "strings" + + jsoniter "github.com/json-iterator/go" + "github.com/pkg/errors" +) + +/* +This file is generated automatically by go generate. Do not edit. +*/ + +// Changed +func (o *ExistsOptions) Changed(fieldName string) bool { + r := reflect.ValueOf(o) + value := reflect.Indirect(r).FieldByName(fieldName) + return !value.IsNil() +} + +// ToParams +func (o *ExistsOptions) 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 + } + fieldName = strings.ToLower(fieldName) + 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.Uint, reflect.Uint64: + // f.Uint() is always an uint64 + params.Set(fieldName, strconv.FormatUint(f.Uint(), 10)) + case reflect.Slice: + typ := reflect.TypeOf(f.Interface()).Elem() + switch typ.Kind() { + case reflect.String: + sl := f.Slice(0, f.Len()) + s, ok := sl.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) + } + } + return params, nil +} + +// WithExternal +func (o *ExistsOptions) WithExternal(value bool) *ExistsOptions { + v := &value + o.External = v + return o +} + +// GetExternal +func (o *ExistsOptions) GetExternal() bool { + var external bool + if o.External == nil { + return external + } + return *o.External +} diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index ae6962c8c..37750bc6c 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -18,7 +18,7 @@ import ( // Exists a lightweight way to determine if an image exists in local storage. It returns a // boolean response. -func Exists(ctx context.Context, nameOrID string) (bool, error) { +func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, error) { conn, err := bindings.GetClient(ctx) if err != nil { return false, err diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go index b3799b8c4..f216dd073 100644 --- a/pkg/bindings/images/types.go +++ b/pkg/bindings/images/types.go @@ -193,3 +193,8 @@ type PullOptions struct { type BuildOptions struct { imagebuildah.BuildOptions } + +//go:generate go run ../generator/generator.go ExistsOptions +// ExistsOptions are optional options for checking if an image exists +type ExistsOptions struct { +} diff --git a/pkg/bindings/images/types_exists_options.go b/pkg/bindings/images/types_exists_options.go new file mode 100644 index 000000000..f0d4be6ce --- /dev/null +++ b/pkg/bindings/images/types_exists_options.go @@ -0,0 +1,88 @@ +package images + +import ( + "net/url" + "reflect" + "strconv" + "strings" + + jsoniter "github.com/json-iterator/go" + "github.com/pkg/errors" +) + +/* +This file is generated automatically by go generate. Do not edit. +*/ + +// Changed +func (o *ExistsOptions) Changed(fieldName string) bool { + r := reflect.ValueOf(o) + value := reflect.Indirect(r).FieldByName(fieldName) + return !value.IsNil() +} + +// ToParams +func (o *ExistsOptions) 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 + } + fieldName = strings.ToLower(fieldName) + 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.Uint, reflect.Uint64: + // f.Uint() is always an uint64 + params.Set(fieldName, strconv.FormatUint(f.Uint(), 10)) + case reflect.Slice: + typ := reflect.TypeOf(f.Interface()).Elem() + switch typ.Kind() { + case reflect.String: + sl := f.Slice(0, f.Len()) + s, ok := sl.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) + } + } + return params, nil +} diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go index 4fcaf81f1..ef30348f8 100644 --- a/pkg/bindings/pods/pods.go +++ b/pkg/bindings/pods/pods.go @@ -38,7 +38,7 @@ func CreatePodFromSpec(ctx context.Context, s *specgen.PodSpecGenerator, options } // Exists is a lightweight method to determine if a pod exists in local storage -func Exists(ctx context.Context, nameOrID string) (bool, error) { +func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, error) { conn, err := bindings.GetClient(ctx) if err != nil { return false, err diff --git a/pkg/bindings/pods/types.go b/pkg/bindings/pods/types.go index 370c1aaa9..cb41cf623 100644 --- a/pkg/bindings/pods/types.go +++ b/pkg/bindings/pods/types.go @@ -70,3 +70,8 @@ type StatsOptions struct { type RemoveOptions struct { Force *bool } + +//go:generate go run ../generator/generator.go ExistsOptions +// ExistsOptions are optional options for checking if a pod exists +type ExistsOptions struct { +} diff --git a/pkg/bindings/pods/types_exists_options.go b/pkg/bindings/pods/types_exists_options.go new file mode 100644 index 000000000..7221afe74 --- /dev/null +++ b/pkg/bindings/pods/types_exists_options.go @@ -0,0 +1,88 @@ +package pods + +import ( + "net/url" + "reflect" + "strconv" + "strings" + + jsoniter "github.com/json-iterator/go" + "github.com/pkg/errors" +) + +/* +This file is generated automatically by go generate. Do not edit. +*/ + +// Changed +func (o *ExistsOptions) Changed(fieldName string) bool { + r := reflect.ValueOf(o) + value := reflect.Indirect(r).FieldByName(fieldName) + return !value.IsNil() +} + +// ToParams +func (o *ExistsOptions) 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 + } + fieldName = strings.ToLower(fieldName) + 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.Uint, reflect.Uint64: + // f.Uint() is always an uint64 + params.Set(fieldName, strconv.FormatUint(f.Uint(), 10)) + case reflect.Slice: + typ := reflect.TypeOf(f.Interface()).Elem() + switch typ.Kind() { + case reflect.String: + sl := f.Slice(0, f.Len()) + s, ok := sl.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) + } + } + return params, nil +} diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index fa601e7e5..3d7526cb8 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -406,7 +406,7 @@ var _ = Describe("Podman containers ", func() { It("podman bogus container does not exist in local storage", func() { // Bogus container existence check should fail - containerExists, err := containers.Exists(bt.conn, "foobar", false) + containerExists, err := containers.Exists(bt.conn, "foobar", nil) Expect(err).To(BeNil()) Expect(containerExists).To(BeFalse()) }) @@ -416,7 +416,7 @@ var _ = Describe("Podman containers ", func() { var name = "top" _, err := bt.RunTopContainer(&name, bindings.PFalse, nil) Expect(err).To(BeNil()) - containerExists, err := containers.Exists(bt.conn, name, false) + containerExists, err := containers.Exists(bt.conn, name, nil) Expect(err).To(BeNil()) Expect(containerExists).To(BeTrue()) }) @@ -426,7 +426,7 @@ var _ = Describe("Podman containers ", func() { var name = "top" cid, err := bt.RunTopContainer(&name, bindings.PFalse, nil) Expect(err).To(BeNil()) - containerExists, err := containers.Exists(bt.conn, cid, false) + containerExists, err := containers.Exists(bt.conn, cid, nil) Expect(err).To(BeNil()) Expect(containerExists).To(BeTrue()) }) @@ -436,7 +436,7 @@ var _ = Describe("Podman containers ", func() { var name = "top" cid, err := bt.RunTopContainer(&name, bindings.PFalse, nil) Expect(err).To(BeNil()) - containerExists, err := containers.Exists(bt.conn, cid[0:12], false) + containerExists, err := containers.Exists(bt.conn, cid[0:12], nil) Expect(err).To(BeNil()) Expect(containerExists).To(BeTrue()) }) @@ -456,7 +456,7 @@ var _ = Describe("Podman containers ", func() { Expect(err).To(BeNil()) err = containers.Kill(bt.conn, name, "SIGINT", nil) Expect(err).To(BeNil()) - _, err = containers.Exists(bt.conn, name, false) + _, err = containers.Exists(bt.conn, name, nil) Expect(err).To(BeNil()) }) @@ -467,7 +467,7 @@ var _ = Describe("Podman containers ", func() { Expect(err).To(BeNil()) err = containers.Kill(bt.conn, cid, "SIGTERM", nil) Expect(err).To(BeNil()) - _, err = containers.Exists(bt.conn, cid, false) + _, err = containers.Exists(bt.conn, cid, nil) Expect(err).To(BeNil()) }) diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index 81959e813..f94960047 100644 --- a/pkg/bindings/test/images_test.go +++ b/pkg/bindings/test/images_test.go @@ -194,17 +194,17 @@ var _ = Describe("Podman images", func() { It("Image Exists", func() { // exists on bogus image should be false, with no error - exists, err := images.Exists(bt.conn, "foobar") + exists, err := images.Exists(bt.conn, "foobar", nil) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) // exists with shortname should be true - exists, err = images.Exists(bt.conn, alpine.shortName) + exists, err = images.Exists(bt.conn, alpine.shortName, nil) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) // exists with fqname should be true - exists, err = images.Exists(bt.conn, alpine.name) + exists, err = images.Exists(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) }) @@ -213,7 +213,7 @@ var _ = Describe("Podman images", func() { // load an image _, errs := images.Remove(bt.conn, []string{alpine.name}, nil) Expect(len(errs)).To(BeZero()) - exists, err := images.Exists(bt.conn, alpine.name) + exists, err := images.Exists(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName)) @@ -222,7 +222,7 @@ var _ = Describe("Podman images", func() { names, err := images.Load(bt.conn, f) Expect(err).To(BeNil()) Expect(names.Names[0]).To(Equal(alpine.name)) - exists, err = images.Exists(bt.conn, alpine.name) + exists, err = images.Exists(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) @@ -231,7 +231,7 @@ var _ = Describe("Podman images", func() { 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) + exists, err = images.Exists(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) names, err = images.Load(bt.conn, f) @@ -243,7 +243,7 @@ var _ = Describe("Podman images", func() { 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) + exists, err = images.Exists(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) }) @@ -266,7 +266,7 @@ var _ = Describe("Podman images", func() { // load an image _, errs := images.Remove(bt.conn, []string{alpine.name}, nil) Expect(len(errs)).To(BeZero()) - exists, err := images.Exists(bt.conn, alpine.name) + exists, err := images.Exists(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName)) @@ -277,7 +277,7 @@ var _ = Describe("Podman images", func() { 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) + exists, err = images.Exists(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) data, err := images.GetImage(bt.conn, alpine.name, nil) @@ -357,7 +357,7 @@ var _ = Describe("Podman images", func() { Expect(err).NotTo(HaveOccurred()) Expect(len(pulledImages)).To(Equal(1)) - exists, err := images.Exists(bt.conn, rawImage) + exists, err := images.Exists(bt.conn, rawImage, nil) Expect(err).NotTo(HaveOccurred()) Expect(exists).To(BeTrue()) diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go index 38c5997ef..058479c26 100644 --- a/pkg/bindings/test/pods_test.go +++ b/pkg/bindings/test/pods_test.go @@ -157,12 +157,12 @@ var _ = Describe("Podman pods", func() { // The test validates if the exists responds It("exists pod", func() { - response, err := pods.Exists(bt.conn, "dummyName") + response, err := pods.Exists(bt.conn, "dummyName", nil) Expect(err).To(BeNil()) Expect(response).To(BeFalse()) // Should exit with no error and response should be true - response, err = pods.Exists(bt.conn, "newpod") + response, err = pods.Exists(bt.conn, "newpod", nil) Expect(err).To(BeNil()) Expect(response).To(BeTrue()) }) @@ -338,7 +338,7 @@ var _ = Describe("Podman pods", func() { _, err := pods.CreatePodFromSpec(bt.conn, &ps, nil) Expect(err).To(BeNil()) - exists, err := pods.Exists(bt.conn, "foobar") + exists, err := pods.Exists(bt.conn, "foobar", nil) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) }) diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 4ee623703..84a07f8e9 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -31,7 +31,7 @@ func (ic *ContainerEngine) ContainerRunlabel(ctx context.Context, label string, } func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string, options entities.ContainerExistsOptions) (*entities.BoolReport, error) { - exists, err := containers.Exists(ic.ClientCtx, nameOrID, options.External) + exists, err := containers.Exists(ic.ClientCtx, nameOrID, new(containers.ExistsOptions).WithExternal(options.External)) return &entities.BoolReport{Value: exists}, err } diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 7a4aa1fbc..2d686b2aa 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -22,7 +22,7 @@ import ( ) func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) { - found, err := images.Exists(ir.ClientCtx, nameOrID) + found, err := images.Exists(ir.ClientCtx, nameOrID, nil) return &entities.BoolReport{Value: found}, err } diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go index aa7b92fa7..d61c95d57 100644 --- a/pkg/domain/infra/tunnel/pods.go +++ b/pkg/domain/infra/tunnel/pods.go @@ -12,7 +12,7 @@ import ( ) func (ic *ContainerEngine) PodExists(ctx context.Context, nameOrID string) (*entities.BoolReport, error) { - exists, err := pods.Exists(ic.ClientCtx, nameOrID) + exists, err := pods.Exists(ic.ClientCtx, nameOrID, nil) return &entities.BoolReport{Value: exists}, err } |