@@ -10533,6 +10533,245 @@ func RunAuthorizationTests(t *testing.T, client *resty.Client, baseURL, user str
10533
10533
})
10534
10534
}
10535
10535
10536
+ func TestSupportedDigestAlgorithms (t * testing.T ) {
10537
+ port := test .GetFreePort ()
10538
+ baseURL := test .GetBaseURL (port )
10539
+
10540
+ conf := config .New ()
10541
+ conf .HTTP .Port = port
10542
+
10543
+ dir := t .TempDir ()
10544
+
10545
+ ctlr := api .NewController (conf )
10546
+ ctlr .Config .Storage .RootDirectory = dir
10547
+ ctlr .Config .Storage .Dedupe = false
10548
+ ctlr .Config .Storage .GC = false
10549
+
10550
+ cm := test .NewControllerManager (ctlr )
10551
+ cm .StartAndWait (port )
10552
+ defer cm .StopServer ()
10553
+
10554
+ Convey ("Test SHA512 single-arch image" , t , func () {
10555
+ image := CreateImageWithDigestAlgorithm (godigest .SHA512 ).
10556
+ RandomLayers (1 , 10 ).DefaultConfig ().Build ()
10557
+
10558
+ name := "algo-sha256"
10559
+ tag := "singlearch"
10560
+
10561
+ err := UploadImage (image , baseURL , name , tag )
10562
+ So (err , ShouldBeNil )
10563
+
10564
+ client := resty .New ()
10565
+
10566
+ // The server picks canonical digests when tags are pushed
10567
+ // See https://github.com/opencontainers/distribution-spec/issues/494
10568
+ // It would be nice to be able to push tags with other digest algorithms and verify those are returned
10569
+ // but there is no way to specify a client preference
10570
+ // so all we can do is verify the correct algorithm is returned
10571
+
10572
+ expectedDigestStr := image .DigestForAlgorithm (godigest .Canonical ).String ()
10573
+
10574
+ headResponse , err := client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10575
+ So (err , ShouldBeNil )
10576
+ So (headResponse , ShouldNotBeNil )
10577
+ So (headResponse .StatusCode (), ShouldEqual , http .StatusOK )
10578
+
10579
+ canonicalDigestStr := headResponse .Header ().Get ("Docker-Content-Digest" )
10580
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10581
+
10582
+ getResponse , err := client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10583
+ So (err , ShouldBeNil )
10584
+ So (getResponse , ShouldNotBeNil )
10585
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10586
+
10587
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10588
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10589
+
10590
+ getResponse , err = client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10591
+ So (err , ShouldBeNil )
10592
+ So (getResponse , ShouldNotBeNil )
10593
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10594
+
10595
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10596
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10597
+
10598
+ getResponse , err = client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10599
+ So (err , ShouldBeNil )
10600
+ So (getResponse , ShouldNotBeNil )
10601
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10602
+
10603
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10604
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10605
+ })
10606
+
10607
+ Convey ("Test SHA384 single-arch image" , t , func () {
10608
+ image := CreateImageWithDigestAlgorithm (godigest .SHA384 ).
10609
+ RandomLayers (1 , 10 ).DefaultConfig ().Build ()
10610
+
10611
+ name := "algo-sha384"
10612
+ tag := "singlearch"
10613
+
10614
+ err := UploadImage (image , baseURL , name , tag )
10615
+ So (err , ShouldBeNil )
10616
+
10617
+ client := resty .New ()
10618
+
10619
+ // The server picks canonical digests when tags are pushed
10620
+ // See https://github.com/opencontainers/distribution-spec/issues/494
10621
+ // It would be nice to be able to push tags with other digest algorithms and verify those are returned
10622
+ // but there is no way to specify a client preference
10623
+ // so all we can do is verify the correct algorithm is returned
10624
+
10625
+ expectedDigestStr := image .DigestForAlgorithm (godigest .Canonical ).String ()
10626
+
10627
+ headResponse , err := client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10628
+ So (err , ShouldBeNil )
10629
+ So (headResponse , ShouldNotBeNil )
10630
+ So (headResponse .StatusCode (), ShouldEqual , http .StatusOK )
10631
+
10632
+ canonicalDigestStr := headResponse .Header ().Get ("Docker-Content-Digest" )
10633
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10634
+
10635
+ getResponse , err := client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10636
+ So (err , ShouldBeNil )
10637
+ So (getResponse , ShouldNotBeNil )
10638
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10639
+
10640
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10641
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10642
+
10643
+ getResponse , err = client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10644
+ So (err , ShouldBeNil )
10645
+ So (getResponse , ShouldNotBeNil )
10646
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10647
+
10648
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10649
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10650
+
10651
+ getResponse , err = client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10652
+ So (err , ShouldBeNil )
10653
+ So (getResponse , ShouldNotBeNil )
10654
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10655
+
10656
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10657
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10658
+ })
10659
+
10660
+ Convey ("Test SHA512 multi-arch image" , t , func () {
10661
+ subImage1 := CreateImageWithDigestAlgorithm (godigest .SHA512 ).RandomLayers (1 , 10 ).
10662
+ DefaultConfig ().Build ()
10663
+ subImage2 := CreateImageWithDigestAlgorithm (godigest .SHA512 ).RandomLayers (1 , 10 ).
10664
+ DefaultConfig ().Build ()
10665
+ multiarch := CreateMultiarchWithDigestAlgorithm (godigest .SHA512 ).
10666
+ Images ([]Image {subImage1 , subImage2 }).Build ()
10667
+
10668
+ name := "algo-sha256"
10669
+ tag := "multiarch"
10670
+
10671
+ err := UploadMultiarchImage (multiarch , baseURL , name , tag )
10672
+ So (err , ShouldBeNil )
10673
+
10674
+ client := resty .New ()
10675
+
10676
+ // The server picks canonical digests when tags are pushed
10677
+ // See https://github.com/opencontainers/distribution-spec/issues/494
10678
+ // It would be nice to be able to push tags with other digest algorithms and verify those are returned
10679
+ // but there is no way to specify a client preference
10680
+ // so all we can do is verify the correct algorithm is returned
10681
+
10682
+ expectedDigestStr := multiarch .DigestForAlgorithm (godigest .Canonical ).String ()
10683
+
10684
+ headResponse , err := client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10685
+ So (err , ShouldBeNil )
10686
+ So (headResponse , ShouldNotBeNil )
10687
+ So (headResponse .StatusCode (), ShouldEqual , http .StatusOK )
10688
+
10689
+ canonicalDigestStr := headResponse .Header ().Get ("Docker-Content-Digest" )
10690
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10691
+
10692
+ getResponse , err := client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10693
+ So (err , ShouldBeNil )
10694
+ So (getResponse , ShouldNotBeNil )
10695
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10696
+
10697
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10698
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10699
+
10700
+ getResponse , err = client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10701
+ So (err , ShouldBeNil )
10702
+ So (getResponse , ShouldNotBeNil )
10703
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10704
+
10705
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10706
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10707
+
10708
+ getResponse , err = client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10709
+ So (err , ShouldBeNil )
10710
+ So (getResponse , ShouldNotBeNil )
10711
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10712
+
10713
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10714
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10715
+ })
10716
+
10717
+ Convey ("Test SHA384 multi-arch image" , t , func () {
10718
+ subImage1 := CreateImageWithDigestAlgorithm (godigest .SHA384 ).RandomLayers (1 , 10 ).
10719
+ DefaultConfig ().Build ()
10720
+ subImage2 := CreateImageWithDigestAlgorithm (godigest .SHA384 ).RandomLayers (1 , 10 ).
10721
+ DefaultConfig ().Build ()
10722
+ multiarch := CreateMultiarchWithDigestAlgorithm (godigest .SHA384 ).
10723
+ Images ([]Image {subImage1 , subImage2 }).Build ()
10724
+
10725
+ name := "algo-sha384"
10726
+ tag := "multiarch"
10727
+
10728
+ err := UploadMultiarchImage (multiarch , baseURL , name , tag )
10729
+ So (err , ShouldBeNil )
10730
+
10731
+ client := resty .New ()
10732
+
10733
+ // The server picks canonical digests when tags are pushed
10734
+ // See https://github.com/opencontainers/distribution-spec/issues/494
10735
+ // It would be nice to be able to push tags with other digest algorithms and verify those are returned
10736
+ // but there is no way to specify a client preference
10737
+ // so all we can do is verify the correct algorithm is returned
10738
+
10739
+ expectedDigestStr := multiarch .DigestForAlgorithm (godigest .Canonical ).String ()
10740
+
10741
+ headResponse , err := client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10742
+ So (err , ShouldBeNil )
10743
+ So (headResponse , ShouldNotBeNil )
10744
+ So (headResponse .StatusCode (), ShouldEqual , http .StatusOK )
10745
+
10746
+ canonicalDigestStr := headResponse .Header ().Get ("Docker-Content-Digest" )
10747
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10748
+
10749
+ getResponse , err := client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , tag ))
10750
+ So (err , ShouldBeNil )
10751
+ So (getResponse , ShouldNotBeNil )
10752
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10753
+
10754
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10755
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10756
+
10757
+ getResponse , err = client .R ().Get (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10758
+ So (err , ShouldBeNil )
10759
+ So (getResponse , ShouldNotBeNil )
10760
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10761
+
10762
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10763
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10764
+
10765
+ getResponse , err = client .R ().Head (fmt .Sprintf ("%s/v2/%s/manifests/%s" , baseURL , name , canonicalDigestStr ))
10766
+ So (err , ShouldBeNil )
10767
+ So (getResponse , ShouldNotBeNil )
10768
+ So (getResponse .StatusCode (), ShouldEqual , http .StatusOK )
10769
+
10770
+ canonicalDigestStr = getResponse .Header ().Get ("Docker-Content-Digest" )
10771
+ So (canonicalDigestStr , ShouldEqual , expectedDigestStr )
10772
+ })
10773
+ }
10774
+
10536
10775
func getEmptyImageConfig () ([]byte , godigest.Digest ) {
10537
10776
config := ispec.Image {}
10538
10777
0 commit comments