(t *testing.T)
| 560 | } |
| 561 | |
| 562 | func TestPullingForeignLayer(t *testing.T) { |
| 563 | // For that sweet, sweet coverage in options. |
| 564 | var b bytes.Buffer |
| 565 | logs.Debug.SetOutput(&b) |
| 566 | |
| 567 | img := randomImage(t) |
| 568 | expectedRepo := "foo/bar" |
| 569 | foreignPath := "/foreign/path" |
| 570 | |
| 571 | foreignLayer, err := random.Layer(1024, types.DockerForeignLayer) |
| 572 | if err != nil { |
| 573 | t.Fatal(err) |
| 574 | } |
| 575 | |
| 576 | foreignServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 577 | switch r.URL.Path { |
| 578 | case foreignPath: |
| 579 | compressed, err := foreignLayer.Compressed() |
| 580 | if err != nil { |
| 581 | t.Fatal(err) |
| 582 | } |
| 583 | if _, err := io.Copy(w, compressed); err != nil { |
| 584 | t.Fatal(err) |
| 585 | } |
| 586 | w.WriteHeader(http.StatusOK) |
| 587 | default: |
| 588 | t.Fatalf("Unexpected path: %v", r.URL.Path) |
| 589 | } |
| 590 | })) |
| 591 | defer foreignServer.Close() |
| 592 | fu, err := url.Parse(foreignServer.URL) |
| 593 | if err != nil { |
| 594 | t.Fatalf("url.Parse(%v) = %v", foreignServer.URL, err) |
| 595 | } |
| 596 | |
| 597 | // Use "localhost" (not "127.0.0.1") so the hostname is not an IP literal |
| 598 | // and is not rejected by validateForeignURL's private-address check. |
| 599 | // DNS-based SSRF is explicitly out of scope for this validation. |
| 600 | img, err = mutate.Append(img, mutate.Addendum{ |
| 601 | Layer: foreignLayer, |
| 602 | URLs: []string{ |
| 603 | "http://localhost:" + fu.Port() + foreignPath, |
| 604 | }, |
| 605 | }) |
| 606 | if err != nil { |
| 607 | t.Fatal(err) |
| 608 | } |
| 609 | |
| 610 | // Set up a fake registry that will respond 404 to the foreign layer, |
| 611 | // but serve everything else correctly. |
| 612 | configPath := fmt.Sprintf("/v2/%s/blobs/%s", expectedRepo, mustConfigName(t, img)) |
| 613 | manifestPath := fmt.Sprintf("/v2/%s/manifests/latest", expectedRepo) |
| 614 | foreignLayerDigest := mustManifest(t, img).Layers[1].Digest |
| 615 | foreignLayerPath := fmt.Sprintf("/v2/%s/blobs/%s", expectedRepo, foreignLayerDigest) |
| 616 | layerDigest := mustManifest(t, img).Layers[0].Digest |
| 617 | layerPath := fmt.Sprintf("/v2/%s/blobs/%s", expectedRepo, layerDigest) |
| 618 | |
| 619 | layer, err := img.LayerByDigest(layerDigest) |
nothing calls this directly
no test coverage detected
searching dependent graphs…