diff options
-rw-r--r-- | docs/source/markdown/podman-container-exists.1.md | 2 | ||||
-rw-r--r-- | libpod/diff.go | 20 | ||||
-rw-r--r-- | libpod/runtime_cstorage.go | 4 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/containers.go | 13 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 12 | ||||
-rw-r--r-- | test/system/030-run.bats | 17 | ||||
-rw-r--r-- | test/system/140-diff.bats | 22 |
7 files changed, 75 insertions, 15 deletions
diff --git a/docs/source/markdown/podman-container-exists.1.md b/docs/source/markdown/podman-container-exists.1.md index d24df2fc8..b8be07cb9 100644 --- a/docs/source/markdown/podman-container-exists.1.md +++ b/docs/source/markdown/podman-container-exists.1.md @@ -24,7 +24,6 @@ Check if an container called `webclient` exists in local storage (the container $ podman container exists webclient $ echo $? 0 -$ ``` Check if an container called `webbackend` exists in local storage (the container does not actually exist). @@ -32,7 +31,6 @@ Check if an container called `webbackend` exists in local storage (the container $ podman container exists webbackend $ echo $? 1 -$ ``` ## SEE ALSO diff --git a/libpod/diff.go b/libpod/diff.go index 5335d701c..43f4d2e96 100644 --- a/libpod/diff.go +++ b/libpod/diff.go @@ -62,18 +62,22 @@ func (r *Runtime) ApplyDiffTarStream(to string, diff io.Reader) error { func (r *Runtime) getLayerID(id string) (string, error) { var toLayer string toImage, err := r.imageRuntime.NewFromLocal(id) + if err == nil { + return toImage.TopLayer(), nil + } + + targetID, err := r.store.Lookup(id) if err != nil { - toCtr, err := r.store.Container(id) + targetID = id + } + toCtr, err := r.store.Container(targetID) + if err != nil { + toLayer, err = layers.FullID(r.store, targetID) if err != nil { - toLayer, err = layers.FullID(r.store, id) - if err != nil { - return "", errors.Errorf("layer, image, or container %s does not exist", id) - } - } else { - toLayer = toCtr.LayerID + return "", errors.Errorf("layer, image, or container %s does not exist", id) } } else { - toLayer = toImage.TopLayer() + toLayer = toCtr.LayerID } return toLayer, nil } diff --git a/libpod/runtime_cstorage.go b/libpod/runtime_cstorage.go index 03eebeefc..61fdd42d3 100644 --- a/libpod/runtime_cstorage.go +++ b/libpod/runtime_cstorage.go @@ -52,6 +52,10 @@ func (r *Runtime) ListStorageContainers() ([]*StorageContainer, error) { return finalCtrs, nil } +func (r *Runtime) StorageContainer(idOrName string) (*storage.Container, error) { + return r.store.Container(idOrName) +} + // RemoveStorageContainer removes a container from c/storage. // The container WILL NOT be removed if it exists in libpod. // Accepts ID or full name of container. diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index 7dde51102..8068ea1b8 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -11,6 +11,7 @@ import ( "github.com/containers/podman/v2/pkg/api/handlers/compat" "github.com/containers/podman/v2/pkg/api/handlers/utils" "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/containers/podman/v2/pkg/domain/infra/abi" "github.com/containers/podman/v2/pkg/ps" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -19,8 +20,12 @@ import ( func ContainerExists(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) + // Now use the ABI implementation to prevent us from having duplicate + // code. + containerEngine := abi.ContainerEngine{Libpod: runtime} + name := utils.GetName(r) - _, err := runtime.LookupContainer(name) + report, err := containerEngine.ContainerExists(r.Context(), name) if err != nil { if errors.Cause(err) == define.ErrNoSuchCtr { utils.ContainerNotFound(w, name, err) @@ -30,7 +35,11 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) { return } - utils.WriteResponse(w, http.StatusNoContent, "") + if report.Value { + utils.WriteResponse(w, http.StatusNoContent, "") + } else { + utils.ContainerNotFound(w, name, define.ErrNoSuchCtr) + } } func ListContainers(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 614fd5fe0..191ad8eec 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -74,11 +74,17 @@ func getContainersByContext(all, latest bool, names []string, runtime *libpod.Ru return } -// TODO: Should return *entities.ContainerExistsReport, error +// ContainerExists returns whether the container exists in container storage func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string) (*entities.BoolReport, error) { _, err := ic.Libpod.LookupContainer(nameOrID) - if err != nil && errors.Cause(err) != define.ErrNoSuchCtr { - return nil, err + if err != nil { + if errors.Cause(err) != define.ErrNoSuchCtr { + return nil, err + } + // Check if container exists in storage + if _, storageErr := ic.Libpod.StorageContainer(nameOrID); storageErr == nil { + err = nil + } } return &entities.BoolReport{Value: err == nil}, nil } diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 28dc7c7a7..a82743c70 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -460,4 +460,21 @@ json-file | f is "$output" "$expect" "podman run with --tz=local, matches host" } +@test "podman container exists" { + rand=$(random_string 30) + run_podman 1 container exists myctr + + run_podman create --name myctr $IMAGE /bin/true + run_podman container exists myctr + + # Create a container that podman does not know about + run buildah from $IMAGE + cid="$output" + + # exists should succeed + run_podman container exists $cid + + run buildah rm $cid +} + # vim: filetype=sh diff --git a/test/system/140-diff.bats b/test/system/140-diff.bats index 01ec5430e..d0f33e438 100644 --- a/test/system/140-diff.bats +++ b/test/system/140-diff.bats @@ -32,4 +32,26 @@ load helpers run_podman rm $n } +@test "podman diff with buildah container " { + rand_file=$(random_string 10) + run buildah from --name buildahctr $IMAGE + run buildah run buildahctr sh -c "touch /$rand_file;rm /etc/services" + + run_podman diff --format json buildahctr + + # Expected results for each type of diff + declare -A expect=( + [added]="/$rand_file" + [changed]="/etc" + [deleted]="/etc/services" + ) + + for field in ${!expect[@]}; do + result=$(jq -r -c ".${field}[]" <<<"$output") + is "$result" "${expect[$field]}" "$field" + done + + run buildah rm buildahctr +} + # vim: filetype=sh |