diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-07-01 15:24:20 +0200 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2021-07-02 17:11:56 +0200 |
commit | 8f6a0243f4b7f861a116c0dba5967b3cfe23d61f (patch) | |
tree | 4525ea01079f4f61104e34b5f19b0a823c17f6a0 /pkg | |
parent | fd1715568b7c14451dcf2581c385c8d3e307d30e (diff) | |
download | podman-8f6a0243f4b7f861a116c0dba5967b3cfe23d61f.tar.gz podman-8f6a0243f4b7f861a116c0dba5967b3cfe23d61f.tar.bz2 podman-8f6a0243f4b7f861a116c0dba5967b3cfe23d61f.zip |
podman diff accept two images or containers
First, make podman diff accept optionally a second argument. This allows
the user to specify a second image/container to compare the first with.
If it is not set the parent layer will be used as before.
Second, podman container diff should only use containers and podman
image diff should only use images. Previously, podman container diff
would use the image when both an image and container with this name
exists.
To make this work two new parameters have been added to the api. If they
are not used the previous behaviour is used. The same applies to the
bindings.
Fixes #10649
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/changes.go | 27 | ||||
-rw-r--r-- | pkg/api/server/register_containers.go | 9 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 11 | ||||
-rw-r--r-- | pkg/bindings/containers/diff.go | 7 | ||||
-rw-r--r-- | pkg/bindings/containers/types.go | 7 | ||||
-rw-r--r-- | pkg/bindings/containers/types_diff_options.go | 32 | ||||
-rw-r--r-- | pkg/bindings/images/types.go | 4 | ||||
-rw-r--r-- | pkg/bindings/images/types_diff_options.go | 32 | ||||
-rw-r--r-- | pkg/domain/entities/engine_container.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/engine_image.go | 1 | ||||
-rw-r--r-- | pkg/domain/entities/types.go | 8 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 18 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 8 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 14 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 10 |
15 files changed, 156 insertions, 34 deletions
diff --git a/pkg/api/handlers/compat/changes.go b/pkg/api/handlers/compat/changes.go index c442abbf9..dfe656755 100644 --- a/pkg/api/handlers/compat/changes.go +++ b/pkg/api/handlers/compat/changes.go @@ -4,14 +4,39 @@ import ( "net/http" "github.com/containers/podman/v3/libpod" + "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/api/handlers/utils" + "github.com/gorilla/schema" + "github.com/pkg/errors" ) func Changes(w http.ResponseWriter, r *http.Request) { + decoder := r.Context().Value("decoder").(*schema.Decoder) runtime := r.Context().Value("runtime").(*libpod.Runtime) + query := struct { + Parent string `schema:"parent"` + DiffType string `schema:"diffType"` + }{} + 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 + } + var diffType define.DiffType + switch query.DiffType { + case "", "all": + diffType = define.DiffAll + case "container": + diffType = define.DiffContainer + case "image": + diffType = define.DiffImage + default: + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Errorf("invalid diffType value %q", query.DiffType)) + return + } + id := utils.GetName(r) - changes, err := runtime.GetDiff("", id) + changes, err := runtime.GetDiff(query.Parent, id, diffType) if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index 88ebb4df5..50e059ecc 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -1505,6 +1505,15 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // type: string // required: true // description: the name or id of the container + // - in: query + // name: parent + // type: string + // description: specify a second layer which is used to compare against it instead of the parent layer + // - in: query + // name: diffType + // type: string + // enum: [all, container, image] + // description: select what you want to match, default is all // responses: // 200: // description: Array of Changes diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 3410c53cd..2103c093c 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -1286,7 +1286,16 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // name: name // type: string // required: true - // description: the name or id of the container + // description: the name or id of the image + // - in: query + // name: parent + // type: string + // description: specify a second layer which is used to compare against it instead of the parent layer + // - in: query + // name: diffType + // type: string + // enum: [all, container, image] + // description: select what you want to match, default is all // responses: // 200: // description: Array of Changes diff --git a/pkg/bindings/containers/diff.go b/pkg/bindings/containers/diff.go index 0d0516044..7d20ae530 100644 --- a/pkg/bindings/containers/diff.go +++ b/pkg/bindings/containers/diff.go @@ -13,13 +13,16 @@ func Diff(ctx context.Context, nameOrID string, options *DiffOptions) ([]archive if options == nil { options = new(DiffOptions) } - _ = options conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } - response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/changes", nil, nil, nameOrID) + params, err := options.ToParams() + if err != nil { + return nil, err + } + response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/changes", params, nil, nameOrID) if err != nil { return nil, err } diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 0d22c32f8..80f382926 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -70,7 +70,12 @@ type CreateOptions struct{} //go:generate go run ../generator/generator.go DiffOptions // DiffOptions are optional options for creating containers -type DiffOptions struct{} +type DiffOptions struct { + // By the default diff will compare against the parent layer. Change the Parent if you want to compare against something else. + Parent *string + // Change the type the backend should match. This can be set to "all", "container" or "image". + DiffType *string +} //go:generate go run ../generator/generator.go ExecInspectOptions // ExecInspectOptions are optional options for inspecting diff --git a/pkg/bindings/containers/types_diff_options.go b/pkg/bindings/containers/types_diff_options.go index ed356335d..e92594d39 100644 --- a/pkg/bindings/containers/types_diff_options.go +++ b/pkg/bindings/containers/types_diff_options.go @@ -19,3 +19,35 @@ func (o *DiffOptions) Changed(fieldName string) bool { func (o *DiffOptions) ToParams() (url.Values, error) { return util.ToParams(o) } + +// WithParent +func (o *DiffOptions) WithParent(value string) *DiffOptions { + v := &value + o.Parent = v + return o +} + +// GetParent +func (o *DiffOptions) GetParent() string { + var parent string + if o.Parent == nil { + return parent + } + return *o.Parent +} + +// WithDiffType +func (o *DiffOptions) WithDiffType(value string) *DiffOptions { + v := &value + o.DiffType = v + return o +} + +// GetDiffType +func (o *DiffOptions) GetDiffType() string { + var diffType string + if o.DiffType == nil { + return diffType + } + return *o.DiffType +} diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go index 0aa75a81e..801f5ed96 100644 --- a/pkg/bindings/images/types.go +++ b/pkg/bindings/images/types.go @@ -16,6 +16,10 @@ type RemoveOptions struct { //go:generate go run ../generator/generator.go DiffOptions // DiffOptions are optional options image diffs type DiffOptions struct { + // By the default diff will compare against the parent layer. Change the Parent if you want to compare against something else. + Parent *string + // Change the type the backend should match. This can be set to "all", "container" or "image". + DiffType *string } //go:generate go run ../generator/generator.go ListOptions diff --git a/pkg/bindings/images/types_diff_options.go b/pkg/bindings/images/types_diff_options.go index f15a9a696..5492323f6 100644 --- a/pkg/bindings/images/types_diff_options.go +++ b/pkg/bindings/images/types_diff_options.go @@ -19,3 +19,35 @@ func (o *DiffOptions) Changed(fieldName string) bool { func (o *DiffOptions) ToParams() (url.Values, error) { return util.ToParams(o) } + +// WithParent +func (o *DiffOptions) WithParent(value string) *DiffOptions { + v := &value + o.Parent = v + return o +} + +// GetParent +func (o *DiffOptions) GetParent() string { + var parent string + if o.Parent == nil { + return parent + } + return *o.Parent +} + +// WithDiffType +func (o *DiffOptions) WithDiffType(value string) *DiffOptions { + v := &value + o.DiffType = v + return o +} + +// GetDiffType +func (o *DiffOptions) GetDiffType() string { + var diffType string + if o.DiffType == nil { + return diffType + } + return *o.DiffType +} diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index 4cd3cfd2a..ec17d7ce3 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -23,7 +23,6 @@ type ContainerEngine interface { ContainerCopyFromArchive(ctx context.Context, nameOrID string, path string, reader io.Reader) (ContainerCopyFunc, error) ContainerCopyToArchive(ctx context.Context, nameOrID string, path string, writer io.Writer) (ContainerCopyFunc, error) ContainerCreate(ctx context.Context, s *specgen.SpecGenerator) (*ContainerCreateReport, error) - ContainerDiff(ctx context.Context, nameOrID string, options DiffOptions) (*DiffReport, error) ContainerExec(ctx context.Context, nameOrID string, options ExecOptions, streams define.AttachStreams) (int, error) ContainerExecDetached(ctx context.Context, nameOrID string, options ExecOptions) (string, error) ContainerExists(ctx context.Context, nameOrID string, options ContainerExistsOptions) (*BoolReport, error) @@ -52,6 +51,7 @@ type ContainerEngine interface { ContainerUnmount(ctx context.Context, nameOrIDs []string, options ContainerUnmountOptions) ([]*ContainerUnmountReport, error) ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error) ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error) + Diff(ctx context.Context, namesOrIds []string, options DiffOptions) (*DiffReport, error) Events(ctx context.Context, opts EventsOptions) error GenerateSystemd(ctx context.Context, nameOrID string, opts GenerateSystemdOptions) (*GenerateSystemdReport, error) GenerateKube(ctx context.Context, nameOrIDs []string, opts GenerateKubeOptions) (*GenerateKubeReport, error) diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go index 1b2de5d5e..b0f9ae408 100644 --- a/pkg/domain/entities/engine_image.go +++ b/pkg/domain/entities/engine_image.go @@ -10,7 +10,6 @@ import ( type ImageEngine interface { Build(ctx context.Context, containerFiles []string, opts BuildOptions) (*BuildReport, error) Config(ctx context.Context) (*config.Config, error) - Diff(ctx context.Context, nameOrID string, options DiffOptions) (*DiffReport, error) Exists(ctx context.Context, nameOrID string) (*BoolReport, error) History(ctx context.Context, nameOrID string, opts ImageHistoryOptions) (*ImageHistoryReport, error) Import(ctx context.Context, opts ImageImportOptions) (*ImageImportReport, error) diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go index 02e374111..9e25b7bf8 100644 --- a/pkg/domain/entities/types.go +++ b/pkg/domain/entities/types.go @@ -4,6 +4,7 @@ import ( "net" buildahDefine "github.com/containers/buildah/define" + "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/storage/pkg/archive" @@ -62,9 +63,10 @@ type InspectOptions struct { // All API and CLI diff commands and diff sub-commands use the same options type DiffOptions struct { - Format string `json:",omitempty"` // CLI only - Latest bool `json:",omitempty"` // API and CLI, only supported by containers - Archive bool `json:",omitempty"` // CLI only + Format string `json:",omitempty"` // CLI only + Latest bool `json:",omitempty"` // API and CLI, only supported by containers + Archive bool `json:",omitempty"` // CLI only + Type define.DiffType // Type which should be compared } // DiffReport provides changes for object diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 47fa553ce..2c5300ccb 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -858,16 +858,26 @@ func (ic *ContainerEngine) ContainerListExternal(ctx context.Context) ([]entitie return ps.GetExternalContainerLists(ic.Libpod) } -// ContainerDiff provides changes to given container -func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrID string, opts entities.DiffOptions) (*entities.DiffReport, error) { +// Diff provides changes to given container +func (ic *ContainerEngine) Diff(ctx context.Context, namesOrIDs []string, opts entities.DiffOptions) (*entities.DiffReport, error) { + var ( + base string + parent string + ) if opts.Latest { ctnr, err := ic.Libpod.GetLatestContainer() if err != nil { return nil, errors.Wrap(err, "unable to get latest container") } - nameOrID = ctnr.ID() + base = ctnr.ID() + } + if len(namesOrIDs) > 0 { + base = namesOrIDs[0] + if len(namesOrIDs) > 1 { + parent = namesOrIDs[1] + } } - changes, err := ic.Libpod.GetDiff("", nameOrID) + changes, err := ic.Libpod.GetDiff(parent, base, opts.Type) return &entities.DiffReport{Changes: changes}, err } diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 5992181d3..6d1acb590 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -403,14 +403,6 @@ func (ir *ImageEngine) Import(ctx context.Context, options entities.ImageImportO return &entities.ImageImportReport{Id: imageID}, nil } -func (ir *ImageEngine) Diff(_ context.Context, nameOrID string, _ entities.DiffOptions) (*entities.DiffReport, error) { - changes, err := ir.Libpod.GetDiff("", nameOrID) - if err != nil { - return nil, err - } - return &entities.DiffReport{Changes: changes}, nil -} - func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) { filter, err := libimage.ParseSearchFilter(opts.Filters) if err != nil { diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index ccebfffa4..1bee521cf 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -765,8 +765,18 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta return &report, err } -func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrID string, _ entities.DiffOptions) (*entities.DiffReport, error) { - changes, err := containers.Diff(ic.ClientCtx, nameOrID, nil) +func (ic *ContainerEngine) Diff(ctx context.Context, namesOrIDs []string, opts entities.DiffOptions) (*entities.DiffReport, error) { + var base string + options := new(containers.DiffOptions).WithDiffType(opts.Type.String()) + if len(namesOrIDs) > 0 { + base = namesOrIDs[0] + if len(namesOrIDs) > 1 { + options.WithParent(namesOrIDs[1]) + } + } else { + return nil, errors.New("no arguments for diff") + } + changes, err := containers.Diff(ic.ClientCtx, base, options) return &entities.DiffReport{Changes: changes}, err } diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 42027a2dc..db4e14aba 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -299,16 +299,6 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, 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) { - options := new(images.DiffOptions) - changes, err := images.Diff(ir.ClientCtx, nameOrID, options) - if err != nil { - return nil, err - } - return &entities.DiffReport{Changes: changes}, nil -} - func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) { mappedFilters := make(map[string][]string) filters, err := libimage.ParseSearchFilter(opts.Filters) |