From c9bd292b32a6ca4c57a5dd8e9b2cc9ae3272e9b6 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 15 Jan 2021 11:50:23 +0100 Subject: Container rename bindings Add bindings and podman-remote support for container rename. Signed-off-by: Paul Holzinger --- cmd/podman/containers/rename.go | 5 +- pkg/bindings/containers/rename.go | 28 +++++++ pkg/bindings/containers/types.go | 7 ++ pkg/bindings/containers/types_rename_options.go | 104 ++++++++++++++++++++++++ pkg/domain/infra/tunnel/containers.go | 2 +- test/e2e/rename_test.go | 1 - 6 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 pkg/bindings/containers/rename.go create mode 100644 pkg/bindings/containers/types_rename_options.go diff --git a/cmd/podman/containers/rename.go b/cmd/podman/containers/rename.go index 9c94e6272..b6c4f792c 100644 --- a/cmd/podman/containers/rename.go +++ b/cmd/podman/containers/rename.go @@ -32,14 +32,13 @@ var ( ) func init() { - // TODO: Once bindings are done, add this to TunnelMode registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: renameCommand, }) registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: containerRenameCommand, Parent: containerCmd, }) diff --git a/pkg/bindings/containers/rename.go b/pkg/bindings/containers/rename.go new file mode 100644 index 000000000..0e8c7f198 --- /dev/null +++ b/pkg/bindings/containers/rename.go @@ -0,0 +1,28 @@ +package containers + +import ( + "context" + "net/http" + + "github.com/containers/podman/v2/pkg/bindings" +) + +// Rename an existing container. +func Rename(ctx context.Context, nameOrID string, options *RenameOptions) error { + if options == nil { + options = new(RenameOptions) + } + conn, err := bindings.GetClient(ctx) + if err != nil { + return err + } + params, err := options.ToParams() + if err != nil { + return err + } + response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/rename", params, nil, nameOrID) + if err != nil { + return err + } + return response.Process(nil) +} diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 24402e982..10f553e52 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -194,6 +194,13 @@ type InitOptions struct{} // ShouldRestartOptions type ShouldRestartOptions struct{} +//go:generate go run ../generator/generator.go RenameOptions +// RenameOptions are options for renaming containers. +// The Name field is required. +type RenameOptions struct { + Name *string +} + //go:generate go run ../generator/generator.go ResizeTTYOptions // ResizeTTYOptions are optional options for resizing // container TTYs diff --git a/pkg/bindings/containers/types_rename_options.go b/pkg/bindings/containers/types_rename_options.go new file mode 100644 index 000000000..b7a723f7a --- /dev/null +++ b/pkg/bindings/containers/types_rename_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 *RenameOptions) Changed(fieldName string) bool { + r := reflect.ValueOf(o) + value := reflect.Indirect(r).FieldByName(fieldName) + return !value.IsNil() +} + +// ToParams +func (o *RenameOptions) 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 +} + +// WithName +func (o *RenameOptions) WithName(value string) *RenameOptions { + v := &value + o.Name = v + return o +} + +// GetName +func (o *RenameOptions) GetName() string { + var name string + if o.Name == nil { + return name + } + return *o.Name +} diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 8aab4a9cd..4ee623703 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -823,5 +823,5 @@ func (ic *ContainerEngine) ShouldRestart(_ context.Context, id string) (bool, er // ContainerRename renames the given container. func (ic *ContainerEngine) ContainerRename(ctx context.Context, nameOrID string, opts entities.ContainerRenameOptions) error { - return errors.Errorf("NOT YET IMPLEMENTED") + return containers.Rename(ic.ClientCtx, nameOrID, new(containers.RenameOptions).WithName(opts.NewName)) } diff --git a/test/e2e/rename_test.go b/test/e2e/rename_test.go index 324e6a54a..7affbaf56 100644 --- a/test/e2e/rename_test.go +++ b/test/e2e/rename_test.go @@ -17,7 +17,6 @@ var _ = Describe("podman rename", func() { ) BeforeEach(func() { - SkipIfRemote("Rename not yet implemented by podman-remote") tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) -- cgit v1.2.3-54-g00ecf From 0688f080b8eeda35cce4f7d217fb2f4635c162c3 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 15 Jan 2021 12:25:54 +0100 Subject: Fix missing podman-container-rename man page link Signed-off-by: Paul Holzinger --- docs/source/markdown/links/podman-container-rename.1 | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/source/markdown/links/podman-container-rename.1 diff --git a/docs/source/markdown/links/podman-container-rename.1 b/docs/source/markdown/links/podman-container-rename.1 new file mode 100644 index 000000000..1e71c57b6 --- /dev/null +++ b/docs/source/markdown/links/podman-container-rename.1 @@ -0,0 +1 @@ +.so man1/podman-rename.1 -- cgit v1.2.3-54-g00ecf