diff options
-rwxr-xr-x | API.md | 16 | ||||
-rw-r--r-- | Dockerfile.fedora | 2 | ||||
-rw-r--r-- | cmd/podman/commands.go | 2 | ||||
-rw-r--r-- | cmd/podman/container.go | 1 | ||||
-rw-r--r-- | cmd/podman/diff.go | 7 | ||||
-rw-r--r-- | cmd/podman/main.go | 1 | ||||
-rw-r--r-- | cmd/podman/search.go | 16 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 9 | ||||
-rw-r--r-- | libpod/image/search.go | 20 | ||||
-rw-r--r-- | pkg/adapter/runtime.go | 6 | ||||
-rw-r--r-- | pkg/adapter/runtime_remote.go | 27 | ||||
-rw-r--r-- | pkg/varlinkapi/images.go | 13 | ||||
-rw-r--r-- | test/e2e/pod_rm_test.go | 32 |
13 files changed, 115 insertions, 37 deletions
@@ -31,6 +31,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func DeleteUnusedImages() []string](#DeleteUnusedImages) +[func Diff(name: string) DiffInfo](#Diff) + [func ExportContainer(name: string, path: string) string](#ExportContainer) [func ExportImage(name: string, destination: string, compress: bool, tags: []string) string](#ExportImage) @@ -173,6 +175,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [type CreateResourceConfig](#CreateResourceConfig) +[type DiffInfo](#DiffInfo) + [type Event](#Event) [type IDMap](#IDMap) @@ -388,6 +392,11 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.DeleteUnusedImages ] } ~~~ +### <a name="Diff"></a>func Diff +<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> + +method Diff(name: [string](https://godoc.org/builtin#string)) [DiffInfo](#DiffInfo)</div> + ### <a name="ExportContainer"></a>func ExportContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -1431,6 +1440,13 @@ pids_limit [int](https://godoc.org/builtin#int) shm_size [int](https://godoc.org/builtin#int) ulimit [[]string](#[]string) +### <a name="DiffInfo"></a>type DiffInfo + + + +path [string](https://godoc.org/builtin#string) + +changeType [string](https://godoc.org/builtin#string) ### <a name="Event"></a>type Event Event describes a libpod struct diff --git a/Dockerfile.fedora b/Dockerfile.fedora index e38e2e056..d4bcc11ea 100644 --- a/Dockerfile.fedora +++ b/Dockerfile.fedora @@ -1,4 +1,4 @@ -FROM registry.fedoraproject.org/fedora:28 +FROM registry.fedoraproject.org/fedora:29 RUN dnf -y install btrfs-progs-devel \ atomic-registries \ diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index 875b2aec8..baa349e1a 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -14,7 +14,6 @@ func getMainCommands() []*cobra.Command { _attachCommand, _commitCommand, _createCommand, - _diffCommand, _execCommand, _generateCommand, _playCommand, @@ -58,7 +57,6 @@ func getContainerSubCommands() []*cobra.Command { _cleanupCommand, _commitCommand, _createCommand, - _diffCommand, _execCommand, _exportCommand, _killCommand, diff --git a/cmd/podman/container.go b/cmd/podman/container.go index 2e9cedbaa..743dec32f 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -52,6 +52,7 @@ var ( containerCommands = []*cobra.Command{ _containerExistsCommand, _contInspectSubCommand, + _diffCommand, _listSubCommand, _logsCommand, } diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index e77e562d4..7f5a313f8 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/pkg/adapter" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -86,18 +86,17 @@ func diffCmd(c *cliconfig.DiffValues) error { return errors.Errorf("container, image, or layer name must be specified: podman diff [options [...]] ID-NAME") } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } defer runtime.Shutdown(false) to := c.InputArgs[0] - changes, err := runtime.GetDiff("", to) + changes, err := runtime.Diff(c, to) if err != nil { return errors.Wrapf(err, "could not get changes for %q", to) } - diffOutput := []diffOutputParams{} outputFormat := c.Format diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 1ea7f74bf..cff9a6961 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -36,6 +36,7 @@ var ( // implemented. var mainCommands = []*cobra.Command{ _buildCommand, + _diffCommand, _eventsCommand, _exportCommand, _historyCommand, diff --git a/cmd/podman/search.go b/cmd/podman/search.go index a10b9d419..e614887fc 100644 --- a/cmd/podman/search.go +++ b/cmd/podman/search.go @@ -83,11 +83,25 @@ func searchCmd(c *cliconfig.SearchValues) error { if len(results) == 0 { return nil } - out := formats.StdoutTemplateArray{Output: searchToGeneric(results), Template: format, Fields: genSearchOutputMap()} + out := formats.StdoutTemplateArray{Output: searchToGeneric(results), Template: format, Fields: searchHeaderMap()} formats.Writer(out).Out() return nil } +// searchHeaderMap returns the headers of a SearchResult. +func searchHeaderMap() map[string]string { + s := new(image.SearchResult) + v := reflect.Indirect(reflect.ValueOf(s)) + values := make(map[string]string, v.NumField()) + + for i := 0; i < v.NumField(); i++ { + key := v.Type().Field(i).Name + value := key + values[key] = strings.ToUpper(splitCamelCase(value)) + } + return values +} + func genSearchFormat(format string) string { if format != "" { // "\t" from the command line is not being recognized as a tab diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 5e996f46b..2ff06a6f6 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -461,6 +461,13 @@ type Event( type: string ) +type DiffInfo( + # path that is different + path: string, + # Add, Delete, Modify + changeType: string +) + # GetVersion returns version and build information of the podman service method GetVersion() -> ( version: string, @@ -1154,6 +1161,8 @@ method LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool) # GetEvents returns known libpod events filtered by the options provided. method GetEvents(filter: []string, since: string, until: string) -> (events: Event) +method Diff(name: string) -> (diffs: []DiffInfo) + # ImageNotFound means the image could not be found by the provided name or ID in local storage. error ImageNotFound (id: string, reason: string) diff --git a/libpod/image/search.go b/libpod/image/search.go index 2c66ce284..03a67636b 100644 --- a/libpod/image/search.go +++ b/libpod/image/search.go @@ -2,7 +2,6 @@ package image import ( "context" - "reflect" "strconv" "strings" "sync" @@ -10,7 +9,6 @@ import ( "github.com/containers/image/docker" "github.com/containers/image/types" sysreg "github.com/containers/libpod/pkg/registries" - "github.com/fatih/camelcase" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" @@ -63,24 +61,6 @@ type SearchFilter struct { IsOfficial types.OptionalBool } -func splitCamelCase(src string) string { - entries := camelcase.Split(src) - return strings.Join(entries, " ") -} - -// HeaderMap returns the headers of a SearchResult. -func (s *SearchResult) HeaderMap() map[string]string { - v := reflect.Indirect(reflect.ValueOf(s)) - values := make(map[string]string, v.NumField()) - - for i := 0; i < v.NumField(); i++ { - key := v.Type().Field(i).Name - value := key - values[key] = strings.ToUpper(splitCamelCase(value)) - } - return values -} - // SearchImages searches images based on term and the specified SearchOptions // in all registries. func SearchImages(term string, options SearchOptions) ([]SearchResult, error) { diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go index 6a68a3aea..dd51c7233 100644 --- a/pkg/adapter/runtime.go +++ b/pkg/adapter/runtime.go @@ -23,6 +23,7 @@ import ( "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" ) @@ -430,3 +431,8 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error { } return nil } + +// Diff shows the difference in two objects +func (r *LocalRuntime) Diff(c *cliconfig.DiffValues, to string) ([]archive.Change, error) { + return r.Runtime.GetDiff("", to) +} diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index dcc2d5aa6..c3a4f322d 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -831,3 +831,30 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error { } return nil } + +// Diff ... +func (r *LocalRuntime) Diff(c *cliconfig.DiffValues, to string) ([]archive.Change, error) { + var changes []archive.Change + reply, err := iopodman.Diff().Call(r.Conn, to) + if err != nil { + return nil, err + } + for _, change := range reply { + changes = append(changes, archive.Change{Path: change.Path, Kind: stringToChangeType(change.ChangeType)}) + } + return changes, nil +} + +func stringToChangeType(change string) archive.ChangeType { + switch change { + case "A": + return archive.ChangeAdd + case "D": + return archive.ChangeDelete + default: + logrus.Errorf("'%s' is unknown archive type", change) + fallthrough + case "C": + return archive.ChangeModify + } +} diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 0ca867410..63d500204 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -910,3 +910,16 @@ func (i *LibpodAPI) LoadImage(call iopodman.VarlinkCall, name, inputFile string, } return call.ReplyLoadImage(br) } + +// Diff ... +func (i *LibpodAPI) Diff(call iopodman.VarlinkCall, name string) error { + var response []iopodman.DiffInfo + changes, err := i.Runtime.GetDiff("", name) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + for _, change := range changes { + response = append(response, iopodman.DiffInfo{Path: change.Path, ChangeType: change.Kind.String()}) + } + return call.ReplyDiff(response) +} diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index f9d7abe8f..5da3d563b 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -3,6 +3,7 @@ package integration import ( + "fmt" "os" . "github.com/containers/libpod/test/utils" @@ -95,28 +96,41 @@ var _ = Describe("Podman pod rm", func() { }) It("podman pod rm -a doesn't remove a running container", func() { + fmt.Printf("To start, there are %d pods\n", podmanTest.NumberOfPods()) _, ec, podid1 := podmanTest.CreatePod("") Expect(ec).To(Equal(0)) _, ec, _ = podmanTest.CreatePod("") Expect(ec).To(Equal(0)) + fmt.Printf("Started %d pods\n", podmanTest.NumberOfPods()) session := podmanTest.RunTopContainerInPod("", podid1) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + podmanTest.WaitForContainer() + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + fmt.Printf("Started container running in one pod") + num_pods := podmanTest.NumberOfPods() + Expect(num_pods).To(Equal(2)) + ps := podmanTest.Podman([]string{"pod", "ps"}) + ps.WaitWithDefaultTimeout() + fmt.Printf("Current %d pod(s):\n%s\n", num_pods, ps.OutputToString()) + + fmt.Printf("Removing all empty pods\n") result := podmanTest.Podman([]string{"pod", "rm", "-a"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Not(Equal(0))) - - result = podmanTest.Podman([]string{"ps", "-q"}) - result.WaitWithDefaultTimeout() - Expect(len(result.OutputToStringArray())).To(Equal(1)) - - // one pod should have been deleted - result = podmanTest.Podman([]string{"pod", "ps", "-q"}) - result.WaitWithDefaultTimeout() - Expect(len(result.OutputToStringArray())).To(Equal(1)) + foundExpectedError, _ := result.ErrorGrepString("contains containers and cannot be removed") + Expect(foundExpectedError).To(Equal(true)) + + num_pods = podmanTest.NumberOfPods() + ps = podmanTest.Podman([]string{"pod", "ps"}) + ps.WaitWithDefaultTimeout() + fmt.Printf("Final %d pod(s):\n%s\n", num_pods, ps.OutputToString()) + Expect(num_pods).To(Equal(1)) + // Confirm top container still running inside remaining pod + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) It("podman pod rm -fa removes everything", func() { |