diff options
-rw-r--r-- | cmd/podman/images/prune.go | 10 | ||||
-rw-r--r-- | pkg/api/handlers/compat/networks.go | 31 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/swagger.go | 3 | ||||
-rw-r--r-- | pkg/api/server/register_networks.go | 14 | ||||
-rw-r--r-- | test/apiv2/python/rest_api/test_v2_0_0_image.py | 11 | ||||
-rw-r--r-- | test/apiv2/python/rest_api/test_v2_0_0_network.py | 27 | ||||
-rw-r--r-- | test/e2e/common_test.go | 39 | ||||
-rw-r--r-- | test/e2e/images_test.go | 21 |
8 files changed, 125 insertions, 31 deletions
diff --git a/cmd/podman/images/prune.go b/cmd/podman/images/prune.go index a082255f6..6ecf4f2aa 100644 --- a/cmd/podman/images/prune.go +++ b/cmd/podman/images/prune.go @@ -59,7 +59,15 @@ func prune(cmd *cobra.Command, args []string) error { return nil } } - + filterMap, err := common.ParseFilters(filter) + if err != nil { + return err + } + for k, v := range filterMap { + for _, val := range v { + pruneOpts.Filter = append(pruneOpts.Filter, fmt.Sprintf("%s=%s", k, val)) + } + } results, err := registry.ImageEngine().Prune(registry.GetContext(), pruneOpts) if err != nil { return err diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index 04f8570ff..4e1f31404 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -28,19 +28,24 @@ import ( func InspectNetwork(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) - // FYI scope and version are currently unused but are described by the API - // Leaving this for if/when we have to enable these - // query := struct { - // scope string - // verbose bool - // }{ - // // override any golang type defaults - // } - // decoder := r.Context().Value("decoder").(*schema.Decoder) - // 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 - // } + // scope is only used to see if the user passes any illegal value, verbose is not used but implemented + // for compatibility purposes only. + query := struct { + scope string `schema:"scope"` + verbose bool `schema:"verbose"` + }{ + scope: "local", + } + decoder := r.Context().Value("decoder").(*schema.Decoder) + 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 + } + + if query.scope != "local" { + utils.Error(w, "Invalid scope value. Can only be local.", http.StatusBadRequest, define.ErrInvalidArg) + return + } config, err := runtime.GetConfig() if err != nil { utils.InternalServerError(w, err) diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go index 2ac5009fc..6116a7274 100644 --- a/pkg/api/handlers/libpod/swagger.go +++ b/pkg/api/handlers/libpod/swagger.go @@ -4,6 +4,7 @@ import ( "net/http" "os" + "github.com/containernetworking/cni/libcni" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/api/handlers/utils" @@ -102,7 +103,7 @@ type swagNetworkRmReport struct { // swagger:response NetworkInspectReport type swagNetworkInspectReport struct { // in:body - Body entities.NetworkInspectReport + Body libcni.NetworkConfigList } // Network list diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go index d122c6a36..cacf83a7f 100644 --- a/pkg/api/server/register_networks.go +++ b/pkg/api/server/register_networks.go @@ -44,6 +44,16 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error { // type: string // required: true // description: the name of the network + // - in: query + // name: verbose + // type: boolean + // required: false + // description: Detailed inspect output for troubleshooting + // - in: query + // name: scope + // type: string + // required: false + // description: Filter the network by scope (swarm, global, or local) // produces: // - application/json // responses: @@ -271,7 +281,9 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error { // tags: // - networks // summary: Inspect a network - // description: Display low level configuration for a CNI network + // description: | + // Display low level configuration for a CNI network. + // - In a 200 response, all of the fields named Bytes are returned as a Base64 encoded string. // parameters: // - in: path // name: name diff --git a/test/apiv2/python/rest_api/test_v2_0_0_image.py b/test/apiv2/python/rest_api/test_v2_0_0_image.py index 2cd7bfa96..cea34e2e7 100644 --- a/test/apiv2/python/rest_api/test_v2_0_0_image.py +++ b/test/apiv2/python/rest_api/test_v2_0_0_image.py @@ -86,10 +86,17 @@ class ImageTestCase(APITestCase): self.assertTrue(keys["id"], "Expected to find id stanza") self.assertTrue(keys["images"], "Expected to find images stanza") self.assertTrue(keys["stream"], "Expected to find stream progress stanza's") + def test_create(self): - r = requests.post(self.podman_url + "/v1.40/images/create?fromImage=alpine&platform=linux/amd64/v8", timeout=15) + r = requests.post( + self.podman_url + "/v1.40/images/create?fromImage=alpine&platform=linux/amd64/v8", + timeout=15, + ) self.assertEqual(r.status_code, 200, r.text) - r = requests.post(self.podman_url + "/v1.40/images/create?fromSrc=-&repo=fedora&message=testing123", timeout=15) + r = requests.post( + self.podman_url + "/v1.40/images/create?fromSrc=-&repo=fedora&message=testing123", + timeout=15, + ) self.assertEqual(r.status_code, 200, r.text) def test_search_compat(self): diff --git a/test/apiv2/python/rest_api/test_v2_0_0_network.py b/test/apiv2/python/rest_api/test_v2_0_0_network.py index 3888123fb..d606b9351 100644 --- a/test/apiv2/python/rest_api/test_v2_0_0_network.py +++ b/test/apiv2/python/rest_api/test_v2_0_0_network.py @@ -102,6 +102,33 @@ class NetworkTestCase(APITestCase): "TestNetwork", payload["NetworkSettings"]["Networks"]["TestNetwork"]["NetworkID"], ) + def test_inspect(self): + name = f"Network_{random.getrandbits(160):x}" + create = requests.post(self.podman_url + "/v1.40/networks/create", json={"Name": name}) + self.assertEqual(create.status_code, 201, create.text) + self.assertId(create.content) + + net = create.json() + self.assertIsInstance(net, dict) + self.assertNotEqual(net["Id"], name) + ident = net["Id"] + + ls = requests.get(self.podman_url + "/v1.40/networks") + self.assertEqual(ls.status_code, 200, ls.text) + + networks = ls.json() + self.assertIsInstance(networks, list) + + found = False + for net in networks: + if net["Name"] == name: + found = True + break + self.assertTrue(found, f"Network '{name}' not found") + + inspect = requests.get(self.podman_url + f"/v1.40/networks/{ident}?verbose=false&scope=local") + self.assertEqual(inspect.status_code, 200, inspect.text) + def test_crud(self): name = f"Network_{random.getrandbits(160):x}" diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 7ffee961c..1aeeca4cb 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -451,19 +451,13 @@ func (p *PodmanTestIntegration) RunLsContainerInPod(name, pod string) (*PodmanSe // BuildImage uses podman build and buildah to build an image // called imageName based on a string dockerfile func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers string) string { - dockerfilePath := filepath.Join(p.TempDir, "Dockerfile") - err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) - Expect(err).To(BeNil()) - cmd := []string{"build", "--pull-never", "--layers=" + layers, "--file", dockerfilePath} - if len(imageName) > 0 { - cmd = append(cmd, []string{"-t", imageName}...) - } - cmd = append(cmd, p.TempDir) - session := p.Podman(cmd) - session.Wait(240) - Expect(session).Should(Exit(0), fmt.Sprintf("BuildImage session output: %q", session.OutputToString())) - output := session.OutputToStringArray() - return output[len(output)-1] + return p.buildImage(dockerfile, imageName, layers, "") +} + +// BuildImageWithLabel uses podman build and buildah to build an image +// called imageName based on a string dockerfile, adds desired label to paramset +func (p *PodmanTestIntegration) BuildImageWithLabel(dockerfile, imageName string, layers string, label string) string { + return p.buildImage(dockerfile, imageName, layers, label) } // PodmanPID execs podman and returns its PID @@ -828,3 +822,22 @@ func (p *PodmanSessionIntegration) jq(jqCommand string) (string, error) { err := cmd.Run() return strings.TrimRight(out.String(), "\n"), err } + +func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers string, label string) string { + dockerfilePath := filepath.Join(p.TempDir, "Dockerfile") + err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + Expect(err).To(BeNil()) + cmd := []string{"build", "--pull-never", "--layers=" + layers, "--file", dockerfilePath} + if label != "" { + cmd = append(cmd, "--label="+label) + } + if len(imageName) > 0 { + cmd = append(cmd, []string{"-t", imageName}...) + } + cmd = append(cmd, p.TempDir) + session := p.Podman(cmd) + session.Wait(240) + Expect(session).Should(Exit(0), fmt.Sprintf("BuildImage session output: %q", session.OutputToString())) + output := session.OutputToStringArray() + return output[len(output)-1] +} diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index f6321ec1c..b4ec7447e 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -425,4 +425,25 @@ LABEL "com.example.vendor"="Example Vendor" Expect(result.OutputToStringArray()).To(Not(Equal(result1.OutputToStringArray()))) }) + It("podman image prune --filter", func() { + dockerfile := `FROM quay.io/libpod/alpine:latest +RUN > file +` + dockerfile2 := `FROM quay.io/libpod/alpine:latest +RUN > file2 +` + podmanTest.BuildImageWithLabel(dockerfile, "foobar.com/workdir:latest", "false", "abc") + podmanTest.BuildImageWithLabel(dockerfile2, "foobar.com/workdir:latest", "false", "xyz") + // --force used to to avoid y/n question + result := podmanTest.Podman([]string{"image", "prune", "--filter", "label=abc", "--force"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(len(result.OutputToStringArray())).To(Equal(1)) + + //check if really abc is removed + result = podmanTest.Podman([]string{"image", "list", "--filter", "label=abc"}) + Expect(len(result.OutputToStringArray())).To(Equal(0)) + + }) + }) |