From 69e56615e8d704dbac04d9090d3b73259dcdb3cb Mon Sep 17 00:00:00 2001 From: Tom Kennedy Date: Fri, 10 Mar 2023 10:28:10 -0500 Subject: [PATCH 01/39] Update golang.org/x/net to v0.7.0 - Patches GHSA-fxg5-wq6x-vr4w and GHSA-vvpx-j8f3-3w6h --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 2c520b26..1573b9f2 100644 --- a/go.mod +++ b/go.mod @@ -283,11 +283,11 @@ require ( go.uber.org/multierr v1.8.0 // indirect golang.org/x/exp v0.0.0-20220823124025-807a23277127 // indirect golang.org/x/mod v0.6.0 // indirect - golang.org/x/net v0.1.0 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.1.0 // indirect - golang.org/x/sys v0.1.0 // indirect - golang.org/x/term v0.1.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect golang.org/x/tools v0.1.12 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect diff --git a/go.sum b/go.sum index d21aad04..aac4badf 100644 --- a/go.sum +++ b/go.sum @@ -1809,8 +1809,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1969,15 +1969,15 @@ golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1987,8 +1987,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 9bd61c35ea9f021b98e68be63ce4d50a3923413f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 15:46:02 +0000 Subject: [PATCH 02/39] Bump actions/checkout from 1 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 1 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v1...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 127bb84a..b57f05c5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,7 +11,7 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Run tests uses: ./.github/actions/run-tests - name: Report coverage From 1c9335272ada74a67edb23f2f72b334e9eb89588 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 16:09:48 +0000 Subject: [PATCH 03/39] Bump golang.org/x/crypto from 0.1.0 to 0.7.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.1.0 to 0.7.0. - [Release notes](https://github.com/golang/crypto/releases) - [Commits](https://github.com/golang/crypto/compare/v0.1.0...v0.7.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 1573b9f2..b1d0e68a 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/vdemeester/k8s-pkg-credentialprovider v1.22.4 github.com/whilp/git-urls v1.0.0 go.uber.org/zap v1.23.0 - golang.org/x/crypto v0.1.0 + golang.org/x/crypto v0.7.0 golang.org/x/sync v0.1.0 k8s.io/api v0.24.8 k8s.io/apimachinery v0.24.8 @@ -282,14 +282,14 @@ require ( go.uber.org/automaxprocs v1.5.1 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/exp v0.0.0-20220823124025-807a23277127 // indirect - golang.org/x/mod v0.6.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.8.0 // indirect golang.org/x/oauth2 v0.1.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.1.12 // indirect + golang.org/x/tools v0.6.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/api v0.99.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index aac4badf..3681d254 100644 --- a/go.sum +++ b/go.sum @@ -1689,8 +1689,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1731,8 +1731,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1809,8 +1809,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1969,15 +1969,15 @@ golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1987,8 +1987,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2083,8 +2083,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 7857820a20481e34b338c345ee4640ada53bb195 Mon Sep 17 00:00:00 2001 From: Yael Harel <43007598+yaelharel@users.noreply.github.com> Date: Fri, 10 Mar 2023 16:09:55 -0500 Subject: [PATCH 04/39] Improve the error message when source resolver is not resolving (#1152) Improve the error message when source resolver is not resolving Signed-off-by: Yael Harel Co-authored-by: Tom Kennedy --- pkg/reconciler/image/image_test.go | 21 +++++++++------------ pkg/reconciler/image/reconcile_build.go | 9 +++++++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pkg/reconciler/image/image_test.go b/pkg/reconciler/image/image_test.go index b56e211b..b9a44be8 100644 --- a/pkg/reconciler/image/image_test.go +++ b/pkg/reconciler/image/image_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/sclevine/spec" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -764,7 +765,11 @@ func testImageReconciler(t *testing.T, when spec.G, it spec.S) { unresolvedSourceResolver(imageWithBuilder), }, WantErr: false, + //no builds are created + WantCreates: nil, }) + + assert.Equal(t, "SourceResolver image-name-source is not ready", imageWithBuilder.Status.GetCondition(corev1alpha1.ConditionReady).Message) }) it("does not schedule a build if the builder is not ready", func() { @@ -2247,16 +2252,7 @@ func testImageReconciler(t *testing.T, when spec.G, it spec.S) { Status: buildapi.ImageStatus{ Status: corev1alpha1.Status{ ObservedGeneration: originalGeneration, - Conditions: corev1alpha1.Conditions{ - { - Type: corev1alpha1.ConditionReady, - Status: corev1.ConditionUnknown, - }, - { - Type: buildapi.ConditionBuilderReady, - Status: corev1.ConditionTrue, - }, - }, + Conditions: conditionReadyUnknown(), }, LatestBuildRef: "image-name-build-1", LatestImage: "some/image@sha256:build-1", @@ -2596,8 +2592,9 @@ func limit(limit int64) *int64 { func conditionReadyUnknown() corev1alpha1.Conditions { return corev1alpha1.Conditions{ { - Type: corev1alpha1.ConditionReady, - Status: corev1.ConditionUnknown, + Type: corev1alpha1.ConditionReady, + Status: corev1.ConditionUnknown, + Message: "SourceResolver image-name-source is not ready", }, { Type: buildapi.ConditionBuilderReady, diff --git a/pkg/reconciler/image/reconcile_build.go b/pkg/reconciler/image/reconcile_build.go index 003bd846..feb2993f 100644 --- a/pkg/reconciler/image/reconcile_build.go +++ b/pkg/reconciler/image/reconcile_build.go @@ -55,7 +55,7 @@ func (c *Reconciler) reconcileBuild(ctx context.Context, image *buildapi.Image, case corev1.ConditionFalse: return buildapi.ImageStatus{ Status: corev1alpha1.Status{ - Conditions: noScheduledBuild(result.ConditionStatus, builder, latestBuild), + Conditions: noScheduledBuild(result.ConditionStatus, builder, latestBuild, sourceResolver), }, LatestBuildRef: latestBuild.BuildRef(), LatestBuildReason: latestBuild.BuildReason(), @@ -70,12 +70,17 @@ func (c *Reconciler) reconcileBuild(ctx context.Context, image *buildapi.Image, } } -func noScheduledBuild(buildNeeded corev1.ConditionStatus, builder buildapi.BuilderResource, build *buildapi.Build) corev1alpha1.Conditions { +func noScheduledBuild(buildNeeded corev1.ConditionStatus, builder buildapi.BuilderResource, build *buildapi.Build, sourceResolver *buildapi.SourceResolver) corev1alpha1.Conditions { if buildNeeded == corev1.ConditionUnknown { + message := "" + if !sourceResolver.Ready() { + message = fmt.Sprintf("SourceResolver %s is not ready", sourceResolver.GetName()) + } return corev1alpha1.Conditions{ { Type: corev1alpha1.ConditionReady, Status: corev1.ConditionUnknown, + Message: message, LastTransitionTime: corev1alpha1.VolatileTime{Inner: metav1.Now()}, }, builderCondition(builder), From fbfb51952517fc2f116be25d1c99e5f94860a271 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Mon, 20 Mar 2023 14:30:28 -0400 Subject: [PATCH 05/39] 2nd attempt at ignoring dependabot prs Signed-off-by: Bohan Chen --- .github/workflows/add-to-project.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml index 22655157..bc11397b 100644 --- a/.github/workflows/add-to-project.yml +++ b/.github/workflows/add-to-project.yml @@ -10,13 +10,12 @@ on: jobs: add-to-project: + if: ${{ github.actor != 'dependabot[bot]' }} name: Add To GitHub Projects Beta runs-on: ubuntu-latest steps: - name: Add To GitHub Projects Beta - uses: actions/add-to-project@v0.3.0 + uses: actions/add-to-project@v0.4.1 with: project-url: https://github.com/orgs/pivotal/projects/18 github-token: ${{ secrets.KPACK_BOT_PAT }} - labeled: dependencies - label-operator: NOT From 3c68cede73d06a452131b91cc2ecaad4f0a246f1 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Fri, 13 Jan 2023 13:47:24 -0500 Subject: [PATCH 06/39] add Buildpack and ClusterBuildpack CRDs and the reconcilers to resolve them Signed-off-by: Bohan Chen --- cmd/controller/main.go | 14 +- cmd/webhook/main.go | 14 +- config/build.yaml | 0 config/buildpack.yaml | 32 +++ config/clusterbuildpack.yaml | 32 +++ config/controller.yaml | 0 config/controllerrole.yaml | 4 + config/image.yaml | 0 docs/local.md | 55 ++++ pkg/apis/build/v1alpha2/buildpack_types.go | 60 +++++ .../build/v1alpha2/buildpack_validation.go | 22 ++ .../v1alpha2/buildpack_validation_test.go | 71 +++++ .../build/v1alpha2/cluster_buildpack_types.go | 57 ++++ .../v1alpha2/cluster_buildpack_validation.go | 28 ++ .../cluster_buildpack_validation_test.go | 73 ++++++ pkg/apis/build/v1alpha2/register.go | 2 + .../build/v1alpha2/zz_generated.deepcopy.go | 225 ++++++++++++++++ .../typed/build/v1alpha2/build_client.go | 10 + .../typed/build/v1alpha2/buildpack.go | 195 ++++++++++++++ .../typed/build/v1alpha2/clusterbuildpack.go | 184 +++++++++++++ .../build/v1alpha2/fake/fake_build_client.go | 8 + .../build/v1alpha2/fake/fake_buildpack.go | 142 ++++++++++ .../v1alpha2/fake/fake_clusterbuildpack.go | 133 ++++++++++ .../build/v1alpha2/generated_expansion.go | 4 + .../build/v1alpha2/buildpack.go | 90 +++++++ .../build/v1alpha2/clusterbuildpack.go | 89 +++++++ .../build/v1alpha2/interface.go | 14 + .../informers/externalversions/generic.go | 4 + .../listers/build/v1alpha2/buildpack.go | 99 +++++++ .../build/v1alpha2/clusterbuildpack.go | 68 +++++ .../build/v1alpha2/expansion_generated.go | 12 + .../buildfakes/fake_metadata_retriever.go | 7 +- pkg/reconciler/buildpack/buildpack.go | 144 ++++++++++ pkg/reconciler/buildpack/buildpack_test.go | 248 ++++++++++++++++++ .../buildpackfakes/fake_store_reader.go | 125 +++++++++ .../clusterbuilder/clusterbuilder.go | 4 +- .../clusterbuilder/clusterbuilder_test.go | 6 +- .../clusterbuildpack/clusterbuildpack.go | 144 ++++++++++ .../clusterbuildpack/clusterbuildpack_test.go | 245 +++++++++++++++++ .../fake_store_reader.go | 125 +++++++++ .../fake_cluster_stack_reader.go | 7 +- .../clusterstorefakes/fake_store_reader.go | 7 +- .../sourceresolverfakes/fake_enqueuer.go | 7 +- .../sourceresolverfakes/fake_resolver.go | 14 +- pkg/reconciler/testhelpers/listers.go | 8 + 45 files changed, 2801 insertions(+), 31 deletions(-) mode change 100755 => 100644 config/build.yaml create mode 100644 config/buildpack.yaml create mode 100644 config/clusterbuildpack.yaml mode change 100755 => 100644 config/controller.yaml mode change 100755 => 100644 config/image.yaml create mode 100644 pkg/apis/build/v1alpha2/buildpack_types.go create mode 100644 pkg/apis/build/v1alpha2/buildpack_validation.go create mode 100644 pkg/apis/build/v1alpha2/buildpack_validation_test.go create mode 100644 pkg/apis/build/v1alpha2/cluster_buildpack_types.go create mode 100644 pkg/apis/build/v1alpha2/cluster_buildpack_validation.go create mode 100644 pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go create mode 100644 pkg/client/clientset/versioned/typed/build/v1alpha2/buildpack.go create mode 100644 pkg/client/clientset/versioned/typed/build/v1alpha2/clusterbuildpack.go create mode 100644 pkg/client/clientset/versioned/typed/build/v1alpha2/fake/fake_buildpack.go create mode 100644 pkg/client/clientset/versioned/typed/build/v1alpha2/fake/fake_clusterbuildpack.go create mode 100644 pkg/client/informers/externalversions/build/v1alpha2/buildpack.go create mode 100644 pkg/client/informers/externalversions/build/v1alpha2/clusterbuildpack.go create mode 100644 pkg/client/listers/build/v1alpha2/buildpack.go create mode 100644 pkg/client/listers/build/v1alpha2/clusterbuildpack.go create mode 100644 pkg/reconciler/buildpack/buildpack.go create mode 100644 pkg/reconciler/buildpack/buildpack_test.go create mode 100644 pkg/reconciler/buildpack/buildpackfakes/fake_store_reader.go create mode 100644 pkg/reconciler/clusterbuildpack/clusterbuildpack.go create mode 100644 pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go create mode 100644 pkg/reconciler/clusterbuildpack/clusterbuildpackfakes/fake_store_reader.go diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 4827304c..12bdb836 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -47,7 +47,9 @@ import ( "github.com/pivotal/kpack/pkg/reconciler" "github.com/pivotal/kpack/pkg/reconciler/build" "github.com/pivotal/kpack/pkg/reconciler/builder" - clusterBuilder "github.com/pivotal/kpack/pkg/reconciler/clusterbuilder" + "github.com/pivotal/kpack/pkg/reconciler/buildpack" + "github.com/pivotal/kpack/pkg/reconciler/clusterbuilder" + "github.com/pivotal/kpack/pkg/reconciler/clusterbuildpack" "github.com/pivotal/kpack/pkg/reconciler/clusterstack" "github.com/pivotal/kpack/pkg/reconciler/clusterstore" "github.com/pivotal/kpack/pkg/reconciler/image" @@ -121,7 +123,9 @@ func main() { imageInformer := informerFactory.Kpack().V1alpha2().Images() sourceResolverInformer := informerFactory.Kpack().V1alpha2().SourceResolvers() builderInformer := informerFactory.Kpack().V1alpha2().Builders() + buildpackInformer := informerFactory.Kpack().V1alpha2().Buildpacks() clusterBuilderInformer := informerFactory.Kpack().V1alpha2().ClusterBuilders() + clusterBuildpackInformer := informerFactory.Kpack().V1alpha2().ClusterBuildpacks() clusterStoreInformer := informerFactory.Kpack().V1alpha2().ClusterStores() clusterStackInformer := informerFactory.Kpack().V1alpha2().ClusterStacks() @@ -208,7 +212,9 @@ func main() { imageController := image.NewController(ctx, options, k8sClient, imageInformer, buildInformer, duckBuilderInformer, sourceResolverInformer, pvcInformer, *enablePriorityClasses) sourceResolverController := sourceresolver.NewController(ctx, options, sourceResolverInformer, gitResolver, blobResolver, registryResolver) builderController, builderResync := builder.NewController(ctx, options, builderInformer, builderCreator, keychainFactory, clusterStoreInformer, clusterStackInformer) - clusterBuilderController, clusterBuilderResync := clusterBuilder.NewController(ctx, options, clusterBuilderInformer, builderCreator, keychainFactory, clusterStoreInformer, clusterStackInformer) + buildpackController := buildpack.NewController(ctx, options, keychainFactory, buildpackInformer, remoteStoreReader) + clusterBuilderController, clusterBuilderResync := clusterbuilder.NewController(ctx, options, clusterBuilderInformer, builderCreator, keychainFactory, clusterStoreInformer, clusterStackInformer) + clusterBuildpackController := clusterbuildpack.NewController(ctx, options, keychainFactory, clusterBuildpackInformer, remoteStoreReader) clusterStoreController := clusterstore.NewController(ctx, options, keychainFactory, clusterStoreInformer, remoteStoreReader) clusterStackController := clusterstack.NewController(ctx, options, keychainFactory, clusterStackInformer, remoteStackReader) lifecycleController := lifecycle.NewController(ctx, options, k8sClient, config.LifecycleConfigName, lifecycleConfigmapInformer, lifecycleProvider) @@ -229,7 +235,9 @@ func main() { podInformer.Informer(), lifecycleConfigmapInformer.Informer(), builderInformer.Informer(), + buildpackInformer.Informer(), clusterBuilderInformer.Informer(), + clusterBuildpackInformer.Informer(), clusterStoreInformer.Informer(), clusterStackInformer.Informer(), ) @@ -240,7 +248,9 @@ func main() { run(imageController, routinesPerController), run(buildController, routinesPerController), run(builderController, routinesPerController), + run(buildpackController, routinesPerController), run(clusterBuilderController, routinesPerController), + run(clusterBuildpackController, routinesPerController), run(clusterStoreController, routinesPerController), run(lifecycleController, routinesPerController), run(sourceResolverController, 2*routinesPerController), diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index fa8d78c2..e4c3a9a9 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -27,12 +27,14 @@ import ( ) var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ - v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ImageKind): &v1alpha2.Image{}, - v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.BuildKind): &v1alpha2.Build{}, - v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.BuilderKind): &v1alpha2.Builder{}, - v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ClusterBuilderKind): &v1alpha2.ClusterBuilder{}, - v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ClusterStoreKind): &v1alpha2.ClusterStore{}, - v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ClusterStackKind): &v1alpha2.ClusterStack{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ImageKind): &v1alpha2.Image{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.BuildKind): &v1alpha2.Build{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.BuilderKind): &v1alpha2.Builder{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.BuildpackKind): &v1alpha2.Buildpack{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ClusterBuilderKind): &v1alpha2.ClusterBuilder{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ClusterBuildpackKind): &v1alpha2.ClusterBuildpack{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ClusterStoreKind): &v1alpha2.ClusterStore{}, + v1alpha2.SchemeGroupVersion.WithKind(v1alpha2.ClusterStackKind): &v1alpha2.ClusterStack{}, } func init() { diff --git a/config/build.yaml b/config/build.yaml old mode 100755 new mode 100644 diff --git a/config/buildpack.yaml b/config/buildpack.yaml new file mode 100644 index 00000000..aec06441 --- /dev/null +++ b/config/buildpack.yaml @@ -0,0 +1,32 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: buildpacks.kpack.io +spec: + group: kpack.io + versions: + - name: v1alpha2 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + additionalPrinterColumns: + - name: Ready + type: string + jsonPath: ".status.conditions[?(@.type==\"Ready\")].status" + names: + kind: Buildpack + listKind: BuildpackList + singular: buildpack + plural: buildpacks + shortNames: + - bp + - bps + categories: + - kpack + scope: Namespaced + diff --git a/config/clusterbuildpack.yaml b/config/clusterbuildpack.yaml new file mode 100644 index 00000000..c7992c7b --- /dev/null +++ b/config/clusterbuildpack.yaml @@ -0,0 +1,32 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clusterbuildpacks.kpack.io +spec: + group: kpack.io + versions: + - name: v1alpha2 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + additionalPrinterColumns: + - name: Ready + type: string + jsonPath: ".status.conditions[?(@.type==\"Ready\")].status" + names: + kind: ClusterBuildpack + listKind: ClusterBuildpackList + singular: clusterbuildpack + plural: clusterbuildpacks + shortNames: + - clstbp + - clstbps + categories: + - kpack + scope: Namespaced + diff --git a/config/controller.yaml b/config/controller.yaml old mode 100755 new mode 100644 diff --git a/config/controllerrole.yaml b/config/controllerrole.yaml index 86659bce..0de28a8f 100644 --- a/config/controllerrole.yaml +++ b/config/controllerrole.yaml @@ -21,8 +21,12 @@ rules: - images/finalizers - builders - builders/status + - buildpacks + - buildpacks/status - clusterbuilders - clusterbuilders/status + - clusterbuildpacks + - clusterbuildpacks/status - clusterstores - clusterstores/status - clusterstacks diff --git a/config/image.yaml b/config/image.yaml old mode 100755 new mode 100644 diff --git a/docs/local.md b/docs/local.md index f6955b36..be58d117 100644 --- a/docs/local.md +++ b/docs/local.md @@ -1,5 +1,7 @@ ### Local Development Install +#### When using public registries + Access to a Kubernetes cluster is needed in order to install the kpack controllers. ```bash @@ -7,6 +9,59 @@ kubectl cluster-info # ensure you have access to a cluster ./hack/apply.sh # is a writable and publicly accessible location ``` +#### When using private registries + +Create a kubernetes secret with the registry creds + +```bash +kubectl create secret docker-registry regcreds -n kpack --docker-server=gcr.io --docker-username=_json_key --docker-password="$(cat gcp.json)" +``` + +Create an overlay to use those registry creds + +```bash +cat > ./config/overlay.yaml < Date: Tue, 24 Jan 2023 16:05:55 -0500 Subject: [PATCH 07/39] update builder to support buildpack crd Signed-off-by: Bohan Chen --- pkg/apis/build/v1alpha2/builder_conversion.go | 33 ++++- .../build/v1alpha2/builder_conversion_test.go | 28 +++- pkg/apis/build/v1alpha2/builder_types.go | 14 +- pkg/apis/build/v1alpha2/builder_validation.go | 23 +++- .../v1alpha2/cluster_builder_conversion.go | 33 ++++- .../cluster_builder_conversion_test.go | 28 +++- .../build/v1alpha2/zz_generated.deepcopy.go | 41 +++++- pkg/cnb/create_builder_test.go | 120 +++++++++--------- pkg/reconciler/builder/builder_test.go | 14 +- .../clusterbuilder/clusterbuilder_test.go | 25 ++-- 10 files changed, 263 insertions(+), 96 deletions(-) diff --git a/pkg/apis/build/v1alpha2/builder_conversion.go b/pkg/apis/build/v1alpha2/builder_conversion.go index 323e9732..3c0cf6ef 100644 --- a/pkg/apis/build/v1alpha2/builder_conversion.go +++ b/pkg/apis/build/v1alpha2/builder_conversion.go @@ -7,6 +7,7 @@ import ( "knative.dev/pkg/apis" "github.com/pivotal/kpack/pkg/apis/build/v1alpha1" + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" ) func (b *Builder) ConvertTo(_ context.Context, to apis.Convertible) error { @@ -39,16 +40,44 @@ func (bs *NamespacedBuilderSpec) convertTo(to *v1alpha1.NamespacedBuilderSpec) { to.Tag = bs.Tag to.Stack = bs.Stack to.Store = bs.Store - to.Order = bs.Order to.ServiceAccount = bs.ServiceAccount() + + for _, builderOrderEntry := range bs.Order { + var coreOrderEntry corev1alpha1.OrderEntry + for _, ref := range builderOrderEntry.Group { + if ref.Id != "" { + coreOrderEntry.Group = append(coreOrderEntry.Group, + corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{Id: ref.Id, Version: ref.Version}, + Optional: ref.Optional, + }, + ) + } + } + to.Order = append(to.Order, coreOrderEntry) + } } func (bs *NamespacedBuilderSpec) convertFrom(from *v1alpha1.NamespacedBuilderSpec) { bs.Tag = from.Tag bs.Stack = from.Stack bs.Store = from.Store - bs.Order = from.Order bs.ServiceAccountName = from.ServiceAccount + + for _, coreOrderEntry := range from.Order { + var builderOrderEntry BuilderOrderEntry + for _, ref := range coreOrderEntry.Group { + builderOrderEntry.Group = append(builderOrderEntry.Group, + BuilderBuildpackRef{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{Id: ref.Id, Version: ref.Version}, + Optional: ref.Optional, + }, + }, + ) + } + bs.Order = append(bs.Order, builderOrderEntry) + } } func (bst *BuilderStatus) convertFrom(from *v1alpha1.BuilderStatus) { diff --git a/pkg/apis/build/v1alpha2/builder_conversion_test.go b/pkg/apis/build/v1alpha2/builder_conversion_test.go index c5770307..9b49751a 100644 --- a/pkg/apis/build/v1alpha2/builder_conversion_test.go +++ b/pkg/apis/build/v1alpha2/builder_conversion_test.go @@ -36,12 +36,23 @@ func testBuilderConversion(t *testing.T, when spec.G, it spec.S) { Kind: "ClusterStore", Name: "some-store", }, - Order: []corev1alpha1.OrderEntry{corev1alpha1.OrderEntry{ - Group: []corev1alpha1.BuildpackRef{{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "org.some-buildpack", + Order: []BuilderOrderEntry{BuilderOrderEntry{ + Group: []BuilderBuildpackRef{ + { + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "org.some-buildpack", + }, + }, }, - }}, + { + ObjectReference: corev1.ObjectReference{ + Kind: "Buildpack", + Name: "some-buildpack", + }, + }, + {Image: "some-repo/some-buildpack"}, + }, }}, }, ServiceAccountName: "some-service-account", @@ -101,6 +112,13 @@ func testBuilderConversion(t *testing.T, when spec.G, it spec.S) { require.Equal(t, v1alpha1Builder, testV1alpha1Builder) testV1alpha2Builder := &Builder{} + v1alpha2Builder.Spec.Order = []BuilderOrderEntry{{ + Group: []BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{Id: "org.some-buildpack"}, + }, + }}, + }} err = testV1alpha2Builder.ConvertFrom(context.TODO(), v1alpha1Builder) require.NoError(t, err) require.Equal(t, testV1alpha2Builder, v1alpha2Builder) diff --git a/pkg/apis/build/v1alpha2/builder_types.go b/pkg/apis/build/v1alpha2/builder_types.go index 4d3468fa..25de1b93 100644 --- a/pkg/apis/build/v1alpha2/builder_types.go +++ b/pkg/apis/build/v1alpha2/builder_types.go @@ -32,7 +32,19 @@ type BuilderSpec struct { Stack corev1.ObjectReference `json:"stack,omitempty"` Store corev1.ObjectReference `json:"store,omitempty"` // +listType - Order []corev1alpha1.OrderEntry `json:"order,omitempty"` + Order []BuilderOrderEntry `json:"order,omitempty"` +} + +type BuilderOrderEntry struct { + // +listType + Group []BuilderBuildpackRef `json:"group,omitempty"` +} + +// +k8s:openapi-gen=true +type BuilderBuildpackRef struct { + corev1alpha1.BuildpackRef `json:",inline"` + corev1.ObjectReference `json:",inline"` + Image string `json:"image,omitempty"` } // +k8s:openapi-gen=true diff --git a/pkg/apis/build/v1alpha2/builder_validation.go b/pkg/apis/build/v1alpha2/builder_validation.go index 01735224..8ff2d78e 100644 --- a/pkg/apis/build/v1alpha2/builder_validation.go +++ b/pkg/apis/build/v1alpha2/builder_validation.go @@ -29,7 +29,8 @@ func (cb *Builder) Validate(ctx context.Context) *apis.FieldError { func (s *BuilderSpec) Validate(ctx context.Context) *apis.FieldError { return validate.Tag(s.Tag). Also(validateStack(s.Stack).ViaField("stack")). - Also(validateStore(s.Store).ViaField("store")) + Also(validateStore(s.Store).ViaField("store")). + Also(validateOrder(s.Order).ViaField("order")) } func (s *NamespacedBuilderSpec) Validate(ctx context.Context) *apis.FieldError { @@ -62,3 +63,23 @@ func validateStore(store v1.ObjectReference) *apis.FieldError { return apis.ErrInvalidValue(store.Kind, "kind") } } + +func validateOrder(order []BuilderOrderEntry) *apis.FieldError { + var errs *apis.FieldError + for i, s := range order { + errs.Also(validateGroup(s).ViaIndex(i)) + } + return errs +} + +func validateGroup(group BuilderOrderEntry) *apis.FieldError { + var errs *apis.FieldError + for i, s := range group.Group { + errs.Also(validateBuildpackRef(s).ViaIndex(i).ViaField("group")) + } + return errs +} + +func validateBuildpackRef(ref BuilderBuildpackRef) *apis.FieldError { + return nil +} diff --git a/pkg/apis/build/v1alpha2/cluster_builder_conversion.go b/pkg/apis/build/v1alpha2/cluster_builder_conversion.go index 5cc09f4a..71ed5e23 100644 --- a/pkg/apis/build/v1alpha2/cluster_builder_conversion.go +++ b/pkg/apis/build/v1alpha2/cluster_builder_conversion.go @@ -7,6 +7,7 @@ import ( "knative.dev/pkg/apis" "github.com/pivotal/kpack/pkg/apis/build/v1alpha1" + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" ) func (b *ClusterBuilder) ConvertTo(_ context.Context, to apis.Convertible) error { @@ -39,14 +40,42 @@ func (cs *ClusterBuilderSpec) convertTo(to *v1alpha1.ClusterBuilderSpec) { to.Tag = cs.Tag to.Stack = cs.Stack to.Store = cs.Store - to.Order = cs.Order to.ServiceAccountRef = cs.ServiceAccountRef + + for _, builderOrderEntry := range cs.Order { + var coreOrderEntry corev1alpha1.OrderEntry + for _, ref := range builderOrderEntry.Group { + if ref.Id != "" { + coreOrderEntry.Group = append(coreOrderEntry.Group, + corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{Id: ref.Id, Version: ref.Version}, + Optional: ref.Optional, + }, + ) + } + } + to.Order = append(to.Order, coreOrderEntry) + } } func (cs *ClusterBuilderSpec) convertFrom(from *v1alpha1.ClusterBuilderSpec) { cs.Tag = from.Tag cs.Stack = from.Stack cs.Store = from.Store - cs.Order = from.Order cs.ServiceAccountRef = from.ServiceAccountRef + + for _, coreOrderEntry := range from.Order { + var builderOrderEntry BuilderOrderEntry + for _, ref := range coreOrderEntry.Group { + builderOrderEntry.Group = append(builderOrderEntry.Group, + BuilderBuildpackRef{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{Id: ref.Id, Version: ref.Version}, + Optional: ref.Optional, + }, + }, + ) + } + cs.Order = append(cs.Order, builderOrderEntry) + } } diff --git a/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go b/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go index 153aa841..39d53d46 100644 --- a/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go +++ b/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go @@ -36,12 +36,23 @@ func testClusterBuilderConversion(t *testing.T, when spec.G, it spec.S) { Kind: "ClusterStore", Name: "some-store", }, - Order: []corev1alpha1.OrderEntry{corev1alpha1.OrderEntry{ - Group: []corev1alpha1.BuildpackRef{{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "org.some-buildpack", + Order: []BuilderOrderEntry{{ + Group: []BuilderBuildpackRef{ + { + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "org.some-buildpack", + }, + }, }, - }}, + { + ObjectReference: corev1.ObjectReference{ + Kind: "Buildpack", + Name: "some-buildpack", + }, + }, + {Image: "some-repo/some-buildpack"}, + }, }}, }, ServiceAccountRef: corev1.ObjectReference{ @@ -97,6 +108,13 @@ func testClusterBuilderConversion(t *testing.T, when spec.G, it spec.S) { require.Equal(t, v1alpha1ClusterBuilder, testV1alpha1ClusterBuilder) testV1alpha2ClusterBuilder := &ClusterBuilder{} + v1alpha2ClusterBuilder.Spec.Order = []BuilderOrderEntry{{ + Group: []BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{Id: "org.some-buildpack"}, + }, + }}, + }} err = testV1alpha2ClusterBuilder.ConvertFrom(context.TODO(), v1alpha1ClusterBuilder) require.NoError(t, err) require.Equal(t, testV1alpha2ClusterBuilder, v1alpha2ClusterBuilder) diff --git a/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go index 790d2ffe..84acc037 100644 --- a/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go @@ -380,6 +380,24 @@ func (in *Builder) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BuilderBuildpackRef) DeepCopyInto(out *BuilderBuildpackRef) { + *out = *in + out.BuildpackRef = in.BuildpackRef + out.ObjectReference = in.ObjectReference + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BuilderBuildpackRef. +func (in *BuilderBuildpackRef) DeepCopy() *BuilderBuildpackRef { + if in == nil { + return nil + } + out := new(BuilderBuildpackRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BuilderList) DeepCopyInto(out *BuilderList) { *out = *in @@ -413,6 +431,27 @@ func (in *BuilderList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BuilderOrderEntry) DeepCopyInto(out *BuilderOrderEntry) { + *out = *in + if in.Group != nil { + in, out := &in.Group, &out.Group + *out = make([]BuilderBuildpackRef, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BuilderOrderEntry. +func (in *BuilderOrderEntry) DeepCopy() *BuilderOrderEntry { + if in == nil { + return nil + } + out := new(BuilderOrderEntry) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BuilderRecord) DeepCopyInto(out *BuilderRecord) { *out = *in @@ -449,7 +488,7 @@ func (in *BuilderSpec) DeepCopyInto(out *BuilderSpec) { out.Store = in.Store if in.Order != nil { in, out := &in.Order, &out.Order - *out = make([]v1alpha1.OrderEntry, len(*in)) + *out = make([]BuilderOrderEntry, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/pkg/cnb/create_builder_test.go b/pkg/cnb/create_builder_test.go index 55db9839..1ca9fdec 100644 --- a/pkg/cnb/create_builder_test.go +++ b/pkg/cnb/create_builder_test.go @@ -145,21 +145,25 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { Name: "some-buildpackRepository", Kind: "ClusterStore", }, - Order: []corev1alpha1.OrderEntry{ + Order: []buildapi.BuilderOrderEntry{ { - Group: []corev1alpha1.BuildpackRef{ + Group: []buildapi.BuilderBuildpackRef{ { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.1", - Version: "v1", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.1", + Version: "v1", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.2", - Version: "v2", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.2", + Version: "v2", + }, + Optional: true, }, - Optional: true, }, }, }, @@ -596,16 +600,16 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }) - clusterBuilderSpec.Order = []corev1alpha1.OrderEntry{ + clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{ { - Group: []corev1alpha1.BuildpackRef{ - { + Group: []buildapi.BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.unsupported.stack", Version: "v4", }, }, - }, + }}, }, } @@ -637,18 +641,16 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }) - clusterBuilderSpec.Order = []corev1alpha1.OrderEntry{ - { - Group: []corev1alpha1.BuildpackRef{ - { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.unsupported.mixin", - Version: "v4", - }, + clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ + Group: []buildapi.BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.unsupported.mixin", + Version: "v4", }, }, - }, - } + }}, + }} _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.mixin@v4: stack missing mixin(s): something-missing-mixin, something-missing-mixin2") @@ -698,18 +700,16 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }) - clusterBuilderSpec.Order = []corev1alpha1.OrderEntry{ - { - Group: []corev1alpha1.BuildpackRef{ - { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.relaxed.mixin", - Version: "v4", - }, + clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ + Group: []buildapi.BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.relaxed.mixin", + Version: "v4", }, }, - }, - } + }}, + }} _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) require.Nil(t, err) @@ -739,18 +739,16 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }) - clusterBuilderSpec.Order = []corev1alpha1.OrderEntry{ - { - Group: []corev1alpha1.BuildpackRef{ - { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.relaxed.old.mixin", - Version: "v4", - }, + clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ + Group: []buildapi.BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.relaxed.old.mixin", + Version: "v4", }, }, - }, - } + }}, + }} _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) require.Error(t, err, "validating buildpack io.buildpack.relaxed.old.mixin@v4: stack missing mixin(s): build:common-mixin, run:common-mixin, another-common-mixin") @@ -779,18 +777,16 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }) - clusterBuilderSpec.Order = []corev1alpha1.OrderEntry{ - { - Group: []corev1alpha1.BuildpackRef{ - { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.unsupported.buildpack.api", - Version: "v4", - }, + clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ + Group: []buildapi.BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.unsupported.buildpack.api", + Version: "v4", }, }, - }, - } + }}, + }} _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.buildpack.api@v4: unsupported buildpack api: 0.1, expecting: 0.2, 0.3") @@ -839,18 +835,16 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }) - clusterBuilderSpec.Order = []corev1alpha1.OrderEntry{ - { - Group: []corev1alpha1.BuildpackRef{ - { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "anystack.buildpack", - Version: "v1", - }, + clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ + Group: []buildapi.BuilderBuildpackRef{{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "anystack.buildpack", + Version: "v1", }, }, - }, - } + }}, + }} _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) require.NoError(t, err) diff --git a/pkg/reconciler/builder/builder_test.go b/pkg/reconciler/builder/builder_test.go index 3f9cee9c..b0beb350 100644 --- a/pkg/reconciler/builder/builder_test.go +++ b/pkg/reconciler/builder/builder_test.go @@ -111,17 +111,19 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { Kind: "ClusterStore", Name: "some-store", }, - Order: []corev1alpha1.OrderEntry{ - { - Group: []corev1alpha1.BuildpackRef{ - { + Order: []buildapi.BuilderOrderEntry{{ + Group: []buildapi.BuilderBuildpackRef{ + { + BuildpackRef: corev1alpha1.BuildpackRef{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "buildpack.id.1", Version: "1.0.0", }, Optional: false, }, - { + }, + { + BuildpackRef: corev1alpha1.BuildpackRef{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "buildpack.id.2", Version: "2.0.0", @@ -130,7 +132,7 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, }, }, - }, + }}, }, ServiceAccountName: "some-service-account", }, diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go index ae06a417..b7f7a940 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go @@ -113,22 +113,27 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { Kind: "ClusterStore", Name: "some-store", }, - Order: []corev1alpha1.OrderEntry{ + Order: []buildapi.BuilderOrderEntry{ { - Group: []corev1alpha1.BuildpackRef{ + Group: []buildapi.BuilderBuildpackRef{ { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "buildpack.id.1", - Version: "1.0.0", + BuildpackRef: corev1alpha1.BuildpackRef{ + + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "buildpack.id.1", + Version: "1.0.0", + }, + Optional: false, }, - Optional: false, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "buildpack.id.2", - Version: "2.0.0", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "buildpack.id.2", + Version: "2.0.0", + }, + Optional: false, }, - Optional: false, }, }, }, From 4937e9560966578de0d6c0a91f1f65d06fc9cc14 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Tue, 24 Jan 2023 17:07:38 -0500 Subject: [PATCH 08/39] rename core/v1alpha1/StoreBuildpack and StoreImage to BuildpackStatus and ImageSource respectively. these new names better reflect what they actually represent (the core api shouldn't care about the concept of a store) Signed-off-by: Bohan Chen --- .../build/v1alpha1/cluster_store_types.go | 4 +- .../v1alpha1/cluster_store_validation_test.go | 4 +- .../build/v1alpha1/zz_generated.deepcopy.go | 4 +- pkg/apis/build/v1alpha2/buildpack_types.go | 6 +- .../v1alpha2/buildpack_validation_test.go | 2 +- .../build/v1alpha2/cluster_buildpack_types.go | 6 +- .../cluster_buildpack_validation_test.go | 2 +- .../v1alpha2/cluster_store_conversion_test.go | 12 +-- .../build/v1alpha2/cluster_store_types.go | 6 +- .../v1alpha2/cluster_store_validation_test.go | 8 +- .../build/v1alpha2/zz_generated.deepcopy.go | 8 +- pkg/apis/core/v1alpha1/buildpack_types.go | 6 +- .../core/v1alpha1/zz_generated.deepcopy.go | 98 +++++++++---------- pkg/cnb/remote_store_reader.go | 8 +- pkg/cnb/remote_store_reader_test.go | 24 ++--- pkg/cnb/store_buildpack_repository.go | 16 +-- pkg/cnb/store_buildpack_repository_test.go | 26 ++--- pkg/reconciler/buildpack/buildpack.go | 4 +- pkg/reconciler/buildpack/buildpack_test.go | 10 +- .../buildpackfakes/fake_store_reader.go | 30 +++--- .../clusterbuildpack/clusterbuildpack.go | 4 +- .../clusterbuildpack/clusterbuildpack_test.go | 10 +- .../fake_store_reader.go | 30 +++--- pkg/reconciler/clusterstore/clusterstore.go | 2 +- .../clusterstore/clusterstore_test.go | 8 +- .../clusterstorefakes/fake_store_reader.go | 30 +++--- test/execute_build_test.go | 2 +- 27 files changed, 185 insertions(+), 185 deletions(-) diff --git a/pkg/apis/build/v1alpha1/cluster_store_types.go b/pkg/apis/build/v1alpha1/cluster_store_types.go index 587c79f7..98265a63 100644 --- a/pkg/apis/build/v1alpha1/cluster_store_types.go +++ b/pkg/apis/build/v1alpha1/cluster_store_types.go @@ -29,7 +29,7 @@ type ClusterStore struct { // +k8s:openapi-gen=true type ClusterStoreSpec struct { // +listType - Sources []corev1alpha1.StoreImage `json:"sources,omitempty"` + Sources []corev1alpha1.ImageSource `json:"sources,omitempty"` } // +k8s:openapi-gen=true @@ -37,7 +37,7 @@ type ClusterStoreStatus struct { corev1alpha1.Status `json:",inline"` // +listType - Buildpacks []corev1alpha1.StoreBuildpack `json:"buildpacks,omitempty"` + Buildpacks []corev1alpha1.BuildpackStatus `json:"buildpacks,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/build/v1alpha1/cluster_store_validation_test.go b/pkg/apis/build/v1alpha1/cluster_store_validation_test.go index d410194e..760e385a 100644 --- a/pkg/apis/build/v1alpha1/cluster_store_validation_test.go +++ b/pkg/apis/build/v1alpha1/cluster_store_validation_test.go @@ -22,7 +22,7 @@ func testClusterStoreValidation(t *testing.T, when spec.G, it spec.S) { Name: "store-name", }, Spec: ClusterStoreSpec{ - Sources: []corev1alpha1.StoreImage{ + Sources: []corev1alpha1.ImageSource{ { Image: "some-registry.io/store-image-1@sha256:78c1b9419976227e05be9d243b7fa583bea44a5258e52018b2af4cdfe23d148d", }, @@ -53,7 +53,7 @@ func testClusterStoreValidation(t *testing.T, when spec.G, it spec.S) { }) it("sources should contain a valid image", func() { - clusterStore.Spec.Sources = append(clusterStore.Spec.Sources, corev1alpha1.StoreImage{Image: "invalid image"}) + clusterStore.Spec.Sources = append(clusterStore.Spec.Sources, corev1alpha1.ImageSource{Image: "invalid image"}) assertValidationError(clusterStore, apis.ErrInvalidArrayValue(clusterStore.Spec.Sources[3], "sources", 3).ViaField("spec")) }) }) diff --git a/pkg/apis/build/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/build/v1alpha1/zz_generated.deepcopy.go index 70a7c618..2a966f71 100644 --- a/pkg/apis/build/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/build/v1alpha1/zz_generated.deepcopy.go @@ -623,7 +623,7 @@ func (in *ClusterStoreSpec) DeepCopyInto(out *ClusterStoreSpec) { *out = *in if in.Sources != nil { in, out := &in.Sources, &out.Sources - *out = make([]corev1alpha1.StoreImage, len(*in)) + *out = make([]corev1alpha1.ImageSource, len(*in)) copy(*out, *in) } return @@ -645,7 +645,7 @@ func (in *ClusterStoreStatus) DeepCopyInto(out *ClusterStoreStatus) { in.Status.DeepCopyInto(&out.Status) if in.Buildpacks != nil { in, out := &in.Buildpacks, &out.Buildpacks - *out = make([]corev1alpha1.StoreBuildpack, len(*in)) + *out = make([]corev1alpha1.BuildpackStatus, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/pkg/apis/build/v1alpha2/buildpack_types.go b/pkg/apis/build/v1alpha2/buildpack_types.go index 8e945e4f..986352cc 100644 --- a/pkg/apis/build/v1alpha2/buildpack_types.go +++ b/pkg/apis/build/v1alpha2/buildpack_types.go @@ -28,8 +28,8 @@ type Buildpack struct { // +k8s:openapi-gen=true type BuildpackSpec struct { // +listType - Source corev1alpha1.StoreImage `json:"source,omitempty"` - ServiceAccountName string `json:"serviceAccountName,omitempty"` + Source corev1alpha1.ImageSource `json:"source,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty"` } // +k8s:openapi-gen=true @@ -37,7 +37,7 @@ type BuildpackStatus struct { corev1alpha1.Status `json:",inline"` // +listType - Buildpacks []corev1alpha1.StoreBuildpack `json:"buildpacks,omitempty"` + Buildpacks []corev1alpha1.BuildpackStatus `json:"buildpacks,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/build/v1alpha2/buildpack_validation_test.go b/pkg/apis/build/v1alpha2/buildpack_validation_test.go index 80725c87..a156c2b4 100644 --- a/pkg/apis/build/v1alpha2/buildpack_validation_test.go +++ b/pkg/apis/build/v1alpha2/buildpack_validation_test.go @@ -22,7 +22,7 @@ func testBuildpackValidation(t *testing.T, when spec.G, it spec.S) { Namespace: "custom-builder-namespace", }, Spec: BuildpackSpec{ - Source: corev1alpha1.StoreImage{ + Source: corev1alpha1.ImageSource{ Image: "some-registry.io/store-image-1@sha256:78c1b9419976227e05be9d243b7fa583bea44a5258e52018b2af4cdfe23d148d", }, ServiceAccountName: "some-service-account", diff --git a/pkg/apis/build/v1alpha2/cluster_buildpack_types.go b/pkg/apis/build/v1alpha2/cluster_buildpack_types.go index cd1790ee..e87c5474 100644 --- a/pkg/apis/build/v1alpha2/cluster_buildpack_types.go +++ b/pkg/apis/build/v1alpha2/cluster_buildpack_types.go @@ -29,8 +29,8 @@ type ClusterBuildpack struct { // +k8s:openapi-gen=true type ClusterBuildpackSpec struct { // +listType - Source corev1alpha1.StoreImage `json:"source,omitempty"` - ServiceAccountRef *corev1.ObjectReference `json:"serviceAccountRef,omitempty"` + Source corev1alpha1.ImageSource `json:"source,omitempty"` + ServiceAccountRef *corev1.ObjectReference `json:"serviceAccountRef,omitempty"` } // +k8s:openapi-gen=true @@ -38,7 +38,7 @@ type ClusterBuildpackStatus struct { corev1alpha1.Status `json:",inline"` // +listType - Buildpacks []corev1alpha1.StoreBuildpack `json:"buildpacks,omitempty"` + Buildpacks []corev1alpha1.BuildpackStatus `json:"buildpacks,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go b/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go index fcf7dd98..f4d2e466 100644 --- a/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go +++ b/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go @@ -23,7 +23,7 @@ func testClusterBuildpackValidation(t *testing.T, when spec.G, it spec.S) { Namespace: "custom-builder-namespace", }, Spec: ClusterBuildpackSpec{ - Source: corev1alpha1.StoreImage{ + Source: corev1alpha1.ImageSource{ Image: "some-registry.io/store-image-1@sha256:78c1b9419976227e05be9d243b7fa583bea44a5258e52018b2af4cdfe23d148d", }, ServiceAccountRef: &corev1.ObjectReference{ diff --git a/pkg/apis/build/v1alpha2/cluster_store_conversion_test.go b/pkg/apis/build/v1alpha2/cluster_store_conversion_test.go index 659b1ef9..fc7ae083 100644 --- a/pkg/apis/build/v1alpha2/cluster_store_conversion_test.go +++ b/pkg/apis/build/v1alpha2/cluster_store_conversion_test.go @@ -24,7 +24,7 @@ func testClusterStoreConversion(t *testing.T, when spec.G, it spec.S) { Annotations: map[string]string{"some-key": "some-value"}, }, Spec: ClusterStoreSpec{ - Sources: []corev1alpha1.StoreImage{{"some-image"}, {"another-image"}}, + Sources: []corev1alpha1.ImageSource{{"some-image"}, {"another-image"}}, ServiceAccountRef: &corev1.ObjectReference{ Namespace: "some-namespace", Name: "some-service-account", @@ -32,7 +32,7 @@ func testClusterStoreConversion(t *testing.T, when spec.G, it spec.S) { }, Status: ClusterStoreStatus{ Status: corev1alpha1.Status{}, - Buildpacks: []corev1alpha1.StoreBuildpack{{ + Buildpacks: []corev1alpha1.BuildpackStatus{{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "cool-buildpack-id", Version: "1.23", @@ -42,7 +42,7 @@ func testClusterStoreConversion(t *testing.T, when spec.G, it spec.S) { Version: "4.56", Homepage: "wow-what-a-site.com", }, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some-image", }, DiffId: "12345", @@ -65,11 +65,11 @@ func testClusterStoreConversion(t *testing.T, when spec.G, it spec.S) { }, }, Spec: v1alpha1.ClusterStoreSpec{ - Sources: []corev1alpha1.StoreImage{{"some-image"}, {"another-image"}}, + Sources: []corev1alpha1.ImageSource{{"some-image"}, {"another-image"}}, }, Status: v1alpha1.ClusterStoreStatus{ Status: corev1alpha1.Status{}, - Buildpacks: []corev1alpha1.StoreBuildpack{{ + Buildpacks: []corev1alpha1.BuildpackStatus{{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "cool-buildpack-id", Version: "1.23", @@ -79,7 +79,7 @@ func testClusterStoreConversion(t *testing.T, when spec.G, it spec.S) { Version: "4.56", Homepage: "wow-what-a-site.com", }, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some-image", }, DiffId: "12345", diff --git a/pkg/apis/build/v1alpha2/cluster_store_types.go b/pkg/apis/build/v1alpha2/cluster_store_types.go index 26992aee..312b14c3 100644 --- a/pkg/apis/build/v1alpha2/cluster_store_types.go +++ b/pkg/apis/build/v1alpha2/cluster_store_types.go @@ -29,8 +29,8 @@ type ClusterStore struct { // +k8s:openapi-gen=true type ClusterStoreSpec struct { // +listType - Sources []corev1alpha1.StoreImage `json:"sources,omitempty"` - ServiceAccountRef *corev1.ObjectReference `json:"serviceAccountRef,omitempty"` + Sources []corev1alpha1.ImageSource `json:"sources,omitempty"` + ServiceAccountRef *corev1.ObjectReference `json:"serviceAccountRef,omitempty"` } // +k8s:openapi-gen=true @@ -38,7 +38,7 @@ type ClusterStoreStatus struct { corev1alpha1.Status `json:",inline"` // +listType - Buildpacks []corev1alpha1.StoreBuildpack `json:"buildpacks,omitempty"` + Buildpacks []corev1alpha1.BuildpackStatus `json:"buildpacks,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/build/v1alpha2/cluster_store_validation_test.go b/pkg/apis/build/v1alpha2/cluster_store_validation_test.go index 378fa2a2..f14fdc9e 100644 --- a/pkg/apis/build/v1alpha2/cluster_store_validation_test.go +++ b/pkg/apis/build/v1alpha2/cluster_store_validation_test.go @@ -23,7 +23,7 @@ func testClusterStoreValidation(t *testing.T, when spec.G, it spec.S) { Name: "store-name", }, Spec: ClusterStoreSpec{ - Sources: []corev1alpha1.StoreImage{ + Sources: []corev1alpha1.ImageSource{ { Image: "some-registry.io/store-image-1@sha256:78c1b9419976227e05be9d243b7fa583bea44a5258e52018b2af4cdfe23d148d", }, @@ -47,7 +47,7 @@ func testClusterStoreValidation(t *testing.T, when spec.G, it spec.S) { Message: "it-is-too-late", }}, }, - Buildpacks: []corev1alpha1.StoreBuildpack{ + Buildpacks: []corev1alpha1.BuildpackStatus{ { BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "", @@ -58,7 +58,7 @@ func testClusterStoreValidation(t *testing.T, when spec.G, it spec.S) { Version: "", Homepage: "", }, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "", }, DiffId: "", @@ -90,7 +90,7 @@ func testClusterStoreValidation(t *testing.T, when spec.G, it spec.S) { }) it("sources should contain a valid image", func() { - clusterStore.Spec.Sources = append(clusterStore.Spec.Sources, corev1alpha1.StoreImage{Image: "invalid image"}) + clusterStore.Spec.Sources = append(clusterStore.Spec.Sources, corev1alpha1.ImageSource{Image: "invalid image"}) assertValidationError(clusterStore, apis.ErrInvalidArrayValue(clusterStore.Spec.Sources[3], "sources", 3).ViaField("spec")) }) diff --git a/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go index 84acc037..2f0f7af9 100644 --- a/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go @@ -628,7 +628,7 @@ func (in *BuildpackStatus) DeepCopyInto(out *BuildpackStatus) { in.Status.DeepCopyInto(&out.Status) if in.Buildpacks != nil { in, out := &in.Buildpacks, &out.Buildpacks - *out = make([]v1alpha1.StoreBuildpack, len(*in)) + *out = make([]v1alpha1.BuildpackStatus, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -830,7 +830,7 @@ func (in *ClusterBuildpackStatus) DeepCopyInto(out *ClusterBuildpackStatus) { in.Status.DeepCopyInto(&out.Status) if in.Buildpacks != nil { in, out := &in.Buildpacks, &out.Buildpacks - *out = make([]v1alpha1.StoreBuildpack, len(*in)) + *out = make([]v1alpha1.BuildpackStatus, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -1064,7 +1064,7 @@ func (in *ClusterStoreSpec) DeepCopyInto(out *ClusterStoreSpec) { *out = *in if in.Sources != nil { in, out := &in.Sources, &out.Sources - *out = make([]v1alpha1.StoreImage, len(*in)) + *out = make([]v1alpha1.ImageSource, len(*in)) copy(*out, *in) } if in.ServiceAccountRef != nil { @@ -1091,7 +1091,7 @@ func (in *ClusterStoreStatus) DeepCopyInto(out *ClusterStoreStatus) { in.Status.DeepCopyInto(&out.Status) if in.Buildpacks != nil { in, out := &in.Buildpacks, &out.Buildpacks - *out = make([]v1alpha1.StoreBuildpack, len(*in)) + *out = make([]v1alpha1.BuildpackStatus, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/pkg/apis/core/v1alpha1/buildpack_types.go b/pkg/apis/core/v1alpha1/buildpack_types.go index 447c3853..625c69c7 100644 --- a/pkg/apis/core/v1alpha1/buildpack_types.go +++ b/pkg/apis/core/v1alpha1/buildpack_types.go @@ -4,16 +4,16 @@ import "fmt" // +k8s:openapi-gen=true // +k8s:deepcopy-gen=true -type StoreImage struct { +type ImageSource struct { Image string `json:"image,omitempty"` } // +k8s:openapi-gen=true // +k8s:deepcopy-gen=true -type StoreBuildpack struct { +type BuildpackStatus struct { BuildpackInfo `json:",inline"` Buildpackage BuildpackageInfo `json:"buildpackage,omitempty"` - StoreImage StoreImage `json:"storeImage,omitempty"` + StoreImage ImageSource `json:"storeImage,omitempty"` DiffId string `json:"diffId,omitempty"` Digest string `json:"digest,omitempty"` Size int64 `json:"size,omitempty"` diff --git a/pkg/apis/core/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/core/v1alpha1/zz_generated.deepcopy.go index 4ff67bef..30c94bee 100644 --- a/pkg/apis/core/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/core/v1alpha1/zz_generated.deepcopy.go @@ -148,6 +148,39 @@ func (in *BuildpackStack) DeepCopy() *BuildpackStack { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BuildpackStatus) DeepCopyInto(out *BuildpackStatus) { + *out = *in + out.BuildpackInfo = in.BuildpackInfo + out.Buildpackage = in.Buildpackage + out.StoreImage = in.StoreImage + if in.Order != nil { + in, out := &in.Order, &out.Order + *out = make([]OrderEntry, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Stacks != nil { + in, out := &in.Stacks, &out.Stacks + *out = make([]BuildpackStack, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BuildpackStatus. +func (in *BuildpackStatus) DeepCopy() *BuildpackStatus { + if in == nil { + return nil + } + out := new(BuildpackStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BuildpackageInfo) DeepCopyInto(out *BuildpackageInfo) { *out = *in @@ -245,6 +278,22 @@ func (in *Git) DeepCopy() *Git { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageSource) DeepCopyInto(out *ImageSource) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageSource. +func (in *ImageSource) DeepCopy() *ImageSource { + if in == nil { + return nil + } + out := new(ImageSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NotaryConfig) DeepCopyInto(out *NotaryConfig) { *out = *in @@ -479,55 +528,6 @@ func (in *Status) DeepCopy() *Status { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StoreBuildpack) DeepCopyInto(out *StoreBuildpack) { - *out = *in - out.BuildpackInfo = in.BuildpackInfo - out.Buildpackage = in.Buildpackage - out.StoreImage = in.StoreImage - if in.Order != nil { - in, out := &in.Order, &out.Order - *out = make([]OrderEntry, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Stacks != nil { - in, out := &in.Stacks, &out.Stacks - *out = make([]BuildpackStack, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StoreBuildpack. -func (in *StoreBuildpack) DeepCopy() *StoreBuildpack { - if in == nil { - return nil - } - out := new(StoreBuildpack) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StoreImage) DeepCopyInto(out *StoreImage) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StoreImage. -func (in *StoreImage) DeepCopy() *StoreImage { - if in == nil { - return nil - } - out := new(StoreImage) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolatileTime) DeepCopyInto(out *VolatileTime) { *out = *in diff --git a/pkg/cnb/remote_store_reader.go b/pkg/cnb/remote_store_reader.go index 72393d1c..56999e8e 100644 --- a/pkg/cnb/remote_store_reader.go +++ b/pkg/cnb/remote_store_reader.go @@ -16,10 +16,10 @@ type RemoteStoreReader struct { RegistryClient RegistryClient } -func (r *RemoteStoreReader) Read(keychain authn.Keychain, storeImages []corev1alpha1.StoreImage) ([]corev1alpha1.StoreBuildpack, error) { +func (r *RemoteStoreReader) Read(keychain authn.Keychain, storeImages []corev1alpha1.ImageSource) ([]corev1alpha1.BuildpackStatus, error) { var g errgroup.Group - c := make(chan corev1alpha1.StoreBuildpack) + c := make(chan corev1alpha1.BuildpackStatus) for _, storeImage := range storeImages { storeImageCopy := storeImage g.Go(func() error { @@ -77,7 +77,7 @@ func (r *RemoteStoreReader) Read(keychain authn.Keychain, storeImages []corev1al return errors.Wrapf(err, "unable to get layer %s digest", info) } - c <- corev1alpha1.StoreBuildpack{ + c <- corev1alpha1.BuildpackStatus{ BuildpackInfo: info, Buildpackage: packageInfo, StoreImage: storeImageCopy, @@ -100,7 +100,7 @@ func (r *RemoteStoreReader) Read(keychain authn.Keychain, storeImages []corev1al close(c) }() - var buildpacks []corev1alpha1.StoreBuildpack + var buildpacks []corev1alpha1.BuildpackStatus for b := range c { buildpacks = append(buildpacks, b) } diff --git a/pkg/cnb/remote_store_reader_test.go b/pkg/cnb/remote_store_reader_test.go index 01d0f122..f2c8aa18 100644 --- a/pkg/cnb/remote_store_reader_test.go +++ b/pkg/cnb/remote_store_reader_test.go @@ -205,7 +205,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { }) it("returns all buildpacks from multiple images", func() { - storeBuildpacks, err := remoteStoreReader.Read(expectedKeychain, []corev1alpha1.StoreImage{ + storeBuildpacks, err := remoteStoreReader.Read(expectedKeychain, []corev1alpha1.ImageSource{ { Image: buildpackageA, }, @@ -216,7 +216,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { require.NoError(t, err) require.Len(t, storeBuildpacks, 4) - require.Contains(t, storeBuildpacks, corev1alpha1.StoreBuildpack{ + require.Contains(t, storeBuildpacks, corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "org.buildpack.multi", Version: "0.0.1", @@ -226,7 +226,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { Version: "0.0.2", Homepage: "some-homepage", }, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: buildpackageA, }, API: "0.2", @@ -244,7 +244,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { Digest: "sha256:52f341c7c36e21e5c344856dd61bc8c2d1188647f259eaba6d375e37c9aed08e", Size: 20, }) - require.Contains(t, storeBuildpacks, corev1alpha1.StoreBuildpack{ + require.Contains(t, storeBuildpacks, corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "org.buildpack.multi", Version: "0.0.2", @@ -254,7 +254,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { Version: "0.0.2", Homepage: "some-homepage", }, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: buildpackageA, }, API: "0.2", @@ -274,7 +274,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { }) require.Contains(t, storeBuildpacks, - corev1alpha1.StoreBuildpack{ + corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "org.buildpack.meta", Version: "0.0.2", @@ -284,7 +284,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { Version: "0.0.2", Homepage: "some-homepage", }, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: buildpackageA, }, API: "0.2", @@ -325,7 +325,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { Size: 10, }) - require.Contains(t, storeBuildpacks, corev1alpha1.StoreBuildpack{ + require.Contains(t, storeBuildpacks, corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "org.buildpack.simple", Version: "0.0.1", @@ -349,14 +349,14 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { ID: "org.simple.only.stack", }, }, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: buildpackageB, }, }) }) it("returns all buildpacks in a deterministic order", func() { - expectedBuildpackOrder, err := remoteStoreReader.Read(expectedKeychain, []corev1alpha1.StoreImage{ + expectedBuildpackOrder, err := remoteStoreReader.Read(expectedKeychain, []corev1alpha1.ImageSource{ { Image: buildpackageA, }, @@ -367,7 +367,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { require.NoError(t, err) for i := 1; i <= 50; i++ { - subsequentOrder, err := remoteStoreReader.Read(expectedKeychain, []corev1alpha1.StoreImage{ + subsequentOrder, err := remoteStoreReader.Read(expectedKeychain, []corev1alpha1.ImageSource{ { Image: buildpackageA, }, @@ -434,7 +434,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { fakeClient.AddImage("image/with_duplicates", imageWithDuplicates, expectedKeychain) - images := []corev1alpha1.StoreImage{ + images := []corev1alpha1.ImageSource{ { Image: buildpackageA, }, diff --git a/pkg/cnb/store_buildpack_repository.go b/pkg/cnb/store_buildpack_repository.go index 5cc3303e..da54037a 100644 --- a/pkg/cnb/store_buildpack_repository.go +++ b/pkg/cnb/store_buildpack_repository.go @@ -59,8 +59,8 @@ func (s *StoreBuildpackRepository) FindByIdAndVersion(id, version string) (Remot }, nil } -func (s *StoreBuildpackRepository) findBuildpack(id, version string) (corev1alpha1.StoreBuildpack, error) { - var matchingBuildpacks []corev1alpha1.StoreBuildpack +func (s *StoreBuildpackRepository) findBuildpack(id, version string) (corev1alpha1.BuildpackStatus, error) { + var matchingBuildpacks []corev1alpha1.BuildpackStatus for _, buildpack := range s.ClusterStore.Status.Buildpacks { if buildpack.Id == id { matchingBuildpacks = append(matchingBuildpacks, buildpack) @@ -68,7 +68,7 @@ func (s *StoreBuildpackRepository) findBuildpack(id, version string) (corev1alph } if len(matchingBuildpacks) == 0 { - return corev1alpha1.StoreBuildpack{}, errors.Errorf("could not find buildpack with id '%s'", id) + return corev1alpha1.BuildpackStatus{}, errors.Errorf("could not find buildpack with id '%s'", id) } if version == "" { @@ -81,7 +81,7 @@ func (s *StoreBuildpackRepository) findBuildpack(id, version string) (corev1alph } } - return corev1alpha1.StoreBuildpack{}, errors.Errorf("could not find buildpack with id '%s' and version '%s'", id, version) + return corev1alpha1.BuildpackStatus{}, errors.Errorf("could not find buildpack with id '%s' and version '%s'", id, version) } // TODO: ensure there are no cycles in the buildpack graph @@ -101,17 +101,17 @@ func (s *StoreBuildpackRepository) layersForOrder(order corev1alpha1.Order) ([]b return buildpackLayers, nil } -func highestVersion(matchingBuildpacks []corev1alpha1.StoreBuildpack) (corev1alpha1.StoreBuildpack, error) { +func highestVersion(matchingBuildpacks []corev1alpha1.BuildpackStatus) (corev1alpha1.BuildpackStatus, error) { for _, bp := range matchingBuildpacks { if _, err := semver.NewVersion(bp.Version); err != nil { - return corev1alpha1.StoreBuildpack{}, errors.Errorf("cannot find buildpack '%s' with latest version due to invalid semver '%s'", bp.Id, bp.Version) + return corev1alpha1.BuildpackStatus{}, errors.Errorf("cannot find buildpack '%s' with latest version due to invalid semver '%s'", bp.Id, bp.Version) } } sort.Sort(byBuildpackVersion(matchingBuildpacks)) return matchingBuildpacks[len(matchingBuildpacks)-1], nil } -type byBuildpackVersion []corev1alpha1.StoreBuildpack +type byBuildpackVersion []corev1alpha1.BuildpackStatus func (b byBuildpackVersion) Len() int { return len(b) @@ -125,7 +125,7 @@ func (b byBuildpackVersion) Less(i, j int) bool { return semver.MustParse(b[i].Version).LessThan(semver.MustParse(b[j].Version)) } -func layerFromStoreBuildpack(keychain authn.Keychain, buildpack corev1alpha1.StoreBuildpack) (v1.Layer, error) { +func layerFromStoreBuildpack(keychain authn.Keychain, buildpack corev1alpha1.BuildpackStatus) (v1.Layer, error) { return imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ Digest: buildpack.Digest, DiffId: buildpack.DiffId, diff --git a/pkg/cnb/store_buildpack_repository_test.go b/pkg/cnb/store_buildpack_repository_test.go index 7206f7ca..c2ac9649 100644 --- a/pkg/cnb/store_buildpack_repository_test.go +++ b/pkg/cnb/store_buildpack_repository_test.go @@ -19,7 +19,7 @@ func TestBuildpackRepository(t *testing.T) { func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { when("FindByIdAndVersion", func() { - engineBuildpack := corev1alpha1.StoreBuildpack{ + engineBuildpack := corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.engine", Version: "1.0.0", @@ -27,7 +27,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { DiffId: "sha256:1bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", Digest: "sha256:d345d1b12ae6b3f7cfc617f7adaebe06c32ce60b1aa30bb80fb622b65523de8f", Size: 50, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry.io/build-package", }, Order: nil, @@ -43,7 +43,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }, } - packageManagerBuildpack := corev1alpha1.StoreBuildpack{ + packageManagerBuildpack := corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.package-manager", Version: "1.0.0", @@ -51,7 +51,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { DiffId: "sha256:2bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", Digest: "sha256:7c1213a54d20137a7479e72150c058268a6604b98c011b4fc11ca45927923d7b", Size: 40, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry.io/build-package", }, Order: nil, @@ -67,7 +67,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }, } - metaBuildpack := corev1alpha1.StoreBuildpack{ + metaBuildpack := corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.meta", Version: "1.0.0", @@ -75,7 +75,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { DiffId: "sha256:3bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", Digest: "sha256:07db84e57fdd7101104c2469984217696fdfe51591cb1edee2928514135920d6", Size: 30, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry.io/build-package", }, Order: []corev1alpha1.OrderEntry{ @@ -110,7 +110,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }, } - v8Buildpack := corev1alpha1.StoreBuildpack{ + v8Buildpack := corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.multi", Version: "8.0.0", @@ -118,7 +118,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { DiffId: "sha256:8bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", Digest: "sha256:fc14806eb95d01b6338ba1b9fea605e84db7c8c09561ae360bad5b80b5d0d80b", Size: 20, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry.io/build-package", }, Order: nil, @@ -134,7 +134,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }, } - v9Buildpack := corev1alpha1.StoreBuildpack{ + v9Buildpack := corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.multi", Version: "9.0.0", @@ -142,7 +142,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", Size: 10, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry.io/build-package", }, Order: nil, @@ -165,7 +165,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { Name: "some-store", }, Status: buildapi.ClusterStoreStatus{ - Buildpacks: []corev1alpha1.StoreBuildpack{ + Buildpacks: []corev1alpha1.BuildpackStatus{ engineBuildpack, v9Buildpack, v8Buildpack, @@ -272,7 +272,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }) it("fails to find the buildpack if version is unspecified and not all buildpacks are semver conformant", func() { - storeBuildpackRepository.ClusterStore.Status.Buildpacks = append(storeBuildpackRepository.ClusterStore.Status.Buildpacks, corev1alpha1.StoreBuildpack{ + storeBuildpackRepository.ClusterStore.Status.Buildpacks = append(storeBuildpackRepository.ClusterStore.Status.Buildpacks, corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.multi", Version: "my-wacky-version", @@ -280,7 +280,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", Size: 10, - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry.io/build-package", }, Order: nil, diff --git a/pkg/reconciler/buildpack/buildpack.go b/pkg/reconciler/buildpack/buildpack.go index dd0f15c2..0ff9242e 100644 --- a/pkg/reconciler/buildpack/buildpack.go +++ b/pkg/reconciler/buildpack/buildpack.go @@ -28,7 +28,7 @@ const ( //go:generate counterfeiter . StoreReader type StoreReader interface { - Read(keychain authn.Keychain, storeImages []corev1alpha1.StoreImage) ([]corev1alpha1.StoreBuildpack, error) + Read(keychain authn.Keychain, storeImages []corev1alpha1.ImageSource) ([]corev1alpha1.BuildpackStatus, error) } func NewController( @@ -128,7 +128,7 @@ func (c *Reconciler) reconcileBuildpackStatus(ctx context.Context, buildpack *bu return buildpack, err } - buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.StoreImage{buildpack.Spec.Source}) + buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.ImageSource{buildpack.Spec.Source}) if err != nil { buildpack.Status = buildapi.BuildpackStatus{ Status: corev1alpha1.CreateStatusWithReadyCondition(buildpack.Generation, err), diff --git a/pkg/reconciler/buildpack/buildpack_test.go b/pkg/reconciler/buildpack/buildpack_test.go index 24f8c7b3..fb977f92 100644 --- a/pkg/reconciler/buildpack/buildpack_test.go +++ b/pkg/reconciler/buildpack/buildpack_test.go @@ -63,21 +63,21 @@ func testBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { Generation: initialGeneration, }, Spec: buildapi.BuildpackSpec{ - Source: corev1alpha1.StoreImage{ + Source: corev1alpha1.ImageSource{ Image: "some.registry/some-image-2", }, }, } when("#Reconcile", func() { - readBuildpacks := []corev1alpha1.StoreBuildpack{ + readBuildpacks := []corev1alpha1.BuildpackStatus{ { BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "paketo-buildpacks/node-engine", Version: "0.0.116", }, DiffId: "sha256:d57937f5ccb6f524afa02dd95224e1914c94a02483d37b07aa668e560dcb3bf4", - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry/some-image-1", }, Order: nil, @@ -88,7 +88,7 @@ func testBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { Version: "0.0.71", }, DiffId: "sha256:c67840e5ccb6f524afa02dd95224e1914c94a02483d37b07aa668e560dcb3bf5", - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry/some-image-2", }, Order: nil, @@ -133,7 +133,7 @@ func testBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { assert.Equal(t, 1, fakeStoreReader.ReadCallCount()) _, StoreSpec := fakeStoreReader.ReadArgsForCall(0) - assert.Equal(t, []corev1alpha1.StoreImage{bp.Spec.Source}, StoreSpec) + assert.Equal(t, []corev1alpha1.ImageSource{bp.Spec.Source}, StoreSpec) }) it("uses the keychain of the referenced service account", func() { diff --git a/pkg/reconciler/buildpack/buildpackfakes/fake_store_reader.go b/pkg/reconciler/buildpack/buildpackfakes/fake_store_reader.go index 638d933a..428c8df2 100644 --- a/pkg/reconciler/buildpack/buildpackfakes/fake_store_reader.go +++ b/pkg/reconciler/buildpack/buildpackfakes/fake_store_reader.go @@ -10,35 +10,35 @@ import ( ) type FakeStoreReader struct { - ReadStub func(authn.Keychain, []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error) + ReadStub func(authn.Keychain, []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error) readMutex sync.RWMutex readArgsForCall []struct { arg1 authn.Keychain - arg2 []v1alpha1.StoreImage + arg2 []v1alpha1.ImageSource } readReturns struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error } readReturnsOnCall map[int]struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *FakeStoreReader) Read(arg1 authn.Keychain, arg2 []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error) { - var arg2Copy []v1alpha1.StoreImage +func (fake *FakeStoreReader) Read(arg1 authn.Keychain, arg2 []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error) { + var arg2Copy []v1alpha1.ImageSource if arg2 != nil { - arg2Copy = make([]v1alpha1.StoreImage, len(arg2)) + arg2Copy = make([]v1alpha1.ImageSource, len(arg2)) copy(arg2Copy, arg2) } fake.readMutex.Lock() ret, specificReturn := fake.readReturnsOnCall[len(fake.readArgsForCall)] fake.readArgsForCall = append(fake.readArgsForCall, struct { arg1 authn.Keychain - arg2 []v1alpha1.StoreImage + arg2 []v1alpha1.ImageSource }{arg1, arg2Copy}) stub := fake.ReadStub fakeReturns := fake.readReturns @@ -59,41 +59,41 @@ func (fake *FakeStoreReader) ReadCallCount() int { return len(fake.readArgsForCall) } -func (fake *FakeStoreReader) ReadCalls(stub func(authn.Keychain, []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error)) { +func (fake *FakeStoreReader) ReadCalls(stub func(authn.Keychain, []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error)) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = stub } -func (fake *FakeStoreReader) ReadArgsForCall(i int) (authn.Keychain, []v1alpha1.StoreImage) { +func (fake *FakeStoreReader) ReadArgsForCall(i int) (authn.Keychain, []v1alpha1.ImageSource) { fake.readMutex.RLock() defer fake.readMutex.RUnlock() argsForCall := fake.readArgsForCall[i] return argsForCall.arg1, argsForCall.arg2 } -func (fake *FakeStoreReader) ReadReturns(result1 []v1alpha1.StoreBuildpack, result2 error) { +func (fake *FakeStoreReader) ReadReturns(result1 []v1alpha1.BuildpackStatus, result2 error) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = nil fake.readReturns = struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }{result1, result2} } -func (fake *FakeStoreReader) ReadReturnsOnCall(i int, result1 []v1alpha1.StoreBuildpack, result2 error) { +func (fake *FakeStoreReader) ReadReturnsOnCall(i int, result1 []v1alpha1.BuildpackStatus, result2 error) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = nil if fake.readReturnsOnCall == nil { fake.readReturnsOnCall = make(map[int]struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }) } fake.readReturnsOnCall[i] = struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }{result1, result2} } diff --git a/pkg/reconciler/clusterbuildpack/clusterbuildpack.go b/pkg/reconciler/clusterbuildpack/clusterbuildpack.go index 8e29d29a..7bad6086 100644 --- a/pkg/reconciler/clusterbuildpack/clusterbuildpack.go +++ b/pkg/reconciler/clusterbuildpack/clusterbuildpack.go @@ -28,7 +28,7 @@ const ( //go:generate counterfeiter . StoreReader type StoreReader interface { - Read(keychain authn.Keychain, storeImages []corev1alpha1.StoreImage) ([]corev1alpha1.StoreBuildpack, error) + Read(keychain authn.Keychain, storeImages []corev1alpha1.ImageSource) ([]corev1alpha1.BuildpackStatus, error) } func NewController( @@ -128,7 +128,7 @@ func (c *Reconciler) reoncileClusterBuildpackStatus(ctx context.Context, cluster return clusterBuildpack, err } - buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.StoreImage{clusterBuildpack.Spec.Source}) + buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.ImageSource{clusterBuildpack.Spec.Source}) if err != nil { clusterBuildpack.Status = buildapi.ClusterBuildpackStatus{ Status: corev1alpha1.CreateStatusWithReadyCondition(clusterBuildpack.Generation, err), diff --git a/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go b/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go index 326d110d..42c4f3be 100644 --- a/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go +++ b/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go @@ -61,21 +61,21 @@ func testClusterBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { Generation: initialGeneration, }, Spec: buildapi.ClusterBuildpackSpec{ - Source: corev1alpha1.StoreImage{ + Source: corev1alpha1.ImageSource{ Image: "some.registry/some-image-2", }, }, } when("#Reconcile", func() { - readBuildpacks := []corev1alpha1.StoreBuildpack{ + readBuildpacks := []corev1alpha1.BuildpackStatus{ { BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "paketo-buildpacks/node-engine", Version: "0.0.116", }, DiffId: "sha256:d57937f5ccb6f524afa02dd95224e1914c94a02483d37b07aa668e560dcb3bf4", - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry/some-image-1", }, Order: nil, @@ -86,7 +86,7 @@ func testClusterBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { Version: "0.0.71", }, DiffId: "sha256:c67840e5ccb6f524afa02dd95224e1914c94a02483d37b07aa668e560dcb3bf5", - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry/some-image-2", }, Order: nil, @@ -131,7 +131,7 @@ func testClusterBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { assert.Equal(t, 1, fakeStoreReader.ReadCallCount()) _, clusterStoreSpec := fakeStoreReader.ReadArgsForCall(0) - assert.Equal(t, []corev1alpha1.StoreImage{cbp.Spec.Source}, clusterStoreSpec) + assert.Equal(t, []corev1alpha1.ImageSource{cbp.Spec.Source}, clusterStoreSpec) }) it("uses the keychain of the referenced service account", func() { diff --git a/pkg/reconciler/clusterbuildpack/clusterbuildpackfakes/fake_store_reader.go b/pkg/reconciler/clusterbuildpack/clusterbuildpackfakes/fake_store_reader.go index da2fba74..88282f61 100644 --- a/pkg/reconciler/clusterbuildpack/clusterbuildpackfakes/fake_store_reader.go +++ b/pkg/reconciler/clusterbuildpack/clusterbuildpackfakes/fake_store_reader.go @@ -10,35 +10,35 @@ import ( ) type FakeStoreReader struct { - ReadStub func(authn.Keychain, []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error) + ReadStub func(authn.Keychain, []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error) readMutex sync.RWMutex readArgsForCall []struct { arg1 authn.Keychain - arg2 []v1alpha1.StoreImage + arg2 []v1alpha1.ImageSource } readReturns struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error } readReturnsOnCall map[int]struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *FakeStoreReader) Read(arg1 authn.Keychain, arg2 []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error) { - var arg2Copy []v1alpha1.StoreImage +func (fake *FakeStoreReader) Read(arg1 authn.Keychain, arg2 []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error) { + var arg2Copy []v1alpha1.ImageSource if arg2 != nil { - arg2Copy = make([]v1alpha1.StoreImage, len(arg2)) + arg2Copy = make([]v1alpha1.ImageSource, len(arg2)) copy(arg2Copy, arg2) } fake.readMutex.Lock() ret, specificReturn := fake.readReturnsOnCall[len(fake.readArgsForCall)] fake.readArgsForCall = append(fake.readArgsForCall, struct { arg1 authn.Keychain - arg2 []v1alpha1.StoreImage + arg2 []v1alpha1.ImageSource }{arg1, arg2Copy}) stub := fake.ReadStub fakeReturns := fake.readReturns @@ -59,41 +59,41 @@ func (fake *FakeStoreReader) ReadCallCount() int { return len(fake.readArgsForCall) } -func (fake *FakeStoreReader) ReadCalls(stub func(authn.Keychain, []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error)) { +func (fake *FakeStoreReader) ReadCalls(stub func(authn.Keychain, []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error)) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = stub } -func (fake *FakeStoreReader) ReadArgsForCall(i int) (authn.Keychain, []v1alpha1.StoreImage) { +func (fake *FakeStoreReader) ReadArgsForCall(i int) (authn.Keychain, []v1alpha1.ImageSource) { fake.readMutex.RLock() defer fake.readMutex.RUnlock() argsForCall := fake.readArgsForCall[i] return argsForCall.arg1, argsForCall.arg2 } -func (fake *FakeStoreReader) ReadReturns(result1 []v1alpha1.StoreBuildpack, result2 error) { +func (fake *FakeStoreReader) ReadReturns(result1 []v1alpha1.BuildpackStatus, result2 error) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = nil fake.readReturns = struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }{result1, result2} } -func (fake *FakeStoreReader) ReadReturnsOnCall(i int, result1 []v1alpha1.StoreBuildpack, result2 error) { +func (fake *FakeStoreReader) ReadReturnsOnCall(i int, result1 []v1alpha1.BuildpackStatus, result2 error) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = nil if fake.readReturnsOnCall == nil { fake.readReturnsOnCall = make(map[int]struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }) } fake.readReturnsOnCall[i] = struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }{result1, result2} } diff --git a/pkg/reconciler/clusterstore/clusterstore.go b/pkg/reconciler/clusterstore/clusterstore.go index 20ad0df6..f9983452 100644 --- a/pkg/reconciler/clusterstore/clusterstore.go +++ b/pkg/reconciler/clusterstore/clusterstore.go @@ -28,7 +28,7 @@ const ( //go:generate counterfeiter . StoreReader type StoreReader interface { - Read(keychain authn.Keychain, storeImages []corev1alpha1.StoreImage) ([]corev1alpha1.StoreBuildpack, error) + Read(keychain authn.Keychain, storeImages []corev1alpha1.ImageSource) ([]corev1alpha1.BuildpackStatus, error) } func NewController( diff --git a/pkg/reconciler/clusterstore/clusterstore_test.go b/pkg/reconciler/clusterstore/clusterstore_test.go index 8c7ab703..78e4db48 100644 --- a/pkg/reconciler/clusterstore/clusterstore_test.go +++ b/pkg/reconciler/clusterstore/clusterstore_test.go @@ -61,7 +61,7 @@ func testClusterStoreReconciler(t *testing.T, when spec.G, it spec.S) { Generation: initialGeneration, }, Spec: buildapi.ClusterStoreSpec{ - Sources: []corev1alpha1.StoreImage{ + Sources: []corev1alpha1.ImageSource{ { Image: "some.registry/some-image-1", }, @@ -73,14 +73,14 @@ func testClusterStoreReconciler(t *testing.T, when spec.G, it spec.S) { } when("#Reconcile", func() { - readBuildpacks := []corev1alpha1.StoreBuildpack{ + readBuildpacks := []corev1alpha1.BuildpackStatus{ { BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "paketo-buildpacks/node-engine", Version: "0.0.116", }, DiffId: "sha256:d57937f5ccb6f524afa02dd95224e1914c94a02483d37b07aa668e560dcb3bf4", - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry/some-image-1", }, Order: nil, @@ -91,7 +91,7 @@ func testClusterStoreReconciler(t *testing.T, when spec.G, it spec.S) { Version: "0.0.71", }, DiffId: "sha256:c67840e5ccb6f524afa02dd95224e1914c94a02483d37b07aa668e560dcb3bf5", - StoreImage: corev1alpha1.StoreImage{ + StoreImage: corev1alpha1.ImageSource{ Image: "some.registry/some-image-2", }, Order: nil, diff --git a/pkg/reconciler/clusterstore/clusterstorefakes/fake_store_reader.go b/pkg/reconciler/clusterstore/clusterstorefakes/fake_store_reader.go index 1c19f026..cc030c62 100644 --- a/pkg/reconciler/clusterstore/clusterstorefakes/fake_store_reader.go +++ b/pkg/reconciler/clusterstore/clusterstorefakes/fake_store_reader.go @@ -10,35 +10,35 @@ import ( ) type FakeStoreReader struct { - ReadStub func(authn.Keychain, []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error) + ReadStub func(authn.Keychain, []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error) readMutex sync.RWMutex readArgsForCall []struct { arg1 authn.Keychain - arg2 []v1alpha1.StoreImage + arg2 []v1alpha1.ImageSource } readReturns struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error } readReturnsOnCall map[int]struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *FakeStoreReader) Read(arg1 authn.Keychain, arg2 []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error) { - var arg2Copy []v1alpha1.StoreImage +func (fake *FakeStoreReader) Read(arg1 authn.Keychain, arg2 []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error) { + var arg2Copy []v1alpha1.ImageSource if arg2 != nil { - arg2Copy = make([]v1alpha1.StoreImage, len(arg2)) + arg2Copy = make([]v1alpha1.ImageSource, len(arg2)) copy(arg2Copy, arg2) } fake.readMutex.Lock() ret, specificReturn := fake.readReturnsOnCall[len(fake.readArgsForCall)] fake.readArgsForCall = append(fake.readArgsForCall, struct { arg1 authn.Keychain - arg2 []v1alpha1.StoreImage + arg2 []v1alpha1.ImageSource }{arg1, arg2Copy}) stub := fake.ReadStub fakeReturns := fake.readReturns @@ -59,41 +59,41 @@ func (fake *FakeStoreReader) ReadCallCount() int { return len(fake.readArgsForCall) } -func (fake *FakeStoreReader) ReadCalls(stub func(authn.Keychain, []v1alpha1.StoreImage) ([]v1alpha1.StoreBuildpack, error)) { +func (fake *FakeStoreReader) ReadCalls(stub func(authn.Keychain, []v1alpha1.ImageSource) ([]v1alpha1.BuildpackStatus, error)) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = stub } -func (fake *FakeStoreReader) ReadArgsForCall(i int) (authn.Keychain, []v1alpha1.StoreImage) { +func (fake *FakeStoreReader) ReadArgsForCall(i int) (authn.Keychain, []v1alpha1.ImageSource) { fake.readMutex.RLock() defer fake.readMutex.RUnlock() argsForCall := fake.readArgsForCall[i] return argsForCall.arg1, argsForCall.arg2 } -func (fake *FakeStoreReader) ReadReturns(result1 []v1alpha1.StoreBuildpack, result2 error) { +func (fake *FakeStoreReader) ReadReturns(result1 []v1alpha1.BuildpackStatus, result2 error) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = nil fake.readReturns = struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }{result1, result2} } -func (fake *FakeStoreReader) ReadReturnsOnCall(i int, result1 []v1alpha1.StoreBuildpack, result2 error) { +func (fake *FakeStoreReader) ReadReturnsOnCall(i int, result1 []v1alpha1.BuildpackStatus, result2 error) { fake.readMutex.Lock() defer fake.readMutex.Unlock() fake.ReadStub = nil if fake.readReturnsOnCall == nil { fake.readReturnsOnCall = make(map[int]struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }) } fake.readReturnsOnCall[i] = struct { - result1 []v1alpha1.StoreBuildpack + result1 []v1alpha1.BuildpackStatus result2 error }{result1, result2} } diff --git a/test/execute_build_test.go b/test/execute_build_test.go index ee7476be..8a501896 100644 --- a/test/execute_build_test.go +++ b/test/execute_build_test.go @@ -125,7 +125,7 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) { Name: clusterStoreName, }, Spec: buildapi.ClusterStoreSpec{ - Sources: []corev1alpha1.StoreImage{ + Sources: []corev1alpha1.ImageSource{ { Image: builderImage, }, From dd585db426941472d54bb6aebb66348ef6d22e89 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Wed, 1 Feb 2023 15:46:09 -0500 Subject: [PATCH 09/39] split remote store reader into 2 parts the resolver will work with kubernetes objects and figure out which BuildpackStatus is being referenced the fetcher will setup/create the remote layers for communicating with the registry the interface between them is the K8sRemoteBuildpack which contains the filled out BuildpackStatus, as well as the secretRef that is used for the registry keychain Signed-off-by: Bohan Chen --- pkg/cnb/buildpack_resolver.go | 246 ++++++++++++++++++ pkg/cnb/create_builder.go | 37 ++- pkg/cnb/dependency_tree.go | 61 +++++ pkg/cnb/dependency_tree_test.go | 94 +++++++ pkg/cnb/fake_layer_test.go | 38 --- pkg/cnb/fakes_test.go | 105 ++++++++ pkg/cnb/remote_buildpack_fetcher.go | 108 ++++++++ ...st.go => remote_buildpack_fetcher_test.go} | 183 +++++-------- pkg/cnb/remote_buildpack_metadata.go | 6 + pkg/cnb/remote_store_reader.go | 4 +- pkg/cnb/remote_store_reader_test.go | 2 +- pkg/cnb/store_buildpack_repository.go | 136 ---------- 12 files changed, 714 insertions(+), 306 deletions(-) create mode 100644 pkg/cnb/buildpack_resolver.go create mode 100644 pkg/cnb/dependency_tree.go create mode 100644 pkg/cnb/dependency_tree_test.go delete mode 100644 pkg/cnb/fake_layer_test.go create mode 100644 pkg/cnb/fakes_test.go create mode 100644 pkg/cnb/remote_buildpack_fetcher.go rename pkg/cnb/{store_buildpack_repository_test.go => remote_buildpack_fetcher_test.go} (68%) delete mode 100644 pkg/cnb/store_buildpack_repository.go diff --git a/pkg/cnb/buildpack_resolver.go b/pkg/cnb/buildpack_resolver.go new file mode 100644 index 00000000..e71ffe0c --- /dev/null +++ b/pkg/cnb/buildpack_resolver.go @@ -0,0 +1,246 @@ +package cnb + +import ( + "fmt" + "sort" + + "github.com/Masterminds/semver/v3" + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/registry" + "github.com/pkg/errors" + v1 "k8s.io/api/core/v1" +) + +// BuildpackResolver will attempt to resolve a Buildpack reference to a +// Buildpack from either the ClusterStore, Buildpacks, or ClusterBuildpacks +type BuildpackResolver interface { + Resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) + ClusterStoreObservedGeneration() int64 +} + +type buildpackResolver struct { + keychainFactory registry.KeychainFactory + clusterstore *v1alpha2.ClusterStore + buildpacks []*v1alpha2.Buildpack + clusterBuildpacks []*v1alpha2.ClusterBuildpack +} + +func NewBuildpackResolver(keychainFactory registry.KeychainFactory, clusterStore *v1alpha2.ClusterStore, buildpacks []*v1alpha2.Buildpack, clusterBuildpacks []*v1alpha2.ClusterBuildpack) BuildpackResolver { + return &buildpackResolver{ + keychainFactory: keychainFactory, + clusterstore: clusterStore, + buildpacks: buildpacks, + clusterBuildpacks: clusterBuildpacks, + } +} + +func (r *buildpackResolver) ClusterStoreObservedGeneration() int64 { + if r.clusterstore != nil { + return r.clusterstore.Status.ObservedGeneration + } + return 0 +} + +func (r *buildpackResolver) Resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { + var matchingBuildpacks []K8sRemoteBuildpack + var err error + switch { + case ref.Kind == v1alpha2.BuildpackKind && ref.Id != "": + bp := findBuildpack(ref.ObjectReference, r.buildpacks) + if bp == nil { + return K8sRemoteBuildpack{}, fmt.Errorf("buildpack not found: %v", ref.Name) + } + + matchingBuildpacks, err = r.resolveFromBuildpack(ref.Id, []*v1alpha2.Buildpack{bp}) + if err != nil { + return K8sRemoteBuildpack{}, err + } + case ref.Kind == v1alpha2.ClusterBuildpackKind && ref.Id != "": + cbp := findClusterBuildpack(ref.ObjectReference, r.clusterBuildpacks) + if cbp == nil { + return K8sRemoteBuildpack{}, fmt.Errorf("cluster buildpack not found: %v", ref.Name) + } + + matchingBuildpacks, err = r.resolveFromClusterBuildpack(ref.Id, []*v1alpha2.ClusterBuildpack{cbp}) + if err != nil { + return K8sRemoteBuildpack{}, err + } + case ref.Kind != "": + bp, err := r.resolveFromObjectReference(ref.ObjectReference) + if err != nil { + return K8sRemoteBuildpack{}, err + } + matchingBuildpacks = []K8sRemoteBuildpack{bp} + case ref.Id != "": + bp, err := r.resolveFromBuildpack(ref.Id, r.buildpacks) + if err != nil { + return K8sRemoteBuildpack{}, err + } + matchingBuildpacks = append(matchingBuildpacks, bp...) + + cbp, err := r.resolveFromClusterBuildpack(ref.Id, r.clusterBuildpacks) + if err != nil { + return K8sRemoteBuildpack{}, err + } + matchingBuildpacks = append(matchingBuildpacks, cbp...) + + cs, err := r.resolveFromClusterStore(ref.Id, r.clusterstore) + if err != nil { + return K8sRemoteBuildpack{}, err + } + matchingBuildpacks = append(matchingBuildpacks, cs...) + case ref.Image != "": + // TODO(chenbh): + return K8sRemoteBuildpack{}, fmt.Errorf("using images in builders not currently supported") + } + + if len(matchingBuildpacks) == 0 { + return K8sRemoteBuildpack{}, errors.Errorf("could not find buildpack with id '%s'", ref.Id) + } + + if ref.Version == "" { + bp, err := highestVersion(matchingBuildpacks) + if err != nil { + return K8sRemoteBuildpack{}, err + } + return bp, nil + } + + for _, result := range matchingBuildpacks { + if result.Buildpack.Version == ref.Version { + return result, nil + } + } + + return K8sRemoteBuildpack{}, errors.Errorf("could not find buildpack with id '%s' and version '%s'", ref.Id, ref.Version) +} + +func (r *buildpackResolver) resolveFromBuildpack(id string, buildpacks []*v1alpha2.Buildpack) ([]K8sRemoteBuildpack, error) { + var matchingBuildpacks []K8sRemoteBuildpack + for _, bp := range buildpacks { + for _, status := range bp.Status.Buildpacks { + if status.Id == id { + + matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ + Buildpack: status, + SecretRef: registry.SecretRef{ + ServiceAccount: bp.Spec.ServiceAccountName, + Namespace: bp.Namespace, + }, + }) + } + } + } + return matchingBuildpacks, nil +} + +func (r *buildpackResolver) resolveFromClusterBuildpack(id string, clusterBuildpacks []*v1alpha2.ClusterBuildpack) ([]K8sRemoteBuildpack, error) { + var matchingBuildpacks []K8sRemoteBuildpack + for _, cbp := range clusterBuildpacks { + for _, status := range cbp.Status.Buildpacks { + if status.Id == id { + secretRef := registry.SecretRef{} + + if cbp.Spec.ServiceAccountRef != nil { + secretRef = registry.SecretRef{ + ServiceAccount: cbp.Spec.ServiceAccountRef.Name, + Namespace: cbp.Spec.ServiceAccountRef.Namespace, + } + } + matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ + Buildpack: status, + SecretRef: secretRef, + }) + } + } + } + return matchingBuildpacks, nil +} + +func (r *buildpackResolver) resolveFromClusterStore(id string, store *v1alpha2.ClusterStore) ([]K8sRemoteBuildpack, error) { + var matchingBuildpacks []K8sRemoteBuildpack + for _, status := range store.Status.Buildpacks { + if status.Id == id { + + matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ + Buildpack: status, + SecretRef: registry.SecretRef{ + ServiceAccount: store.Spec.ServiceAccountRef.Name, + Namespace: store.Spec.ServiceAccountRef.Namespace, + }, + }) + } + } + return matchingBuildpacks, nil +} + +// resolveFromObjectReference will get the object and figure out the root +// buildpack by converting it to a buildpack dependency tree +func (r *buildpackResolver) resolveFromObjectReference(ref v1.ObjectReference) (K8sRemoteBuildpack, error) { + var bps []corev1alpha1.BuildpackStatus + var secretRef registry.SecretRef + switch ref.Kind { + case v1alpha2.BuildpackKind: + bp := findBuildpack(ref, r.buildpacks) + + bps = bp.Status.Buildpacks + secretRef = registry.SecretRef{ + ServiceAccount: bp.Spec.ServiceAccountName, + Namespace: bp.Namespace, + } + case v1alpha2.ClusterBuildpackKind: + cbp := findClusterBuildpack(ref, r.clusterBuildpacks) + + bps = cbp.Status.Buildpacks + secretRef = registry.SecretRef{ + ServiceAccount: cbp.Spec.ServiceAccountRef.Name, + Namespace: cbp.Spec.ServiceAccountRef.Namespace, + } + } + + trees := NewTree(bps) + if len(trees) != 1 { + return K8sRemoteBuildpack{}, fmt.Errorf("unexpected number of root buildpacks: %v", len(trees)) + } + + return K8sRemoteBuildpack{ + Buildpack: *trees[0].Buildpack, + SecretRef: secretRef, + }, nil +} + +// TODO: combine findBuildpack and findClusterBuildpack into a single func +// if/when golang generics has support for field values +func findBuildpack(ref v1.ObjectReference, buildpacks []*v1alpha2.Buildpack) *v1alpha2.Buildpack { + for _, bp := range buildpacks { + if bp.Name == ref.Name { + return bp + } + } + return nil +} + +func findClusterBuildpack(ref v1.ObjectReference, clusterBuildpacks []*v1alpha2.ClusterBuildpack) *v1alpha2.ClusterBuildpack { + for _, cbp := range clusterBuildpacks { + if cbp.Name == ref.Name { + return cbp + } + } + return nil +} + +// TODO: error if the highest version has multiple diff ids +func highestVersion(matchingBuildpacks []K8sRemoteBuildpack) (K8sRemoteBuildpack, error) { + for _, bp := range matchingBuildpacks { + if _, err := semver.NewVersion(bp.Buildpack.Version); err != nil { + return K8sRemoteBuildpack{}, errors.Errorf("cannot find buildpack '%s' with latest version due to invalid semver '%s'", bp.Buildpack.Id, bp.Buildpack.Version) + } + } + + sort.SliceStable(matchingBuildpacks, func(i, j int) bool { + return semver.MustParse(matchingBuildpacks[i].Buildpack.Version). + LessThan(semver.MustParse(matchingBuildpacks[j].Buildpack.Version)) + }) + return matchingBuildpacks[len(matchingBuildpacks)-1], nil +} diff --git a/pkg/cnb/create_builder.go b/pkg/cnb/create_builder.go index 8419cf36..a02e27ae 100644 --- a/pkg/cnb/create_builder.go +++ b/pkg/cnb/create_builder.go @@ -1,11 +1,14 @@ package cnb import ( + "context" + "github.com/google/go-containerregistry/pkg/authn" v1 "github.com/google/go-containerregistry/pkg/v1" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/registry" ) type RegistryClient interface { @@ -21,19 +24,26 @@ type LifecycleProvider interface { LayerForOS(os string) (v1.Layer, LifecycleMetadata, error) } -type NewBuildpackRepository func(clusterStore *buildapi.ClusterStore) BuildpackRepository +type BuilderCreator interface { + CreateBuilder(ctx context.Context, keychain authn.Keychain, resolver BuildpackResolver, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) +} type RemoteBuilderCreator struct { - RegistryClient RegistryClient - NewBuildpackRepository NewBuildpackRepository - LifecycleProvider LifecycleProvider - KpackVersion string + RegistryClient RegistryClient + LifecycleProvider LifecycleProvider + KpackVersion string + KeychainFactory registry.KeychainFactory } -func (r *RemoteBuilderCreator) CreateBuilder(keychain authn.Keychain, clusterStore *buildapi.ClusterStore, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) { - buildpackRepo := r.NewBuildpackRepository(clusterStore) +var _ BuilderCreator = (*RemoteBuilderCreator)(nil) - buildImage, _, err := r.RegistryClient.Fetch(keychain, clusterStack.Status.BuildImage.LatestImage) +func (r *RemoteBuilderCreator) CreateBuilder( + ctx context.Context, + builderKeychain authn.Keychain, + resolver BuildpackResolver, fetcher RemoteBuildpackFetcher, + clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec, +) (buildapi.BuilderRecord, error) { + buildImage, _, err := r.RegistryClient.Fetch(builderKeychain, clusterStack.Status.BuildImage.LatestImage) if err != nil { return buildapi.BuilderRecord{}, err } @@ -56,7 +66,12 @@ func (r *RemoteBuilderCreator) CreateBuilder(keychain authn.Keychain, clusterSto buildpacks := make([]RemoteBuildpackRef, 0, len(group.Group)) for _, buildpack := range group.Group { - remoteBuildpack, err := buildpackRepo.FindByIdAndVersion(buildpack.Id, buildpack.Version) + resolvedBuildpack, err := resolver.Resolve(buildpack) + if err != nil { + return buildapi.BuilderRecord{}, err + } + + remoteBuildpack, err := fetcher.Fetch(ctx, resolvedBuildpack) if err != nil { return buildapi.BuilderRecord{}, err } @@ -71,7 +86,7 @@ func (r *RemoteBuilderCreator) CreateBuilder(keychain authn.Keychain, clusterSto return buildapi.BuilderRecord{}, err } - identifier, err := r.RegistryClient.Save(keychain, spec.Tag, writeableImage) + identifier, err := r.RegistryClient.Save(builderKeychain, spec.Tag, writeableImage) if err != nil { return buildapi.BuilderRecord{}, err } @@ -90,7 +105,7 @@ func (r *RemoteBuilderCreator) CreateBuilder(keychain authn.Keychain, clusterSto Buildpacks: buildpackMetadata(builderBldr.buildpacks()), Order: builderBldr.order, ObservedStackGeneration: clusterStack.Status.ObservedGeneration, - ObservedStoreGeneration: clusterStore.Status.ObservedGeneration, + ObservedStoreGeneration: resolver.ClusterStoreObservedGeneration(), OS: config.OS, }, nil } diff --git a/pkg/cnb/dependency_tree.go b/pkg/cnb/dependency_tree.go new file mode 100644 index 00000000..204a1d65 --- /dev/null +++ b/pkg/cnb/dependency_tree.go @@ -0,0 +1,61 @@ +package cnb + +import ( + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" +) + +type Node struct { + Buildpack *corev1alpha1.BuildpackStatus + Children []*Node +} + +// NewTree generates a list of dependency trees for the given buildpacks. A +// buildpack's dependency tree is just the buildpack's group[].order[] but in +// proper tree form. +func NewTree(buildpacks []corev1alpha1.BuildpackStatus) []*Node { + lookup := make(map[string]*corev1alpha1.BuildpackStatus) + for i := range buildpacks { + // explictly create a new var here, since using pointers in for-loops gets nasty + bp := buildpacks[i] + lookup[bp.Id] = &bp + } + + usedBuildpacks := make(map[string]bool) + for _, bp := range buildpacks { + for _, order := range bp.Order { + for _, status := range order.Group { + usedBuildpacks[status.Id] = true + } + } + } + + var unusedBuildpacks []string + for _, bp := range buildpacks { + if _, found := usedBuildpacks[bp.Id]; !found { + unusedBuildpacks = append(unusedBuildpacks, bp.Id) + } + } + + trees := make([]*Node, len(unusedBuildpacks)) + for i, id := range unusedBuildpacks { + trees[i] = makeTree(lookup, id) + } + + return trees +} + +func makeTree(lookup map[string]*corev1alpha1.BuildpackStatus, id string) *Node { + bp := lookup[id] + + var children []*Node + for _, order := range bp.Order { + for _, status := range order.Group { + children = append(children, makeTree(lookup, status.Id)) + } + } + + return &Node{ + Buildpack: bp, + Children: children, + } +} diff --git a/pkg/cnb/dependency_tree_test.go b/pkg/cnb/dependency_tree_test.go new file mode 100644 index 00000000..15afd0f2 --- /dev/null +++ b/pkg/cnb/dependency_tree_test.go @@ -0,0 +1,94 @@ +package cnb_test + +import ( + "testing" + + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/cnb" + "github.com/sclevine/spec" + "github.com/stretchr/testify/assert" +) + +func TestDependencyTree(t *testing.T) { + spec.Run(t, "Dependency Tree", testNewTree) +} + +func testNewTree(t *testing.T, when spec.G, it spec.S) { + when("there is 1 root tree", func() { + it("builds the tree", func() { + buildpacks := []v1alpha1.BuildpackStatus{ + { + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "parent-buildpack"}, + Order: []v1alpha1.OrderEntry{ + { + Group: []v1alpha1.BuildpackRef{ + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-1"}}, + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-2"}}, + }, + }, + { + Group: []v1alpha1.BuildpackRef{ + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-3"}}, + }, + }, + }, + }, + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-1"}}, + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-2"}}, + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-3"}}, + } + tree := cnb.NewTree(buildpacks) + assert.Len(t, tree, 1) + assert.NotNil(t, tree[0].Buildpack) + assert.Equal(t, tree[0].Buildpack.Id, "parent-buildpack") + assert.Len(t, tree[0].Children, 3) + }) + + it("handles nested children", func() { + buildpacks := []v1alpha1.BuildpackStatus{ + { + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "parent-buildpack"}, + Order: []v1alpha1.OrderEntry{{ + Group: []v1alpha1.BuildpackRef{{ + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-1"}}, + }}, + }}, + { + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-1"}, + Order: []v1alpha1.OrderEntry{{ + Group: []v1alpha1.BuildpackRef{ + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "grandchild-buildpack-1"}}, + }, + }}, + }, + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "grandchild-buildpack-1"}}, + } + + tree := cnb.NewTree(buildpacks) + assert.Len(t, tree, 1) + assert.Equal(t, tree[0].Buildpack.Id, "parent-buildpack") + assert.Len(t, tree[0].Children[0].Children, 1) + }) + }) + + when("There is multiple root tree", func() { + it("builds the tree", func() { + buildpacks := []v1alpha1.BuildpackStatus{ + { + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "parent-buildpack-1"}, + Order: []v1alpha1.OrderEntry{{ + Group: []v1alpha1.BuildpackRef{{ + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-1"}}, + }}, + }}, + { + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "parent-buildpack-2"}, + }, + {BuildpackInfo: v1alpha1.BuildpackInfo{Id: "child-buildpack-1"}}, + } + + tree := cnb.NewTree(buildpacks) + assert.Len(t, tree, 2) + }) + }) +} diff --git a/pkg/cnb/fake_layer_test.go b/pkg/cnb/fake_layer_test.go deleted file mode 100644 index 6387e840..00000000 --- a/pkg/cnb/fake_layer_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package cnb - -import ( - "io" - - v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/google/go-containerregistry/pkg/v1/types" -) - -type fakeLayer struct { - digest string - diffID string - size int64 -} - -func (f fakeLayer) Digest() (v1.Hash, error) { - return v1.NewHash(f.digest) -} - -func (f fakeLayer) DiffID() (v1.Hash, error) { - return v1.NewHash(f.diffID) -} - -func (f fakeLayer) Size() (int64, error) { - return f.size, nil -} - -func (f fakeLayer) MediaType() (types.MediaType, error) { - return types.DockerLayer, nil -} - -func (f fakeLayer) Compressed() (io.ReadCloser, error) { - panic("Not implemented For Tests") -} - -func (f fakeLayer) Uncompressed() (io.ReadCloser, error) { - panic("Not implemented For Tests") -} diff --git a/pkg/cnb/fakes_test.go b/pkg/cnb/fakes_test.go new file mode 100644 index 00000000..a7a97455 --- /dev/null +++ b/pkg/cnb/fakes_test.go @@ -0,0 +1,105 @@ +package cnb + +import ( + "context" + "fmt" + "io" + "testing" + + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/types" + buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +type fakeLayer struct { + digest string + diffID string + size int64 +} + +func (f fakeLayer) Digest() (v1.Hash, error) { + return v1.NewHash(f.digest) +} + +func (f fakeLayer) DiffID() (v1.Hash, error) { + return v1.NewHash(f.diffID) +} + +func (f fakeLayer) Size() (int64, error) { + return f.size, nil +} + +func (f fakeLayer) MediaType() (types.MediaType, error) { + return types.DockerLayer, nil +} + +func (f fakeLayer) Compressed() (io.ReadCloser, error) { + panic("Not implemented For Tests") +} + +func (f fakeLayer) Uncompressed() (io.ReadCloser, error) { + panic("Not implemented For Tests") +} + +type buildpackRefContainer struct { + Ref buildapi.BuilderBuildpackRef + Buildpack K8sRemoteBuildpack +} + +type fakeResolver struct { + buildpacks map[string]K8sRemoteBuildpack + observedGeneration int64 +} + +func (r *fakeResolver) Resolve(ref buildapi.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { + buildpack, ok := r.buildpacks[fmt.Sprintf("%s@%s", ref.Id, ref.Version)] + if !ok { + return K8sRemoteBuildpack{}, errors.New("buildpack not found") + } + return buildpack, nil +} + +func (f *fakeResolver) AddBuildpack(t *testing.T, ref buildapi.BuilderBuildpackRef, buildpack K8sRemoteBuildpack) { + t.Helper() + assert.NotEqual(t, ref.Id, "", "buildpack ref missing id") + f.buildpacks[fmt.Sprintf("%s@%s", ref.Id, ref.Version)] = buildpack +} + +func (r *fakeResolver) ClusterStoreObservedGeneration() int64 { + return r.observedGeneration +} + +func makeRef(id, version string) buildapi.BuilderBuildpackRef { + return buildapi.BuilderBuildpackRef{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: id, + Version: version, + }, + }, + } +} + +type fakeFetcher struct { + buildpacks map[string][]buildpackLayer +} + +func (f *fakeFetcher) Fetch(ctx context.Context, buildpack K8sRemoteBuildpack) (RemoteBuildpackInfo, error) { + layers, ok := f.buildpacks[fmt.Sprintf("%s@%s", buildpack.Buildpack.Id, buildpack.Buildpack.Version)] + if !ok { + return RemoteBuildpackInfo{}, errors.New("buildpack not found") + } + + return RemoteBuildpackInfo{ + BuildpackInfo: buildpackInfoInLayers(layers, buildpack.Buildpack.Id, buildpack.Buildpack.Version), + Layers: layers, + }, nil +} + +func (f *fakeFetcher) AddBuildpack(t *testing.T, id, version string, layers []buildpackLayer) { + t.Helper() + f.buildpacks[fmt.Sprintf("%s@%s", id, version)] = layers +} diff --git a/pkg/cnb/remote_buildpack_fetcher.go b/pkg/cnb/remote_buildpack_fetcher.go new file mode 100644 index 00000000..66d231c9 --- /dev/null +++ b/pkg/cnb/remote_buildpack_fetcher.go @@ -0,0 +1,108 @@ +package cnb + +import ( + "context" + + "github.com/google/go-containerregistry/pkg/authn" + v1 "github.com/google/go-containerregistry/pkg/v1" + + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/registry" + "github.com/pivotal/kpack/pkg/registry/imagehelpers" +) + +type RemoteBuildpackFetcher interface { + Fetch(ctx context.Context, remoteBuildpack K8sRemoteBuildpack) (RemoteBuildpackInfo, error) +} + +type remoteBuildpackFetcher struct { + BuildpackResolver BuildpackResolver + KeychainFactory registry.KeychainFactory +} + +func NewRemoteBuildpackFetcher(resolver BuildpackResolver, factory registry.KeychainFactory) RemoteBuildpackFetcher { + return &remoteBuildpackFetcher{ + BuildpackResolver: resolver, + KeychainFactory: factory, + } +} + +func (s *remoteBuildpackFetcher) Fetch(ctx context.Context, remoteBuildpack K8sRemoteBuildpack) (RemoteBuildpackInfo, error) { + buildpack := remoteBuildpack.Buildpack + keychain, err := s.KeychainFactory.KeychainForSecretRef(ctx, remoteBuildpack.SecretRef) + if err != nil { + return RemoteBuildpackInfo{}, err + } + + layer, err := layerForBuildpack(keychain, buildpack) + if err != nil { + return RemoteBuildpackInfo{}, err + } + + layers, err := s.layersForOrder(ctx, buildpack.Order) + if err != nil { + return RemoteBuildpackInfo{}, err + } + + info := DescriptiveBuildpackInfo{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: buildpack.Id, + Version: buildpack.Version, + }, + Homepage: buildpack.Homepage, + } + + return RemoteBuildpackInfo{ + BuildpackInfo: info, + Layers: append(layers, buildpackLayer{ + v1Layer: layer, + BuildpackInfo: info, + BuildpackLayerInfo: BuildpackLayerInfo{ + LayerDiffID: buildpack.DiffId, + Order: buildpack.Order, + API: buildpack.API, + Stacks: buildpack.Stacks, + Homepage: buildpack.Homepage, + }, + }), + }, nil +} + +// TODO: ensure there are no cycles in the buildpack graph +func (s *remoteBuildpackFetcher) layersForOrder(ctx context.Context, order corev1alpha1.Order) ([]buildpackLayer, error) { + var buildpackLayers []buildpackLayer + for _, orderEntry := range order { + for _, buildpackRef := range orderEntry.Group { + buildpack, err := s.BuildpackResolver.Resolve(v1alpha2.BuilderBuildpackRef{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: buildpackRef.Id, + Version: buildpackRef.Version, + }, + }, + }) + if err != nil { + return nil, err + } + + buildpackInfo, err := s.Fetch(ctx, buildpack) + if err != nil { + return nil, err + } + + buildpackLayers = append(buildpackLayers, buildpackInfo.Layers...) + } + } + return buildpackLayers, nil +} + +func layerForBuildpack(keychain authn.Keychain, buildpack corev1alpha1.BuildpackStatus) (v1.Layer, error) { + return imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ + Digest: buildpack.Digest, + DiffId: buildpack.DiffId, + Image: buildpack.StoreImage.Image, + Size: buildpack.Size, + Keychain: keychain, + }) +} diff --git a/pkg/cnb/store_buildpack_repository_test.go b/pkg/cnb/remote_buildpack_fetcher_test.go similarity index 68% rename from pkg/cnb/store_buildpack_repository_test.go rename to pkg/cnb/remote_buildpack_fetcher_test.go index c2ac9649..0029355e 100644 --- a/pkg/cnb/store_buildpack_repository_test.go +++ b/pkg/cnb/remote_buildpack_fetcher_test.go @@ -1,24 +1,34 @@ package cnb import ( + "context" "testing" + "github.com/google/go-containerregistry/pkg/authn" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/sclevine/spec" "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/registry" "github.com/pivotal/kpack/pkg/registry/imagehelpers" + "github.com/pivotal/kpack/pkg/registry/registryfakes" ) -func TestBuildpackRepository(t *testing.T) { - spec.Run(t, "TestBuildpackRepository", testBuildpackRepository) +func TestRemoteBuildpackFetcher(t *testing.T) { + spec.Run(t, "TestRemoteBuildpackFetcher", testRemoteBuildpackFetcher) } -func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { - when("FindByIdAndVersion", func() { +func testRemoteBuildpackFetcher(t *testing.T, when spec.G, it spec.S) { + var ( + keychainFactory = ®istryfakes.FakeKeychainFactory{} + keychain = authn.NewMultiKeychain(authn.DefaultKeychain) + resolver = &fakeResolver{buildpacks: map[string]K8sRemoteBuildpack{}} + secretRef = registry.SecretRef{} + ctx = context.Background() + ) + + when("Fetch", func() { engineBuildpack := corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: "io.buildpack.engine", @@ -158,34 +168,43 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }, } - storeBuildpackRepository := &StoreBuildpackRepository{ - Keychain: nil, - ClusterStore: &buildapi.ClusterStore{ - ObjectMeta: metav1.ObjectMeta{ - Name: "some-store", - }, - Status: buildapi.ClusterStoreStatus{ - Buildpacks: []corev1alpha1.BuildpackStatus{ - engineBuildpack, - v9Buildpack, - v8Buildpack, - packageManagerBuildpack, - metaBuildpack, - }, - }, - }, + it.Before(func() { + for _, bp := range []corev1alpha1.BuildpackStatus{ + engineBuildpack, + v9Buildpack, + v8Buildpack, + packageManagerBuildpack, + metaBuildpack, + } { + resolver.AddBuildpack(t, makeRef(bp.Id, bp.Version), K8sRemoteBuildpack{ + Buildpack: bp, + SecretRef: secretRef, + }) + } + + keychainFactory.AddKeychainForSecretRef(t, secretRef, keychain) + }) + + storeBuildpackRepository := &remoteBuildpackFetcher{ + KeychainFactory: keychainFactory, + BuildpackResolver: resolver, } it("returns layer info from store image", func() { - info, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.engine", "1.0.0") + info, err := storeBuildpackRepository.Fetch(ctx, K8sRemoteBuildpack{ + Buildpack: engineBuildpack, + SecretRef: secretRef, + }) require.NoError(t, err) expectedLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ - Digest: engineBuildpack.Digest, - DiffId: engineBuildpack.DiffId, - Image: engineBuildpack.StoreImage.Image, - Size: engineBuildpack.Size, + Digest: engineBuildpack.Digest, + DiffId: engineBuildpack.DiffId, + Image: engineBuildpack.StoreImage.Image, + Size: engineBuildpack.Size, + Keychain: keychain, }) + require.NoError(t, err) require.Equal(t, info, RemoteBuildpackInfo{ BuildpackInfo: DescriptiveBuildpackInfo{ @@ -223,107 +242,37 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }) }) - it("returns the semver newest buildpack if version is unspecified", func() { - info, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.multi", "") - require.NoError(t, err) - - expectedLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ - Digest: v9Buildpack.Digest, - DiffId: v9Buildpack.DiffId, - Image: v9Buildpack.StoreImage.Image, - Size: v9Buildpack.Size, - }) - require.NoError(t, err) - - require.Equal(t, info, RemoteBuildpackInfo{ - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.multi", - Version: "9.0.0", - }, - Homepage: "buildpack.multi.com", - }, - Layers: []buildpackLayer{ - { - v1Layer: expectedLayer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.multi", - Version: "9.0.0", - }, - Homepage: "buildpack.multi.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.2", - LayerDiffID: diffID(t, expectedLayer), - Homepage: "buildpack.multi.com", - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: "io.custom.stack", - }, - { - ID: "io.stack.only.v9.works", - }, - }, - }, - }, - }, - }) - }) - - it("fails to find the buildpack if version is unspecified and not all buildpacks are semver conformant", func() { - storeBuildpackRepository.ClusterStore.Status.Buildpacks = append(storeBuildpackRepository.ClusterStore.Status.Buildpacks, corev1alpha1.BuildpackStatus{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.multi", - Version: "my-wacky-version", - }, - DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", - Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", - Size: 10, - StoreImage: corev1alpha1.ImageSource{ - Image: "some.registry.io/build-package", - }, - Order: nil, - API: "0.2", - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: "io.custom.stack", - }, - { - ID: "io.stack.only.v9.works", - }, - }, - }) - - _, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.multi", "") - require.EqualError(t, err, "cannot find buildpack 'io.buildpack.multi' with latest version due to invalid semver 'my-wacky-version'") - }) - it("returns all buildpack layers in a meta buildpack", func() { - info, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.meta", "1.0.0") + info, err := storeBuildpackRepository.Fetch(ctx, K8sRemoteBuildpack{ + Buildpack: metaBuildpack, + SecretRef: secretRef, + }) require.NoError(t, err) expectedEngineLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ - Digest: engineBuildpack.Digest, - DiffId: engineBuildpack.DiffId, - Image: engineBuildpack.StoreImage.Image, - Size: engineBuildpack.Size, + Digest: engineBuildpack.Digest, + DiffId: engineBuildpack.DiffId, + Image: engineBuildpack.StoreImage.Image, + Size: engineBuildpack.Size, + Keychain: keychain, }) require.NoError(t, err) expectedPackageManagerLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ - Digest: packageManagerBuildpack.Digest, - DiffId: packageManagerBuildpack.DiffId, - Image: packageManagerBuildpack.StoreImage.Image, - Size: packageManagerBuildpack.Size, + Digest: packageManagerBuildpack.Digest, + DiffId: packageManagerBuildpack.DiffId, + Image: packageManagerBuildpack.StoreImage.Image, + Size: packageManagerBuildpack.Size, + Keychain: keychain, }) require.NoError(t, err) expectedMetaLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ - Digest: metaBuildpack.Digest, - DiffId: metaBuildpack.DiffId, - Image: metaBuildpack.StoreImage.Image, - Size: metaBuildpack.Size, + Digest: metaBuildpack.Digest, + DiffId: metaBuildpack.DiffId, + Image: metaBuildpack.StoreImage.Image, + Size: metaBuildpack.Size, + Keychain: keychain, }) require.NoError(t, err) @@ -430,9 +379,7 @@ func testBuildpackRepository(t *testing.T, when spec.G, it spec.S) { }, }, info) }) - }) - } func diffID(t *testing.T, layer v1.Layer) string { diff --git a/pkg/cnb/remote_buildpack_metadata.go b/pkg/cnb/remote_buildpack_metadata.go index 069977b7..aeaa34cf 100644 --- a/pkg/cnb/remote_buildpack_metadata.go +++ b/pkg/cnb/remote_buildpack_metadata.go @@ -4,6 +4,7 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/registry" ) type RemoteBuildpackInfo struct { @@ -37,3 +38,8 @@ type buildpackLayer struct { BuildpackInfo DescriptiveBuildpackInfo BuildpackLayerInfo BuildpackLayerInfo } + +type K8sRemoteBuildpack struct { + Buildpack corev1alpha1.BuildpackStatus + SecretRef registry.SecretRef +} diff --git a/pkg/cnb/remote_store_reader.go b/pkg/cnb/remote_store_reader.go index 56999e8e..899d87bc 100644 --- a/pkg/cnb/remote_store_reader.go +++ b/pkg/cnb/remote_store_reader.go @@ -12,11 +12,11 @@ import ( "github.com/pivotal/kpack/pkg/registry/imagehelpers" ) -type RemoteStoreReader struct { +type RemoteBuildpackReader struct { RegistryClient RegistryClient } -func (r *RemoteStoreReader) Read(keychain authn.Keychain, storeImages []corev1alpha1.ImageSource) ([]corev1alpha1.BuildpackStatus, error) { +func (r *RemoteBuildpackReader) Read(keychain authn.Keychain, storeImages []corev1alpha1.ImageSource) ([]corev1alpha1.BuildpackStatus, error) { var g errgroup.Group c := make(chan corev1alpha1.BuildpackStatus) diff --git a/pkg/cnb/remote_store_reader_test.go b/pkg/cnb/remote_store_reader_test.go index f2c8aa18..9e9424c6 100644 --- a/pkg/cnb/remote_store_reader_test.go +++ b/pkg/cnb/remote_store_reader_test.go @@ -28,7 +28,7 @@ func testRemoteStoreReader(t *testing.T, when spec.G, it spec.S) { var ( expectedKeychain = authn.NewMultiKeychain(authn.DefaultKeychain) fakeClient = registryfakes.NewFakeClient() - remoteStoreReader = &RemoteStoreReader{ + remoteStoreReader = &RemoteBuildpackReader{ RegistryClient: fakeClient, } ) diff --git a/pkg/cnb/store_buildpack_repository.go b/pkg/cnb/store_buildpack_repository.go deleted file mode 100644 index da54037a..00000000 --- a/pkg/cnb/store_buildpack_repository.go +++ /dev/null @@ -1,136 +0,0 @@ -package cnb - -import ( - "sort" - - "github.com/Masterminds/semver/v3" - "github.com/google/go-containerregistry/pkg/authn" - v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/pkg/errors" - - buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" - corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" - "github.com/pivotal/kpack/pkg/registry/imagehelpers" -) - -type StoreBuildpackRepository struct { - Keychain authn.Keychain - - ClusterStore *buildapi.ClusterStore -} - -func (s *StoreBuildpackRepository) FindByIdAndVersion(id, version string) (RemoteBuildpackInfo, error) { - storeBuildpack, err := s.findBuildpack(id, version) - if err != nil { - return RemoteBuildpackInfo{}, err - } - - layer, err := layerFromStoreBuildpack(s.Keychain, storeBuildpack) - if err != nil { - return RemoteBuildpackInfo{}, err - } - - layers, err := s.layersForOrder(storeBuildpack.Order) - if err != nil { - return RemoteBuildpackInfo{}, err - } - - info := DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: storeBuildpack.Id, - Version: storeBuildpack.Version, - }, - Homepage: storeBuildpack.Homepage, - } - - return RemoteBuildpackInfo{ - BuildpackInfo: info, - Layers: append(layers, buildpackLayer{ - v1Layer: layer, - BuildpackInfo: info, - BuildpackLayerInfo: BuildpackLayerInfo{ - LayerDiffID: storeBuildpack.DiffId, - Order: storeBuildpack.Order, - API: storeBuildpack.API, - Stacks: storeBuildpack.Stacks, - Homepage: storeBuildpack.Homepage, - }, - }), - }, nil -} - -func (s *StoreBuildpackRepository) findBuildpack(id, version string) (corev1alpha1.BuildpackStatus, error) { - var matchingBuildpacks []corev1alpha1.BuildpackStatus - for _, buildpack := range s.ClusterStore.Status.Buildpacks { - if buildpack.Id == id { - matchingBuildpacks = append(matchingBuildpacks, buildpack) - } - } - - if len(matchingBuildpacks) == 0 { - return corev1alpha1.BuildpackStatus{}, errors.Errorf("could not find buildpack with id '%s'", id) - } - - if version == "" { - return highestVersion(matchingBuildpacks) - } - - for _, buildpack := range matchingBuildpacks { - if buildpack.Version == version { - return buildpack, nil - } - } - - return corev1alpha1.BuildpackStatus{}, errors.Errorf("could not find buildpack with id '%s' and version '%s'", id, version) -} - -// TODO: ensure there are no cycles in the buildpack graph -func (s *StoreBuildpackRepository) layersForOrder(order corev1alpha1.Order) ([]buildpackLayer, error) { - var buildpackLayers []buildpackLayer - for _, orderEntry := range order { - for _, buildpackRef := range orderEntry.Group { - buildpackInfo, err := s.FindByIdAndVersion(buildpackRef.Id, buildpackRef.Version) - if err != nil { - return nil, err - } - - buildpackLayers = append(buildpackLayers, buildpackInfo.Layers...) - } - - } - return buildpackLayers, nil -} - -func highestVersion(matchingBuildpacks []corev1alpha1.BuildpackStatus) (corev1alpha1.BuildpackStatus, error) { - for _, bp := range matchingBuildpacks { - if _, err := semver.NewVersion(bp.Version); err != nil { - return corev1alpha1.BuildpackStatus{}, errors.Errorf("cannot find buildpack '%s' with latest version due to invalid semver '%s'", bp.Id, bp.Version) - } - } - sort.Sort(byBuildpackVersion(matchingBuildpacks)) - return matchingBuildpacks[len(matchingBuildpacks)-1], nil -} - -type byBuildpackVersion []corev1alpha1.BuildpackStatus - -func (b byBuildpackVersion) Len() int { - return len(b) -} - -func (b byBuildpackVersion) Swap(i, j int) { - b[i], b[j] = b[j], b[i] -} - -func (b byBuildpackVersion) Less(i, j int) bool { - return semver.MustParse(b[i].Version).LessThan(semver.MustParse(b[j].Version)) -} - -func layerFromStoreBuildpack(keychain authn.Keychain, buildpack corev1alpha1.BuildpackStatus) (v1.Layer, error) { - return imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ - Digest: buildpack.Digest, - DiffId: buildpack.DiffId, - Image: buildpack.StoreImage.Image, - Size: buildpack.Size, - Keychain: keychain, - }) -} From e6347ad673b592e56f3b406bd1fb4a3db5d68ce5 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Fri, 3 Feb 2023 10:47:48 -0500 Subject: [PATCH 10/39] update reconcilers to use the resolver and fetcher Signed-off-by: Bohan Chen --- cmd/controller/main.go | 29 +++------ config/clusterbuildpack.yaml | 3 +- pkg/apis/build/v1alpha2/builder_validation.go | 1 - pkg/reconciler/builder/builder.go | 62 ++++++++++++------- .../clusterbuilder/clusterbuilder.go | 48 ++++++++------ 5 files changed, 75 insertions(+), 68 deletions(-) diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 12bdb836..7dde981b 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -11,7 +11,6 @@ import ( "time" "github.com/Masterminds/semver/v3" - "github.com/google/go-containerregistry/pkg/authn" "go.uber.org/zap" "golang.org/x/sync/errgroup" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -186,7 +185,7 @@ func main() { blobResolver := &blob.Resolver{} registryResolver := ®istry.Resolver{} - remoteStoreReader := &cnb.RemoteStoreReader{ + remoteStoreReader := &cnb.RemoteBuildpackReader{ RegistryClient: ®istry.Client{}, } @@ -194,26 +193,21 @@ func main() { RegistryClient: ®istry.Client{}, } - kpackKeychain, err := keychainFactory.KeychainForSecretRef(ctx, registry.SecretRef{}) - if err != nil { - log.Fatalf("could not create empty keychain %s", err) - } - lifecycleProvider := config.NewLifecycleProvider(®istry.Client{}, keychainFactory) builderCreator := &cnb.RemoteBuilderCreator{ - RegistryClient: ®istry.Client{}, - KpackVersion: cmd.Identifer, - LifecycleProvider: lifecycleProvider, - NewBuildpackRepository: newBuildpackRepository(kpackKeychain), + RegistryClient: ®istry.Client{}, + KpackVersion: cmd.Identifer, + LifecycleProvider: lifecycleProvider, + KeychainFactory: keychainFactory, } buildController := build.NewController(ctx, options, k8sClient, buildInformer, podInformer, metadataRetriever, buildpodGenerator, keychainFactory, *injectedSidecarSupport) imageController := image.NewController(ctx, options, k8sClient, imageInformer, buildInformer, duckBuilderInformer, sourceResolverInformer, pvcInformer, *enablePriorityClasses) sourceResolverController := sourceresolver.NewController(ctx, options, sourceResolverInformer, gitResolver, blobResolver, registryResolver) - builderController, builderResync := builder.NewController(ctx, options, builderInformer, builderCreator, keychainFactory, clusterStoreInformer, clusterStackInformer) + builderController, builderResync := builder.NewController(ctx, options, builderInformer, builderCreator, keychainFactory, clusterStoreInformer, buildpackInformer, clusterBuildpackInformer, clusterStackInformer) buildpackController := buildpack.NewController(ctx, options, keychainFactory, buildpackInformer, remoteStoreReader) - clusterBuilderController, clusterBuilderResync := clusterbuilder.NewController(ctx, options, clusterBuilderInformer, builderCreator, keychainFactory, clusterStoreInformer, clusterStackInformer) + clusterBuilderController, clusterBuilderResync := clusterbuilder.NewController(ctx, options, clusterBuilderInformer, builderCreator, keychainFactory, clusterStoreInformer, clusterBuildpackInformer, clusterStackInformer) clusterBuildpackController := clusterbuildpack.NewController(ctx, options, keychainFactory, clusterBuildpackInformer, remoteStoreReader) clusterStoreController := clusterstore.NewController(ctx, options, keychainFactory, clusterStoreInformer, remoteStoreReader) clusterStackController := clusterstack.NewController(ctx, options, keychainFactory, clusterStackInformer, remoteStackReader) @@ -290,15 +284,6 @@ func runGroup(ctx context.Context, fns ...func(ctx context.Context) error) error return eg.Wait() } -func newBuildpackRepository(keychain authn.Keychain) func(clusterStore *buildapi.ClusterStore) cnb.BuildpackRepository { - return func(clusterStore *buildapi.ClusterStore) cnb.BuildpackRepository { - return &cnb.StoreBuildpackRepository{ - Keychain: keychain, - ClusterStore: clusterStore, - } - } -} - const controllerCount = 7 // lifted from knative.dev/pkg/injection/sharedmain diff --git a/config/clusterbuildpack.yaml b/config/clusterbuildpack.yaml index c7992c7b..6ac1a51a 100644 --- a/config/clusterbuildpack.yaml +++ b/config/clusterbuildpack.yaml @@ -28,5 +28,4 @@ spec: - clstbps categories: - kpack - scope: Namespaced - + scope: Cluster diff --git a/pkg/apis/build/v1alpha2/builder_validation.go b/pkg/apis/build/v1alpha2/builder_validation.go index 8ff2d78e..6745cb65 100644 --- a/pkg/apis/build/v1alpha2/builder_validation.go +++ b/pkg/apis/build/v1alpha2/builder_validation.go @@ -29,7 +29,6 @@ func (cb *Builder) Validate(ctx context.Context) *apis.FieldError { func (s *BuilderSpec) Validate(ctx context.Context) *apis.FieldError { return validate.Tag(s.Tag). Also(validateStack(s.Stack).ViaField("stack")). - Also(validateStore(s.Store).ViaField("store")). Also(validateOrder(s.Order).ViaField("order")) } diff --git a/pkg/reconciler/builder/builder.go b/pkg/reconciler/builder/builder.go index e9e99298..f2fc7fe2 100644 --- a/pkg/reconciler/builder/builder.go +++ b/pkg/reconciler/builder/builder.go @@ -5,11 +5,11 @@ import ( "go.uber.org/zap" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "knative.dev/pkg/logging/logkey" - "github.com/google/go-containerregistry/pkg/authn" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/equality" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -31,28 +31,26 @@ const ( ReconcilerName = "Builders" ) -type NewBuildpackRepository func(clusterStore *buildapi.ClusterStore) cnb.BuildpackRepository - -type BuilderCreator interface { - CreateBuilder(keychain authn.Keychain, clusterStore *buildapi.ClusterStore, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) -} - func NewController( ctx context.Context, opt reconciler.Options, builderInformer buildinformers.BuilderInformer, - builderCreator BuilderCreator, + builderCreator cnb.BuilderCreator, keychainFactory registry.KeychainFactory, clusterStoreInformer buildinformers.ClusterStoreInformer, + buildpackInformer buildinformers.BuildpackInformer, + clusterBuildpackInformer buildinformers.ClusterBuildpackInformer, clusterStackInformer buildinformers.ClusterStackInformer, ) (*controller.Impl, func()) { c := &Reconciler{ - Client: opt.Client, - BuilderLister: builderInformer.Lister(), - BuilderCreator: builderCreator, - KeychainFactory: keychainFactory, - ClusterStoreLister: clusterStoreInformer.Lister(), - ClusterStackLister: clusterStackInformer.Lister(), + Client: opt.Client, + BuilderLister: builderInformer.Lister(), + BuilderCreator: builderCreator, + KeychainFactory: keychainFactory, + ClusterStoreLister: clusterStoreInformer.Lister(), + BuildpackLister: buildpackInformer.Lister(), + ClusterBuildpackLister: clusterBuildpackInformer.Lister(), + ClusterStackLister: clusterStackInformer.Lister(), } logger := opt.Logger.With( @@ -86,13 +84,15 @@ func NewController( } type Reconciler struct { - Client versioned.Interface - BuilderLister buildlisters.BuilderLister - BuilderCreator BuilderCreator - KeychainFactory registry.KeychainFactory - Tracker reconciler.Tracker - ClusterStoreLister buildlisters.ClusterStoreLister - ClusterStackLister buildlisters.ClusterStackLister + Client versioned.Interface + BuilderLister buildlisters.BuilderLister + BuilderCreator cnb.BuilderCreator + KeychainFactory registry.KeychainFactory + Tracker reconciler.Tracker + ClusterStoreLister buildlisters.ClusterStoreLister + BuildpackLister buildlisters.BuildpackLister + ClusterBuildpackLister buildlisters.ClusterBuildpackLister + ClusterStackLister buildlisters.ClusterStackLister } func (c *Reconciler) Reconcile(ctx context.Context, key string) error { @@ -154,7 +154,20 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui return buildapi.BuilderRecord{}, err } - clusterStore, err := c.ClusterStoreLister.Get(builder.Spec.Store.Name) + var clusterStore *buildapi.ClusterStore + if builder.Spec.Store.Name != "" { + clusterStore, err = c.ClusterStoreLister.Get(builder.Spec.Store.Name) + if err != nil { + return buildapi.BuilderRecord{}, err + } + } + + buildpacks, err := c.BuildpackLister.Buildpacks(builder.Namespace).List(labels.Everything()) + if err != nil { + return buildapi.BuilderRecord{}, err + } + + clusterBuildpacks, err := c.ClusterBuildpackLister.List(labels.Everything()) if err != nil { return buildapi.BuilderRecord{}, err } @@ -176,7 +189,10 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui return buildapi.BuilderRecord{}, err } - return c.BuilderCreator.CreateBuilder(keychain, clusterStore, clusterStack, builder.Spec.BuilderSpec) + resolver := cnb.NewBuildpackResolver(c.KeychainFactory, clusterStore, buildpacks, clusterBuildpacks) + fetcher := cnb.NewRemoteBuildpackFetcher(resolver, c.KeychainFactory) + + return c.BuilderCreator.CreateBuilder(ctx, keychain, resolver, fetcher, clusterStack, builder.Spec.BuilderSpec) } func (c *Reconciler) updateStatus(ctx context.Context, desired *buildapi.Builder) error { diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder.go b/pkg/reconciler/clusterbuilder/clusterbuilder.go index df60a251..4ed47f54 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder.go @@ -6,11 +6,11 @@ import ( "go.uber.org/zap" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "knative.dev/pkg/logging/logkey" - "github.com/google/go-containerregistry/pkg/authn" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/equality" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -22,6 +22,7 @@ import ( "github.com/pivotal/kpack/pkg/client/clientset/versioned" buildinformers "github.com/pivotal/kpack/pkg/client/informers/externalversions/build/v1alpha2" buildlisters "github.com/pivotal/kpack/pkg/client/listers/build/v1alpha2" + "github.com/pivotal/kpack/pkg/cnb" "github.com/pivotal/kpack/pkg/reconciler" "github.com/pivotal/kpack/pkg/registry" "github.com/pivotal/kpack/pkg/tracker" @@ -31,26 +32,24 @@ const ( ReconcilerName = "ClusterBuilders" ) -type BuilderCreator interface { - CreateBuilder(keychain authn.Keychain, clusterStore *buildapi.ClusterStore, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) -} - func NewController( ctx context.Context, opt reconciler.Options, clusterBuilderInformer buildinformers.ClusterBuilderInformer, - builderCreator BuilderCreator, + builderCreator cnb.BuilderCreator, keychainFactory registry.KeychainFactory, clusterStoreInformer buildinformers.ClusterStoreInformer, + clusterBuildpackInformer buildinformers.ClusterBuildpackInformer, clusterStackInformer buildinformers.ClusterStackInformer, ) (*controller.Impl, func()) { c := &Reconciler{ - Client: opt.Client, - ClusterBuilderLister: clusterBuilderInformer.Lister(), - BuilderCreator: builderCreator, - KeychainFactory: keychainFactory, - ClusterStoreLister: clusterStoreInformer.Lister(), - ClusterStackLister: clusterStackInformer.Lister(), + Client: opt.Client, + ClusterBuilderLister: clusterBuilderInformer.Lister(), + BuilderCreator: builderCreator, + KeychainFactory: keychainFactory, + ClusterStoreLister: clusterStoreInformer.Lister(), + ClusterBuildpackLister: clusterBuildpackInformer.Lister(), + ClusterStackLister: clusterStackInformer.Lister(), } logger := opt.Logger.With( @@ -84,13 +83,14 @@ func NewController( } type Reconciler struct { - Client versioned.Interface - ClusterBuilderLister buildlisters.ClusterBuilderLister - BuilderCreator BuilderCreator - KeychainFactory registry.KeychainFactory - Tracker reconciler.Tracker - ClusterStoreLister buildlisters.ClusterStoreLister - ClusterStackLister buildlisters.ClusterStackLister + Client versioned.Interface + ClusterBuilderLister buildlisters.ClusterBuilderLister + BuilderCreator cnb.BuilderCreator + KeychainFactory registry.KeychainFactory + Tracker reconciler.Tracker + ClusterStoreLister buildlisters.ClusterStoreLister + ClusterBuildpackLister buildlisters.ClusterBuildpackLister + ClusterStackLister buildlisters.ClusterStackLister } func (c *Reconciler) Reconcile(ctx context.Context, key string) error { @@ -158,6 +158,11 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu return buildapi.BuilderRecord{}, err } + clusterBuildpacks, err := c.ClusterBuildpackLister.List(labels.Everything()) + if err != nil { + return buildapi.BuilderRecord{}, err + } + clusterStack, err := c.ClusterStackLister.Get(builder.Spec.Stack.Name) if err != nil { return buildapi.BuilderRecord{}, err @@ -175,7 +180,10 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu return buildapi.BuilderRecord{}, err } - return c.BuilderCreator.CreateBuilder(keychain, clusterStore, clusterStack, builder.Spec.BuilderSpec) + resolver := cnb.NewBuildpackResolver(c.KeychainFactory, clusterStore, nil, clusterBuildpacks) + fetcher := cnb.NewRemoteBuildpackFetcher(resolver, c.KeychainFactory) + + return c.BuilderCreator.CreateBuilder(ctx, keychain, resolver, fetcher, clusterStack, builder.Spec.BuilderSpec) } func (c *Reconciler) updateStatus(ctx context.Context, desired *buildapi.ClusterBuilder) error { From 9017664b270f0db36c6562da45611f4e6672c650 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Fri, 3 Feb 2023 10:50:29 -0500 Subject: [PATCH 11/39] update tests Signed-off-by: Bohan Chen --- pkg/cnb/buildpack_resolver_test.go | 428 ++++++++++++++++++ pkg/cnb/create_builder_test.go | 357 +++++++-------- pkg/reconciler/builder/builder_test.go | 40 +- .../clusterbuilder/clusterbuilder_test.go | 31 +- .../testhelpers/fake_builder_creator.go | 15 +- .../testhelpers/fake_buildpack_repository.go | 14 - 6 files changed, 651 insertions(+), 234 deletions(-) create mode 100644 pkg/cnb/buildpack_resolver_test.go delete mode 100644 pkg/reconciler/testhelpers/fake_buildpack_repository.go diff --git a/pkg/cnb/buildpack_resolver_test.go b/pkg/cnb/buildpack_resolver_test.go new file mode 100644 index 00000000..d3bffb17 --- /dev/null +++ b/pkg/cnb/buildpack_resolver_test.go @@ -0,0 +1,428 @@ +package cnb + +// func TestBuildpackResolver(t *testing.T) { +// spec.Run(t, "TestBuildpackResolver", testBuildpackResolver) +// } + +// func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { +// var ( +// keychainFactory = ®istryfakes.FakeKeychainFactory{} +// resolver = &fakeResolver{} +// ctx = context.Background() +// ) + +// when("Fetch", func() { +// engineBuildpack := corev1alpha1.BuildpackStatus{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.engine", +// Version: "1.0.0", +// }, +// DiffId: "sha256:1bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", +// Digest: "sha256:d345d1b12ae6b3f7cfc617f7adaebe06c32ce60b1aa30bb80fb622b65523de8f", +// Size: 50, +// StoreImage: corev1alpha1.ImageSource{ +// Image: "some.registry.io/build-package", +// }, +// Order: nil, +// Homepage: "buildpack.engine.com", +// API: "0.1", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.engine.works", +// }, +// }, +// } + +// packageManagerBuildpack := corev1alpha1.BuildpackStatus{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.package-manager", +// Version: "1.0.0", +// }, +// DiffId: "sha256:2bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", +// Digest: "sha256:7c1213a54d20137a7479e72150c058268a6604b98c011b4fc11ca45927923d7b", +// Size: 40, +// StoreImage: corev1alpha1.ImageSource{ +// Image: "some.registry.io/build-package", +// }, +// Order: nil, +// Homepage: "buildpack.package-manager.com", +// API: "0.2", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.package.works", +// }, +// }, +// } + +// metaBuildpack := corev1alpha1.BuildpackStatus{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.meta", +// Version: "1.0.0", +// }, +// DiffId: "sha256:3bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", +// Digest: "sha256:07db84e57fdd7101104c2469984217696fdfe51591cb1edee2928514135920d6", +// Size: 30, +// StoreImage: corev1alpha1.ImageSource{ +// Image: "some.registry.io/build-package", +// }, +// Order: []corev1alpha1.OrderEntry{ +// { +// Group: []corev1alpha1.BuildpackRef{ +// { +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.engine", +// Version: "1.0.0", +// }, +// Optional: false, +// }, +// { +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.package-manager", +// Version: "1.0.0", +// }, +// Optional: true, +// }, +// }, +// }, +// }, +// Homepage: "buildpack.meta.com", +// API: "0.3", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.meta.works", +// }, +// }, +// } + +// v8Buildpack := corev1alpha1.BuildpackStatus{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.multi", +// Version: "8.0.0", +// }, +// DiffId: "sha256:8bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", +// Digest: "sha256:fc14806eb95d01b6338ba1b9fea605e84db7c8c09561ae360bad5b80b5d0d80b", +// Size: 20, +// StoreImage: corev1alpha1.ImageSource{ +// Image: "some.registry.io/build-package", +// }, +// Order: nil, +// Homepage: "buildpack.multi.com", +// API: "0.2", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.v8.works", +// }, +// }, +// } + +// v9Buildpack := corev1alpha1.BuildpackStatus{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.multi", +// Version: "9.0.0", +// }, +// DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", +// Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", +// Size: 10, +// StoreImage: corev1alpha1.ImageSource{ +// Image: "some.registry.io/build-package", +// }, +// Order: nil, +// Homepage: "buildpack.multi.com", +// API: "0.2", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.v9.works", +// }, +// }, +// } + +// for _, bp := range []corev1alpha1.BuildpackStatus{ +// engineBuildpack, +// v9Buildpack, +// v8Buildpack, +// packageManagerBuildpack, +// metaBuildpack, +// } { +// resolver.AddBuildpackRef(t, makeRef(bp.Id, bp.Version), K8sRemoteBuildpack{ +// Buildpack: bp, +// SecretRef: registry.SecretRef{}, +// }) +// } + +// storeBuildpackRepository := &RemoteBuildpackFetcher{ +// KeychainFactory: keychainFactory, +// BuildpackResolver: resolver, +// } + +// it("returns layer info from store image", func() { +// info, err := storeBuildpackRepository.Fetch(ctx, engineBuildpack) +// require.NoError(t, err) + +// expectedLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ +// Digest: engineBuildpack.Digest, +// DiffId: engineBuildpack.DiffId, +// Image: engineBuildpack.StoreImage.Image, +// Size: engineBuildpack.Size, +// }) + +// require.Equal(t, info, RemoteBuildpackInfo{ +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.engine", +// Version: "1.0.0", +// }, +// Homepage: "buildpack.engine.com", +// }, +// Layers: []buildpackLayer{ +// { +// v1Layer: expectedLayer, +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.engine", +// Version: "1.0.0", +// }, +// Homepage: "buildpack.engine.com", +// }, +// BuildpackLayerInfo: BuildpackLayerInfo{ +// API: "0.1", +// LayerDiffID: diffID(t, expectedLayer), +// Homepage: "buildpack.engine.com", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.engine.works", +// }, +// }, +// }, +// }, +// }, +// }) +// }) + +// it("returns the semver newest buildpack if version is unspecified", func() { +// info, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.multi", "") +// require.NoError(t, err) + +// expectedLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ +// Digest: v9Buildpack.Digest, +// DiffId: v9Buildpack.DiffId, +// Image: v9Buildpack.StoreImage.Image, +// Size: v9Buildpack.Size, +// }) +// require.NoError(t, err) + +// require.Equal(t, info, RemoteBuildpackInfo{ +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.multi", +// Version: "9.0.0", +// }, +// Homepage: "buildpack.multi.com", +// }, +// Layers: []buildpackLayer{ +// { +// v1Layer: expectedLayer, +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.multi", +// Version: "9.0.0", +// }, +// Homepage: "buildpack.multi.com", +// }, +// BuildpackLayerInfo: BuildpackLayerInfo{ +// API: "0.2", +// LayerDiffID: diffID(t, expectedLayer), +// Homepage: "buildpack.multi.com", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.v9.works", +// }, +// }, +// }, +// }, +// }, +// }) +// }) + +// it("fails to find the buildpack if version is unspecified and not all buildpacks are semver conformant", func() { +// storeBuildpackRepository.ClusterStore.Status.Buildpacks = append(storeBuildpackRepository.ClusterStore.Status.Buildpacks, corev1alpha1.BuildpackStatus{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.multi", +// Version: "my-wacky-version", +// }, +// DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", +// Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", +// Size: 10, +// StoreImage: corev1alpha1.ImageSource{ +// Image: "some.registry.io/build-package", +// }, +// Order: nil, +// API: "0.2", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.v9.works", +// }, +// }, +// }) + +// _, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.multi", "") +// require.EqualError(t, err, "cannot find buildpack 'io.buildpack.multi' with latest version due to invalid semver 'my-wacky-version'") +// }) + +// it("returns all buildpack layers in a meta buildpack", func() { +// info, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.meta", "1.0.0") +// require.NoError(t, err) + +// expectedEngineLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ +// Digest: engineBuildpack.Digest, +// DiffId: engineBuildpack.DiffId, +// Image: engineBuildpack.StoreImage.Image, +// Size: engineBuildpack.Size, +// }) +// require.NoError(t, err) + +// expectedPackageManagerLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ +// Digest: packageManagerBuildpack.Digest, +// DiffId: packageManagerBuildpack.DiffId, +// Image: packageManagerBuildpack.StoreImage.Image, +// Size: packageManagerBuildpack.Size, +// }) +// require.NoError(t, err) + +// expectedMetaLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ +// Digest: metaBuildpack.Digest, +// DiffId: metaBuildpack.DiffId, +// Image: metaBuildpack.StoreImage.Image, +// Size: metaBuildpack.Size, +// }) +// require.NoError(t, err) + +// require.Equal(t, RemoteBuildpackInfo{ +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.meta", +// Version: "1.0.0", +// }, +// Homepage: "buildpack.meta.com", +// }, +// Layers: []buildpackLayer{ +// { +// v1Layer: expectedEngineLayer, +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.engine", +// Version: "1.0.0", +// }, +// Homepage: "buildpack.engine.com", +// }, +// BuildpackLayerInfo: BuildpackLayerInfo{ +// API: "0.1", +// LayerDiffID: diffID(t, expectedEngineLayer), +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.engine.works", +// }, +// }, +// Homepage: "buildpack.engine.com", +// }, +// }, +// { +// v1Layer: expectedPackageManagerLayer, +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.package-manager", +// Version: "1.0.0", +// }, +// Homepage: "buildpack.package-manager.com", +// }, +// BuildpackLayerInfo: BuildpackLayerInfo{ +// API: "0.2", +// LayerDiffID: diffID(t, expectedPackageManagerLayer), +// Homepage: "buildpack.package-manager.com", +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// }, +// { +// ID: "io.stack.only.package.works", +// }, +// }, +// }, +// }, +// { +// v1Layer: expectedMetaLayer, +// BuildpackInfo: DescriptiveBuildpackInfo{ +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.meta", +// Version: "1.0.0", +// }, +// Homepage: "buildpack.meta.com", +// }, +// BuildpackLayerInfo: BuildpackLayerInfo{ +// API: "0.3", +// LayerDiffID: diffID(t, expectedMetaLayer), +// Homepage: "buildpack.meta.com", +// Order: corev1alpha1.Order{ +// { +// Group: []corev1alpha1.BuildpackRef{ +// { +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.engine", +// Version: "1.0.0", +// }, +// Optional: false, +// }, +// { +// BuildpackInfo: corev1alpha1.BuildpackInfo{ +// Id: "io.buildpack.package-manager", +// Version: "1.0.0", +// }, +// Optional: true, +// }, +// }, +// }, +// }, +// Stacks: []corev1alpha1.BuildpackStack{ +// { +// ID: "io.custom.stack", +// Mixins: nil, +// }, +// { +// ID: "io.stack.only.meta.works", +// Mixins: nil, +// }, +// }, +// }, +// }, +// }, +// }, info) +// }) + +// }) +// } diff --git a/pkg/cnb/create_builder_test.go b/pkg/cnb/create_builder_test.go index 1ca9fdec..4e476008 100644 --- a/pkg/cnb/create_builder_test.go +++ b/pkg/cnb/create_builder_test.go @@ -2,6 +2,7 @@ package cnb import ( "archive/tar" + "context" "fmt" "path" "strings" @@ -12,7 +13,6 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/random" - "github.com/pkg/errors" "github.com/sclevine/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -21,6 +21,7 @@ import ( buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/registry" "github.com/pivotal/kpack/pkg/registry/imagehelpers" "github.com/pivotal/kpack/pkg/registry/registryfakes" ) @@ -55,12 +56,14 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { var ( registryClient = registryfakes.NewFakeClient() - keychain = authn.NewMultiKeychain(authn.DefaultKeychain) + keychainFactory = ®istryfakes.FakeKeychainFactory{} + keychain = authn.NewMultiKeychain(authn.DefaultKeychain) + secretRef = registry.SecretRef{} - buildpackRepository = &fakeBuildpackRepository{buildpacks: map[string][]buildpackLayer{}} - newBuildpackRepo = func(store *buildapi.ClusterStore) BuildpackRepository { - return buildpackRepository - } + ctx = context.Background() + + resolver = &fakeResolver{buildpacks: map[string]K8sRemoteBuildpack{}, observedGeneration: 10} + fetcher = &fakeFetcher{buildpacks: map[string][]buildpackLayer{}} linuxLifecycle = &fakeLayer{ digest: "sha256:5d43d12dabe6070c4a4036e700a6f88a52278c02097b5f200e0b49b3d874c954", @@ -90,17 +93,6 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { size: 100, } - store = &buildapi.ClusterStore{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sample-store", - }, - Status: buildapi.ClusterStoreStatus{ - Status: corev1alpha1.Status{ - ObservedGeneration: 10, - }, - }, - } - stack = &buildapi.ClusterStack{ ObjectMeta: metav1.ObjectMeta{ Name: "sample-stack", @@ -173,15 +165,63 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { lifecycleProvider = &fakeLifecycleProvider{} subject = RemoteBuilderCreator{ - RegistryClient: registryClient, - KpackVersion: "v1.2.3 (git sha: abcdefg123456)", - NewBuildpackRepository: newBuildpackRepo, - LifecycleProvider: lifecycleProvider, + RegistryClient: registryClient, + KpackVersion: "v1.2.3 (git sha: abcdefg123456)", + KeychainFactory: keychainFactory, + LifecycleProvider: lifecycleProvider, + } + + addBuildpack = func(t *testing.T, id, version, homepage, api string, stacks []corev1alpha1.BuildpackStack) { + ref := buildapi.BuilderBuildpackRef{ + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: id, + Version: version, + }, + }, + } + + remote := K8sRemoteBuildpack{ + Buildpack: corev1alpha1.BuildpackStatus{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: id, + Version: version, + }, + DiffId: buildpack1Layer.diffID, + Digest: buildpack1Layer.digest, + Size: buildpack1Layer.size, + Homepage: homepage, + API: api, + Stacks: stacks, + }, + SecretRef: secretRef, + } + + layer := buildpackLayer{ + v1Layer: buildpack1Layer, + BuildpackInfo: DescriptiveBuildpackInfo{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: id, + Version: version, + }, + Homepage: homepage, + }, + BuildpackLayerInfo: BuildpackLayerInfo{ + API: api, + LayerDiffID: buildpack1Layer.diffID, + Stacks: stacks, + }, + } + + resolver.AddBuildpack(t, ref, remote) + fetcher.AddBuildpack(t, id, version, []buildpackLayer{layer}) } ) - buildpackRepository.AddBP("io.buildpack.1", "v1", []buildpackLayer{ - { + it.Before(func() { + keychainFactory.AddKeychainForSecretRef(t, secretRef, keychain) + + buildpack1 := buildpackLayer{ v1Layer: buildpack1Layer, BuildpackInfo: DescriptiveBuildpackInfo{ BuildpackInfo: corev1alpha1.BuildpackInfo{ @@ -200,33 +240,9 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }, }, - }, - }) + } - buildpackRepository.AddBP("io.buildpack.2", "v2", []buildpackLayer{ - { - v1Layer: buildpack3Layer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.3", - Version: "v3", - }, - Homepage: "buildpack.3.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.3", - LayerDiffID: buildpack3Layer.diffID, - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: stackID, - }, - { - ID: "io.some.other.stack", - }, - }, - }, - }, - { + buildpack2 := buildpackLayer{ v1Layer: buildpack2Layer, BuildpackInfo: DescriptiveBuildpackInfo{ BuildpackInfo: corev1alpha1.BuildpackInfo{ @@ -252,7 +268,36 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, }, }, - }, + } + buildpack3 := buildpackLayer{ + v1Layer: buildpack3Layer, + BuildpackInfo: DescriptiveBuildpackInfo{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.3", + Version: "v3", + }, + Homepage: "buildpack.3.com", + }, + BuildpackLayerInfo: BuildpackLayerInfo{ + API: "0.3", + LayerDiffID: buildpack3Layer.diffID, + Stacks: []corev1alpha1.BuildpackStack{ + { + ID: stackID, + }, + { + ID: "io.some.other.stack", + }, + }, + }, + } + + resolver.AddBuildpack(t, makeRef("io.buildpack.1", "v1"), layerToRemoteBuildpack(buildpack1, buildpack1Layer, secretRef)) + resolver.AddBuildpack(t, makeRef("io.buildpack.2", "v2"), layerToRemoteBuildpack(buildpack2, buildpack2Layer, secretRef)) + resolver.AddBuildpack(t, makeRef("io.buildpack.3", "v3"), layerToRemoteBuildpack(buildpack3, buildpack3Layer, secretRef)) + + fetcher.AddBuildpack(t, "io.buildpack.1", "v1", []buildpackLayer{buildpack1}) + fetcher.AddBuildpack(t, "io.buildpack.2", "v2", []buildpackLayer{buildpack3, buildpack2}) }) registryClient.AddSaveKeychain("custom/example", keychain) @@ -302,7 +347,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates a custom builder", func() { - builderRecord, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + builderRecord, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) assert.Len(t, builderRecord.Buildpacks, 3) @@ -564,11 +609,11 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates images deterministically ", func() { - original, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + original, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) for i := 1; i <= 50; i++ { - other, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + other, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) require.Equal(t, original.Image, other.Image) @@ -578,27 +623,12 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { when("validating buildpacks", func() { it("errors with unsupported stack", func() { - buildpackRepository.AddBP("io.buildpack.unsupported.stack", "v4", []buildpackLayer{ - { - v1Layer: buildpack1Layer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.unsupported.stack", - Version: "v4", - }, - Homepage: "buildpack.4.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.2", - LayerDiffID: buildpack1Layer.diffID, - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: "io.buildpacks.stacks.unsupported", - }, - }, + addBuildpack(t, "io.buildpack.unsupported.stack", "v4", "buildpack.4.com", "0.2", + []corev1alpha1.BuildpackStack{ + { + ID: "io.buildpacks.stacks.unsupported", }, - }, - }) + }) clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{ { @@ -613,33 +643,18 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.stack@v4: stack io.buildpacks.stacks.some-stack is not supported") }) it("errors with unsupported mixin", func() { - buildpackRepository.AddBP("io.buildpack.unsupported.mixin", "v4", []buildpackLayer{ - { - v1Layer: buildpack1Layer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.unsupported.mixin", - Version: "v4", - }, - Homepage: "buildpack.1.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.2", - LayerDiffID: buildpack1Layer.diffID, - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: stackID, - Mixins: []string{mixin, "something-missing-mixin", "something-missing-mixin2"}, - }, - }, + addBuildpack(t, "io.buildpack.unsupported.mixin", "v4", "buildpack.1.com", "0.2", + []corev1alpha1.BuildpackStack{ + { + ID: stackID, + Mixins: []string{mixin, "something-missing-mixin", "something-missing-mixin2"}, }, - }, - }) + }) clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ Group: []buildapi.BuilderBuildpackRef{{ @@ -652,7 +667,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.mixin@v4: stack missing mixin(s): something-missing-mixin, something-missing-mixin2") }) @@ -677,28 +692,14 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - buildpackRepository.AddBP("io.buildpack.relaxed.mixin", "v4", []buildpackLayer{ - { - v1Layer: buildpack1Layer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.relaxed.mixin", - Version: "v4", - }, - Homepage: "buildpack.1.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.2", - LayerDiffID: buildpack1Layer.diffID, - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: stackID, - Mixins: []string{mixin, "build:common-mixin", "run:common-mixin", "another-common-mixin"}, - }, - }, + addBuildpack(t, "io.buildpack.relaxed.mixin", "v4", "buildpack.1.com", "0.2", + []corev1alpha1.BuildpackStack{ + { + ID: stackID, + Mixins: []string{mixin, "build:common-mixin", "run:common-mixin", "another-common-mixin"}, }, }, - }) + ) clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ Group: []buildapi.BuilderBuildpackRef{{ @@ -711,33 +712,19 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.Nil(t, err) }) it("ignores relaxed mixin contract with an older platform api", func() { - buildpackRepository.AddBP("io.buildpack.relaxed.old.mixin", "v4", []buildpackLayer{ - { - v1Layer: buildpack1Layer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.relaxed.old.mixin", - Version: "v4", - }, - Homepage: "buildpack.1.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.3", - LayerDiffID: buildpack1Layer.diffID, - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: stackID, - Mixins: []string{mixin, "build:common-mixin", "run:common-mixin", "another-common-mixin"}, - }, - }, + addBuildpack(t, "io.buildpack.relaxed.old.mixin", "v4", "buildpack.1.com", "0.3", + []corev1alpha1.BuildpackStack{ + { + ID: stackID, + Mixins: []string{mixin, "build:common-mixin", "run:common-mixin", "another-common-mixin"}, }, }, - }) + ) clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ Group: []buildapi.BuilderBuildpackRef{{ @@ -750,32 +737,17 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.Error(t, err, "validating buildpack io.buildpack.relaxed.old.mixin@v4: stack missing mixin(s): build:common-mixin, run:common-mixin, another-common-mixin") }) it("errors with unsupported buildpack version", func() { - buildpackRepository.AddBP("io.buildpack.unsupported.buildpack.api", "v4", []buildpackLayer{ - { - v1Layer: buildpack1Layer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "io.buildpack.unsupported.buildpack.api", - Version: "v4", - }, - Homepage: "buildpack.4.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.1", - LayerDiffID: buildpack1Layer.diffID, - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: stackID, - }, - }, + addBuildpack(t, "io.buildpack.unsupported.buildpack.api", "v4", "buildpack.4.com", "0.1", + []corev1alpha1.BuildpackStack{ + { + ID: stackID, }, - }, - }) + }) clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ Group: []buildapi.BuilderBuildpackRef{{ @@ -788,7 +760,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.buildpack.api@v4: unsupported buildpack api: 0.1, expecting: 0.2, 0.3") }) @@ -813,27 +785,12 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - buildpackRepository.AddBP("anystack.buildpack", "v1", []buildpackLayer{ - { - v1Layer: buildpack3Layer, - BuildpackInfo: DescriptiveBuildpackInfo{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "anystack.buildpack", - Version: "v1", - }, - Homepage: "buildpacks.com", - }, - BuildpackLayerInfo: BuildpackLayerInfo{ - API: "0.5", - LayerDiffID: buildpack3Layer.diffID, - Stacks: []corev1alpha1.BuildpackStack{ - { - ID: "*", - }, - }, + addBuildpack(t, "anystack.buildpack", "v1", "buildpacks.com", "0.5", + []corev1alpha1.BuildpackStack{ + { + ID: "*", }, - }, - }) + }) clusterBuilderSpec.Order = []buildapi.BuilderOrderEntry{{ Group: []buildapi.BuilderBuildpackRef{{ @@ -846,7 +803,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) }) }) @@ -873,7 +830,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, err := subject.CreateBuilder(keychain, store, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "unsupported platform apis in kpack lifecycle: 0.1, 0.2, 0.999, expecting one of: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8") }) }) @@ -889,22 +846,6 @@ func (p *fakeLifecycleProvider) LayerForOS(os string) (v1.Layer, LifecycleMetada return p.layers[os], p.metadata, nil } -type fakeBuildpackRepository struct { - buildpacks map[string][]buildpackLayer -} - -func (f *fakeBuildpackRepository) FindByIdAndVersion(id, version string) (RemoteBuildpackInfo, error) { - layers, ok := f.buildpacks[fmt.Sprintf("%s@%s", id, version)] - if !ok { - return RemoteBuildpackInfo{}, errors.New("buildpack not found") - } - - return RemoteBuildpackInfo{ - BuildpackInfo: buildpackInfoInLayers(layers, id, version), - Layers: layers, - }, nil -} - func buildpackInfoInLayers(buildpackLayers []buildpackLayer, id, version string) DescriptiveBuildpackInfo { for _, b := range buildpackLayers { if b.BuildpackInfo.Id == id && b.BuildpackInfo.Version == version { @@ -914,10 +855,6 @@ func buildpackInfoInLayers(buildpackLayers []buildpackLayer, id, version string) panic("unexpected missing buildpack info") } -func (f *fakeBuildpackRepository) AddBP(id, version string, layers []buildpackLayer) { - f.buildpacks[fmt.Sprintf("%s@%s", id, version)] = layers -} - type content struct { typeflag byte fileContent string @@ -1013,3 +950,21 @@ func (i *layerIteratorTester) testNextLayer(name string, test func(index int)) { test(int(*i)) *i++ } + +func layerToRemoteBuildpack(bpLayer buildpackLayer, layer *fakeLayer, secretRef registry.SecretRef) K8sRemoteBuildpack { + return K8sRemoteBuildpack{ + Buildpack: corev1alpha1.BuildpackStatus{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: bpLayer.BuildpackInfo.Id, + Version: bpLayer.BuildpackInfo.Version, + }, + DiffId: layer.diffID, + Digest: layer.digest, + Size: layer.size, + Homepage: bpLayer.BuildpackInfo.Homepage, + API: bpLayer.BuildpackLayerInfo.API, + Stacks: bpLayer.BuildpackLayerInfo.Stacks, + }, + SecretRef: secretRef, + } +} diff --git a/pkg/reconciler/builder/builder_test.go b/pkg/reconciler/builder/builder_test.go index b0beb350..e6425c21 100644 --- a/pkg/reconciler/builder/builder_test.go +++ b/pkg/reconciler/builder/builder_test.go @@ -7,6 +7,7 @@ import ( "github.com/sclevine/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/net/context" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -18,6 +19,7 @@ import ( buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/client/clientset/versioned/fake" + "github.com/pivotal/kpack/pkg/cnb" kreconciler "github.com/pivotal/kpack/pkg/reconciler" "github.com/pivotal/kpack/pkg/reconciler/builder" "github.com/pivotal/kpack/pkg/reconciler/testhelpers" @@ -50,13 +52,15 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { listers := testhelpers.NewListers(row.Objects) fakeClient := fake.NewSimpleClientset(listers.BuildServiceObjects()...) r := &builder.Reconciler{ - Client: fakeClient, - BuilderLister: listers.GetBuilderLister(), - BuilderCreator: builderCreator, - KeychainFactory: keychainFactory, - Tracker: fakeTracker, - ClusterStoreLister: listers.GetClusterStoreLister(), - ClusterStackLister: listers.GetClusterStackLister(), + Client: fakeClient, + BuilderLister: listers.GetBuilderLister(), + BuilderCreator: builderCreator, + KeychainFactory: keychainFactory, + Tracker: fakeTracker, + ClusterStoreLister: listers.GetClusterStoreLister(), + BuildpackLister: listers.GetBuildpackLister(), + ClusterBuildpackLister: listers.GetClusterBuildpackLister(), + ClusterStackLister: listers.GetClusterStackLister(), } return &kreconciler.NetworkErrorReconciler{Reconciler: r}, rtesting.ActionRecorderList{fakeClient}, rtesting.EventList{Recorder: record.NewFakeRecorder(10)} }) @@ -94,6 +98,19 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, } + buildpack := &buildapi.Buildpack{ + ObjectMeta: metav1.ObjectMeta{ + Name: "buildpack.id.3", + Namespace: testNamespace, + }, + } + + clusterBuildpack := &buildapi.ClusterBuildpack{ + ObjectMeta: metav1.ObjectMeta{ + Name: "buildpack.id.4", + }, + } + builder := &buildapi.Builder{ ObjectMeta: metav1.ObjectMeta{ Name: builderName, @@ -202,12 +219,17 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, } + expectedResolver := cnb.NewBuildpackResolver(keychainFactory, clusterStore, []*buildapi.Buildpack{buildpack}, []*buildapi.ClusterBuildpack{clusterBuildpack}) + expectedFetcher := cnb.NewRemoteBuildpackFetcher(expectedResolver, keychainFactory) + rt.Test(rtesting.TableRow{ Key: builderKey, Objects: []runtime.Object{ clusterStack, clusterStore, builder, + buildpack, + clusterBuildpack, }, WantErr: false, WantStatusUpdates: []clientgotesting.UpdateActionImpl{ @@ -218,8 +240,10 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) assert.Equal(t, []testhelpers.CreateBuilderArgs{{ + Context: context.Background(), Keychain: ®istryfakes.FakeKeychain{}, - ClusterStore: clusterStore, + Resolver: expectedResolver, + Fetcher: expectedFetcher, ClusterStack: clusterStack, BuilderSpec: builder.Spec.BuilderSpec, }}, builderCreator.CreateBuilderCalls) diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go index b7f7a940..d1afeee8 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go @@ -1,6 +1,7 @@ package clusterbuilder_test import ( + "context" "errors" "testing" @@ -18,6 +19,7 @@ import ( buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/client/clientset/versioned/fake" + "github.com/pivotal/kpack/pkg/cnb" kreconciler "github.com/pivotal/kpack/pkg/reconciler" "github.com/pivotal/kpack/pkg/reconciler/clusterbuilder" "github.com/pivotal/kpack/pkg/reconciler/testhelpers" @@ -49,13 +51,14 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { listers := testhelpers.NewListers(row.Objects) fakeClient := fake.NewSimpleClientset(listers.BuildServiceObjects()...) r := &clusterbuilder.Reconciler{ - Client: fakeClient, - ClusterBuilderLister: listers.GetClusterBuilderLister(), - BuilderCreator: builderCreator, - KeychainFactory: keychainFactory, - Tracker: fakeTracker, - ClusterStoreLister: listers.GetClusterStoreLister(), - ClusterStackLister: listers.GetClusterStackLister(), + Client: fakeClient, + ClusterBuilderLister: listers.GetClusterBuilderLister(), + BuilderCreator: builderCreator, + KeychainFactory: keychainFactory, + Tracker: fakeTracker, + ClusterStoreLister: listers.GetClusterStoreLister(), + ClusterBuildpackLister: listers.GetClusterBuildpackLister(), + ClusterStackLister: listers.GetClusterStackLister(), } return &kreconciler.NetworkErrorReconciler{Reconciler: r}, rtesting.ActionRecorderList{fakeClient}, rtesting.EventList{Recorder: record.NewFakeRecorder(10)} }) @@ -93,6 +96,12 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, } + clusterBuildpack := &buildapi.ClusterBuildpack{ + ObjectMeta: metav1.ObjectMeta{ + Name: "buildpack.id.4", + }, + } + builder := &buildapi.ClusterBuilder{ ObjectMeta: metav1.ObjectMeta{ Name: builderName, @@ -211,12 +220,16 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, } + expectedResolver := cnb.NewBuildpackResolver(keychainFactory, clusterStore, nil, []*buildapi.ClusterBuildpack{clusterBuildpack}) + expectedFetcher := cnb.NewRemoteBuildpackFetcher(expectedResolver, keychainFactory) + rt.Test(rtesting.TableRow{ Key: builderKey, Objects: []runtime.Object{ clusterStack, clusterStore, builder, + clusterBuildpack, }, WantErr: false, WantStatusUpdates: []clientgotesting.UpdateActionImpl{ @@ -227,8 +240,10 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) assert.Equal(t, []testhelpers.CreateBuilderArgs{{ + Context: context.Background(), Keychain: ®istryfakes.FakeKeychain{}, - ClusterStore: clusterStore, + Resolver: expectedResolver, + Fetcher: expectedFetcher, ClusterStack: clusterStack, BuilderSpec: builder.Spec.BuilderSpec, }}, builderCreator.CreateBuilderCalls) diff --git a/pkg/reconciler/testhelpers/fake_builder_creator.go b/pkg/reconciler/testhelpers/fake_builder_creator.go index 8db45785..ecd8279b 100644 --- a/pkg/reconciler/testhelpers/fake_builder_creator.go +++ b/pkg/reconciler/testhelpers/fake_builder_creator.go @@ -1,9 +1,12 @@ package testhelpers import ( + "context" + "github.com/google/go-containerregistry/pkg/authn" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + "github.com/pivotal/kpack/pkg/cnb" ) type FakeBuilderCreator struct { @@ -14,16 +17,22 @@ type FakeBuilderCreator struct { } type CreateBuilderArgs struct { + Context context.Context Keychain authn.Keychain + Resolver cnb.BuildpackResolver + Fetcher cnb.RemoteBuildpackFetcher ClusterStack *buildapi.ClusterStack - ClusterStore *buildapi.ClusterStore BuilderSpec buildapi.BuilderSpec } -func (f *FakeBuilderCreator) CreateBuilder(keychain authn.Keychain, clusterStore *buildapi.ClusterStore, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) (buildapi.BuilderRecord, error) { +var _ cnb.BuilderCreator = (*FakeBuilderCreator)(nil) + +func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, resolver cnb.BuildpackResolver, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) (buildapi.BuilderRecord, error) { f.CreateBuilderCalls = append(f.CreateBuilderCalls, CreateBuilderArgs{ + Context: ctx, Keychain: keychain, - ClusterStore: clusterStore, + Resolver: resolver, + Fetcher: fetcher, ClusterStack: clusterStack, BuilderSpec: builder, }) diff --git a/pkg/reconciler/testhelpers/fake_buildpack_repository.go b/pkg/reconciler/testhelpers/fake_buildpack_repository.go deleted file mode 100644 index d6c32072..00000000 --- a/pkg/reconciler/testhelpers/fake_buildpack_repository.go +++ /dev/null @@ -1,14 +0,0 @@ -package testhelpers - -import ( - buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" - "github.com/pivotal/kpack/pkg/cnb" -) - -type FakeBuildpackRepository struct { - ClusterStore *buildapi.ClusterStore -} - -func (f FakeBuildpackRepository) FindByIdAndVersion(id, version string) (cnb.RemoteBuildpackInfo, error) { - return cnb.RemoteBuildpackInfo{}, nil -} From 7c8cb33a6321420afaabda0e717edd3cd4fec7b6 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Fri, 3 Feb 2023 10:50:45 -0500 Subject: [PATCH 12/39] add stricter builder validation Signed-off-by: Bohan Chen --- pkg/apis/build/v1alpha2/builder_validation.go | 50 +++++++-- .../build/v1alpha2/builder_validation_test.go | 106 ++++++++++++++++-- 2 files changed, 138 insertions(+), 18 deletions(-) diff --git a/pkg/apis/build/v1alpha2/builder_validation.go b/pkg/apis/build/v1alpha2/builder_validation.go index 6745cb65..d5d3bca2 100644 --- a/pkg/apis/build/v1alpha2/builder_validation.go +++ b/pkg/apis/build/v1alpha2/builder_validation.go @@ -2,11 +2,13 @@ package v1alpha2 import ( "context" + "strings" v1 "k8s.io/api/core/v1" "knative.dev/pkg/apis" + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/apis/validate" ) @@ -29,6 +31,7 @@ func (cb *Builder) Validate(ctx context.Context) *apis.FieldError { func (s *BuilderSpec) Validate(ctx context.Context) *apis.FieldError { return validate.Tag(s.Tag). Also(validateStack(s.Stack).ViaField("stack")). + Also(validateStore(s.Store).ViaField("store")). Also(validateOrder(s.Order).ViaField("order")) } @@ -51,22 +54,16 @@ func validateStack(stack v1.ObjectReference) *apis.FieldError { } func validateStore(store v1.ObjectReference) *apis.FieldError { - if store.Name == "" { - return apis.ErrMissingField("name") - } - - switch store.Kind { - case ClusterStoreKind: + if store.Name == "" && store.Kind == "" { return nil - default: - return apis.ErrInvalidValue(store.Kind, "kind") } + return validateObjectRef(store, []string{ClusterStoreKind}) } func validateOrder(order []BuilderOrderEntry) *apis.FieldError { var errs *apis.FieldError for i, s := range order { - errs.Also(validateGroup(s).ViaIndex(i)) + errs = errs.Also(validateGroup(s).ViaIndex(i)) } return errs } @@ -74,11 +71,42 @@ func validateOrder(order []BuilderOrderEntry) *apis.FieldError { func validateGroup(group BuilderOrderEntry) *apis.FieldError { var errs *apis.FieldError for i, s := range group.Group { - errs.Also(validateBuildpackRef(s).ViaIndex(i).ViaField("group")) + errs = errs.Also(validateBuildpackRef(s).ViaIndex(i).ViaField("group")) } return errs } func validateBuildpackRef(ref BuilderBuildpackRef) *apis.FieldError { - return nil + var errs *apis.FieldError + if ref.Name != "" || ref.Kind != "" { + errs = errs.Also(validateObjectRef(ref.ObjectReference, []string{BuildpackKind, ClusterBuildpackKind})) + } + + switch { + case ref.Image != "": + errs = errs.Also(validate.Image(ref.Image)). + Also(apis.CheckDisallowedFields(ref.BuildpackInfo, v1alpha1.BuildpackInfo{})). + Also(apis.CheckDisallowedFields(ref.ObjectReference, v1.ObjectReference{})) + case ref.Id != "" || ref.Name != "" || ref.Kind != "": + if ref.Image != "" { + errs = errs.Also(apis.ErrDisallowedFields("image")) + } + default: + errs = errs.Also(apis.ErrMissingOneOf("image", "id", "name + kind")) + } + return errs +} + +func validateObjectRef(ref v1.ObjectReference, kinds []string) *apis.FieldError { + var errs *apis.FieldError + if ref.Name == "" { + errs = errs.Also(apis.ErrMissingField("name")) + } + + for _, k := range kinds { + if ref.Kind == k { + return nil + } + } + return errs.Also(apis.ErrInvalidValue(ref.Kind, "kind", "must be one of "+strings.Join(kinds, ", "))) } diff --git a/pkg/apis/build/v1alpha2/builder_validation_test.go b/pkg/apis/build/v1alpha2/builder_validation_test.go index d475552d..6842ad68 100644 --- a/pkg/apis/build/v1alpha2/builder_validation_test.go +++ b/pkg/apis/build/v1alpha2/builder_validation_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/sclevine/spec" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -32,7 +33,40 @@ func testBuilderValidation(t *testing.T, when spec.G, it spec.S) { Kind: "ClusterStore", Name: "some-registry.io/store", }, - Order: nil, // No order validation + Order: []BuilderOrderEntry{{ + Group: []BuilderBuildpackRef{ + { + BuildpackRef: v1alpha1.BuildpackRef{ + BuildpackInfo: v1alpha1.BuildpackInfo{ + Id: "some-buildpack", + Version: "v1", + }, + Optional: true, + }, + }, + { + Image: "some-registry.io/buildpack", + }, + { + ObjectReference: corev1.ObjectReference{ + Name: "some-buildpack", + Kind: "Buildpack", + }, + }, + { + ObjectReference: corev1.ObjectReference{ + Name: "some-clusterbuildpack", + Kind: "ClusterBuildpack", + }, + BuildpackRef: v1alpha1.BuildpackRef{ + BuildpackInfo: v1alpha1.BuildpackInfo{ + Id: "some-buildpack", + Version: "v1", + }, + }, + }, + }, + }}, }, ServiceAccountName: "some-service-account", }, @@ -103,14 +137,72 @@ func testBuilderValidation(t *testing.T, when spec.G, it spec.S) { assertValidationError(builder, apis.ErrInvalidValue("FakeStack", "kind").ViaField("spec", "stack")) }) - it("missing store name", func() { - builder.Spec.Store.Name = "" - assertValidationError(builder, apis.ErrMissingField("name").ViaField("spec", "store")) - }) - it("invalid store kind", func() { builder.Spec.Store.Kind = "FakeStore" - assertValidationError(builder, apis.ErrInvalidValue("FakeStore", "kind").ViaField("spec", "store")) + assertValidationError(builder, apis.ErrInvalidValue("FakeStore", "kind", "must be one of ClusterStore").ViaField("spec", "store")) + }) + + when("order", func() { + assertValidationError = func(builder *Builder, expectedError *apis.FieldError) { + t.Helper() + err := builder.Validate(context.TODO()) + assert.EqualError(t, err, + expectedError. + ViaIndex(0).ViaField("group"). + ViaIndex(0).ViaField("spec", "order").Error(), + ) + } + + it("invalid object kind", func() { + builder.Spec.Order = []BuilderOrderEntry{{ + Group: []BuilderBuildpackRef{{ + ObjectReference: corev1.ObjectReference{ + Name: "some-buildpack", + Kind: "FakeBuildpack", + }, + }}, + }} + + assertValidationError(builder, apis.ErrInvalidValue("FakeBuildpack", "kind", "must be one of Buildpack, ClusterBuildpack")) + }) + + it("invalid image", func() { + builder.Spec.Order = []BuilderOrderEntry{{ + Group: []BuilderBuildpackRef{{ + Image: "some-image@1234", + }}, + }} + + assertValidationError(builder, apis.ErrInvalidValue("some-image@1234", "image")) + }) + + it("invalid when both image and id are defined", func() { + builder.Spec.Order = []BuilderOrderEntry{{ + Group: []BuilderBuildpackRef{{ + Image: "foo", + BuildpackRef: v1alpha1.BuildpackRef{ + BuildpackInfo: v1alpha1.BuildpackInfo{Id: "some-buildpack"}, + }, + }}, + }} + assertValidationError(builder, apis.ErrDisallowedFields("id")) + }) + + it("valid when both id and object are defined", func() { + builder.Spec.Order = []BuilderOrderEntry{{Group: []BuilderBuildpackRef{{ + BuildpackRef: v1alpha1.BuildpackRef{ + BuildpackInfo: v1alpha1.BuildpackInfo{ + Id: "some-buildpack", + Version: "v1", + }, + }, + ObjectReference: corev1.ObjectReference{ + Name: "some-buildpack", + Kind: "Buildpack", + }, + }}}} + assert.Nil(t, builder.Validate(context.TODO())) + }) }) }) } From 548ee527a182a5a12b2b24712ab6e56dfbf79330 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Mon, 6 Feb 2023 11:23:50 -0500 Subject: [PATCH 13/39] add tests for BuildpackResolver Signed-off-by: Bohan Chen --- pkg/cnb/buildpack_resolver.go | 34 +- pkg/cnb/buildpack_resolver_test.go | 987 +++++++++++++---------- pkg/cnb/dependency_tree_test.go | 4 +- pkg/cnb/fakes_test.go | 26 +- pkg/cnb/remote_buildpack_fetcher_test.go | 9 +- 5 files changed, 614 insertions(+), 446 deletions(-) diff --git a/pkg/cnb/buildpack_resolver.go b/pkg/cnb/buildpack_resolver.go index e71ffe0c..2f81a956 100644 --- a/pkg/cnb/buildpack_resolver.go +++ b/pkg/cnb/buildpack_resolver.go @@ -93,6 +93,8 @@ func (r *buildpackResolver) Resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemote case ref.Image != "": // TODO(chenbh): return K8sRemoteBuildpack{}, fmt.Errorf("using images in builders not currently supported") + default: + return K8sRemoteBuildpack{}, fmt.Errorf("invalid buildpack reference") } if len(matchingBuildpacks) == 0 { @@ -159,16 +161,24 @@ func (r *buildpackResolver) resolveFromClusterBuildpack(id string, clusterBuildp } func (r *buildpackResolver) resolveFromClusterStore(id string, store *v1alpha2.ClusterStore) ([]K8sRemoteBuildpack, error) { + if store == nil { + return nil, nil + } + var matchingBuildpacks []K8sRemoteBuildpack for _, status := range store.Status.Buildpacks { if status.Id == id { + secretRef := registry.SecretRef{} - matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ - Buildpack: status, - SecretRef: registry.SecretRef{ + if store.Spec.ServiceAccountRef != nil { + secretRef = registry.SecretRef{ ServiceAccount: store.Spec.ServiceAccountRef.Name, Namespace: store.Spec.ServiceAccountRef.Namespace, - }, + } + } + matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ + Buildpack: status, + SecretRef: secretRef, }) } } @@ -183,6 +193,9 @@ func (r *buildpackResolver) resolveFromObjectReference(ref v1.ObjectReference) ( switch ref.Kind { case v1alpha2.BuildpackKind: bp := findBuildpack(ref, r.buildpacks) + if bp == nil { + return K8sRemoteBuildpack{}, fmt.Errorf("no buildpack with name '%v'", ref.Name) + } bps = bp.Status.Buildpacks secretRef = registry.SecretRef{ @@ -191,12 +204,19 @@ func (r *buildpackResolver) resolveFromObjectReference(ref v1.ObjectReference) ( } case v1alpha2.ClusterBuildpackKind: cbp := findClusterBuildpack(ref, r.clusterBuildpacks) + if cbp == nil { + return K8sRemoteBuildpack{}, fmt.Errorf("no cluster buildpack with name '%v'", ref.Name) + } bps = cbp.Status.Buildpacks - secretRef = registry.SecretRef{ - ServiceAccount: cbp.Spec.ServiceAccountRef.Name, - Namespace: cbp.Spec.ServiceAccountRef.Namespace, + if cbp.Spec.ServiceAccountRef != nil { + secretRef = registry.SecretRef{ + ServiceAccount: cbp.Spec.ServiceAccountRef.Name, + Namespace: cbp.Spec.ServiceAccountRef.Namespace, + } } + default: + return K8sRemoteBuildpack{}, fmt.Errorf("kind must be either %v or %v", v1alpha2.BuildpackKind, v1alpha2.ClusterBuildpackKind) } trees := NewTree(bps) diff --git a/pkg/cnb/buildpack_resolver_test.go b/pkg/cnb/buildpack_resolver_test.go index d3bffb17..3a88757e 100644 --- a/pkg/cnb/buildpack_resolver_test.go +++ b/pkg/cnb/buildpack_resolver_test.go @@ -1,428 +1,563 @@ package cnb -// func TestBuildpackResolver(t *testing.T) { -// spec.Run(t, "TestBuildpackResolver", testBuildpackResolver) -// } - -// func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { -// var ( -// keychainFactory = ®istryfakes.FakeKeychainFactory{} -// resolver = &fakeResolver{} -// ctx = context.Background() -// ) - -// when("Fetch", func() { -// engineBuildpack := corev1alpha1.BuildpackStatus{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.engine", -// Version: "1.0.0", -// }, -// DiffId: "sha256:1bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", -// Digest: "sha256:d345d1b12ae6b3f7cfc617f7adaebe06c32ce60b1aa30bb80fb622b65523de8f", -// Size: 50, -// StoreImage: corev1alpha1.ImageSource{ -// Image: "some.registry.io/build-package", -// }, -// Order: nil, -// Homepage: "buildpack.engine.com", -// API: "0.1", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.engine.works", -// }, -// }, -// } - -// packageManagerBuildpack := corev1alpha1.BuildpackStatus{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.package-manager", -// Version: "1.0.0", -// }, -// DiffId: "sha256:2bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", -// Digest: "sha256:7c1213a54d20137a7479e72150c058268a6604b98c011b4fc11ca45927923d7b", -// Size: 40, -// StoreImage: corev1alpha1.ImageSource{ -// Image: "some.registry.io/build-package", -// }, -// Order: nil, -// Homepage: "buildpack.package-manager.com", -// API: "0.2", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.package.works", -// }, -// }, -// } - -// metaBuildpack := corev1alpha1.BuildpackStatus{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.meta", -// Version: "1.0.0", -// }, -// DiffId: "sha256:3bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", -// Digest: "sha256:07db84e57fdd7101104c2469984217696fdfe51591cb1edee2928514135920d6", -// Size: 30, -// StoreImage: corev1alpha1.ImageSource{ -// Image: "some.registry.io/build-package", -// }, -// Order: []corev1alpha1.OrderEntry{ -// { -// Group: []corev1alpha1.BuildpackRef{ -// { -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.engine", -// Version: "1.0.0", -// }, -// Optional: false, -// }, -// { -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.package-manager", -// Version: "1.0.0", -// }, -// Optional: true, -// }, -// }, -// }, -// }, -// Homepage: "buildpack.meta.com", -// API: "0.3", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.meta.works", -// }, -// }, -// } - -// v8Buildpack := corev1alpha1.BuildpackStatus{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.multi", -// Version: "8.0.0", -// }, -// DiffId: "sha256:8bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", -// Digest: "sha256:fc14806eb95d01b6338ba1b9fea605e84db7c8c09561ae360bad5b80b5d0d80b", -// Size: 20, -// StoreImage: corev1alpha1.ImageSource{ -// Image: "some.registry.io/build-package", -// }, -// Order: nil, -// Homepage: "buildpack.multi.com", -// API: "0.2", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.v8.works", -// }, -// }, -// } - -// v9Buildpack := corev1alpha1.BuildpackStatus{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.multi", -// Version: "9.0.0", -// }, -// DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", -// Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", -// Size: 10, -// StoreImage: corev1alpha1.ImageSource{ -// Image: "some.registry.io/build-package", -// }, -// Order: nil, -// Homepage: "buildpack.multi.com", -// API: "0.2", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.v9.works", -// }, -// }, -// } - -// for _, bp := range []corev1alpha1.BuildpackStatus{ -// engineBuildpack, -// v9Buildpack, -// v8Buildpack, -// packageManagerBuildpack, -// metaBuildpack, -// } { -// resolver.AddBuildpackRef(t, makeRef(bp.Id, bp.Version), K8sRemoteBuildpack{ -// Buildpack: bp, -// SecretRef: registry.SecretRef{}, -// }) -// } - -// storeBuildpackRepository := &RemoteBuildpackFetcher{ -// KeychainFactory: keychainFactory, -// BuildpackResolver: resolver, -// } - -// it("returns layer info from store image", func() { -// info, err := storeBuildpackRepository.Fetch(ctx, engineBuildpack) -// require.NoError(t, err) - -// expectedLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ -// Digest: engineBuildpack.Digest, -// DiffId: engineBuildpack.DiffId, -// Image: engineBuildpack.StoreImage.Image, -// Size: engineBuildpack.Size, -// }) - -// require.Equal(t, info, RemoteBuildpackInfo{ -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.engine", -// Version: "1.0.0", -// }, -// Homepage: "buildpack.engine.com", -// }, -// Layers: []buildpackLayer{ -// { -// v1Layer: expectedLayer, -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.engine", -// Version: "1.0.0", -// }, -// Homepage: "buildpack.engine.com", -// }, -// BuildpackLayerInfo: BuildpackLayerInfo{ -// API: "0.1", -// LayerDiffID: diffID(t, expectedLayer), -// Homepage: "buildpack.engine.com", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.engine.works", -// }, -// }, -// }, -// }, -// }, -// }) -// }) - -// it("returns the semver newest buildpack if version is unspecified", func() { -// info, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.multi", "") -// require.NoError(t, err) - -// expectedLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ -// Digest: v9Buildpack.Digest, -// DiffId: v9Buildpack.DiffId, -// Image: v9Buildpack.StoreImage.Image, -// Size: v9Buildpack.Size, -// }) -// require.NoError(t, err) - -// require.Equal(t, info, RemoteBuildpackInfo{ -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.multi", -// Version: "9.0.0", -// }, -// Homepage: "buildpack.multi.com", -// }, -// Layers: []buildpackLayer{ -// { -// v1Layer: expectedLayer, -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.multi", -// Version: "9.0.0", -// }, -// Homepage: "buildpack.multi.com", -// }, -// BuildpackLayerInfo: BuildpackLayerInfo{ -// API: "0.2", -// LayerDiffID: diffID(t, expectedLayer), -// Homepage: "buildpack.multi.com", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.v9.works", -// }, -// }, -// }, -// }, -// }, -// }) -// }) - -// it("fails to find the buildpack if version is unspecified and not all buildpacks are semver conformant", func() { -// storeBuildpackRepository.ClusterStore.Status.Buildpacks = append(storeBuildpackRepository.ClusterStore.Status.Buildpacks, corev1alpha1.BuildpackStatus{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.multi", -// Version: "my-wacky-version", -// }, -// DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", -// Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", -// Size: 10, -// StoreImage: corev1alpha1.ImageSource{ -// Image: "some.registry.io/build-package", -// }, -// Order: nil, -// API: "0.2", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.v9.works", -// }, -// }, -// }) - -// _, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.multi", "") -// require.EqualError(t, err, "cannot find buildpack 'io.buildpack.multi' with latest version due to invalid semver 'my-wacky-version'") -// }) - -// it("returns all buildpack layers in a meta buildpack", func() { -// info, err := storeBuildpackRepository.FindByIdAndVersion("io.buildpack.meta", "1.0.0") -// require.NoError(t, err) - -// expectedEngineLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ -// Digest: engineBuildpack.Digest, -// DiffId: engineBuildpack.DiffId, -// Image: engineBuildpack.StoreImage.Image, -// Size: engineBuildpack.Size, -// }) -// require.NoError(t, err) - -// expectedPackageManagerLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ -// Digest: packageManagerBuildpack.Digest, -// DiffId: packageManagerBuildpack.DiffId, -// Image: packageManagerBuildpack.StoreImage.Image, -// Size: packageManagerBuildpack.Size, -// }) -// require.NoError(t, err) - -// expectedMetaLayer, err := imagehelpers.NewLazyMountableLayer(imagehelpers.LazyMountableLayerArgs{ -// Digest: metaBuildpack.Digest, -// DiffId: metaBuildpack.DiffId, -// Image: metaBuildpack.StoreImage.Image, -// Size: metaBuildpack.Size, -// }) -// require.NoError(t, err) - -// require.Equal(t, RemoteBuildpackInfo{ -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.meta", -// Version: "1.0.0", -// }, -// Homepage: "buildpack.meta.com", -// }, -// Layers: []buildpackLayer{ -// { -// v1Layer: expectedEngineLayer, -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.engine", -// Version: "1.0.0", -// }, -// Homepage: "buildpack.engine.com", -// }, -// BuildpackLayerInfo: BuildpackLayerInfo{ -// API: "0.1", -// LayerDiffID: diffID(t, expectedEngineLayer), -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.engine.works", -// }, -// }, -// Homepage: "buildpack.engine.com", -// }, -// }, -// { -// v1Layer: expectedPackageManagerLayer, -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.package-manager", -// Version: "1.0.0", -// }, -// Homepage: "buildpack.package-manager.com", -// }, -// BuildpackLayerInfo: BuildpackLayerInfo{ -// API: "0.2", -// LayerDiffID: diffID(t, expectedPackageManagerLayer), -// Homepage: "buildpack.package-manager.com", -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// }, -// { -// ID: "io.stack.only.package.works", -// }, -// }, -// }, -// }, -// { -// v1Layer: expectedMetaLayer, -// BuildpackInfo: DescriptiveBuildpackInfo{ -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.meta", -// Version: "1.0.0", -// }, -// Homepage: "buildpack.meta.com", -// }, -// BuildpackLayerInfo: BuildpackLayerInfo{ -// API: "0.3", -// LayerDiffID: diffID(t, expectedMetaLayer), -// Homepage: "buildpack.meta.com", -// Order: corev1alpha1.Order{ -// { -// Group: []corev1alpha1.BuildpackRef{ -// { -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.engine", -// Version: "1.0.0", -// }, -// Optional: false, -// }, -// { -// BuildpackInfo: corev1alpha1.BuildpackInfo{ -// Id: "io.buildpack.package-manager", -// Version: "1.0.0", -// }, -// Optional: true, -// }, -// }, -// }, -// }, -// Stacks: []corev1alpha1.BuildpackStack{ -// { -// ID: "io.custom.stack", -// Mixins: nil, -// }, -// { -// ID: "io.stack.only.meta.works", -// Mixins: nil, -// }, -// }, -// }, -// }, -// }, -// }, info) -// }) - -// }) -// } +import ( + "testing" + + buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/registry/registryfakes" + "github.com/sclevine/spec" + "github.com/stretchr/testify/assert" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestBuildpackResolver(t *testing.T) { + spec.Run(t, "TestBuildpackResolver", testBuildpackResolver) +} + +func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { + var ( + keychainFactory = ®istryfakes.FakeKeychainFactory{} + testNamespace = "some-namespace" + + engineBuildpack = corev1alpha1.BuildpackStatus{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.engine", + Version: "1.0.0", + }, + DiffId: "sha256:1bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", + Digest: "sha256:d345d1b12ae6b3f7cfc617f7adaebe06c32ce60b1aa30bb80fb622b65523de8f", + Size: 50, + StoreImage: corev1alpha1.ImageSource{ + Image: "some.registry.io/build-package", + }, + Order: nil, + Homepage: "buildpack.engine.com", + API: "0.1", + Stacks: []corev1alpha1.BuildpackStack{ + { + ID: "io.custom.stack", + }, + { + ID: "io.stack.only.engine.works", + }, + }, + } + + packageManagerBuildpack = corev1alpha1.BuildpackStatus{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.package-manager", + Version: "1.0.0", + }, + DiffId: "sha256:2bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", + Digest: "sha256:7c1213a54d20137a7479e72150c058268a6604b98c011b4fc11ca45927923d7b", + Size: 40, + StoreImage: corev1alpha1.ImageSource{ + Image: "some.registry.io/build-package", + }, + Order: nil, + Homepage: "buildpack.package-manager.com", + API: "0.2", + Stacks: []corev1alpha1.BuildpackStack{ + { + ID: "io.custom.stack", + }, + { + ID: "io.stack.only.package.works", + }, + }, + } + + metaBuildpack = corev1alpha1.BuildpackStatus{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.meta", + Version: "1.0.0", + }, + DiffId: "sha256:3bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", + Digest: "sha256:07db84e57fdd7101104c2469984217696fdfe51591cb1edee2928514135920d6", + Size: 30, + StoreImage: corev1alpha1.ImageSource{ + Image: "some.registry.io/build-package", + }, + Order: []corev1alpha1.OrderEntry{ + { + Group: []corev1alpha1.BuildpackRef{ + { + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.engine", + Version: "1.0.0", + }, + Optional: false, + }, + { + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.package-manager", + Version: "1.0.0", + }, + Optional: true, + }, + }, + }, + }, + Homepage: "buildpack.meta.com", + API: "0.3", + Stacks: []corev1alpha1.BuildpackStack{ + { + ID: "io.custom.stack", + }, + { + ID: "io.stack.only.meta.works", + }, + }, + } + + v8Buildpack = corev1alpha1.BuildpackStatus{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.multi", + Version: "8.0.0", + }, + DiffId: "sha256:8bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", + Digest: "sha256:fc14806eb95d01b6338ba1b9fea605e84db7c8c09561ae360bad5b80b5d0d80b", + Size: 20, + StoreImage: corev1alpha1.ImageSource{ + Image: "some.registry.io/build-package", + }, + Order: nil, + Homepage: "buildpack.multi.com", + API: "0.2", + Stacks: []corev1alpha1.BuildpackStack{ + { + ID: "io.custom.stack", + }, + { + ID: "io.stack.only.v8.works", + }, + }, + } + + v9Buildpack = corev1alpha1.BuildpackStatus{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "io.buildpack.multi", + Version: "9.0.0", + }, + DiffId: "sha256:9bf8899667b8d1e6b124f663faca32903b470831e5e4e992644ac5c839ab3462", + Digest: "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", + Size: 10, + StoreImage: corev1alpha1.ImageSource{ + Image: "some.registry.io/build-package", + }, + Order: nil, + Homepage: "buildpack.multi.com", + API: "0.2", + Stacks: []corev1alpha1.BuildpackStack{ + { + ID: "io.custom.stack", + }, + { + ID: "io.stack.only.v9.works", + }, + }, + } + ) + + when("Resolve", func() { + when("using the clusterstore", func() { + var ( + resolver BuildpackResolver + store = &buildapi.ClusterStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-store", + }, + Spec: buildapi.ClusterStoreSpec{}, + Status: buildapi.ClusterStoreStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + metaBuildpack, + engineBuildpack, + packageManagerBuildpack, + v8Buildpack, + v9Buildpack, + }, + }, + } + ) + + it.Before(func() { + resolver = NewBuildpackResolver(keychainFactory, store, nil, nil) + }) + + it("finds it using id", func() { + ref := makeRef("io.buildpack.engine", "") + expectedBuildpack := engineBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds it using id and version", func() { + ref := makeRef("io.buildpack.multi", "8.0.0") + expectedBuildpack := v8Buildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("fails on invalid id", func() { + ref := makeRef("fake-buildpack", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + }) + + it("fails on unknown version", func() { + ref := makeRef("io.buildpack.multi", "8.0.1") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + }) + }) + + when("using the buildpack resources", func() { + var ( + resolver BuildpackResolver + buildpacks = []*buildapi.Buildpack{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.meta", + Namespace: testNamespace, + }, + Status: buildapi.BuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + metaBuildpack, + engineBuildpack, + packageManagerBuildpack, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi-8.0.0", + Namespace: testNamespace, + }, + Status: buildapi.BuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v8Buildpack, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi-9.0.0", + Namespace: testNamespace, + }, + Status: buildapi.BuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v9Buildpack, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi", + Namespace: testNamespace, + }, + Status: buildapi.BuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v8Buildpack, + v9Buildpack, + }, + }, + }, + } + ) + + it.Before(func() { + resolver = NewBuildpackResolver(keychainFactory, nil, buildpacks, nil) + }) + + when("using id", func() { + it("finds it using id", func() { + ref := makeRef("io.buildpack.meta", "") + expectedBuildpack := metaBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds nested ids", func() { + ref := makeRef("io.buildpack.engine", "") + expectedBuildpack := engineBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds it using id and version", func() { + ref := makeRef("io.buildpack.multi", "8.0.0") + expectedBuildpack := v8Buildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("fails on invalid id", func() { + ref := makeRef("fake-buildpack", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + }) + + it("fails on unknown version", func() { + ref := makeRef("io.buildpack.multi", "8.0.1") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + }) + }) + + when("using object ref", func() { + it("finds the resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "", "") + expectedBuildpack := metaBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("fails on invalid kind", func() { + ref := makeObjectRef("io.buildpack.meta", "FakeBuildpack", "", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "kind must be either Buildpack or ClusterBuildpack") + }) + + it("fails on object not found", func() { + ref := makeObjectRef("fake-buildpack", buildapi.BuildpackKind, "", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "no buildpack with name 'fake-buildpack'") + }) + }) + + when("using id and object ref together", func() { + it("finds id in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "io.buildpack.meta", "") + expectedBuildpack := metaBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds nested id in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "io.buildpack.engine", "") + expectedBuildpack := engineBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds the correct version in resource", func() { + ref := makeObjectRef("io.buildpack.multi", buildapi.BuildpackKind, "io.buildpack.multi", "8.0.0") + expectedBuildpack := v8Buildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("fails on id not found in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "fake-buildpack", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + }) + + it("fails on version not found in resource", func() { + ref := makeObjectRef("io.buildpack.multi", buildapi.BuildpackKind, "io.buildpack.multi", "8.0.1") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + }) + + it("fails on id not found in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "fake-buildpack", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + }) + }) + }) + + when("using the clusterbuildpack resources", func() { + var ( + resolver BuildpackResolver + clusterBuildpacks = []*buildapi.ClusterBuildpack{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.meta", + Namespace: testNamespace, + }, + Status: buildapi.ClusterBuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + metaBuildpack, + engineBuildpack, + packageManagerBuildpack, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi-8.0.0", + Namespace: testNamespace, + }, + Status: buildapi.ClusterBuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v8Buildpack, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi-9.0.0", + Namespace: testNamespace, + }, + Status: buildapi.ClusterBuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v9Buildpack, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi", + Namespace: testNamespace, + }, + Status: buildapi.ClusterBuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v8Buildpack, + v9Buildpack, + }, + }, + }, + } + ) + + it.Before(func() { + resolver = NewBuildpackResolver(keychainFactory, nil, nil, clusterBuildpacks) + }) + + when("using id", func() { + it("finds it using id", func() { + ref := makeRef("io.buildpack.meta", "") + expectedBuildpack := metaBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds nested ids", func() { + ref := makeRef("io.buildpack.engine", "") + expectedBuildpack := engineBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds it using id and version", func() { + ref := makeRef("io.buildpack.multi", "8.0.0") + expectedBuildpack := v8Buildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("fails on invalid id", func() { + ref := makeRef("fake-buildpack", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + }) + + it("fails on unknown version", func() { + ref := makeRef("io.buildpack.multi", "8.0.1") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + }) + }) + + when("using object ref", func() { + it("finds the resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "", "") + expectedBuildpack := metaBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("fails on invalid kind", func() { + ref := makeObjectRef("io.buildpack.meta", "FakeClusterBuildpack", "", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "kind must be either Buildpack or ClusterBuildpack") + }) + + it("fails on object not found", func() { + ref := makeObjectRef("fake-buildpack", buildapi.ClusterBuildpackKind, "", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "no cluster buildpack with name 'fake-buildpack'") + }) + }) + + when("using id and object ref together", func() { + it("finds id in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "io.buildpack.meta", "") + expectedBuildpack := metaBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds nested id in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "io.buildpack.engine", "") + expectedBuildpack := engineBuildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("finds the correct version in resource", func() { + ref := makeObjectRef("io.buildpack.multi", buildapi.ClusterBuildpackKind, "io.buildpack.multi", "8.0.0") + expectedBuildpack := v8Buildpack + + buildpack, err := resolver.Resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + }) + + it("fails on id not found in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "fake-buildpack", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + }) + + it("fails on version not found in resource", func() { + ref := makeObjectRef("io.buildpack.multi", buildapi.ClusterBuildpackKind, "io.buildpack.multi", "8.0.1") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + }) + + it("fails on id not found in resource", func() { + ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "fake-buildpack", "") + _, err := resolver.Resolve(ref) + assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + }) + }) + }) + + // when("resolving via image", func() { + // }) + }) +} diff --git a/pkg/cnb/dependency_tree_test.go b/pkg/cnb/dependency_tree_test.go index 15afd0f2..8f424b97 100644 --- a/pkg/cnb/dependency_tree_test.go +++ b/pkg/cnb/dependency_tree_test.go @@ -14,7 +14,7 @@ func TestDependencyTree(t *testing.T) { } func testNewTree(t *testing.T, when spec.G, it spec.S) { - when("there is 1 root tree", func() { + when("single tree", func() { it("builds the tree", func() { buildpacks := []v1alpha1.BuildpackStatus{ { @@ -71,7 +71,7 @@ func testNewTree(t *testing.T, when spec.G, it spec.S) { }) }) - when("There is multiple root tree", func() { + when("multiple trees", func() { it("builds the tree", func() { buildpacks := []v1alpha1.BuildpackStatus{ { diff --git a/pkg/cnb/fakes_test.go b/pkg/cnb/fakes_test.go index a7a97455..385693c6 100644 --- a/pkg/cnb/fakes_test.go +++ b/pkg/cnb/fakes_test.go @@ -6,12 +6,13 @@ import ( "io" "testing" - v1 "github.com/google/go-containerregistry/pkg/v1" + registryv1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/types" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pkg/errors" "github.com/stretchr/testify/assert" + k8scorev1 "k8s.io/api/core/v1" ) type fakeLayer struct { @@ -20,12 +21,12 @@ type fakeLayer struct { size int64 } -func (f fakeLayer) Digest() (v1.Hash, error) { - return v1.NewHash(f.digest) +func (f fakeLayer) Digest() (registryv1.Hash, error) { + return registryv1.NewHash(f.digest) } -func (f fakeLayer) DiffID() (v1.Hash, error) { - return v1.NewHash(f.diffID) +func (f fakeLayer) DiffID() (registryv1.Hash, error) { + return registryv1.NewHash(f.diffID) } func (f fakeLayer) Size() (int64, error) { @@ -83,6 +84,21 @@ func makeRef(id, version string) buildapi.BuilderBuildpackRef { } } +func makeObjectRef(name, kind, id, version string) buildapi.BuilderBuildpackRef { + return buildapi.BuilderBuildpackRef{ + ObjectReference: k8scorev1.ObjectReference{ + Name: name, + Kind: kind, + }, + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: id, + Version: version, + }, + }, + } +} + type fakeFetcher struct { buildpacks map[string][]buildpackLayer } diff --git a/pkg/cnb/remote_buildpack_fetcher_test.go b/pkg/cnb/remote_buildpack_fetcher_test.go index 0029355e..9ecf0587 100644 --- a/pkg/cnb/remote_buildpack_fetcher_test.go +++ b/pkg/cnb/remote_buildpack_fetcher_test.go @@ -185,13 +185,10 @@ func testRemoteBuildpackFetcher(t *testing.T, when spec.G, it spec.S) { keychainFactory.AddKeychainForSecretRef(t, secretRef, keychain) }) - storeBuildpackRepository := &remoteBuildpackFetcher{ - KeychainFactory: keychainFactory, - BuildpackResolver: resolver, - } + fetcher := NewRemoteBuildpackFetcher(resolver, keychainFactory) it("returns layer info from store image", func() { - info, err := storeBuildpackRepository.Fetch(ctx, K8sRemoteBuildpack{ + info, err := fetcher.Fetch(ctx, K8sRemoteBuildpack{ Buildpack: engineBuildpack, SecretRef: secretRef, }) @@ -243,7 +240,7 @@ func testRemoteBuildpackFetcher(t *testing.T, when spec.G, it spec.S) { }) it("returns all buildpack layers in a meta buildpack", func() { - info, err := storeBuildpackRepository.Fetch(ctx, K8sRemoteBuildpack{ + info, err := fetcher.Fetch(ctx, K8sRemoteBuildpack{ Buildpack: metaBuildpack, SecretRef: secretRef, }) From ca3641ea6f9a54b972521040555a3f99c62c543d Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Mon, 6 Feb 2023 16:25:48 -0500 Subject: [PATCH 14/39] introduce a CachedKeychainFactory this will mainly be used in the remote buildpack fetcher to avoid duplicating calls to the k8s api. Signed-off-by: Bohan Chen --- pkg/dockercreds/cached_keychain.go | 42 +++++++++ pkg/dockercreds/cached_keychain_test.go | 88 +++++++++++++++++++ .../k8sdockercreds/k8s_keychain.go | 2 +- 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 pkg/dockercreds/cached_keychain.go create mode 100644 pkg/dockercreds/cached_keychain_test.go diff --git a/pkg/dockercreds/cached_keychain.go b/pkg/dockercreds/cached_keychain.go new file mode 100644 index 00000000..0c9d6337 --- /dev/null +++ b/pkg/dockercreds/cached_keychain.go @@ -0,0 +1,42 @@ +package dockercreds + +import ( + "context" + "fmt" + + "github.com/google/go-containerregistry/pkg/authn" + "github.com/pivotal/kpack/pkg/registry" +) + +type cacheKey string + +type cachedKeychainFactory struct { + keychainFactory registry.KeychainFactory + cache map[cacheKey]authn.Keychain +} + +func NewCachedKeychainFactory(keychainFactory registry.KeychainFactory) registry.KeychainFactory { + return &cachedKeychainFactory{ + keychainFactory: keychainFactory, + cache: make(map[cacheKey]authn.Keychain), + } +} + +func (f *cachedKeychainFactory) KeychainForSecretRef(ctx context.Context, secretRef registry.SecretRef) (authn.Keychain, error) { + key := makeKey(secretRef) + if keychain, found := f.cache[key]; found { + return keychain, nil + } + + keychain, err := f.keychainFactory.KeychainForSecretRef(ctx, secretRef) + if err != nil { + return nil, err + } + + f.cache[key] = keychain + return keychain, nil +} + +func makeKey(secretRef registry.SecretRef) cacheKey { + return cacheKey(fmt.Sprintf("%v/%v", secretRef.Namespace, secretRef.ServiceAccount)) +} diff --git a/pkg/dockercreds/cached_keychain_test.go b/pkg/dockercreds/cached_keychain_test.go new file mode 100644 index 00000000..1efeb3a5 --- /dev/null +++ b/pkg/dockercreds/cached_keychain_test.go @@ -0,0 +1,88 @@ +package dockercreds + +import ( + "context" + "testing" + + "github.com/google/go-containerregistry/pkg/authn" + "github.com/pivotal/kpack/pkg/registry" + "github.com/sclevine/spec" + "github.com/stretchr/testify/assert" +) + +func TestCachedKeychainFactory(t *testing.T) { + spec.Run(t, "CachedSecretKeychainFactory", testCachedKeychainFactory) +} + +func testCachedKeychainFactory(t *testing.T, when spec.G, it spec.S) { + var ( + ctx = context.Background() + expectedKeychain = authn.NewMultiKeychain(authn.DefaultKeychain) + baseFactory *fakeFactory + factory registry.KeychainFactory + ) + it.Before(func() { + baseFactory = &fakeFactory{keychain: expectedKeychain, err: nil} + factory = NewCachedKeychainFactory(baseFactory) + }) + + it("returns the correct keychain", func() { + ref := registry.SecretRef{} + keychain, err := factory.KeychainForSecretRef(ctx, ref) + assert.NoError(t, err) + assert.Equal(t, expectedKeychain, keychain) + + assert.Len(t, baseFactory.argsForCall, 1) + assert.Equal(t, ref, baseFactory.argsForCall[0]) + }) + + it("caches results", func() { + ref := registry.SecretRef{ + ServiceAccount: "some-service-account", + Namespace: "some-namespace", + } + keychain, err := factory.KeychainForSecretRef(ctx, ref) + assert.NoError(t, err) + assert.Equal(t, expectedKeychain, keychain) + + keychain, err = factory.KeychainForSecretRef(ctx, ref) + assert.NoError(t, err) + assert.Equal(t, expectedKeychain, keychain) + + assert.Len(t, baseFactory.argsForCall, 1) + assert.Equal(t, ref, baseFactory.argsForCall[0]) + }) + + it("can handle multiple keychains", func() { + ref1 := registry.SecretRef{ + ServiceAccount: "some-service-account", + Namespace: "some-namespace", + } + keychain, err := factory.KeychainForSecretRef(ctx, ref1) + assert.NoError(t, err) + assert.Equal(t, expectedKeychain, keychain) + + ref2 := registry.SecretRef{ + ServiceAccount: "some-other-service-account", + Namespace: "some-other-namespace", + } + keychain, err = factory.KeychainForSecretRef(ctx, ref2) + assert.NoError(t, err) + assert.Equal(t, expectedKeychain, keychain) + + assert.Len(t, baseFactory.argsForCall, 2) + assert.Equal(t, ref1, baseFactory.argsForCall[0]) + assert.Equal(t, ref2, baseFactory.argsForCall[1]) + }) +} + +type fakeFactory struct { + keychain authn.Keychain + err error + argsForCall []registry.SecretRef +} + +func (f *fakeFactory) KeychainForSecretRef(_ context.Context, ref registry.SecretRef) (authn.Keychain, error) { + f.argsForCall = append(f.argsForCall, ref) + return f.keychain, f.err +} diff --git a/pkg/dockercreds/k8sdockercreds/k8s_keychain.go b/pkg/dockercreds/k8sdockercreds/k8s_keychain.go index 6bcc59f4..26547b1f 100644 --- a/pkg/dockercreds/k8sdockercreds/k8s_keychain.go +++ b/pkg/dockercreds/k8sdockercreds/k8s_keychain.go @@ -24,7 +24,7 @@ type k8sSecretKeychainFactory struct { volumeKeychain authn.Keychain } -func NewSecretKeychainFactory(client k8sclient.Interface) (*k8sSecretKeychainFactory, error) { +func NewSecretKeychainFactory(client k8sclient.Interface) (registry.KeychainFactory, error) { volumeKeychain, err := dockercreds.NewVolumeSecretKeychain() if err != nil { return nil, err From d856ed0fcd83088120aaf496b103d7c12e33414d Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Mon, 6 Feb 2023 16:29:18 -0500 Subject: [PATCH 15/39] fold BuildpackResolver into RemoteBuildpackFetcher since these 2 are pretty much created and used in tandem, and the main reason for them to be separate interfaces is for more modular testing. Signed-off-by: Bohan Chen --- pkg/cnb/buildpack_resolver.go | 4 +- pkg/cnb/buildpack_resolver_test.go | 10 ++-- pkg/cnb/create_builder.go | 13 ++-- pkg/cnb/create_builder_test.go | 59 ++++--------------- pkg/cnb/fakes_test.go | 13 ++-- pkg/cnb/remote_buildpack_fetcher.go | 41 +++++++++---- pkg/cnb/remote_buildpack_fetcher_test.go | 9 ++- pkg/reconciler/builder/builder.go | 5 +- pkg/reconciler/builder/builder_test.go | 4 +- .../clusterbuilder/clusterbuilder.go | 5 +- .../clusterbuilder/clusterbuilder_test.go | 4 +- .../testhelpers/fake_builder_creator.go | 4 +- 12 files changed, 74 insertions(+), 97 deletions(-) diff --git a/pkg/cnb/buildpack_resolver.go b/pkg/cnb/buildpack_resolver.go index 2f81a956..bb0f3200 100644 --- a/pkg/cnb/buildpack_resolver.go +++ b/pkg/cnb/buildpack_resolver.go @@ -20,15 +20,13 @@ type BuildpackResolver interface { } type buildpackResolver struct { - keychainFactory registry.KeychainFactory clusterstore *v1alpha2.ClusterStore buildpacks []*v1alpha2.Buildpack clusterBuildpacks []*v1alpha2.ClusterBuildpack } -func NewBuildpackResolver(keychainFactory registry.KeychainFactory, clusterStore *v1alpha2.ClusterStore, buildpacks []*v1alpha2.Buildpack, clusterBuildpacks []*v1alpha2.ClusterBuildpack) BuildpackResolver { +func NewBuildpackResolver(clusterStore *v1alpha2.ClusterStore, buildpacks []*v1alpha2.Buildpack, clusterBuildpacks []*v1alpha2.ClusterBuildpack) BuildpackResolver { return &buildpackResolver{ - keychainFactory: keychainFactory, clusterstore: clusterStore, buildpacks: buildpacks, clusterBuildpacks: clusterBuildpacks, diff --git a/pkg/cnb/buildpack_resolver_test.go b/pkg/cnb/buildpack_resolver_test.go index 3a88757e..8f8c2119 100644 --- a/pkg/cnb/buildpack_resolver_test.go +++ b/pkg/cnb/buildpack_resolver_test.go @@ -5,7 +5,6 @@ import ( buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" - "github.com/pivotal/kpack/pkg/registry/registryfakes" "github.com/sclevine/spec" "github.com/stretchr/testify/assert" @@ -18,8 +17,7 @@ func TestBuildpackResolver(t *testing.T) { func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { var ( - keychainFactory = ®istryfakes.FakeKeychainFactory{} - testNamespace = "some-namespace" + testNamespace = "some-namespace" engineBuildpack = corev1alpha1.BuildpackStatus{ BuildpackInfo: corev1alpha1.BuildpackInfo{ @@ -183,7 +181,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { ) it.Before(func() { - resolver = NewBuildpackResolver(keychainFactory, store, nil, nil) + resolver = NewBuildpackResolver(store, nil, nil) }) it("finds it using id", func() { @@ -272,7 +270,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { ) it.Before(func() { - resolver = NewBuildpackResolver(keychainFactory, nil, buildpacks, nil) + resolver = NewBuildpackResolver(nil, buildpacks, nil) }) when("using id", func() { @@ -442,7 +440,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { ) it.Before(func() { - resolver = NewBuildpackResolver(keychainFactory, nil, nil, clusterBuildpacks) + resolver = NewBuildpackResolver(nil, nil, clusterBuildpacks) }) when("using id", func() { diff --git a/pkg/cnb/create_builder.go b/pkg/cnb/create_builder.go index a02e27ae..819d221e 100644 --- a/pkg/cnb/create_builder.go +++ b/pkg/cnb/create_builder.go @@ -25,7 +25,7 @@ type LifecycleProvider interface { } type BuilderCreator interface { - CreateBuilder(ctx context.Context, keychain authn.Keychain, resolver BuildpackResolver, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) + CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) } type RemoteBuilderCreator struct { @@ -40,7 +40,7 @@ var _ BuilderCreator = (*RemoteBuilderCreator)(nil) func (r *RemoteBuilderCreator) CreateBuilder( ctx context.Context, builderKeychain authn.Keychain, - resolver BuildpackResolver, fetcher RemoteBuildpackFetcher, + fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec, ) (buildapi.BuilderRecord, error) { buildImage, _, err := r.RegistryClient.Fetch(builderKeychain, clusterStack.Status.BuildImage.LatestImage) @@ -66,12 +66,7 @@ func (r *RemoteBuilderCreator) CreateBuilder( buildpacks := make([]RemoteBuildpackRef, 0, len(group.Group)) for _, buildpack := range group.Group { - resolvedBuildpack, err := resolver.Resolve(buildpack) - if err != nil { - return buildapi.BuilderRecord{}, err - } - - remoteBuildpack, err := fetcher.Fetch(ctx, resolvedBuildpack) + remoteBuildpack, err := fetcher.ResolveAndFetch(ctx, buildpack) if err != nil { return buildapi.BuilderRecord{}, err } @@ -105,7 +100,7 @@ func (r *RemoteBuilderCreator) CreateBuilder( Buildpacks: buildpackMetadata(builderBldr.buildpacks()), Order: builderBldr.order, ObservedStackGeneration: clusterStack.Status.ObservedGeneration, - ObservedStoreGeneration: resolver.ClusterStoreObservedGeneration(), + ObservedStoreGeneration: fetcher.ClusterStoreObservedGeneration(), OS: config.OS, }, nil } diff --git a/pkg/cnb/create_builder_test.go b/pkg/cnb/create_builder_test.go index 4e476008..469171be 100644 --- a/pkg/cnb/create_builder_test.go +++ b/pkg/cnb/create_builder_test.go @@ -62,8 +62,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { ctx = context.Background() - resolver = &fakeResolver{buildpacks: map[string]K8sRemoteBuildpack{}, observedGeneration: 10} - fetcher = &fakeFetcher{buildpacks: map[string][]buildpackLayer{}} + fetcher = &fakeFetcher{buildpacks: map[string][]buildpackLayer{}, observedGeneration: 10} linuxLifecycle = &fakeLayer{ digest: "sha256:5d43d12dabe6070c4a4036e700a6f88a52278c02097b5f200e0b49b3d874c954", @@ -172,32 +171,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { } addBuildpack = func(t *testing.T, id, version, homepage, api string, stacks []corev1alpha1.BuildpackStack) { - ref := buildapi.BuilderBuildpackRef{ - BuildpackRef: corev1alpha1.BuildpackRef{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: id, - Version: version, - }, - }, - } - - remote := K8sRemoteBuildpack{ - Buildpack: corev1alpha1.BuildpackStatus{ - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: id, - Version: version, - }, - DiffId: buildpack1Layer.diffID, - Digest: buildpack1Layer.digest, - Size: buildpack1Layer.size, - Homepage: homepage, - API: api, - Stacks: stacks, - }, - SecretRef: secretRef, - } - - layer := buildpackLayer{ + fetcher.AddBuildpack(t, id, version, []buildpackLayer{{ v1Layer: buildpack1Layer, BuildpackInfo: DescriptiveBuildpackInfo{ BuildpackInfo: corev1alpha1.BuildpackInfo{ @@ -211,10 +185,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { LayerDiffID: buildpack1Layer.diffID, Stacks: stacks, }, - } - - resolver.AddBuildpack(t, ref, remote) - fetcher.AddBuildpack(t, id, version, []buildpackLayer{layer}) + }}) } ) @@ -292,10 +263,6 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - resolver.AddBuildpack(t, makeRef("io.buildpack.1", "v1"), layerToRemoteBuildpack(buildpack1, buildpack1Layer, secretRef)) - resolver.AddBuildpack(t, makeRef("io.buildpack.2", "v2"), layerToRemoteBuildpack(buildpack2, buildpack2Layer, secretRef)) - resolver.AddBuildpack(t, makeRef("io.buildpack.3", "v3"), layerToRemoteBuildpack(buildpack3, buildpack3Layer, secretRef)) - fetcher.AddBuildpack(t, "io.buildpack.1", "v1", []buildpackLayer{buildpack1}) fetcher.AddBuildpack(t, "io.buildpack.2", "v2", []buildpackLayer{buildpack3, buildpack2}) }) @@ -347,7 +314,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates a custom builder", func() { - builderRecord, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + builderRecord, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) assert.Len(t, builderRecord.Buildpacks, 3) @@ -609,11 +576,11 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates images deterministically ", func() { - original, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + original, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) for i := 1; i <= 50; i++ { - other, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + other, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) require.Equal(t, original.Image, other.Image) @@ -643,7 +610,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.stack@v4: stack io.buildpacks.stacks.some-stack is not supported") }) @@ -667,7 +634,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.mixin@v4: stack missing mixin(s): something-missing-mixin, something-missing-mixin2") }) @@ -712,7 +679,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.Nil(t, err) }) @@ -737,7 +704,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.Error(t, err, "validating buildpack io.buildpack.relaxed.old.mixin@v4: stack missing mixin(s): build:common-mixin, run:common-mixin, another-common-mixin") }) @@ -760,7 +727,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.buildpack.api@v4: unsupported buildpack api: 0.1, expecting: 0.2, 0.3") }) @@ -803,7 +770,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) }) }) @@ -830,7 +797,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, err := subject.CreateBuilder(ctx, keychain, resolver, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "unsupported platform apis in kpack lifecycle: 0.1, 0.2, 0.999, expecting one of: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8") }) }) diff --git a/pkg/cnb/fakes_test.go b/pkg/cnb/fakes_test.go index 385693c6..36e471fb 100644 --- a/pkg/cnb/fakes_test.go +++ b/pkg/cnb/fakes_test.go @@ -100,21 +100,26 @@ func makeObjectRef(name, kind, id, version string) buildapi.BuilderBuildpackRef } type fakeFetcher struct { - buildpacks map[string][]buildpackLayer + buildpacks map[string][]buildpackLayer + observedGeneration int64 } -func (f *fakeFetcher) Fetch(ctx context.Context, buildpack K8sRemoteBuildpack) (RemoteBuildpackInfo, error) { - layers, ok := f.buildpacks[fmt.Sprintf("%s@%s", buildpack.Buildpack.Id, buildpack.Buildpack.Version)] +func (f *fakeFetcher) ResolveAndFetch(_ context.Context, buildpack buildapi.BuilderBuildpackRef) (RemoteBuildpackInfo, error) { + layers, ok := f.buildpacks[fmt.Sprintf("%s@%s", buildpack.Id, buildpack.Version)] if !ok { return RemoteBuildpackInfo{}, errors.New("buildpack not found") } return RemoteBuildpackInfo{ - BuildpackInfo: buildpackInfoInLayers(layers, buildpack.Buildpack.Id, buildpack.Buildpack.Version), + BuildpackInfo: buildpackInfoInLayers(layers, buildpack.Id, buildpack.Version), Layers: layers, }, nil } +func (f *fakeFetcher) ClusterStoreObservedGeneration() int64 { + return f.observedGeneration +} + func (f *fakeFetcher) AddBuildpack(t *testing.T, id, version string, layers []buildpackLayer) { t.Helper() f.buildpacks[fmt.Sprintf("%s@%s", id, version)] = layers diff --git a/pkg/cnb/remote_buildpack_fetcher.go b/pkg/cnb/remote_buildpack_fetcher.go index 66d231c9..9d9bc76c 100644 --- a/pkg/cnb/remote_buildpack_fetcher.go +++ b/pkg/cnb/remote_buildpack_fetcher.go @@ -6,31 +6,46 @@ import ( "github.com/google/go-containerregistry/pkg/authn" v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" + "github.com/pivotal/kpack/pkg/dockercreds" "github.com/pivotal/kpack/pkg/registry" "github.com/pivotal/kpack/pkg/registry/imagehelpers" ) type RemoteBuildpackFetcher interface { - Fetch(ctx context.Context, remoteBuildpack K8sRemoteBuildpack) (RemoteBuildpackInfo, error) + ResolveAndFetch(context.Context, buildapi.BuilderBuildpackRef) (RemoteBuildpackInfo, error) + ClusterStoreObservedGeneration() int64 } type remoteBuildpackFetcher struct { - BuildpackResolver BuildpackResolver - KeychainFactory registry.KeychainFactory + resolver BuildpackResolver + keychainFactory registry.KeychainFactory } -func NewRemoteBuildpackFetcher(resolver BuildpackResolver, factory registry.KeychainFactory) RemoteBuildpackFetcher { +func NewRemoteBuildpackFetcher( + factory registry.KeychainFactory, + clusterStore *buildapi.ClusterStore, + buildpacks []*buildapi.Buildpack, clusterBuildpacks []*buildapi.ClusterBuildpack, +) RemoteBuildpackFetcher { return &remoteBuildpackFetcher{ - BuildpackResolver: resolver, - KeychainFactory: factory, + resolver: NewBuildpackResolver(clusterStore, buildpacks, clusterBuildpacks), + keychainFactory: dockercreds.NewCachedKeychainFactory(factory), } } -func (s *remoteBuildpackFetcher) Fetch(ctx context.Context, remoteBuildpack K8sRemoteBuildpack) (RemoteBuildpackInfo, error) { +func (s *remoteBuildpackFetcher) ResolveAndFetch(ctx context.Context, ref buildapi.BuilderBuildpackRef) (RemoteBuildpackInfo, error) { + remote, err := s.resolver.Resolve(ref) + if err != nil { + return RemoteBuildpackInfo{}, err + } + + return s.fetch(ctx, remote) +} + +func (s *remoteBuildpackFetcher) fetch(ctx context.Context, remoteBuildpack K8sRemoteBuildpack) (RemoteBuildpackInfo, error) { buildpack := remoteBuildpack.Buildpack - keychain, err := s.KeychainFactory.KeychainForSecretRef(ctx, remoteBuildpack.SecretRef) + keychain, err := s.keychainFactory.KeychainForSecretRef(ctx, remoteBuildpack.SecretRef) if err != nil { return RemoteBuildpackInfo{}, err } @@ -69,12 +84,16 @@ func (s *remoteBuildpackFetcher) Fetch(ctx context.Context, remoteBuildpack K8sR }, nil } +func (s *remoteBuildpackFetcher) ClusterStoreObservedGeneration() int64 { + return s.resolver.ClusterStoreObservedGeneration() +} + // TODO: ensure there are no cycles in the buildpack graph func (s *remoteBuildpackFetcher) layersForOrder(ctx context.Context, order corev1alpha1.Order) ([]buildpackLayer, error) { var buildpackLayers []buildpackLayer for _, orderEntry := range order { for _, buildpackRef := range orderEntry.Group { - buildpack, err := s.BuildpackResolver.Resolve(v1alpha2.BuilderBuildpackRef{ + buildpack, err := s.resolver.Resolve(buildapi.BuilderBuildpackRef{ BuildpackRef: corev1alpha1.BuildpackRef{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: buildpackRef.Id, @@ -86,7 +105,7 @@ func (s *remoteBuildpackFetcher) layersForOrder(ctx context.Context, order corev return nil, err } - buildpackInfo, err := s.Fetch(ctx, buildpack) + buildpackInfo, err := s.fetch(ctx, buildpack) if err != nil { return nil, err } diff --git a/pkg/cnb/remote_buildpack_fetcher_test.go b/pkg/cnb/remote_buildpack_fetcher_test.go index 9ecf0587..e620a8e4 100644 --- a/pkg/cnb/remote_buildpack_fetcher_test.go +++ b/pkg/cnb/remote_buildpack_fetcher_test.go @@ -185,10 +185,13 @@ func testRemoteBuildpackFetcher(t *testing.T, when spec.G, it spec.S) { keychainFactory.AddKeychainForSecretRef(t, secretRef, keychain) }) - fetcher := NewRemoteBuildpackFetcher(resolver, keychainFactory) + fetcher := &remoteBuildpackFetcher{ + resolver: resolver, + keychainFactory: keychainFactory, + } it("returns layer info from store image", func() { - info, err := fetcher.Fetch(ctx, K8sRemoteBuildpack{ + info, err := fetcher.fetch(ctx, K8sRemoteBuildpack{ Buildpack: engineBuildpack, SecretRef: secretRef, }) @@ -240,7 +243,7 @@ func testRemoteBuildpackFetcher(t *testing.T, when spec.G, it spec.S) { }) it("returns all buildpack layers in a meta buildpack", func() { - info, err := fetcher.Fetch(ctx, K8sRemoteBuildpack{ + info, err := fetcher.fetch(ctx, K8sRemoteBuildpack{ Buildpack: metaBuildpack, SecretRef: secretRef, }) diff --git a/pkg/reconciler/builder/builder.go b/pkg/reconciler/builder/builder.go index f2fc7fe2..024adc89 100644 --- a/pkg/reconciler/builder/builder.go +++ b/pkg/reconciler/builder/builder.go @@ -189,10 +189,9 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui return buildapi.BuilderRecord{}, err } - resolver := cnb.NewBuildpackResolver(c.KeychainFactory, clusterStore, buildpacks, clusterBuildpacks) - fetcher := cnb.NewRemoteBuildpackFetcher(resolver, c.KeychainFactory) + fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, buildpacks, clusterBuildpacks) - return c.BuilderCreator.CreateBuilder(ctx, keychain, resolver, fetcher, clusterStack, builder.Spec.BuilderSpec) + return c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) } func (c *Reconciler) updateStatus(ctx context.Context, desired *buildapi.Builder) error { diff --git a/pkg/reconciler/builder/builder_test.go b/pkg/reconciler/builder/builder_test.go index e6425c21..21b246d3 100644 --- a/pkg/reconciler/builder/builder_test.go +++ b/pkg/reconciler/builder/builder_test.go @@ -219,8 +219,7 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, } - expectedResolver := cnb.NewBuildpackResolver(keychainFactory, clusterStore, []*buildapi.Buildpack{buildpack}, []*buildapi.ClusterBuildpack{clusterBuildpack}) - expectedFetcher := cnb.NewRemoteBuildpackFetcher(expectedResolver, keychainFactory) + expectedFetcher := cnb.NewRemoteBuildpackFetcher(keychainFactory, clusterStore, []*buildapi.Buildpack{buildpack}, []*buildapi.ClusterBuildpack{clusterBuildpack}) rt.Test(rtesting.TableRow{ Key: builderKey, @@ -242,7 +241,6 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { assert.Equal(t, []testhelpers.CreateBuilderArgs{{ Context: context.Background(), Keychain: ®istryfakes.FakeKeychain{}, - Resolver: expectedResolver, Fetcher: expectedFetcher, ClusterStack: clusterStack, BuilderSpec: builder.Spec.BuilderSpec, diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder.go b/pkg/reconciler/clusterbuilder/clusterbuilder.go index 4ed47f54..bcfc4654 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder.go @@ -180,10 +180,9 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu return buildapi.BuilderRecord{}, err } - resolver := cnb.NewBuildpackResolver(c.KeychainFactory, clusterStore, nil, clusterBuildpacks) - fetcher := cnb.NewRemoteBuildpackFetcher(resolver, c.KeychainFactory) + fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, nil, clusterBuildpacks) - return c.BuilderCreator.CreateBuilder(ctx, keychain, resolver, fetcher, clusterStack, builder.Spec.BuilderSpec) + return c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) } func (c *Reconciler) updateStatus(ctx context.Context, desired *buildapi.ClusterBuilder) error { diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go index d1afeee8..faac0fac 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go @@ -220,8 +220,7 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, } - expectedResolver := cnb.NewBuildpackResolver(keychainFactory, clusterStore, nil, []*buildapi.ClusterBuildpack{clusterBuildpack}) - expectedFetcher := cnb.NewRemoteBuildpackFetcher(expectedResolver, keychainFactory) + expectedFetcher := cnb.NewRemoteBuildpackFetcher(keychainFactory, clusterStore, nil, []*buildapi.ClusterBuildpack{clusterBuildpack}) rt.Test(rtesting.TableRow{ Key: builderKey, @@ -242,7 +241,6 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { assert.Equal(t, []testhelpers.CreateBuilderArgs{{ Context: context.Background(), Keychain: ®istryfakes.FakeKeychain{}, - Resolver: expectedResolver, Fetcher: expectedFetcher, ClusterStack: clusterStack, BuilderSpec: builder.Spec.BuilderSpec, diff --git a/pkg/reconciler/testhelpers/fake_builder_creator.go b/pkg/reconciler/testhelpers/fake_builder_creator.go index ecd8279b..6e7ee14c 100644 --- a/pkg/reconciler/testhelpers/fake_builder_creator.go +++ b/pkg/reconciler/testhelpers/fake_builder_creator.go @@ -19,7 +19,6 @@ type FakeBuilderCreator struct { type CreateBuilderArgs struct { Context context.Context Keychain authn.Keychain - Resolver cnb.BuildpackResolver Fetcher cnb.RemoteBuildpackFetcher ClusterStack *buildapi.ClusterStack BuilderSpec buildapi.BuilderSpec @@ -27,11 +26,10 @@ type CreateBuilderArgs struct { var _ cnb.BuilderCreator = (*FakeBuilderCreator)(nil) -func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, resolver cnb.BuildpackResolver, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) (buildapi.BuilderRecord, error) { +func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) (buildapi.BuilderRecord, error) { f.CreateBuilderCalls = append(f.CreateBuilderCalls, CreateBuilderArgs{ Context: ctx, Keychain: keychain, - Resolver: resolver, Fetcher: fetcher, ClusterStack: clusterStack, BuilderSpec: builder, From d48f698f9c08f2da6616934e1d5326ecff985adc Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Tue, 7 Feb 2023 16:56:35 -0500 Subject: [PATCH 16/39] track which objects were used to resolve buildpack as a result of this change, the [cluster]builders no longer track the clusterstore if none of the buildpacks from it is used. and also embed the resolver interface in the fetcher directly so we don't have to create wrapper functions Signed-off-by: Bohan Chen --- pkg/cnb/buildpack_resolver.go | 27 ++++++++-- pkg/cnb/create_builder.go | 38 +++++++------- pkg/cnb/remote_buildpack_fetcher.go | 16 +++--- pkg/cnb/remote_buildpack_metadata.go | 7 +-- pkg/reconciler/builder/builder.go | 47 +++++++++++------ .../clusterbuilder/clusterbuilder.go | 51 ++++++++++++------- 6 files changed, 115 insertions(+), 71 deletions(-) diff --git a/pkg/cnb/buildpack_resolver.go b/pkg/cnb/buildpack_resolver.go index bb0f3200..b338b928 100644 --- a/pkg/cnb/buildpack_resolver.go +++ b/pkg/cnb/buildpack_resolver.go @@ -15,14 +15,16 @@ import ( // BuildpackResolver will attempt to resolve a Buildpack reference to a // Buildpack from either the ClusterStore, Buildpacks, or ClusterBuildpacks type BuildpackResolver interface { - Resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) + resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) ClusterStoreObservedGeneration() int64 + UsedObjects() []v1.ObjectReference } type buildpackResolver struct { clusterstore *v1alpha2.ClusterStore buildpacks []*v1alpha2.Buildpack clusterBuildpacks []*v1alpha2.ClusterBuildpack + usedObjects []v1.ObjectReference } func NewBuildpackResolver(clusterStore *v1alpha2.ClusterStore, buildpacks []*v1alpha2.Buildpack, clusterBuildpacks []*v1alpha2.ClusterBuildpack) BuildpackResolver { @@ -30,6 +32,7 @@ func NewBuildpackResolver(clusterStore *v1alpha2.ClusterStore, buildpacks []*v1a clusterstore: clusterStore, buildpacks: buildpacks, clusterBuildpacks: clusterBuildpacks, + usedObjects: make([]v1.ObjectReference, 0), } } @@ -40,7 +43,11 @@ func (r *buildpackResolver) ClusterStoreObservedGeneration() int64 { return 0 } -func (r *buildpackResolver) Resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { +func (r *buildpackResolver) UsedObjects() []v1.ObjectReference { + return r.usedObjects +} + +func (r *buildpackResolver) resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { var matchingBuildpacks []K8sRemoteBuildpack var err error switch { @@ -104,11 +111,13 @@ func (r *buildpackResolver) Resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemote if err != nil { return K8sRemoteBuildpack{}, err } + r.usedObjects = append(r.usedObjects, bp.source) return bp, nil } for _, result := range matchingBuildpacks { if result.Buildpack.Version == ref.Version { + r.usedObjects = append(r.usedObjects, result.source) return result, nil } } @@ -121,13 +130,13 @@ func (r *buildpackResolver) resolveFromBuildpack(id string, buildpacks []*v1alph for _, bp := range buildpacks { for _, status := range bp.Status.Buildpacks { if status.Id == id { - matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ Buildpack: status, SecretRef: registry.SecretRef{ ServiceAccount: bp.Spec.ServiceAccountName, Namespace: bp.Namespace, }, + source: v1.ObjectReference{Name: bp.Name, Namespace: bp.Namespace, Kind: bp.Kind}, }) } } @@ -151,6 +160,7 @@ func (r *buildpackResolver) resolveFromClusterBuildpack(id string, clusterBuildp matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ Buildpack: status, SecretRef: secretRef, + source: v1.ObjectReference{Name: cbp.Name, Namespace: cbp.Namespace, Kind: cbp.Kind}, }) } } @@ -177,6 +187,7 @@ func (r *buildpackResolver) resolveFromClusterStore(id string, store *v1alpha2.C matchingBuildpacks = append(matchingBuildpacks, K8sRemoteBuildpack{ Buildpack: status, SecretRef: secretRef, + source: v1.ObjectReference{Name: store.Name, Namespace: store.Namespace, Kind: store.Kind}, }) } } @@ -186,8 +197,11 @@ func (r *buildpackResolver) resolveFromClusterStore(id string, store *v1alpha2.C // resolveFromObjectReference will get the object and figure out the root // buildpack by converting it to a buildpack dependency tree func (r *buildpackResolver) resolveFromObjectReference(ref v1.ObjectReference) (K8sRemoteBuildpack, error) { - var bps []corev1alpha1.BuildpackStatus - var secretRef registry.SecretRef + var ( + bps []corev1alpha1.BuildpackStatus + secretRef registry.SecretRef + objRef v1.ObjectReference + ) switch ref.Kind { case v1alpha2.BuildpackKind: bp := findBuildpack(ref, r.buildpacks) @@ -196,6 +210,7 @@ func (r *buildpackResolver) resolveFromObjectReference(ref v1.ObjectReference) ( } bps = bp.Status.Buildpacks + objRef = v1.ObjectReference{Name: bp.Name, Namespace: bp.Namespace, Kind: bp.Kind} secretRef = registry.SecretRef{ ServiceAccount: bp.Spec.ServiceAccountName, Namespace: bp.Namespace, @@ -207,6 +222,7 @@ func (r *buildpackResolver) resolveFromObjectReference(ref v1.ObjectReference) ( } bps = cbp.Status.Buildpacks + objRef = v1.ObjectReference{Name: cbp.Name, Namespace: cbp.Namespace, Kind: cbp.Kind} if cbp.Spec.ServiceAccountRef != nil { secretRef = registry.SecretRef{ ServiceAccount: cbp.Spec.ServiceAccountRef.Name, @@ -225,6 +241,7 @@ func (r *buildpackResolver) resolveFromObjectReference(ref v1.ObjectReference) ( return K8sRemoteBuildpack{ Buildpack: *trees[0].Buildpack, SecretRef: secretRef, + source: objRef, }, nil } diff --git a/pkg/cnb/create_builder.go b/pkg/cnb/create_builder.go index 819d221e..a5b4ab5a 100644 --- a/pkg/cnb/create_builder.go +++ b/pkg/cnb/create_builder.go @@ -4,28 +4,24 @@ import ( "context" "github.com/google/go-containerregistry/pkg/authn" - v1 "github.com/google/go-containerregistry/pkg/v1" - + ggcrv1 "github.com/google/go-containerregistry/pkg/v1" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/registry" + k8scorev1 "k8s.io/api/core/v1" ) type RegistryClient interface { - Fetch(keychain authn.Keychain, repoName string) (v1.Image, string, error) - Save(keychain authn.Keychain, tag string, image v1.Image) (string, error) -} - -type BuildpackRepository interface { - FindByIdAndVersion(id, version string) (RemoteBuildpackInfo, error) + Fetch(keychain authn.Keychain, repoName string) (ggcrv1.Image, string, error) + Save(keychain authn.Keychain, tag string, image ggcrv1.Image) (string, error) } type LifecycleProvider interface { - LayerForOS(os string) (v1.Layer, LifecycleMetadata, error) + LayerForOS(os string) (ggcrv1.Layer, LifecycleMetadata, error) } type BuilderCreator interface { - CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) + CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) ([]k8scorev1.ObjectReference, buildapi.BuilderRecord, error) } type RemoteBuilderCreator struct { @@ -42,22 +38,22 @@ func (r *RemoteBuilderCreator) CreateBuilder( builderKeychain authn.Keychain, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec, -) (buildapi.BuilderRecord, error) { +) ([]k8scorev1.ObjectReference, buildapi.BuilderRecord, error) { buildImage, _, err := r.RegistryClient.Fetch(builderKeychain, clusterStack.Status.BuildImage.LatestImage) if err != nil { - return buildapi.BuilderRecord{}, err + return nil, buildapi.BuilderRecord{}, err } builderBldr := newBuilderBldr(r.KpackVersion) err = builderBldr.AddStack(buildImage, clusterStack) if err != nil { - return buildapi.BuilderRecord{}, err + return nil, buildapi.BuilderRecord{}, err } lifecycleLayer, lifecycleMetadata, err := r.LifecycleProvider.LayerForOS(builderBldr.os) if err != nil { - return buildapi.BuilderRecord{}, err + return nil, buildapi.BuilderRecord{}, err } builderBldr.AddLifecycle(lifecycleLayer, lifecycleMetadata) @@ -68,7 +64,7 @@ func (r *RemoteBuilderCreator) CreateBuilder( for _, buildpack := range group.Group { remoteBuildpack, err := fetcher.ResolveAndFetch(ctx, buildpack) if err != nil { - return buildapi.BuilderRecord{}, err + return nil, buildapi.BuilderRecord{}, err } buildpacks = append(buildpacks, remoteBuildpack.Optional(buildpack.Optional)) @@ -78,20 +74,20 @@ func (r *RemoteBuilderCreator) CreateBuilder( writeableImage, err := builderBldr.WriteableImage() if err != nil { - return buildapi.BuilderRecord{}, err + return nil, buildapi.BuilderRecord{}, err } identifier, err := r.RegistryClient.Save(builderKeychain, spec.Tag, writeableImage) if err != nil { - return buildapi.BuilderRecord{}, err + return nil, buildapi.BuilderRecord{}, err } config, err := writeableImage.ConfigFile() if err != nil { - return buildapi.BuilderRecord{}, err + return nil, buildapi.BuilderRecord{}, err } - return buildapi.BuilderRecord{ + builder := buildapi.BuilderRecord{ Image: identifier, Stack: corev1alpha1.BuildStack{ RunImage: clusterStack.Status.RunImage.LatestImage, @@ -102,7 +98,9 @@ func (r *RemoteBuilderCreator) CreateBuilder( ObservedStackGeneration: clusterStack.Status.ObservedGeneration, ObservedStoreGeneration: fetcher.ClusterStoreObservedGeneration(), OS: config.OS, - }, nil + } + + return fetcher.UsedObjects(), builder, nil } func buildpackMetadata(buildpacks []DescriptiveBuildpackInfo) corev1alpha1.BuildpackMetadataList { diff --git a/pkg/cnb/remote_buildpack_fetcher.go b/pkg/cnb/remote_buildpack_fetcher.go index 9d9bc76c..78d4eb28 100644 --- a/pkg/cnb/remote_buildpack_fetcher.go +++ b/pkg/cnb/remote_buildpack_fetcher.go @@ -14,12 +14,12 @@ import ( ) type RemoteBuildpackFetcher interface { + BuildpackResolver ResolveAndFetch(context.Context, buildapi.BuilderBuildpackRef) (RemoteBuildpackInfo, error) - ClusterStoreObservedGeneration() int64 } type remoteBuildpackFetcher struct { - resolver BuildpackResolver + BuildpackResolver keychainFactory registry.KeychainFactory } @@ -29,13 +29,13 @@ func NewRemoteBuildpackFetcher( buildpacks []*buildapi.Buildpack, clusterBuildpacks []*buildapi.ClusterBuildpack, ) RemoteBuildpackFetcher { return &remoteBuildpackFetcher{ - resolver: NewBuildpackResolver(clusterStore, buildpacks, clusterBuildpacks), - keychainFactory: dockercreds.NewCachedKeychainFactory(factory), + BuildpackResolver: NewBuildpackResolver(clusterStore, buildpacks, clusterBuildpacks), + keychainFactory: dockercreds.NewCachedKeychainFactory(factory), } } func (s *remoteBuildpackFetcher) ResolveAndFetch(ctx context.Context, ref buildapi.BuilderBuildpackRef) (RemoteBuildpackInfo, error) { - remote, err := s.resolver.Resolve(ref) + remote, err := s.resolve(ref) if err != nil { return RemoteBuildpackInfo{}, err } @@ -84,16 +84,12 @@ func (s *remoteBuildpackFetcher) fetch(ctx context.Context, remoteBuildpack K8sR }, nil } -func (s *remoteBuildpackFetcher) ClusterStoreObservedGeneration() int64 { - return s.resolver.ClusterStoreObservedGeneration() -} - // TODO: ensure there are no cycles in the buildpack graph func (s *remoteBuildpackFetcher) layersForOrder(ctx context.Context, order corev1alpha1.Order) ([]buildpackLayer, error) { var buildpackLayers []buildpackLayer for _, orderEntry := range order { for _, buildpackRef := range orderEntry.Group { - buildpack, err := s.resolver.Resolve(buildapi.BuilderBuildpackRef{ + buildpack, err := s.resolve(buildapi.BuilderBuildpackRef{ BuildpackRef: corev1alpha1.BuildpackRef{ BuildpackInfo: corev1alpha1.BuildpackInfo{ Id: buildpackRef.Id, diff --git a/pkg/cnb/remote_buildpack_metadata.go b/pkg/cnb/remote_buildpack_metadata.go index aeaa34cf..e35f0a0f 100644 --- a/pkg/cnb/remote_buildpack_metadata.go +++ b/pkg/cnb/remote_buildpack_metadata.go @@ -1,10 +1,10 @@ package cnb import ( - v1 "github.com/google/go-containerregistry/pkg/v1" - + ggcrv1 "github.com/google/go-containerregistry/pkg/v1" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/registry" + k8sv1 "k8s.io/api/core/v1" ) type RemoteBuildpackInfo struct { @@ -34,7 +34,7 @@ func (r RemoteBuildpackRef) buildpackRef() corev1alpha1.BuildpackRef { } type buildpackLayer struct { - v1Layer v1.Layer + v1Layer ggcrv1.Layer BuildpackInfo DescriptiveBuildpackInfo BuildpackLayerInfo BuildpackLayerInfo } @@ -42,4 +42,5 @@ type buildpackLayer struct { type K8sRemoteBuildpack struct { Buildpack corev1alpha1.BuildpackStatus SecretRef registry.SecretRef + source k8sv1.ObjectReference } diff --git a/pkg/reconciler/builder/builder.go b/pkg/reconciler/builder/builder.go index 024adc89..9c621c95 100644 --- a/pkg/reconciler/builder/builder.go +++ b/pkg/reconciler/builder/builder.go @@ -77,6 +77,16 @@ func NewController( c.Tracker.OnChanged, buildapi.SchemeGroupVersion.WithKind(buildapi.ClusterStackKind)), )) + buildpackInformer.Informer().AddEventHandler(controller.HandleAll( + controller.EnsureTypeMeta( + c.Tracker.OnChanged, + buildapi.SchemeGroupVersion.WithKind(buildapi.BuildpackKind)), + )) + clusterBuildpackInformer.Informer().AddEventHandler(controller.HandleAll( + controller.EnsureTypeMeta( + c.Tracker.OnChanged, + buildapi.SchemeGroupVersion.WithKind(buildapi.ClusterBuildpackKind)), + )) return impl, func() { impl.GlobalResync(builderInformer.Informer()) @@ -127,20 +137,6 @@ func (c *Reconciler) Reconcile(ctx context.Context, key string) error { func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Builder) (buildapi.BuilderRecord, error) { err := c.Tracker.Track(reconciler.Key{ - NamespacedName: types.NamespacedName{ - Name: builder.Spec.Store.Name, - Namespace: v1.NamespaceAll, - }, - GroupKind: schema.GroupKind{ - Group: "kpack.io", - Kind: buildapi.ClusterStoreKind, - }, - }, builder.NamespacedName()) - if err != nil { - return buildapi.BuilderRecord{}, err - } - - err = c.Tracker.Track(reconciler.Key{ NamespacedName: types.NamespacedName{ Name: builder.Spec.Stack.Name, Namespace: v1.NamespaceAll, @@ -191,7 +187,28 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, buildpacks, clusterBuildpacks) - return c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + buildpackSources, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + if err != nil { + return buildapi.BuilderRecord{}, err + } + + for _, source := range buildpackSources { + err = c.Tracker.Track(reconciler.Key{ + NamespacedName: types.NamespacedName{ + Name: source.Name, + Namespace: source.Namespace, + }, + GroupKind: schema.GroupKind{ + Group: "kpack.io", + Kind: source.Kind, + }, + }, builder.NamespacedName()) + if err != nil { + return buildapi.BuilderRecord{}, err + } + } + + return buildRecord, nil } func (c *Reconciler) updateStatus(ctx context.Context, desired *buildapi.Builder) error { diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder.go b/pkg/reconciler/clusterbuilder/clusterbuilder.go index bcfc4654..1b9b4fb4 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder.go @@ -76,6 +76,11 @@ func NewController( c.Tracker.OnChanged, buildapi.SchemeGroupVersion.WithKind(buildapi.ClusterStackKind)), )) + clusterBuildpackInformer.Informer().AddEventHandler(controller.HandleAll( + controller.EnsureTypeMeta( + c.Tracker.OnChanged, + buildapi.SchemeGroupVersion.WithKind(buildapi.ClusterBuildpackKind)), + )) return impl, func() { impl.GlobalResync(clusterBuilderInformer.Informer()) @@ -126,20 +131,6 @@ func (c *Reconciler) Reconcile(ctx context.Context, key string) error { func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.ClusterBuilder) (buildapi.BuilderRecord, error) { err := c.Tracker.Track(reconciler.Key{ - NamespacedName: types.NamespacedName{ - Name: builder.Spec.Store.Name, - Namespace: v1.NamespaceAll, - }, - GroupKind: schema.GroupKind{ - Group: "kpack.io", - Kind: buildapi.ClusterStoreKind, - }, - }, builder.NamespacedName()) - if err != nil { - return buildapi.BuilderRecord{}, err - } - - err = c.Tracker.Track(reconciler.Key{ NamespacedName: types.NamespacedName{ Name: builder.Spec.Stack.Name, Namespace: v1.NamespaceAll, @@ -153,9 +144,12 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu return buildapi.BuilderRecord{}, err } - clusterStore, err := c.ClusterStoreLister.Get(builder.Spec.Store.Name) - if err != nil { - return buildapi.BuilderRecord{}, err + var clusterStore *buildapi.ClusterStore + if builder.Spec.Store.Name != "" { + clusterStore, err = c.ClusterStoreLister.Get(builder.Spec.Store.Name) + if err != nil { + return buildapi.BuilderRecord{}, err + } } clusterBuildpacks, err := c.ClusterBuildpackLister.List(labels.Everything()) @@ -182,7 +176,28 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, nil, clusterBuildpacks) - return c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + buildpackSources, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + if err != nil { + return buildapi.BuilderRecord{}, err + } + + for _, source := range buildpackSources { + err = c.Tracker.Track(reconciler.Key{ + NamespacedName: types.NamespacedName{ + Name: source.Name, + Namespace: source.Namespace, + }, + GroupKind: schema.GroupKind{ + Group: "kpack.io", + Kind: source.Kind, + }, + }, builder.NamespacedName()) + if err != nil { + return buildapi.BuilderRecord{}, err + } + } + + return buildRecord, nil } func (c *Reconciler) updateStatus(ctx context.Context, desired *buildapi.ClusterBuilder) error { From e54790d2e15799b529023a54a1cbc10eaa9cf061 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Tue, 7 Feb 2023 16:59:14 -0500 Subject: [PATCH 17/39] update tests Signed-off-by: Bohan Chen --- pkg/cnb/buildpack_resolver_test.go | 361 +++++++++++++++--- pkg/cnb/create_builder_test.go | 20 +- pkg/cnb/fakes_test.go | 14 +- pkg/cnb/remote_buildpack_fetcher_test.go | 4 +- pkg/reconciler/builder/builder_test.go | 26 +- .../clusterbuilder/clusterbuilder_test.go | 21 +- .../testhelpers/fake_builder_creator.go | 10 +- 7 files changed, 369 insertions(+), 87 deletions(-) diff --git a/pkg/cnb/buildpack_resolver_test.go b/pkg/cnb/buildpack_resolver_test.go index 8f8c2119..044a6389 100644 --- a/pkg/cnb/buildpack_resolver_test.go +++ b/pkg/cnb/buildpack_resolver_test.go @@ -8,6 +8,7 @@ import ( "github.com/sclevine/spec" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -164,6 +165,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { var ( resolver BuildpackResolver store = &buildapi.ClusterStore{ + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterStore"}, ObjectMeta: metav1.ObjectMeta{ Name: "some-store", }, @@ -188,30 +190,44 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { ref := makeRef("io.buildpack.engine", "") expectedBuildpack := engineBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "some-store", + Kind: "ClusterStore", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds it using id and version", func() { ref := makeRef("io.buildpack.multi", "8.0.0") expectedBuildpack := v8Buildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "some-store", + Kind: "ClusterStore", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid id", func() { ref := makeRef("fake-buildpack", "") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on unknown version", func() { ref := makeRef("io.buildpack.multi", "8.0.1") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + assert.Len(t, resolver.UsedObjects(), 0) }) }) @@ -220,6 +236,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { resolver BuildpackResolver buildpacks = []*buildapi.Buildpack{ { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "Buildpack"}, ObjectMeta: metav1.ObjectMeta{ Name: "io.buildpack.meta", Namespace: testNamespace, @@ -233,6 +250,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { }, }, { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "Buildpack"}, ObjectMeta: metav1.ObjectMeta{ Name: "io.buildpack.multi-8.0.0", Namespace: testNamespace, @@ -244,6 +262,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { }, }, { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "Buildpack"}, ObjectMeta: metav1.ObjectMeta{ Name: "io.buildpack.multi-9.0.0", Namespace: testNamespace, @@ -255,6 +274,7 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { }, }, { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "Buildpack"}, ObjectMeta: metav1.ObjectMeta{ Name: "io.buildpack.multi", Namespace: testNamespace, @@ -278,109 +298,165 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { ref := makeRef("io.buildpack.meta", "") expectedBuildpack := metaBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested ids", func() { ref := makeRef("io.buildpack.engine", "") expectedBuildpack := engineBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds it using id and version", func() { ref := makeRef("io.buildpack.multi", "8.0.0") expectedBuildpack := v8Buildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.multi-8.0.0", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid id", func() { ref := makeRef("fake-buildpack", "") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on unknown version", func() { ref := makeRef("io.buildpack.multi", "8.0.1") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + assert.Len(t, resolver.UsedObjects(), 0) }) }) when("using object ref", func() { it("finds the resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "", "") + ref := makeObjectRef("io.buildpack.meta", "Buildpack", "", "") expectedBuildpack := metaBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid kind", func() { ref := makeObjectRef("io.buildpack.meta", "FakeBuildpack", "", "") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "kind must be either Buildpack or ClusterBuildpack") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on object not found", func() { - ref := makeObjectRef("fake-buildpack", buildapi.BuildpackKind, "", "") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("fake-buildpack", "Buildpack", "", "") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "no buildpack with name 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) }) when("using id and object ref together", func() { it("finds id in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "io.buildpack.meta", "") + ref := makeObjectRef("io.buildpack.meta", "Buildpack", "io.buildpack.meta", "") expectedBuildpack := metaBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested id in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "io.buildpack.engine", "") + ref := makeObjectRef("io.buildpack.meta", "Buildpack", "io.buildpack.engine", "") expectedBuildpack := engineBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds the correct version in resource", func() { - ref := makeObjectRef("io.buildpack.multi", buildapi.BuildpackKind, "io.buildpack.multi", "8.0.0") + ref := makeObjectRef("io.buildpack.multi", "Buildpack", "io.buildpack.multi", "8.0.0") expectedBuildpack := v8Buildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.multi", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on id not found in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "fake-buildpack", "") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("io.buildpack.meta", "Buildpack", "fake-buildpack", "") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on version not found in resource", func() { - ref := makeObjectRef("io.buildpack.multi", buildapi.BuildpackKind, "io.buildpack.multi", "8.0.1") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("io.buildpack.multi", "Buildpack", "io.buildpack.multi", "8.0.1") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on id not found in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.BuildpackKind, "fake-buildpack", "") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("io.buildpack.meta", "Buildpack", "fake-buildpack", "") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) }) }) @@ -390,9 +466,9 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { resolver BuildpackResolver clusterBuildpacks = []*buildapi.ClusterBuildpack{ { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterBuildpack"}, ObjectMeta: metav1.ObjectMeta{ - Name: "io.buildpack.meta", - Namespace: testNamespace, + Name: "io.buildpack.meta", }, Status: buildapi.ClusterBuildpackStatus{ Buildpacks: []corev1alpha1.BuildpackStatus{ @@ -403,9 +479,9 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { }, }, { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterBuildpack"}, ObjectMeta: metav1.ObjectMeta{ - Name: "io.buildpack.multi-8.0.0", - Namespace: testNamespace, + Name: "io.buildpack.multi-8.0.0", }, Status: buildapi.ClusterBuildpackStatus{ Buildpacks: []corev1alpha1.BuildpackStatus{ @@ -414,9 +490,9 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { }, }, { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterBuildpack"}, ObjectMeta: metav1.ObjectMeta{ - Name: "io.buildpack.multi-9.0.0", - Namespace: testNamespace, + Name: "io.buildpack.multi-9.0.0", }, Status: buildapi.ClusterBuildpackStatus{ Buildpacks: []corev1alpha1.BuildpackStatus{ @@ -425,9 +501,9 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { }, }, { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterBuildpack"}, ObjectMeta: metav1.ObjectMeta{ - Name: "io.buildpack.multi", - Namespace: testNamespace, + Name: "io.buildpack.multi", }, Status: buildapi.ClusterBuildpackStatus{ Buildpacks: []corev1alpha1.BuildpackStatus{ @@ -448,113 +524,286 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { ref := makeRef("io.buildpack.meta", "") expectedBuildpack := metaBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested ids", func() { ref := makeRef("io.buildpack.engine", "") expectedBuildpack := engineBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds it using id and version", func() { ref := makeRef("io.buildpack.multi", "8.0.0") expectedBuildpack := v8Buildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.multi-8.0.0", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid id", func() { ref := makeRef("fake-buildpack", "") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on unknown version", func() { ref := makeRef("io.buildpack.multi", "8.0.1") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + assert.Len(t, resolver.UsedObjects(), 0) }) }) when("using object ref", func() { it("finds the resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "", "") + ref := makeObjectRef("io.buildpack.meta", "ClusterBuildpack", "", "") expectedBuildpack := metaBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid kind", func() { ref := makeObjectRef("io.buildpack.meta", "FakeClusterBuildpack", "", "") - _, err := resolver.Resolve(ref) + _, err := resolver.resolve(ref) assert.EqualError(t, err, "kind must be either Buildpack or ClusterBuildpack") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on object not found", func() { - ref := makeObjectRef("fake-buildpack", buildapi.ClusterBuildpackKind, "", "") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("fake-buildpack", "ClusterBuildpack", "", "") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "no cluster buildpack with name 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) }) when("using id and object ref together", func() { it("finds id in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "io.buildpack.meta", "") + ref := makeObjectRef("io.buildpack.meta", "ClusterBuildpack", "io.buildpack.meta", "") expectedBuildpack := metaBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested id in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "io.buildpack.engine", "") + ref := makeObjectRef("io.buildpack.meta", "ClusterBuildpack", "io.buildpack.engine", "") expectedBuildpack := engineBuildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.meta", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds the correct version in resource", func() { - ref := makeObjectRef("io.buildpack.multi", buildapi.ClusterBuildpackKind, "io.buildpack.multi", "8.0.0") + ref := makeObjectRef("io.buildpack.multi", "ClusterBuildpack", "io.buildpack.multi", "8.0.0") expectedBuildpack := v8Buildpack - buildpack, err := resolver.Resolve(ref) + buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.multi", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on id not found in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "fake-buildpack", "") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("io.buildpack.meta", "ClusterBuildpack", "fake-buildpack", "") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on version not found in resource", func() { - ref := makeObjectRef("io.buildpack.multi", buildapi.ClusterBuildpackKind, "io.buildpack.multi", "8.0.1") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("io.buildpack.multi", "ClusterBuildpack", "io.buildpack.multi", "8.0.1") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") + assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on id not found in resource", func() { - ref := makeObjectRef("io.buildpack.meta", buildapi.ClusterBuildpackKind, "fake-buildpack", "") - _, err := resolver.Resolve(ref) + ref := makeObjectRef("io.buildpack.meta", "ClusterBuildpack", "fake-buildpack", "") + _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") + assert.Len(t, resolver.UsedObjects(), 0) }) }) }) + when("using multiple resource kinds", func() { + var ( + resolver BuildpackResolver + store = &buildapi.ClusterStore{ + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterStore"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "some-store", + }, + Spec: buildapi.ClusterStoreSpec{}, + Status: buildapi.ClusterStoreStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + metaBuildpack, + v8Buildpack, + }, + }, + } + buildpacks = []*buildapi.Buildpack{ + { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "Buildpack"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi-8.0.0", + Namespace: testNamespace, + }, + Status: buildapi.BuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v8Buildpack, + }, + }, + }, + } + clusterBuildpacks = []*buildapi.ClusterBuildpack{ + { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterBuildpack"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi-8.0.0", + }, + Status: buildapi.ClusterBuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v8Buildpack, + }, + }, + }, + { + TypeMeta: metav1.TypeMeta{APIVersion: "v1alpha2", Kind: "ClusterBuildpack"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "io.buildpack.multi-9.0.0", + }, + Status: buildapi.ClusterBuildpackStatus{ + Buildpacks: []corev1alpha1.BuildpackStatus{ + v9Buildpack, + }, + }, + }, + } + ) + + it.Before(func() { + resolver = NewBuildpackResolver(store, buildpacks, clusterBuildpacks) + }) + + it("records which objects were used", func() { + buildpack, err := resolver.resolve(makeRef("io.buildpack.meta", "")) + assert.Nil(t, err) + assert.Equal(t, metaBuildpack, buildpack.Buildpack) + + buildpack, err = resolver.resolve(makeRef("io.buildpack.multi", "8.0.0")) + + assert.Nil(t, err) + assert.Equal(t, v8Buildpack, buildpack.Buildpack) + + buildpack, err = resolver.resolve(makeRef("io.buildpack.multi", "9.0.0")) + assert.Nil(t, err) + assert.Equal(t, v9Buildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{ + { + Name: "some-store", + Kind: "ClusterStore", + }, + { + Name: "io.buildpack.multi-8.0.0", + Namespace: testNamespace, + Kind: "Buildpack", + }, + { + Name: "io.buildpack.multi-9.0.0", + Kind: "ClusterBuildpack", + }, + } + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) + }) + + it("resolves buildpacks before anything else", func() { + ref := makeRef("io.buildpack.multi", "8.0.0") + expectedBuildpack := v8Buildpack + + buildpack, err := resolver.resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.multi-8.0.0", + Namespace: testNamespace, + Kind: "Buildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) + }) + + it("resolves cluster buildpacks before cluster store", func() { + ref := makeRef("io.buildpack.multi", "9.0.0") + expectedBuildpack := v9Buildpack + + buildpack, err := resolver.resolve(ref) + assert.Nil(t, err) + assert.Equal(t, expectedBuildpack, buildpack.Buildpack) + + expectedUsedObjects := []corev1.ObjectReference{{ + Name: "io.buildpack.multi-9.0.0", + Kind: "ClusterBuildpack", + }} + assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) + }) + }) + // when("resolving via image", func() { // }) }) diff --git a/pkg/cnb/create_builder_test.go b/pkg/cnb/create_builder_test.go index 469171be..b75b120a 100644 --- a/pkg/cnb/create_builder_test.go +++ b/pkg/cnb/create_builder_test.go @@ -314,7 +314,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates a custom builder", func() { - builderRecord, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, builderRecord, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) assert.Len(t, builderRecord.Buildpacks, 3) @@ -576,11 +576,11 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates images deterministically ", func() { - original, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, original, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) for i := 1; i <= 50; i++ { - other, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, other, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) require.Equal(t, original.Image, other.Image) @@ -610,7 +610,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.stack@v4: stack io.buildpacks.stacks.some-stack is not supported") }) @@ -634,7 +634,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.mixin@v4: stack missing mixin(s): something-missing-mixin, something-missing-mixin2") }) @@ -679,7 +679,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.Nil(t, err) }) @@ -704,7 +704,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.Error(t, err, "validating buildpack io.buildpack.relaxed.old.mixin@v4: stack missing mixin(s): build:common-mixin, run:common-mixin, another-common-mixin") }) @@ -727,7 +727,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.buildpack.api@v4: unsupported buildpack api: 0.1, expecting: 0.2, 0.3") }) @@ -770,7 +770,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) }) }) @@ -797,7 +797,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "unsupported platform apis in kpack lifecycle: 0.1, 0.2, 0.999, expecting one of: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8") }) }) diff --git a/pkg/cnb/fakes_test.go b/pkg/cnb/fakes_test.go index 36e471fb..f42c081e 100644 --- a/pkg/cnb/fakes_test.go +++ b/pkg/cnb/fakes_test.go @@ -55,7 +55,7 @@ type fakeResolver struct { observedGeneration int64 } -func (r *fakeResolver) Resolve(ref buildapi.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { +func (r *fakeResolver) resolve(ref buildapi.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { buildpack, ok := r.buildpacks[fmt.Sprintf("%s@%s", ref.Id, ref.Version)] if !ok { return K8sRemoteBuildpack{}, errors.New("buildpack not found") @@ -63,6 +63,10 @@ func (r *fakeResolver) Resolve(ref buildapi.BuilderBuildpackRef) (K8sRemoteBuild return buildpack, nil } +func (f *fakeResolver) UsedObjects() []k8scorev1.ObjectReference { + return nil +} + func (f *fakeResolver) AddBuildpack(t *testing.T, ref buildapi.BuilderBuildpackRef, buildpack K8sRemoteBuildpack) { t.Helper() assert.NotEqual(t, ref.Id, "", "buildpack ref missing id") @@ -120,6 +124,14 @@ func (f *fakeFetcher) ClusterStoreObservedGeneration() int64 { return f.observedGeneration } +func (f *fakeFetcher) UsedObjects() []k8scorev1.ObjectReference { + return nil +} + +func (f *fakeFetcher) resolve(ref buildapi.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { + panic("Not implemented For Tests") +} + func (f *fakeFetcher) AddBuildpack(t *testing.T, id, version string, layers []buildpackLayer) { t.Helper() f.buildpacks[fmt.Sprintf("%s@%s", id, version)] = layers diff --git a/pkg/cnb/remote_buildpack_fetcher_test.go b/pkg/cnb/remote_buildpack_fetcher_test.go index e620a8e4..a2403299 100644 --- a/pkg/cnb/remote_buildpack_fetcher_test.go +++ b/pkg/cnb/remote_buildpack_fetcher_test.go @@ -186,8 +186,8 @@ func testRemoteBuildpackFetcher(t *testing.T, when spec.G, it spec.S) { }) fetcher := &remoteBuildpackFetcher{ - resolver: resolver, - keychainFactory: keychainFactory, + BuildpackResolver: resolver, + keychainFactory: keychainFactory, } it("returns layer info from store image", func() { diff --git a/pkg/reconciler/builder/builder_test.go b/pkg/reconciler/builder/builder_test.go index 21b246d3..7527624a 100644 --- a/pkg/reconciler/builder/builder_test.go +++ b/pkg/reconciler/builder/builder_test.go @@ -103,12 +103,20 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { Name: "buildpack.id.3", Namespace: testNamespace, }, + TypeMeta: metav1.TypeMeta{ + Kind: "Buildpack", + APIVersion: "kpack.io/v1alpha2", + }, } clusterBuildpack := &buildapi.ClusterBuildpack{ ObjectMeta: metav1.ObjectMeta{ Name: "buildpack.id.4", }, + TypeMeta: metav1.TypeMeta{ + Kind: "ClusterBuildpack", + APIVersion: "kpack.io/v1alpha2", + }, } builder := &buildapi.Builder{ @@ -247,7 +255,7 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }}, builderCreator.CreateBuilderCalls) }) - it("tracks the stack and store for a custom builder", func() { + it("tracks the store and buildpack sources for a custom builder", func() { builderCreator.Record = buildapi.BuilderRecord{ Image: builderIdentifier, Stack: corev1alpha1.BuildStack{ @@ -256,6 +264,11 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, Buildpacks: corev1alpha1.BuildpackMetadataList{}, } + builderCreator.ObjectsToTrack = []corev1.ObjectReference{ + {Name: clusterStore.Name, Kind: clusterStore.Kind}, + {Name: buildpack.Name, Kind: buildpack.Kind, Namespace: testNamespace}, + {Name: clusterBuildpack.Name, Kind: clusterBuildpack.Kind}, + } expectedBuilder := &buildapi.Builder{ ObjectMeta: builder.ObjectMeta, @@ -284,6 +297,8 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { Objects: []runtime.Object{ clusterStack, clusterStore, + buildpack, + clusterBuildpack, expectedBuilder, }, WantErr: false, @@ -295,6 +310,12 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { require.True(t, fakeTracker.IsTracking( kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) + require.True(t, fakeTracker.IsTracking( + kreconciler.KeyForObject(buildpack), + builder.NamespacedName())) + require.True(t, fakeTracker.IsTracking( + kreconciler.KeyForObject(clusterBuildpack), + builder.NamespacedName())) }) it("does not update the status with no status change", func() { @@ -433,7 +454,6 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) // still track resources - require.True(t, fakeTracker.IsTracking(kreconciler.KeyForObject(clusterStore), builder.NamespacedName())) require.True(t, fakeTracker.IsTracking(kreconciler.KeyForObject(notReadyClusterStack), builder.NamespacedName())) require.Len(t, builderCreator.CreateBuilderCalls, 0) }) @@ -469,7 +489,6 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) // still track resources - require.True(t, fakeTracker.IsTracking(kreconciler.KeyForObject(clusterStore), builder.NamespacedName())) require.True(t, fakeTracker.IsTracking(kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) require.Len(t, builderCreator.CreateBuilderCalls, 0) }) @@ -505,7 +524,6 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) // still track resources - require.True(t, fakeTracker.IsTracking(kreconciler.KeyForObject(clusterStore), builder.NamespacedName())) require.True(t, fakeTracker.IsTracking(kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) require.Len(t, builderCreator.CreateBuilderCalls, 0) }) diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go index faac0fac..be447523 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go @@ -100,6 +100,10 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { ObjectMeta: metav1.ObjectMeta{ Name: "buildpack.id.4", }, + TypeMeta: metav1.TypeMeta{ + Kind: "ClusterBuildpack", + APIVersion: "kpack.io/v1alpha2", + }, } builder := &buildapi.ClusterBuilder{ @@ -247,7 +251,7 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }}, builderCreator.CreateBuilderCalls) }) - it("tracks the stack and store for a custom builder", func() { + it("tracks the stack and buildpack sources for a custom builder", func() { builderCreator.Record = buildapi.BuilderRecord{ Image: builderIdentifier, Stack: corev1alpha1.BuildStack{ @@ -256,6 +260,10 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, Buildpacks: corev1alpha1.BuildpackMetadataList{}, } + builderCreator.ObjectsToTrack = []corev1.ObjectReference{ + {Name: clusterStore.Name, Kind: clusterStore.Kind}, + {Name: clusterBuildpack.Name, Kind: clusterBuildpack.Kind}, + } expectedBuilder := &buildapi.ClusterBuilder{ ObjectMeta: builder.ObjectMeta, @@ -294,6 +302,8 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { kreconciler.KeyForObject(clusterStore), expectedBuilder.NamespacedName())) require.True(t, fakeTracker.IsTracking( kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) + require.True(t, fakeTracker.IsTracking( + kreconciler.KeyForObject(clusterBuildpack), expectedBuilder.NamespacedName())) }) it("does not update the status with no status change", func() { @@ -435,9 +445,6 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) // still track resources - require.True(t, fakeTracker.IsTracking( - kreconciler.KeyForObject(clusterStore), - builder.NamespacedName())) require.True(t, fakeTracker.IsTracking( kreconciler.KeyForObject(notReadyClusterStack), builder.NamespacedName())) @@ -476,9 +483,6 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) // still track resources - require.True(t, fakeTracker.IsTracking( - kreconciler.KeyForObject(clusterStore), - builder.NamespacedName())) require.True(t, fakeTracker.IsTracking( kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) @@ -517,9 +521,6 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }) // still track resources - require.True(t, fakeTracker.IsTracking( - kreconciler.KeyForObject(clusterStore), - builder.NamespacedName())) require.True(t, fakeTracker.IsTracking( kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) diff --git a/pkg/reconciler/testhelpers/fake_builder_creator.go b/pkg/reconciler/testhelpers/fake_builder_creator.go index 6e7ee14c..968ffa4e 100644 --- a/pkg/reconciler/testhelpers/fake_builder_creator.go +++ b/pkg/reconciler/testhelpers/fake_builder_creator.go @@ -4,14 +4,16 @@ import ( "context" "github.com/google/go-containerregistry/pkg/authn" + corev1 "k8s.io/api/core/v1" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" "github.com/pivotal/kpack/pkg/cnb" ) type FakeBuilderCreator struct { - Record buildapi.BuilderRecord - CreateErr error + Record buildapi.BuilderRecord + CreateErr error + ObjectsToTrack []corev1.ObjectReference CreateBuilderCalls []CreateBuilderArgs } @@ -26,7 +28,7 @@ type CreateBuilderArgs struct { var _ cnb.BuilderCreator = (*FakeBuilderCreator)(nil) -func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) (buildapi.BuilderRecord, error) { +func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) ([]corev1.ObjectReference, buildapi.BuilderRecord, error) { f.CreateBuilderCalls = append(f.CreateBuilderCalls, CreateBuilderArgs{ Context: ctx, Keychain: keychain, @@ -35,5 +37,5 @@ func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.K BuilderSpec: builder, }) - return f.Record, f.CreateErr + return f.ObjectsToTrack, f.Record, f.CreateErr } From 9703c9af4f9f858c6e0011f9103c188c86805bf8 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Mon, 13 Feb 2023 10:29:14 -0500 Subject: [PATCH 18/39] update integration tests to use buildpack resource the builder will test - resolving clusterbuildpack via buildpack id - resolving buildpack via object reference and buildpack id - resolving clusterstore via buildpack id the cluster builder will test - resolving clusterbuildpack via object reference - resolving buildpack before clusterstore for same buildpack id - resolving clusterstore via buildpack id Signed-off-by: Bohan Chen --- test/execute_build_test.go | 166 ++++++++++++++++++++++++++----------- 1 file changed, 116 insertions(+), 50 deletions(-) diff --git a/test/execute_build_test.go b/test/execute_build_test.go index 8a501896..9562e2f8 100644 --- a/test/execute_build_test.go +++ b/test/execute_build_test.go @@ -41,14 +41,15 @@ func TestCreateImage(t *testing.T) { func testCreateImage(t *testing.T, when spec.G, it spec.S) { const ( - testNamespace = "test" - dockerSecret = "docker-secret" - serviceAccountName = "image-service-account" - builderImage = "gcr.io/paketo-buildpacks/builder:base" - clusterStoreName = "store" - clusterStackName = "stack" - builderName = "custom-builder" - clusterBuilderName = "custom-cluster-builder" + testNamespace = "test" + dockerSecret = "docker-secret" + serviceAccountName = "image-service-account" + clusterStoreName = "store" + buildpackName = "buildpack" + clusterBuildpackName = "cluster-buildpack" + clusterStackName = "stack" + builderName = "custom-builder" + clusterBuilderName = "custom-cluster-builder" ) var ( @@ -69,6 +70,16 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) { require.NoError(t, err) } + err = clients.client.KpackV1alpha2().Buildpacks(testNamespace).Delete(ctx, buildpackName, metav1.DeleteOptions{}) + if !errors.IsNotFound(err) { + require.NoError(t, err) + } + + err = clients.client.KpackV1alpha2().ClusterBuildpacks().Delete(ctx, clusterBuildpackName, metav1.DeleteOptions{}) + if !errors.IsNotFound(err) { + require.NoError(t, err) + } + err = clients.client.KpackV1alpha2().ClusterStacks().Delete(ctx, clusterStackName, metav1.DeleteOptions{}) if !errors.IsNotFound(err) { require.NoError(t, err) @@ -126,12 +137,36 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) { }, Spec: buildapi.ClusterStoreSpec{ Sources: []corev1alpha1.ImageSource{ - { - Image: builderImage, - }, - { - Image: "gcr.io/paketo-buildpacks/gradle", - }, + {Image: "gcr.io/paketo-buildpacks/bellsoft-liberica"}, + {Image: "gcr.io/paketo-buildpacks/gradle"}, + {Image: "gcr.io/paketo-buildpacks/syft"}, + {Image: "gcr.io/paketo-buildpacks/executable-jar"}, + {Image: "gcr.io/paketo-buildpacks/dist-zip"}, + {Image: "gcr.io/paketo-buildpacks/spring-boot"}, + }, + }, + }, metav1.CreateOptions{}) + require.NoError(t, err) + + _, err = clients.client.KpackV1alpha2().Buildpacks(testNamespace).Create(ctx, &buildapi.Buildpack{ + ObjectMeta: metav1.ObjectMeta{ + Name: buildpackName, + }, + Spec: buildapi.BuildpackSpec{ + Source: corev1alpha1.ImageSource{ + Image: "gcr.io/paketo-buildpacks/bellsoft-liberica", + }, + }, + }, metav1.CreateOptions{}) + require.NoError(t, err) + + _, err = clients.client.KpackV1alpha2().ClusterBuildpacks().Create(ctx, &buildapi.ClusterBuildpack{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterBuildpackName, + }, + Spec: buildapi.ClusterBuildpackSpec{ + Source: corev1alpha1.ImageSource{ + Image: "gcr.io/paketo-buildpacks/nodejs", }, }, }, metav1.CreateOptions{}) @@ -169,47 +204,65 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) { Name: clusterStoreName, Kind: "ClusterStore", }, - Order: []corev1alpha1.OrderEntry{ + Order: []buildapi.BuilderOrderEntry{ { - Group: []corev1alpha1.BuildpackRef{ + Group: []buildapi.BuilderBuildpackRef{ { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/nodejs", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/nodejs", + }, }, }, }, }, { - Group: []corev1alpha1.BuildpackRef{ + Group: []buildapi.BuilderBuildpackRef{ { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/bellsoft-liberica", + ObjectReference: corev1.ObjectReference{ + Name: buildpackName, + Kind: "Buildpack", + }, + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/bellsoft-liberica", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/gradle", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/gradle", + }, + Optional: true, }, - Optional: true, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/syft", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/syft", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/executable-jar", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/executable-jar", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/dist-zip", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/dist-zip", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/spring-boot", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/spring-boot", + }, }, }, }, @@ -236,47 +289,60 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) { Name: clusterStoreName, Kind: "ClusterStore", }, - Order: []corev1alpha1.OrderEntry{ + Order: []buildapi.BuilderOrderEntry{ { - Group: []corev1alpha1.BuildpackRef{ + Group: []buildapi.BuilderBuildpackRef{ { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/nodejs", + ObjectReference: corev1.ObjectReference{ + Name: clusterBuildpackName, + Kind: "ClusterBuildpack", }, }, }, }, { - Group: []corev1alpha1.BuildpackRef{ + Group: []buildapi.BuilderBuildpackRef{ { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/bellsoft-liberica", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/bellsoft-liberica", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/gradle", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/gradle", + }, + Optional: true, }, - Optional: true, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/syft", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/syft", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/executable-jar", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/executable-jar", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/dist-zip", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/dist-zip", + }, }, }, { - BuildpackInfo: corev1alpha1.BuildpackInfo{ - Id: "paketo-buildpacks/spring-boot", + BuildpackRef: corev1alpha1.BuildpackRef{ + BuildpackInfo: corev1alpha1.BuildpackInfo{ + Id: "paketo-buildpacks/spring-boot", + }, }, }, }, From 0c2303bc8ff07473b7a34fdc3514484c66697fe3 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Mon, 13 Feb 2023 15:29:54 -0500 Subject: [PATCH 19/39] add docs for buildpack resource Signed-off-by: Bohan Chen --- README.md | 6 +-- docs/builders.md | 98 ++++++++++++++++++++++++++++++++++++++-------- docs/buildpacks.md | 94 ++++++++++++++++++++++++++++++++++++++++++++ docs/store.md | 53 ------------------------- 4 files changed, 179 insertions(+), 72 deletions(-) create mode 100644 docs/buildpacks.md delete mode 100644 docs/store.md diff --git a/README.md b/README.md index 6cbbaa26..14134af9 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,12 @@ kpack also provides a build type to execute a single Cloud Native Buildpack OCI ### Documentation & Getting Started - [Install kpack](docs/install.md) -- Get started with [the tutorial](docs/tutorial.md) +- Get started with [the tutorial](docs/tutorial.md) - Check out the documentation on kpack concepts: - [Stacks](docs/stack.md) - - [Stores](docs/store.md) - [Images](docs/image.md) - [Secrets](docs/secrets.md) + - [Buildpacks and Stores](docs/buildpacks.md) - [Builders](docs/builders.md) - [Builds](docs/build.md) - [Service Bindings](docs/legacy-cnb-servicebindings.md) @@ -32,7 +32,7 @@ kpack also provides a build type to execute a single Cloud Native Buildpack OCI - Interact with kpack using [kpack CLI](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp.md) - Tailing logs with the kpack [log utility](docs/logs.md) - + - Documentation on [Local Development](docs/local.md) ### kpack Working Group diff --git a/docs/builders.md b/docs/builders.md index 613c4376..5ade1cdf 100644 --- a/docs/builders.md +++ b/docs/builders.md @@ -3,15 +3,23 @@ kpack provides Builder and ClusterBuilder resources to define and create [Cloud Native Buildpacks builders](https://buildpacks.io/docs/using-pack/working-with-builders/) all within the kpack api. This allows granular control of how stacks, buildpacks, and buildpack versions are utilized and updated. -Before creating Builders you will need to create a [ClusterStack](stack.md) and [ClusterStore](store.md) resources below. +Before creating Builders you will need to create a [ClusterStack](stack.md) and +either [Buildpack](buildpacks.md#buildpack), [ClusterBuildpack](buildpacks.md#cluster-buildpack), or +[ClusterStore](buildpacks.md#cluster-store) resources below. -> Note: The Builder and ClusterBuilder were previously named CustomBuilder and CustomClusterBuilder. The previous Builder and ClusterBuilder resources that utilized pre-built builders were removed and should no longer be used with kpack. This was discussed in an approved [RFC](https://github.com/pivotal/kpack/pull/439). +> Note: The Builder and ClusterBuilder were previously named CustomBuilder and +> CustomClusterBuilder. The previous Builder and ClusterBuilder resources that +> utilized pre-built builders were removed and should no longer be used with +> kpack. This was discussed in an approved +> [RFC](https://github.com/pivotal/kpack/pull/439). -Corresponding `kp` cli command docs for [builders](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_builder.md) and [cluster builders](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_clusterbuilder.md). +Corresponding `kp` cli command docs for +[builders](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_builder.md) +and [cluster builders](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_clusterbuilder.md). ### Builders -The Builder uses a [ClusterStore](store.md), a [ClusterStack](stack.md), and an order definition to construct a builder image. +The Builder uses a [ClusterStack](stack.md), an optional [ClusterStore](buildpacks.md#cluster-store), and an order definition to construct a builder image. ```yaml apiVersion: kpack.io/v1alpha2 @@ -30,13 +38,21 @@ spec: order: - group: - id: paketo-buildpacks/java - - group: - - id: paketo-buildpacks/nodejs - group: - id: kpack/my-custom-buildpack version: 1.2.3 - id: kpack/my-optional-custom-buildpack optional: true + - group: + - name: sample-buildpack + kind: Buildpack + - name: sample-cluster-buildpack + kind: ClusterBuildpack + id: paketo-buildpacks/nodejs + - name: sample-cluster-store + kind: ClusterStore + id: paketo-buildpacks/nodejs + version: 1.2.3 ``` * `tag`: The tag to save the builder image. You must have access via the referenced service account. @@ -44,12 +60,18 @@ spec: * `order`: The [builder order](https://buildpacks.io/docs/reference/builder-config/). See the [Order](#order) section below. * `stack.name`: The name of the stack resource to use as the builder stack. All buildpacks in the order must be compatible with the clusterStack. * `stack.kind`: The type as defined in kubernetes. This will always be ClusterStack. -* `store.name`: The name of the ClusterStore resource in kubernetes. -* `store.kind`: The type as defined in kubernetes. This will always be ClusterStore. +* `store`: If using ClusterStore, then the reference to the ClusterStore. See the [Resolving Buildpack IDs](#resolving-buildpack-ids) section below. + * `name`: The name of the ClusterStore resource in kubernetes. + * `kind`: The type as defined in kubernetes. This will always be ClusterStore. ### Cluster Builders -The ClusterBuilder resource is almost identical to a Builder but, it is a cluster scoped resource that can be referenced by an image in any namespace. Because ClusterBuilders are not in a namespace they cannot reference local service accounts. Instead the `serviceAccount` field is replaced with a `serviceAccountRef` field which is an object reference to a service account in any namespace. +The ClusterBuilder resource is almost identical to a Builder but, it is a +cluster scoped resource that can be referenced by an image in any namespace. +Because ClusterBuilders are not in a namespace they cannot reference local +service accounts. Instead the `serviceAccount` field is replaced with a +`serviceAccountRef` field which is an object reference to a service account in +any namespace. ```yaml apiVersion: kpack.io/v1alpha2 @@ -70,33 +92,77 @@ spec: order: - group: - id: paketo-buildpacks/java - - group: - - id: paketo-buildpacks/nodejs - group: - id: kpack/my-custom-buildpack version: 1.2.3 - id: kpack/my-optional-custom-buildpack optional: true + - group: + - name: sample-cluster-buildpack + kind: ClusterBuildpack + id: paketo-buildpacks/nodejs + - name: sample-cluster-store + kind: ClusterStore + id: paketo-buildpacks/nodejs + version: 1.2.3 ``` * `serviceAccountRef`: An object reference to a service account in any namespace. The object reference must contain `name` and `namespace`. ### Order -The `spec.order` is cloud native buildpacks [builder order](https://buildpacks.io/docs/reference/builder-config/) that contains a list of buildpack groups. +The `spec.order` is cloud native buildpacks [builder order](https://buildpacks.io/docs/reference/builder-config/) +that contains a list of buildpack groups. -This list determines the order in which groups of buildpacks will be tested during detection. Detection is a phase of the buildpack execution where buildpacks are tested, one group at a time, for compatibility with the provided application source code. The first group whose non-optional buildpacks all pass detection will be the group selected for the remainder of the build. +This list determines the order in which groups of buildpacks will be tested +during detection. Detection is a phase of the buildpack execution where +buildpacks are tested, one group at a time, for compatibility with the provided +application source code. The first group whose non-optional buildpacks all pass +detection will be the group selected for the remainder of the build. - **`group`** _(list, required)_\ - A set of buildpack references. Each buildpack reference specified has the following fields: + A set of buildpack references. Each buildpack reference specified is one of the following: + - A kubernetes object reference: + - **`kind`** _(string, required)_\ + The kubernetes kind, must be one of `Buildpack` (Builder only), + `ClusterBuildpack`, or `ClusterStore`. + + - **`name`** _(string, required)_\ + The name of the kubernetes object. + - Buildpack info: - **`id`** _(string, required)_\ - The identifier of a buildpack from the configuration's top-level `buildpacks` list. This buildpack *must* be in available in the referenced store. + The identifier of a buildpack from the configuration's top-level + `buildpacks` list. For rules on which resource the buildpack is resolved + from, see [Resolving BuildpackIDs](#resolving-buildpack-ids) section + below. - **`version`** _(string, optional, default: inferred)_\ - The buildpack version to chose from the store. If this field is omitted, the highest semver version number will be chosen in the store. + The buildpack version to chose from the store. If this field is omitted, + the highest semver version number will be chosen in the store. - **`optional`** _(boolean, optional, default: `false`)_\ Whether or not this buildpack is optional during detection. + - Both object reference and buildpack info together. + > Note: Buildpacks with the same ID may appear in multiple groups at once but never in the same group. + +### Resolving Buildpack IDs + +When using the kubernetes object reference with buildpack info, kpack will try +to locate the specified buildpack and version within the resource. If using +Buildpack resources, it must be within the same namespace as the Builder. + +When using the kubernetes object reference without any buildpack info, the +"root" buildpack will be chosen. A "root" buildpack is any buildpack that is +not specified in the order of another buildpack. If there are multiple "root" +buildpacks, the buildpack resource will fail to reconcile. + +When using just the buildpack info, kpack will try to find the buildpack (and +version) in the following order: + +1. As a sub-buildpack of any Buildpacks in the Builder's namespace (i.e. + `paketo-buildpacks/gradle` is a sub-buildpack of `paketo-buildpacks/java`) +1. As a sub-buildpack of any ClusterBuildpacks +1. As a sub-buildpack in the ClusterStore specified in the Builder spec. diff --git a/docs/buildpacks.md b/docs/buildpacks.md new file mode 100644 index 00000000..4e7b3ca6 --- /dev/null +++ b/docs/buildpacks.md @@ -0,0 +1,94 @@ +# Buildpacks + +The Buildpack, ClusterBuildpack, and ClusterStore resources are a repository of +[buildpacks](http://buildpacks.io/) packaged in +[buildpackages](https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/) +that can be used by kpack to build OCI images. + +These objects will be referenced by a [builder](builders.md) resource. + +### Buildpack Configuration + +Buildpack is a namespaced resource that represents an external buildpackage. + +```yaml +apiVersion: kpack.io/v1alpha2 +kind: Buildpack +metadata: + name: sample-buildpack +spec: + serviceAccountName: sample-sa + source: + # image: gcr.io/paketo-buildpacks/java + # image: gcr.io/paketo-buildpacks/java:8.9.0 + image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de +``` + +* `serviceAccountName`: A service account with the sercrets needed to pull the buildpack image. +* `source.image`: The url of the buildpackage. + +### Cluster Buildpack Configuration + +ClusterBuildpack is the cluster scoped version of Buildpack + +```yaml +apiVersion: kpack.io/v1alpha2 +kind: ClusterBuildpack +metadata: + name: sample-cluster-buildpack +spec: + serviceAccountRef: + name: sample-sa + namespace: sample-namespace + source: + # image: gcr.io/paketo-buildpacks/java + # image: gcr.io/paketo-buildpacks/java:8.9.0 + image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de +``` + +* `serviceAccountRef`: An object reference to a service account in any namespace. The object reference must contain `name` and `namespace`. +* `source.image`: The url of the buildpackage. + + +### Cluster Store Configuration + +ClusterStore is a cluster scoped resource that can reference multiple buildpackages. + +Corresponding `kp` cli command docs [here](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_clusterstore.md). + +```yaml +apiVersion: kpack.io/v1alpha2 +kind: ClusterStore +metadata: + name: sample-cluster-store +spec: + serviceAccountRef: + name: sample-sa + namespace: sample-namespace + sources: + - image: gcr.io/cf-build-service-public/node-engine-buildpackage@sha256:95ff756f0ef0e026440a8523f4bab02fd8b45dc1a8a3a7ba063cefdba5cb9493 + - image: gcr.io/cf-build-service-public/npm-buildpackage@sha256:5058ceb9a562ec647ea5a41008b0d11e32a56e13e8c9ec20c4db63d220373e33 + - image: gcr.io/paketo-buildpacks/builder:base +``` + +* `serviceAccountRef`: An object reference to a service account in any namespace. The object reference must contain `name` and `namespace`. +* `sources`: List of buildpackage images to make available in the ClusterStore. Each image is an object with the key image. + +> Note: ClusterBuilders will also work with a prebuilt builder image if a builpack is not available in a buildpackage. + + +### Updating Buildpacks + +The Buildpack, ClusterBuildpack, and ClusterStore resources will not poll for +updates. A CI/CD tool is needed to update the resource with new digests when +new images are available. + +### Suggested buildpackages + +The most commonly used buildpackages are [paketo buildpacks](https://paketo.io/). + +### Creating your own buildpackage + +To create your own buildpackage with custom buildpacks follow the instructions +on creating them and packaging them using the [pack +cli](https://buildpacks.io/docs/buildpack-author-guide/). diff --git a/docs/store.md b/docs/store.md deleted file mode 100644 index c1ca5c4b..00000000 --- a/docs/store.md +++ /dev/null @@ -1,53 +0,0 @@ -# Stores - -A store resource is a repository of [buildpacks](http://buildpacks.io/) packaged in [buildpackages](https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/) that can be used by kpack to build OCI images. - -The store will be referenced by a [builder](builders.md) resource. - -At this time only a Cluster scoped `ClusterStore` is available. - -Corresponding `kp` cli command docs [here](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_clusterstore.md). - -### Cluster Store Configuration - -```yaml -apiVersion: kpack.io/v1alpha2 -kind: ClusterStore -metadata: - name: sample-cluster-store -spec: - sources: - - image: gcr.io/cf-build-service-public/node-engine-buildpackage@sha256:95ff756f0ef0e026440a8523f4bab02fd8b45dc1a8a3a7ba063cefdba5cb9493 - - image: gcr.io/cf-build-service-public/npm-buildpackage@sha256:5058ceb9a562ec647ea5a41008b0d11e32a56e13e8c9ec20c4db63d220373e33 - - image: gcr.io/paketo-buildpacks/builder:base -``` - -* `sources`: List of buildpackage images to make available in the ClusterStore. Each image is an object with the key image. - -> Note: ClusterBuilders will also work with a prebuilt builder image if a builpack is not available in a buildpackage. - -### Using a private registry - -To use the buildpackage images from a private registry, you have to add a `serviceAccountRef` referencing a serviceaccount with the secrets needed to pull from this registry. - -```yaml -spec: - serviceAccountRef: - name: private - namespace: private -``` - -* `serviceAccountRef`: An object reference to a service account in any namespace. The object reference must contain `name` and `namespace`. - -### Updating a store - -The store resource will not poll for updates. A CI/CD tool is needed to update the resource with new digests when new images are available. - -### Suggested buildpackages - -The most commonly used buildpackages are [paketo buildpacks](https://paketo.io/). - -### Creating your own buildpackage - -To create your own buildpackage with custom buildpacks follow the instructions on creating them and packaging them using the [pack cli](https://buildpacks.io/docs/buildpack-author-guide/). - From 09997c278074bbc7050c2069131f8d6bbd4c0834 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Mon, 13 Feb 2023 15:37:07 -0500 Subject: [PATCH 20/39] disallow using image references in builders this will be implemented in a follow-up pr Signed-off-by: Bohan Chen --- .../build/v1alpha2/builder_conversion_test.go | 2 +- pkg/apis/build/v1alpha2/builder_validation.go | 8 ++-- .../build/v1alpha2/builder_validation_test.go | 44 ++++++++++++------- .../cluster_builder_conversion_test.go | 2 +- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/pkg/apis/build/v1alpha2/builder_conversion_test.go b/pkg/apis/build/v1alpha2/builder_conversion_test.go index 9b49751a..94330e40 100644 --- a/pkg/apis/build/v1alpha2/builder_conversion_test.go +++ b/pkg/apis/build/v1alpha2/builder_conversion_test.go @@ -51,7 +51,7 @@ func testBuilderConversion(t *testing.T, when spec.G, it spec.S) { Name: "some-buildpack", }, }, - {Image: "some-repo/some-buildpack"}, + // {Image: "some-repo/some-buildpack"}, }, }}, }, diff --git a/pkg/apis/build/v1alpha2/builder_validation.go b/pkg/apis/build/v1alpha2/builder_validation.go index d5d3bca2..69d60d3c 100644 --- a/pkg/apis/build/v1alpha2/builder_validation.go +++ b/pkg/apis/build/v1alpha2/builder_validation.go @@ -8,7 +8,6 @@ import ( "knative.dev/pkg/apis" - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/apis/validate" ) @@ -84,9 +83,10 @@ func validateBuildpackRef(ref BuilderBuildpackRef) *apis.FieldError { switch { case ref.Image != "": - errs = errs.Also(validate.Image(ref.Image)). - Also(apis.CheckDisallowedFields(ref.BuildpackInfo, v1alpha1.BuildpackInfo{})). - Also(apis.CheckDisallowedFields(ref.ObjectReference, v1.ObjectReference{})) + errs = errs.Also(apis.ErrDisallowedFields("image reference currently not supported")) + // errs = errs.Also(validate.Image(ref.Image)). + // Also(apis.CheckDisallowedFields(ref.BuildpackInfo, v1alpha1.BuildpackInfo{})). + // Also(apis.CheckDisallowedFields(ref.ObjectReference, v1.ObjectReference{})) case ref.Id != "" || ref.Name != "" || ref.Kind != "": if ref.Image != "" { errs = errs.Also(apis.ErrDisallowedFields("image")) diff --git a/pkg/apis/build/v1alpha2/builder_validation_test.go b/pkg/apis/build/v1alpha2/builder_validation_test.go index 6842ad68..625e4c5c 100644 --- a/pkg/apis/build/v1alpha2/builder_validation_test.go +++ b/pkg/apis/build/v1alpha2/builder_validation_test.go @@ -44,9 +44,9 @@ func testBuilderValidation(t *testing.T, when spec.G, it spec.S) { Optional: true, }, }, - { - Image: "some-registry.io/buildpack", - }, + // { + // Image: "some-registry.io/buildpack", + // }, { ObjectReference: corev1.ObjectReference{ Name: "some-buildpack", @@ -166,27 +166,37 @@ func testBuilderValidation(t *testing.T, when spec.G, it spec.S) { assertValidationError(builder, apis.ErrInvalidValue("FakeBuildpack", "kind", "must be one of Buildpack, ClusterBuildpack")) }) - it("invalid image", func() { + it("invalid when image is used", func() { builder.Spec.Order = []BuilderOrderEntry{{ Group: []BuilderBuildpackRef{{ - Image: "some-image@1234", + Image: "some-registry.io/buildpack", }}, }} - assertValidationError(builder, apis.ErrInvalidValue("some-image@1234", "image")) + assertValidationError(builder, apis.ErrDisallowedFields("image reference currently not supported")) }) - it("invalid when both image and id are defined", func() { - builder.Spec.Order = []BuilderOrderEntry{{ - Group: []BuilderBuildpackRef{{ - Image: "foo", - BuildpackRef: v1alpha1.BuildpackRef{ - BuildpackInfo: v1alpha1.BuildpackInfo{Id: "some-buildpack"}, - }, - }}, - }} - assertValidationError(builder, apis.ErrDisallowedFields("id")) - }) + // it("invalid image", func() { + // builder.Spec.Order = []BuilderOrderEntry{{ + // Group: []BuilderBuildpackRef{{ + // Image: "some-image@1234", + // }}, + // }} + + // assertValidationError(builder, apis.ErrInvalidValue("some-image@1234", "image")) + // }) + + // it("invalid when both image and id are defined", func() { + // builder.Spec.Order = []BuilderOrderEntry{{ + // Group: []BuilderBuildpackRef{{ + // Image: "foo", + // BuildpackRef: v1alpha1.BuildpackRef{ + // BuildpackInfo: v1alpha1.BuildpackInfo{Id: "some-buildpack"}, + // }, + // }}, + // }} + // assertValidationError(builder, apis.ErrDisallowedFields("id")) + // }) it("valid when both id and object are defined", func() { builder.Spec.Order = []BuilderOrderEntry{{Group: []BuilderBuildpackRef{{ diff --git a/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go b/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go index 39d53d46..a6f72ff3 100644 --- a/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go +++ b/pkg/apis/build/v1alpha2/cluster_builder_conversion_test.go @@ -51,7 +51,7 @@ func testClusterBuilderConversion(t *testing.T, when spec.G, it spec.S) { Name: "some-buildpack", }, }, - {Image: "some-repo/some-buildpack"}, + // {Image: "some-repo/some-buildpack"}, }, }}, }, From 159cfbbc80fe0a775ca8f8dea1382cf97f91c977 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Tue, 21 Feb 2023 14:10:16 -0500 Subject: [PATCH 21/39] clarify buildpackage image requirements Signed-off-by: Bohan Chen --- docs/buildpacks.md | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/docs/buildpacks.md b/docs/buildpacks.md index 4e7b3ca6..a295187e 100644 --- a/docs/buildpacks.md +++ b/docs/buildpacks.md @@ -5,7 +5,16 @@ The Buildpack, ClusterBuildpack, and ClusterStore resources are a repository of [buildpackages](https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/) that can be used by kpack to build OCI images. -These objects will be referenced by a [builder](builders.md) resource. +These resources are to be used with the [Builder and +ClusterBuilder](builders.md) resources. + +### Difference from CNB buildpacks + +Kpack will allow any image with a valid `io.buildpacks.buildpack.layers` label +to be used as the source of a buildpackage. This means that you can also use a +CNB builder image (i.e. `index.docker.io/paketobuildpacks/builder-jammy-base`) +in addition to regular CNB buildpack images (i.e. +`gcr.io/paketo-buildpacks/java:8.9.0`). ### Buildpack Configuration @@ -24,8 +33,9 @@ spec: image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de ``` -* `serviceAccountName`: A service account with the sercrets needed to pull the buildpack image. -* `source.image`: The url of the buildpackage. +* `serviceAccountName`: A service account with the sercrets needed to pull the + buildpack image. +* `source.image`: The uri of the buildpackage. ### Cluster Buildpack Configuration @@ -46,15 +56,17 @@ spec: image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de ``` -* `serviceAccountRef`: An object reference to a service account in any namespace. The object reference must contain `name` and `namespace`. -* `source.image`: The url of the buildpackage. +* `serviceAccountRef`: An object reference to a service account in any + namespace. The object reference must contain `name` and `namespace`. +* `source.image`: The uri of the buildpackage. ### Cluster Store Configuration ClusterStore is a cluster scoped resource that can reference multiple buildpackages. -Corresponding `kp` cli command docs [here](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_clusterstore.md). +Corresponding `kp` cli command docs +[here](https://github.com/vmware-tanzu/kpack-cli/blob/main/docs/kp_clusterstore.md). ```yaml apiVersion: kpack.io/v1alpha2 @@ -68,13 +80,13 @@ spec: sources: - image: gcr.io/cf-build-service-public/node-engine-buildpackage@sha256:95ff756f0ef0e026440a8523f4bab02fd8b45dc1a8a3a7ba063cefdba5cb9493 - image: gcr.io/cf-build-service-public/npm-buildpackage@sha256:5058ceb9a562ec647ea5a41008b0d11e32a56e13e8c9ec20c4db63d220373e33 - - image: gcr.io/paketo-buildpacks/builder:base + - image: index.docker.io/paketobuildpacks/builder-jammy-base ``` -* `serviceAccountRef`: An object reference to a service account in any namespace. The object reference must contain `name` and `namespace`. -* `sources`: List of buildpackage images to make available in the ClusterStore. Each image is an object with the key image. - -> Note: ClusterBuilders will also work with a prebuilt builder image if a builpack is not available in a buildpackage. +* `serviceAccountRef`: An object reference to a service account in any + namespace. The object reference must contain `name` and `namespace`. +* `sources`: List of buildpackage images to make available in the + ClusterStore. Each image is an object with the key image. ### Updating Buildpacks From cc9182c1bd7bcd1d1b677f104c193b213b115d8a Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Tue, 21 Feb 2023 14:10:57 -0500 Subject: [PATCH 22/39] clusterstores can't be used in object refs since there's already an object ref to it in the builder spec. Signed-off-by: Bohan Chen --- docs/builders.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/builders.md b/docs/builders.md index 5ade1cdf..c93d22bd 100644 --- a/docs/builders.md +++ b/docs/builders.md @@ -49,9 +49,6 @@ spec: - name: sample-cluster-buildpack kind: ClusterBuildpack id: paketo-buildpacks/nodejs - - name: sample-cluster-store - kind: ClusterStore - id: paketo-buildpacks/nodejs version: 1.2.3 ``` @@ -124,8 +121,8 @@ detection will be the group selected for the remainder of the build. A set of buildpack references. Each buildpack reference specified is one of the following: - A kubernetes object reference: - **`kind`** _(string, required)_\ - The kubernetes kind, must be one of `Buildpack` (Builder only), - `ClusterBuildpack`, or `ClusterStore`. + The kubernetes kind, must be either `Buildpack` (Builder only), or + `ClusterBuildpack`. - **`name`** _(string, required)_\ The name of the kubernetes object. From 22fba6894c62f5c96b9f25a59748441079417aaf Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Wed, 22 Feb 2023 10:48:19 -0500 Subject: [PATCH 23/39] address pr comments: unnest source.image in spec also, move the BuilderCreator interface to where it's used rather than defined Signed-off-by: Bohan Chen --- docs/buildpacks.md | 18 ++++++++---------- pkg/apis/build/v1alpha2/buildpack_types.go | 4 ++-- .../build/v1alpha2/buildpack_validation.go | 2 +- .../v1alpha2/buildpack_validation_test.go | 10 +++++----- .../build/v1alpha2/cluster_buildpack_types.go | 4 ++-- .../v1alpha2/cluster_buildpack_validation.go | 2 +- .../cluster_buildpack_validation_test.go | 10 +++++----- .../build/v1alpha2/zz_generated.deepcopy.go | 4 ++-- pkg/cnb/create_builder.go | 6 ------ pkg/reconciler/builder/builder.go | 16 +++++++++++----- pkg/reconciler/buildpack/buildpack.go | 2 +- pkg/reconciler/buildpack/buildpack_test.go | 4 ++-- .../clusterbuilder/clusterbuilder.go | 13 +++++++++---- .../clusterbuildpack/clusterbuildpack.go | 2 +- .../clusterbuildpack/clusterbuildpack_test.go | 4 ++-- .../testhelpers/fake_builder_creator.go | 2 -- test/execute_build_test.go | 4 ++-- 17 files changed, 54 insertions(+), 53 deletions(-) diff --git a/docs/buildpacks.md b/docs/buildpacks.md index a295187e..4a251647 100644 --- a/docs/buildpacks.md +++ b/docs/buildpacks.md @@ -27,15 +27,14 @@ metadata: name: sample-buildpack spec: serviceAccountName: sample-sa - source: - # image: gcr.io/paketo-buildpacks/java - # image: gcr.io/paketo-buildpacks/java:8.9.0 - image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de + # image: gcr.io/paketo-buildpacks/java + # image: gcr.io/paketo-buildpacks/java:8.9.0 + image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de ``` * `serviceAccountName`: A service account with the sercrets needed to pull the buildpack image. -* `source.image`: The uri of the buildpackage. +* `image`: The uri of the buildpackage. ### Cluster Buildpack Configuration @@ -50,15 +49,14 @@ spec: serviceAccountRef: name: sample-sa namespace: sample-namespace - source: - # image: gcr.io/paketo-buildpacks/java - # image: gcr.io/paketo-buildpacks/java:8.9.0 - image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de + # image: gcr.io/paketo-buildpacks/java + # image: gcr.io/paketo-buildpacks/java:8.9.0 + image: gcr.io/paketo-buildpacks/java@sha256:fc1c6fba46b582f63b13490b89e50e93c95ce08142a8737f4a6b70c826c995de ``` * `serviceAccountRef`: An object reference to a service account in any namespace. The object reference must contain `name` and `namespace`. -* `source.image`: The uri of the buildpackage. +* `image`: The uri of the buildpackage. ### Cluster Store Configuration diff --git a/pkg/apis/build/v1alpha2/buildpack_types.go b/pkg/apis/build/v1alpha2/buildpack_types.go index 986352cc..50f4af8d 100644 --- a/pkg/apis/build/v1alpha2/buildpack_types.go +++ b/pkg/apis/build/v1alpha2/buildpack_types.go @@ -28,8 +28,8 @@ type Buildpack struct { // +k8s:openapi-gen=true type BuildpackSpec struct { // +listType - Source corev1alpha1.ImageSource `json:"source,omitempty"` - ServiceAccountName string `json:"serviceAccountName,omitempty"` + corev1alpha1.ImageSource `json:",inline"` + ServiceAccountName string `json:"serviceAccountName,omitempty"` } // +k8s:openapi-gen=true diff --git a/pkg/apis/build/v1alpha2/buildpack_validation.go b/pkg/apis/build/v1alpha2/buildpack_validation.go index a1d28303..b6c68d8a 100644 --- a/pkg/apis/build/v1alpha2/buildpack_validation.go +++ b/pkg/apis/build/v1alpha2/buildpack_validation.go @@ -18,5 +18,5 @@ func (cb *Buildpack) Validate(ctx context.Context) *apis.FieldError { } func (s *BuildpackSpec) Validate(ctx context.Context) *apis.FieldError { - return validate.Image(s.Source.Image).ViaField("source") + return validate.Image(s.Image) } diff --git a/pkg/apis/build/v1alpha2/buildpack_validation_test.go b/pkg/apis/build/v1alpha2/buildpack_validation_test.go index a156c2b4..fc4952ab 100644 --- a/pkg/apis/build/v1alpha2/buildpack_validation_test.go +++ b/pkg/apis/build/v1alpha2/buildpack_validation_test.go @@ -22,7 +22,7 @@ func testBuildpackValidation(t *testing.T, when spec.G, it spec.S) { Namespace: "custom-builder-namespace", }, Spec: BuildpackSpec{ - Source: corev1alpha1.ImageSource{ + ImageSource: corev1alpha1.ImageSource{ Image: "some-registry.io/store-image-1@sha256:78c1b9419976227e05be9d243b7fa583bea44a5258e52018b2af4cdfe23d148d", }, ServiceAccountName: "some-service-account", @@ -56,15 +56,15 @@ func testBuildpackValidation(t *testing.T, when spec.G, it spec.S) { } it("missing source image", func() { - buildpack.Spec.Source.Image = "" - assertValidationError(buildpack, apis.ErrMissingField("image").ViaField("spec", "source")) + buildpack.Spec.Image = "" + assertValidationError(buildpack, apis.ErrMissingField("image").ViaField("spec")) }) it("invalid source image", func() { - buildpack.Spec.Source.Image = "ftp//invalid/tag@@" + buildpack.Spec.Image = "ftp//invalid/tag@@" assertValidationError(buildpack, - apis.ErrInvalidValue(buildpack.Spec.Source.Image, "image").ViaField("spec", "source"), + apis.ErrInvalidValue(buildpack.Spec.Image, "image").ViaField("spec"), ) }) }) diff --git a/pkg/apis/build/v1alpha2/cluster_buildpack_types.go b/pkg/apis/build/v1alpha2/cluster_buildpack_types.go index e87c5474..b364e208 100644 --- a/pkg/apis/build/v1alpha2/cluster_buildpack_types.go +++ b/pkg/apis/build/v1alpha2/cluster_buildpack_types.go @@ -29,8 +29,8 @@ type ClusterBuildpack struct { // +k8s:openapi-gen=true type ClusterBuildpackSpec struct { // +listType - Source corev1alpha1.ImageSource `json:"source,omitempty"` - ServiceAccountRef *corev1.ObjectReference `json:"serviceAccountRef,omitempty"` + corev1alpha1.ImageSource `json:"source,omitempty"` + ServiceAccountRef *corev1.ObjectReference `json:"serviceAccountRef,omitempty"` } // +k8s:openapi-gen=true diff --git a/pkg/apis/build/v1alpha2/cluster_buildpack_validation.go b/pkg/apis/build/v1alpha2/cluster_buildpack_validation.go index 6fc09206..d120ba7f 100644 --- a/pkg/apis/build/v1alpha2/cluster_buildpack_validation.go +++ b/pkg/apis/build/v1alpha2/cluster_buildpack_validation.go @@ -24,5 +24,5 @@ func (s *ClusterBuildpackSpec) Validate(ctx context.Context) *apis.FieldError { } } - return validate.Image(s.Source.Image).ViaField("source") + return validate.Image(s.Image).ViaField() } diff --git a/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go b/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go index f4d2e466..9533c399 100644 --- a/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go +++ b/pkg/apis/build/v1alpha2/cluster_buildpack_validation_test.go @@ -23,7 +23,7 @@ func testClusterBuildpackValidation(t *testing.T, when spec.G, it spec.S) { Namespace: "custom-builder-namespace", }, Spec: ClusterBuildpackSpec{ - Source: corev1alpha1.ImageSource{ + ImageSource: corev1alpha1.ImageSource{ Image: "some-registry.io/store-image-1@sha256:78c1b9419976227e05be9d243b7fa583bea44a5258e52018b2af4cdfe23d148d", }, ServiceAccountRef: &corev1.ObjectReference{ @@ -45,15 +45,15 @@ func testClusterBuildpackValidation(t *testing.T, when spec.G, it spec.S) { } it("missing source image", func() { - clusterBuildpack.Spec.Source.Image = "" - assertValidationError(clusterBuildpack, apis.ErrMissingField("image").ViaField("spec", "source")) + clusterBuildpack.Spec.Image = "" + assertValidationError(clusterBuildpack, apis.ErrMissingField("image").ViaField("spec")) }) it("invalid source image", func() { - clusterBuildpack.Spec.Source.Image = "ftp//invalid/tag@@" + clusterBuildpack.Spec.Image = "ftp//invalid/tag@@" assertValidationError(clusterBuildpack, - apis.ErrInvalidValue(clusterBuildpack.Spec.Source.Image, "image").ViaField("spec", "source"), + apis.ErrInvalidValue(clusterBuildpack.Spec.Image, "image").ViaField("spec"), ) }) diff --git a/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go index 2f0f7af9..d619d7de 100644 --- a/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/build/v1alpha2/zz_generated.deepcopy.go @@ -608,7 +608,7 @@ func (in *BuildpackList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BuildpackSpec) DeepCopyInto(out *BuildpackSpec) { *out = *in - out.Source = in.Source + out.ImageSource = in.ImageSource return } @@ -805,7 +805,7 @@ func (in *ClusterBuildpackList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterBuildpackSpec) DeepCopyInto(out *ClusterBuildpackSpec) { *out = *in - out.Source = in.Source + out.ImageSource = in.ImageSource if in.ServiceAccountRef != nil { in, out := &in.ServiceAccountRef, &out.ServiceAccountRef *out = new(v1.ObjectReference) diff --git a/pkg/cnb/create_builder.go b/pkg/cnb/create_builder.go index a5b4ab5a..6c64c23f 100644 --- a/pkg/cnb/create_builder.go +++ b/pkg/cnb/create_builder.go @@ -20,10 +20,6 @@ type LifecycleProvider interface { LayerForOS(os string) (ggcrv1.Layer, LifecycleMetadata, error) } -type BuilderCreator interface { - CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) ([]k8scorev1.ObjectReference, buildapi.BuilderRecord, error) -} - type RemoteBuilderCreator struct { RegistryClient RegistryClient LifecycleProvider LifecycleProvider @@ -31,8 +27,6 @@ type RemoteBuilderCreator struct { KeychainFactory registry.KeychainFactory } -var _ BuilderCreator = (*RemoteBuilderCreator)(nil) - func (r *RemoteBuilderCreator) CreateBuilder( ctx context.Context, builderKeychain authn.Keychain, diff --git a/pkg/reconciler/builder/builder.go b/pkg/reconciler/builder/builder.go index 9c621c95..7ef46e50 100644 --- a/pkg/reconciler/builder/builder.go +++ b/pkg/reconciler/builder/builder.go @@ -4,12 +4,14 @@ import ( "context" "go.uber.org/zap" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "knative.dev/pkg/logging/logkey" + "github.com/google/go-containerregistry/pkg/authn" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/equality" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -31,11 +33,15 @@ const ( ReconcilerName = "Builders" ) +type BuilderCreator interface { + CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) ([]corev1.ObjectReference, buildapi.BuilderRecord, error) +} + func NewController( ctx context.Context, opt reconciler.Options, builderInformer buildinformers.BuilderInformer, - builderCreator cnb.BuilderCreator, + builderCreator BuilderCreator, keychainFactory registry.KeychainFactory, clusterStoreInformer buildinformers.ClusterStoreInformer, buildpackInformer buildinformers.BuildpackInformer, @@ -96,7 +102,7 @@ func NewController( type Reconciler struct { Client versioned.Interface BuilderLister buildlisters.BuilderLister - BuilderCreator cnb.BuilderCreator + BuilderCreator BuilderCreator KeychainFactory registry.KeychainFactory Tracker reconciler.Tracker ClusterStoreLister buildlisters.ClusterStoreLister @@ -139,7 +145,7 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui err := c.Tracker.Track(reconciler.Key{ NamespacedName: types.NamespacedName{ Name: builder.Spec.Stack.Name, - Namespace: v1.NamespaceAll, + Namespace: metav1.NamespaceAll, }, GroupKind: schema.GroupKind{ Group: "kpack.io", @@ -223,6 +229,6 @@ func (c *Reconciler) updateStatus(ctx context.Context, desired *buildapi.Builder return nil } - _, err = c.Client.KpackV1alpha2().Builders(desired.Namespace).UpdateStatus(ctx, desired, v1.UpdateOptions{}) + _, err = c.Client.KpackV1alpha2().Builders(desired.Namespace).UpdateStatus(ctx, desired, metav1.UpdateOptions{}) return err } diff --git a/pkg/reconciler/buildpack/buildpack.go b/pkg/reconciler/buildpack/buildpack.go index 0ff9242e..2f4a83eb 100644 --- a/pkg/reconciler/buildpack/buildpack.go +++ b/pkg/reconciler/buildpack/buildpack.go @@ -128,7 +128,7 @@ func (c *Reconciler) reconcileBuildpackStatus(ctx context.Context, buildpack *bu return buildpack, err } - buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.ImageSource{buildpack.Spec.Source}) + buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.ImageSource{buildpack.Spec.ImageSource}) if err != nil { buildpack.Status = buildapi.BuildpackStatus{ Status: corev1alpha1.CreateStatusWithReadyCondition(buildpack.Generation, err), diff --git a/pkg/reconciler/buildpack/buildpack_test.go b/pkg/reconciler/buildpack/buildpack_test.go index fb977f92..58bfe729 100644 --- a/pkg/reconciler/buildpack/buildpack_test.go +++ b/pkg/reconciler/buildpack/buildpack_test.go @@ -63,7 +63,7 @@ func testBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { Generation: initialGeneration, }, Spec: buildapi.BuildpackSpec{ - Source: corev1alpha1.ImageSource{ + ImageSource: corev1alpha1.ImageSource{ Image: "some.registry/some-image-2", }, }, @@ -133,7 +133,7 @@ func testBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { assert.Equal(t, 1, fakeStoreReader.ReadCallCount()) _, StoreSpec := fakeStoreReader.ReadArgsForCall(0) - assert.Equal(t, []corev1alpha1.ImageSource{bp.Spec.Source}, StoreSpec) + assert.Equal(t, []corev1alpha1.ImageSource{bp.Spec.ImageSource}, StoreSpec) }) it("uses the keychain of the referenced service account", func() { diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder.go b/pkg/reconciler/clusterbuilder/clusterbuilder.go index 1b9b4fb4..2d8b9543 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder.go @@ -4,13 +4,14 @@ import ( "context" "go.uber.org/zap" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "knative.dev/pkg/logging/logkey" + "github.com/google/go-containerregistry/pkg/authn" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/equality" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -32,11 +33,15 @@ const ( ReconcilerName = "ClusterBuilders" ) +type BuilderCreator interface { + CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) ([]corev1.ObjectReference, buildapi.BuilderRecord, error) +} + func NewController( ctx context.Context, opt reconciler.Options, clusterBuilderInformer buildinformers.ClusterBuilderInformer, - builderCreator cnb.BuilderCreator, + builderCreator BuilderCreator, keychainFactory registry.KeychainFactory, clusterStoreInformer buildinformers.ClusterStoreInformer, clusterBuildpackInformer buildinformers.ClusterBuildpackInformer, @@ -90,7 +95,7 @@ func NewController( type Reconciler struct { Client versioned.Interface ClusterBuilderLister buildlisters.ClusterBuilderLister - BuilderCreator cnb.BuilderCreator + BuilderCreator BuilderCreator KeychainFactory registry.KeychainFactory Tracker reconciler.Tracker ClusterStoreLister buildlisters.ClusterStoreLister @@ -133,7 +138,7 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu err := c.Tracker.Track(reconciler.Key{ NamespacedName: types.NamespacedName{ Name: builder.Spec.Stack.Name, - Namespace: v1.NamespaceAll, + Namespace: corev1.NamespaceAll, }, GroupKind: schema.GroupKind{ Group: "kpack.io", diff --git a/pkg/reconciler/clusterbuildpack/clusterbuildpack.go b/pkg/reconciler/clusterbuildpack/clusterbuildpack.go index 7bad6086..e3f1bd04 100644 --- a/pkg/reconciler/clusterbuildpack/clusterbuildpack.go +++ b/pkg/reconciler/clusterbuildpack/clusterbuildpack.go @@ -128,7 +128,7 @@ func (c *Reconciler) reoncileClusterBuildpackStatus(ctx context.Context, cluster return clusterBuildpack, err } - buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.ImageSource{clusterBuildpack.Spec.Source}) + buildpacks, err := c.StoreReader.Read(keychain, []corev1alpha1.ImageSource{clusterBuildpack.Spec.ImageSource}) if err != nil { clusterBuildpack.Status = buildapi.ClusterBuildpackStatus{ Status: corev1alpha1.CreateStatusWithReadyCondition(clusterBuildpack.Generation, err), diff --git a/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go b/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go index 42c4f3be..22057e2f 100644 --- a/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go +++ b/pkg/reconciler/clusterbuildpack/clusterbuildpack_test.go @@ -61,7 +61,7 @@ func testClusterBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { Generation: initialGeneration, }, Spec: buildapi.ClusterBuildpackSpec{ - Source: corev1alpha1.ImageSource{ + ImageSource: corev1alpha1.ImageSource{ Image: "some.registry/some-image-2", }, }, @@ -131,7 +131,7 @@ func testClusterBuildpackReconciler(t *testing.T, when spec.G, it spec.S) { assert.Equal(t, 1, fakeStoreReader.ReadCallCount()) _, clusterStoreSpec := fakeStoreReader.ReadArgsForCall(0) - assert.Equal(t, []corev1alpha1.ImageSource{cbp.Spec.Source}, clusterStoreSpec) + assert.Equal(t, []corev1alpha1.ImageSource{cbp.Spec.ImageSource}, clusterStoreSpec) }) it("uses the keychain of the referenced service account", func() { diff --git a/pkg/reconciler/testhelpers/fake_builder_creator.go b/pkg/reconciler/testhelpers/fake_builder_creator.go index 968ffa4e..3c506233 100644 --- a/pkg/reconciler/testhelpers/fake_builder_creator.go +++ b/pkg/reconciler/testhelpers/fake_builder_creator.go @@ -26,8 +26,6 @@ type CreateBuilderArgs struct { BuilderSpec buildapi.BuilderSpec } -var _ cnb.BuilderCreator = (*FakeBuilderCreator)(nil) - func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) ([]corev1.ObjectReference, buildapi.BuilderRecord, error) { f.CreateBuilderCalls = append(f.CreateBuilderCalls, CreateBuilderArgs{ Context: ctx, diff --git a/test/execute_build_test.go b/test/execute_build_test.go index 9562e2f8..1dc2b932 100644 --- a/test/execute_build_test.go +++ b/test/execute_build_test.go @@ -153,7 +153,7 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) { Name: buildpackName, }, Spec: buildapi.BuildpackSpec{ - Source: corev1alpha1.ImageSource{ + ImageSource: corev1alpha1.ImageSource{ Image: "gcr.io/paketo-buildpacks/bellsoft-liberica", }, }, @@ -165,7 +165,7 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) { Name: clusterBuildpackName, }, Spec: buildapi.ClusterBuildpackSpec{ - Source: corev1alpha1.ImageSource{ + ImageSource: corev1alpha1.ImageSource{ Image: "gcr.io/paketo-buildpacks/nodejs", }, }, From 5ddfd9b353400e6237bfe4e1f97a8253296dd565 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Wed, 22 Feb 2023 11:07:23 -0500 Subject: [PATCH 24/39] reconcile builders on any builpack change ..instead of explicitly tracking individual objects. this is mainly to deal with the scenario where the builder only specifies an id for a buildpack. we need to reconcile if a brand new buildpack resource is added to the cluster since it can provide a newer version of the specified id. Signed-off-by: Bohan Chen --- pkg/reconciler/builder/builder.go | 49 ++--- pkg/reconciler/builder/builder_test.go | 16 +- .../clusterbuilder/clusterbuilder.go | 50 +++-- .../clusterbuilder/clusterbuilder_test.go | 13 +- pkg/reconciler/image/image.go | 5 +- pkg/reconciler/image/image_test.go | 2 +- pkg/reconciler/lifecycle/lifecycle_test.go | 2 +- pkg/reconciler/testhelpers/fake_tracker.go | 48 ++++- pkg/reconciler/tracker.go | 3 +- pkg/tracker/tracker.go | 44 +++-- pkg/tracker/tracker_test.go | 184 +++++++++++++++--- 11 files changed, 298 insertions(+), 118 deletions(-) diff --git a/pkg/reconciler/builder/builder.go b/pkg/reconciler/builder/builder.go index 7ef46e50..fa300575 100644 --- a/pkg/reconciler/builder/builder.go +++ b/pkg/reconciler/builder/builder.go @@ -142,7 +142,7 @@ func (c *Reconciler) Reconcile(ctx context.Context, key string) error { } func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Builder) (buildapi.BuilderRecord, error) { - err := c.Tracker.Track(reconciler.Key{ + c.Tracker.Track(reconciler.Key{ NamespacedName: types.NamespacedName{ Name: builder.Spec.Stack.Name, Namespace: metav1.NamespaceAll, @@ -152,18 +152,39 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui Kind: buildapi.ClusterStackKind, }, }, builder.NamespacedName()) - if err != nil { - return buildapi.BuilderRecord{}, err - } - var clusterStore *buildapi.ClusterStore + var ( + clusterStore *buildapi.ClusterStore + err error + ) if builder.Spec.Store.Name != "" { + c.Tracker.Track(reconciler.Key{ + NamespacedName: types.NamespacedName{ + Name: builder.Spec.Store.Name, + Namespace: metav1.NamespaceAll, + }, + GroupKind: schema.GroupKind{ + Group: "kpack.io", + Kind: buildapi.ClusterStoreKind, + }, + }, builder.NamespacedName()) + clusterStore, err = c.ClusterStoreLister.Get(builder.Spec.Store.Name) if err != nil { return buildapi.BuilderRecord{}, err } } + c.Tracker.TrackKind(schema.GroupKind{ + Group: "kpack.io", + Kind: buildapi.BuildpackKind, + }, builder.NamespacedName()) + + c.Tracker.TrackKind(schema.GroupKind{ + Group: "kpack.io", + Kind: buildapi.ClusterBuildpackKind, + }, builder.NamespacedName()) + buildpacks, err := c.BuildpackLister.Buildpacks(builder.Namespace).List(labels.Everything()) if err != nil { return buildapi.BuilderRecord{}, err @@ -193,27 +214,11 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, buildpacks, clusterBuildpacks) - buildpackSources, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + _, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) if err != nil { return buildapi.BuilderRecord{}, err } - for _, source := range buildpackSources { - err = c.Tracker.Track(reconciler.Key{ - NamespacedName: types.NamespacedName{ - Name: source.Name, - Namespace: source.Namespace, - }, - GroupKind: schema.GroupKind{ - Group: "kpack.io", - Kind: source.Kind, - }, - }, builder.NamespacedName()) - if err != nil { - return buildapi.BuilderRecord{}, err - } - } - return buildRecord, nil } diff --git a/pkg/reconciler/builder/builder_test.go b/pkg/reconciler/builder/builder_test.go index 7527624a..50006392 100644 --- a/pkg/reconciler/builder/builder_test.go +++ b/pkg/reconciler/builder/builder_test.go @@ -44,7 +44,7 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { var ( builderCreator = &testhelpers.FakeBuilderCreator{} keychainFactory = ®istryfakes.FakeKeychainFactory{} - fakeTracker = testhelpers.FakeTracker{} + fakeTracker = &testhelpers.FakeTracker{} ) rt := testhelpers.ReconcilerTester(t, @@ -264,11 +264,6 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, Buildpacks: corev1alpha1.BuildpackMetadataList{}, } - builderCreator.ObjectsToTrack = []corev1.ObjectReference{ - {Name: clusterStore.Name, Kind: clusterStore.Kind}, - {Name: buildpack.Name, Kind: buildpack.Kind, Namespace: testNamespace}, - {Name: clusterBuildpack.Name, Kind: clusterBuildpack.Kind}, - } expectedBuilder := &buildapi.Builder{ ObjectMeta: builder.ObjectMeta, @@ -310,11 +305,12 @@ func testBuilderReconciler(t *testing.T, when spec.G, it spec.S) { require.True(t, fakeTracker.IsTracking( kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) - require.True(t, fakeTracker.IsTracking( - kreconciler.KeyForObject(buildpack), + + require.True(t, fakeTracker.IsTrackingKind( + kreconciler.KeyForObject(buildpack).GroupKind, builder.NamespacedName())) - require.True(t, fakeTracker.IsTracking( - kreconciler.KeyForObject(clusterBuildpack), + require.True(t, fakeTracker.IsTrackingKind( + kreconciler.KeyForObject(clusterBuildpack).GroupKind, builder.NamespacedName())) }) diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder.go b/pkg/reconciler/clusterbuilder/clusterbuilder.go index 2d8b9543..74e6ad3c 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder.go @@ -69,6 +69,7 @@ func NewController( controller.ControllerOptions{WorkQueueName: ReconcilerName, Logger: logger}, ) clusterBuilderInformer.Informer().AddEventHandler(controller.HandleAll(impl.Enqueue)) + clusterBuildpackInformer.Informer().AddEventHandler(controller.HandleAll(impl.Enqueue)) c.Tracker = tracker.New(impl.EnqueueKey, opt.TrackerResyncPeriod()) clusterStoreInformer.Informer().AddEventHandler(controller.HandleAll( @@ -81,11 +82,6 @@ func NewController( c.Tracker.OnChanged, buildapi.SchemeGroupVersion.WithKind(buildapi.ClusterStackKind)), )) - clusterBuildpackInformer.Informer().AddEventHandler(controller.HandleAll( - controller.EnsureTypeMeta( - c.Tracker.OnChanged, - buildapi.SchemeGroupVersion.WithKind(buildapi.ClusterBuildpackKind)), - )) return impl, func() { impl.GlobalResync(clusterBuilderInformer.Informer()) @@ -135,7 +131,7 @@ func (c *Reconciler) Reconcile(ctx context.Context, key string) error { } func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.ClusterBuilder) (buildapi.BuilderRecord, error) { - err := c.Tracker.Track(reconciler.Key{ + c.Tracker.Track(reconciler.Key{ NamespacedName: types.NamespacedName{ Name: builder.Spec.Stack.Name, Namespace: corev1.NamespaceAll, @@ -145,18 +141,34 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu Kind: buildapi.ClusterStackKind, }, }, builder.NamespacedName()) - if err != nil { - return buildapi.BuilderRecord{}, err - } - var clusterStore *buildapi.ClusterStore + var ( + clusterStore *buildapi.ClusterStore + err error + ) if builder.Spec.Store.Name != "" { + c.Tracker.Track(reconciler.Key{ + NamespacedName: types.NamespacedName{ + Name: builder.Spec.Store.Name, + Namespace: metav1.NamespaceAll, + }, + GroupKind: schema.GroupKind{ + Group: "kpack.io", + Kind: buildapi.ClusterStoreKind, + }, + }, builder.NamespacedName()) + clusterStore, err = c.ClusterStoreLister.Get(builder.Spec.Store.Name) if err != nil { return buildapi.BuilderRecord{}, err } } + c.Tracker.TrackKind(schema.GroupKind{ + Group: "kpack.io", + Kind: buildapi.ClusterBuildpackKind, + }, builder.NamespacedName()) + clusterBuildpacks, err := c.ClusterBuildpackLister.List(labels.Everything()) if err != nil { return buildapi.BuilderRecord{}, err @@ -181,27 +193,11 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, nil, clusterBuildpacks) - buildpackSources, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + _, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) if err != nil { return buildapi.BuilderRecord{}, err } - for _, source := range buildpackSources { - err = c.Tracker.Track(reconciler.Key{ - NamespacedName: types.NamespacedName{ - Name: source.Name, - Namespace: source.Namespace, - }, - GroupKind: schema.GroupKind{ - Group: "kpack.io", - Kind: source.Kind, - }, - }, builder.NamespacedName()) - if err != nil { - return buildapi.BuilderRecord{}, err - } - } - return buildRecord, nil } diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go index be447523..7bada2c0 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder_test.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder_test.go @@ -43,7 +43,7 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { var ( builderCreator = &testhelpers.FakeBuilderCreator{} keychainFactory = ®istryfakes.FakeKeychainFactory{} - fakeTracker = testhelpers.FakeTracker{} + fakeTracker = &testhelpers.FakeTracker{} ) rt := testhelpers.ReconcilerTester(t, @@ -251,7 +251,7 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }}, builderCreator.CreateBuilderCalls) }) - it("tracks the stack and buildpack sources for a custom builder", func() { + it("tracks the stack and store for a custom builder", func() { builderCreator.Record = buildapi.BuilderRecord{ Image: builderIdentifier, Stack: corev1alpha1.BuildStack{ @@ -260,10 +260,6 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { }, Buildpacks: corev1alpha1.BuildpackMetadataList{}, } - builderCreator.ObjectsToTrack = []corev1.ObjectReference{ - {Name: clusterStore.Name, Kind: clusterStore.Kind}, - {Name: clusterBuildpack.Name, Kind: clusterBuildpack.Kind}, - } expectedBuilder := &buildapi.ClusterBuilder{ ObjectMeta: builder.ObjectMeta, @@ -302,8 +298,9 @@ func testClusterBuilderReconciler(t *testing.T, when spec.G, it spec.S) { kreconciler.KeyForObject(clusterStore), expectedBuilder.NamespacedName())) require.True(t, fakeTracker.IsTracking( kreconciler.KeyForObject(clusterStack), builder.NamespacedName())) - require.True(t, fakeTracker.IsTracking( - kreconciler.KeyForObject(clusterBuildpack), expectedBuilder.NamespacedName())) + + require.True(t, fakeTracker.IsTrackingKind( + kreconciler.KeyForObject(clusterBuildpack).GroupKind, builder.NamespacedName())) }) it("does not update the status with no status change", func() { diff --git a/pkg/reconciler/image/image.go b/pkg/reconciler/image/image.go index 1f8362fd..a716ff9e 100644 --- a/pkg/reconciler/image/image.go +++ b/pkg/reconciler/image/image.go @@ -133,10 +133,7 @@ func (c *Reconciler) Reconcile(ctx context.Context, key string) error { } func (c *Reconciler) reconcileImage(ctx context.Context, image *buildapi.Image) (*buildapi.Image, error) { - err := c.Tracker.Track(reconcilerKeyForBuilderKind(image), image.NamespacedName()) - if err != nil { - return nil, err - } + c.Tracker.Track(reconcilerKeyForBuilderKind(image), image.NamespacedName()) builder, err := c.DuckBuilderLister.Namespace(image.Namespace).Get(image.Spec.Builder) if err != nil && !k8serrors.IsNotFound(err) { diff --git a/pkg/reconciler/image/image_test.go b/pkg/reconciler/image/image_test.go index b9a44be8..2b2dfa42 100644 --- a/pkg/reconciler/image/image_test.go +++ b/pkg/reconciler/image/image_test.go @@ -46,7 +46,7 @@ func testImageReconciler(t *testing.T, when spec.G, it spec.S) { someValueToPassThrough = "to-pass-through" originalGeneration int64 = 1 ) - fakeTracker := testhelpers.FakeTracker{} + fakeTracker := &testhelpers.FakeTracker{} rt := testhelpers.ReconcilerTester(t, func(t *testing.T, row *rtesting.TableRow) (reconciler controller.Reconciler, lists rtesting.ActionRecorderList, list rtesting.EventList) { diff --git a/pkg/reconciler/lifecycle/lifecycle_test.go b/pkg/reconciler/lifecycle/lifecycle_test.go index 202b8223..24e2e093 100644 --- a/pkg/reconciler/lifecycle/lifecycle_test.go +++ b/pkg/reconciler/lifecycle/lifecycle_test.go @@ -27,7 +27,7 @@ func TestLifecycleReconciler(t *testing.T) { func testLifecycleReconciler(t *testing.T, when spec.G, it spec.S) { var ( - fakeTracker = testhelpers.FakeTracker{} + fakeTracker = &testhelpers.FakeTracker{} lifecycleImageRef = "gcr.io/lifecycle@sha256:some-sha" serviceAccountName = "lifecycle-sa" namespace = "kpack" diff --git a/pkg/reconciler/testhelpers/fake_tracker.go b/pkg/reconciler/testhelpers/fake_tracker.go index 5d9a88fa..9d7a8877 100644 --- a/pkg/reconciler/testhelpers/fake_tracker.go +++ b/pkg/reconciler/testhelpers/fake_tracker.go @@ -4,27 +4,57 @@ import ( "fmt" "github.com/pivotal/kpack/pkg/reconciler" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ) -type FakeTracker map[string]map[types.NamespacedName]struct{} +type FakeTracker struct { + objects map[string]map[types.NamespacedName]struct{} + kinds map[string]map[types.NamespacedName]struct{} +} + +func (f *FakeTracker) Track(ref reconciler.Key, obj types.NamespacedName) { + if f.objects == nil { + f.objects = make(map[string]map[types.NamespacedName]struct{}) + } + + _, ok := f.objects[ref.String()] + if !ok { + f.objects[ref.String()] = map[types.NamespacedName]struct{}{} + } + + f.objects[ref.String()][obj] = struct{}{} +} + +func (f *FakeTracker) TrackKind(kind schema.GroupKind, obj types.NamespacedName) { + if f.kinds == nil { + f.kinds = make(map[string]map[types.NamespacedName]struct{}) + } -func (f FakeTracker) Track(ref reconciler.Key, obj types.NamespacedName) error { - _, ok := f[ref.String()] + _, ok := f.kinds[kind.String()] if !ok { - f[ref.String()] = map[types.NamespacedName]struct{}{} + f.kinds[kind.String()] = map[types.NamespacedName]struct{}{} } - f[ref.String()][obj] = struct{}{} - return nil + f.kinds[kind.String()][obj] = struct{}{} } -func (FakeTracker) OnChanged(obj interface{}) { +func (*FakeTracker) OnChanged(obj interface{}) { panic("I should not be called in tests") } -func (f FakeTracker) IsTracking(ref reconciler.Key, obj types.NamespacedName) bool { - trackingObs, ok := f[ref.String()] +func (f *FakeTracker) IsTracking(ref reconciler.Key, obj types.NamespacedName) bool { + trackingObs, ok := f.objects[ref.String()] + if !ok { + return false + } + _, ok = trackingObs[obj] + + return ok +} + +func (f *FakeTracker) IsTrackingKind(kind schema.GroupKind, obj types.NamespacedName) bool { + trackingObs, ok := f.kinds[kind.String()] if !ok { return false } diff --git a/pkg/reconciler/tracker.go b/pkg/reconciler/tracker.go index 480a7b39..3a3db867 100644 --- a/pkg/reconciler/tracker.go +++ b/pkg/reconciler/tracker.go @@ -43,6 +43,7 @@ func KeyForObject(obj Object) Key { } type Tracker interface { - Track(ref Key, obj types.NamespacedName) error + Track(ref Key, obj types.NamespacedName) + TrackKind(kind schema.GroupKind, obj types.NamespacedName) OnChanged(obj interface{}) } diff --git a/pkg/tracker/tracker.go b/pkg/tracker/tracker.go index 38578623..636543d9 100644 --- a/pkg/tracker/tracker.go +++ b/pkg/tracker/tracker.go @@ -26,11 +26,14 @@ import ( "time" "github.com/pivotal/kpack/pkg/reconciler" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ) func New(callback func(types.NamespacedName), lease time.Duration) *Tracker { return &Tracker{ + objects: make(map[string]set), + kinds: make(map[string]set), leaseDuration: lease, cb: callback, } @@ -38,9 +41,13 @@ func New(callback func(types.NamespacedName), lease time.Duration) *Tracker { type Tracker struct { m sync.Mutex - // mapping maps from an object reference to the set of + // objects maps from an object reference to the set of // keys for objects watching it. - mapping map[string]set + objects map[string]set + + // kinds maps from group version kind to the set of + // keys for objects watching it. + kinds map[string]set // The amount of time that an object may watch another // before having to renew the lease. @@ -53,28 +60,38 @@ type Tracker struct { type set map[types.NamespacedName]time.Time // Track implements Interface. -func (i *Tracker) Track(ref reconciler.Key, obj types.NamespacedName) error { +func (i *Tracker) Track(ref reconciler.Key, obj types.NamespacedName) { i.m.Lock() defer i.m.Unlock() - if i.mapping == nil { - i.mapping = make(map[string]set) - } - l, ok := i.mapping[ref.String()] + l, ok := i.objects[ref.String()] if !ok { l = set{} } // Overwrite the key with a new expiration. l[obj] = time.Now().Add(i.leaseDuration) - i.mapping[ref.String()] = l - return nil + i.objects[ref.String()] = l } func isExpired(expiry time.Time) bool { return time.Now().After(expiry) } +func (i *Tracker) TrackKind(kind schema.GroupKind, obj types.NamespacedName) { + i.m.Lock() + defer i.m.Unlock() + + l, ok := i.objects[kind.String()] + if !ok { + l = set{} + } + // Overwrite the key with a new expiration. + l[obj] = time.Now().Add(i.leaseDuration) + + i.kinds[kind.String()] = l +} + // OnChanged implements Interface. func (i *Tracker) OnChanged(obj interface{}) { reconcilerObj, ok := obj.(reconciler.Object) @@ -88,7 +105,12 @@ func (i *Tracker) OnChanged(obj interface{}) { // smaller scope and leveraging a per-set lock to guard its access. i.m.Lock() defer i.m.Unlock() - s, ok := i.mapping[key.String()] + i.notify(i.objects, key.String()) + i.notify(i.kinds, key.GroupKind.String()) +} + +func (i *Tracker) notify(mapping map[string]set, key string) { + s, ok := mapping[key] if !ok { // TODO(mattmoor): We should consider logging here. return @@ -104,6 +126,6 @@ func (i *Tracker) OnChanged(obj interface{}) { } if len(s) == 0 { - delete(i.mapping, key.String()) + delete(mapping, key) } } diff --git a/pkg/tracker/tracker_test.go b/pkg/tracker/tracker_test.go index a07cec1f..e3688b19 100644 --- a/pkg/tracker/tracker_test.go +++ b/pkg/tracker/tracker_test.go @@ -7,6 +7,7 @@ import ( "github.com/sclevine/spec" "github.com/stretchr/testify/require" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" @@ -20,37 +21,135 @@ func TestTracker(t *testing.T) { func testTracker(t *testing.T, when spec.G, it spec.S) { when("#Track", func() { + var ( + reconcilerName = types.NamespacedName{ + Namespace: "some-other-namespace", + Name: "call-me-when-builder-changes", + } + ) when("tracking a namespace scoped object", func() { + var ( + wasCalledWith types.NamespacedName + + builder = &buildapi.Builder{ + ObjectMeta: v1.ObjectMeta{ + Name: "some-name", + Namespace: "some-namespace", + }, + } + + otherBuilder = &buildapi.Builder{ + ObjectMeta: v1.ObjectMeta{ + Name: "some-other-name", + Namespace: "some-other-namespace", + }, + } + ) it("calls the callback when OnChanged is called", func() { + track := tracker.New(func(key types.NamespacedName) { + wasCalledWith = key + }, 5*time.Minute) + + track.Track(reconciler.KeyForObject(builder), reconcilerName) + + track.OnChanged(builder) + + require.Equal(t, wasCalledWith, reconcilerName) + }) + + it("doesn't do anything if OnChanged is called for a different object", func() { var wasCalledWith types.NamespacedName track := tracker.New(func(key types.NamespacedName) { wasCalledWith = key }, 5*time.Minute) - builder := &buildapi.Builder{ + track.Track(reconciler.KeyForObject(builder), reconcilerName) + + track.OnChanged(otherBuilder) + + require.Equal(t, wasCalledWith, types.NamespacedName{}) + }) + }) + + when("tracking a cluster scoped object", func() { + var ( + wasCalledWith types.NamespacedName + clusterBuilder = &buildapi.ClusterBuilder{ ObjectMeta: v1.ObjectMeta{ - Name: "some-name", - Namespace: "some-namespace", + Name: "some-name", + }, + TypeMeta: v1.TypeMeta{ + Kind: "ClusterBuilder", + APIVersion: "kpack.io/v1alpha2", }, } - err := track.Track(reconciler.KeyForObject(builder), types.NamespacedName{ - Namespace: "some-other-namespace", - Name: "call-me-when-builder-changes", - }) - require.NoError(t, err) - track.OnChanged(builder) + otherClusterBuilder = &buildapi.ClusterBuilder{ + ObjectMeta: v1.ObjectMeta{ + Name: "some-other-name", + }, + TypeMeta: v1.TypeMeta{ + Kind: "ClusterBuilder", + APIVersion: "kpack.io/v1alpha2", + }, + } + ) + it("calls the callback when OnChanged is called", func() { + track := tracker.New(func(key types.NamespacedName) { + wasCalledWith = key + }, 5*time.Minute) + + track.Track(reconciler.KeyForObject(clusterBuilder), reconcilerName) + + track.OnChanged(clusterBuilder) + + require.Equal(t, wasCalledWith, reconcilerName) + }) + + it("doesn't do anything if OnChanged is called for a different object", func() { + track := tracker.New(func(key types.NamespacedName) { + wasCalledWith = key + }, 5*time.Minute) + + track.Track(reconciler.KeyForObject(clusterBuilder), reconcilerName) + + track.OnChanged(otherClusterBuilder) - require.Equal(t, wasCalledWith, types.NamespacedName{ - Namespace: "some-other-namespace", - Name: "call-me-when-builder-changes", - }) + require.Equal(t, wasCalledWith, types.NamespacedName{}) }) }) - when("tracking a cluster scoped object", func() { + when("tracking a group kind", func() { + var ( + wasCalledWith types.NamespacedName + groupKind = schema.GroupKind{ + Group: "kpack.io", + Kind: "Builder", + } + ) it("calls the callback when OnChanged is called", func() { - var wasCalledWith types.NamespacedName + track := tracker.New(func(key types.NamespacedName) { + wasCalledWith = key + }, 5*time.Minute) + + builder := &buildapi.Builder{ + ObjectMeta: v1.ObjectMeta{ + Name: "some-name", + }, + TypeMeta: v1.TypeMeta{ + Kind: "Builder", + APIVersion: "kpack.io/v1alpha2", + }, + } + + track.TrackKind(groupKind, reconcilerName) + + track.OnChanged(builder) + + require.Equal(t, wasCalledWith, reconcilerName) + }) + + it("doesn't do anything if OnChanged is called for a different kind", func() { track := tracker.New(func(key types.NamespacedName) { wasCalledWith = key }, 5*time.Minute) @@ -64,18 +163,55 @@ func testTracker(t *testing.T, when spec.G, it spec.S) { APIVersion: "kpack.io/v1alpha2", }, } - err := track.Track(reconciler.KeyForObject(clusterBuilder), types.NamespacedName{ - Namespace: "some-other-namespace", - Name: "call-me-when-builder-changes", - }) - require.NoError(t, err) + + track.TrackKind(groupKind, reconcilerName) track.OnChanged(clusterBuilder) - require.Equal(t, wasCalledWith, types.NamespacedName{ - Namespace: "some-other-namespace", - Name: "call-me-when-builder-changes", - }) + require.Equal(t, wasCalledWith, types.NamespacedName{}) + }) + }) + + when("tracking expires", func() { + var ( + wasCalledWith types.NamespacedName + builder = &buildapi.Builder{ + ObjectMeta: v1.ObjectMeta{ + Name: "some-name", + Namespace: "some-namespace", + }, + TypeMeta: v1.TypeMeta{ + Kind: "Builder", + APIVersion: "kpack.io/v1alpha2", + }, + } + groupKind = schema.GroupKind{ + Group: "kpack.io", + Kind: "Builder", + } + ) + it("doesn't call the OnChanged for object", func() { + track := tracker.New(func(key types.NamespacedName) { + wasCalledWith = key + }, 0) + + track.TrackKind(groupKind, reconcilerName) + + track.OnChanged(builder) + + require.Equal(t, wasCalledWith, types.NamespacedName{}) + }) + + it("doesn't call the OnChanged for kind ", func() { + track := tracker.New(func(key types.NamespacedName) { + wasCalledWith = key + }, 0) + + track.TrackKind(groupKind, reconcilerName) + + track.OnChanged(builder) + + require.Equal(t, wasCalledWith, types.NamespacedName{}) }) }) }) From ce4b9eca4f271b60d5cb2b0ef4e8999a38d2f97b Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Thu, 23 Feb 2023 10:18:14 -0500 Subject: [PATCH 25/39] remove UsedObjects() from the buildpack resolver this was originally used to figure out which objects needed to be tracked. But since we've switched to a flow that tracked all resources of a particular kind, we no longer need this Signed-off-by: Bohan Chen --- pkg/cnb/buildpack_resolver.go | 9 - pkg/cnb/buildpack_resolver_test.go | 156 ------------------ pkg/cnb/create_builder.go | 19 +-- pkg/cnb/create_builder_test.go | 20 +-- pkg/cnb/fakes_test.go | 4 - pkg/reconciler/builder/builder.go | 5 +- .../clusterbuilder/clusterbuilder.go | 4 +- .../testhelpers/fake_builder_creator.go | 4 +- 8 files changed, 25 insertions(+), 196 deletions(-) diff --git a/pkg/cnb/buildpack_resolver.go b/pkg/cnb/buildpack_resolver.go index b338b928..591e3e46 100644 --- a/pkg/cnb/buildpack_resolver.go +++ b/pkg/cnb/buildpack_resolver.go @@ -17,14 +17,12 @@ import ( type BuildpackResolver interface { resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) ClusterStoreObservedGeneration() int64 - UsedObjects() []v1.ObjectReference } type buildpackResolver struct { clusterstore *v1alpha2.ClusterStore buildpacks []*v1alpha2.Buildpack clusterBuildpacks []*v1alpha2.ClusterBuildpack - usedObjects []v1.ObjectReference } func NewBuildpackResolver(clusterStore *v1alpha2.ClusterStore, buildpacks []*v1alpha2.Buildpack, clusterBuildpacks []*v1alpha2.ClusterBuildpack) BuildpackResolver { @@ -32,7 +30,6 @@ func NewBuildpackResolver(clusterStore *v1alpha2.ClusterStore, buildpacks []*v1a clusterstore: clusterStore, buildpacks: buildpacks, clusterBuildpacks: clusterBuildpacks, - usedObjects: make([]v1.ObjectReference, 0), } } @@ -43,10 +40,6 @@ func (r *buildpackResolver) ClusterStoreObservedGeneration() int64 { return 0 } -func (r *buildpackResolver) UsedObjects() []v1.ObjectReference { - return r.usedObjects -} - func (r *buildpackResolver) resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemoteBuildpack, error) { var matchingBuildpacks []K8sRemoteBuildpack var err error @@ -111,13 +104,11 @@ func (r *buildpackResolver) resolve(ref v1alpha2.BuilderBuildpackRef) (K8sRemote if err != nil { return K8sRemoteBuildpack{}, err } - r.usedObjects = append(r.usedObjects, bp.source) return bp, nil } for _, result := range matchingBuildpacks { if result.Buildpack.Version == ref.Version { - r.usedObjects = append(r.usedObjects, result.source) return result, nil } } diff --git a/pkg/cnb/buildpack_resolver_test.go b/pkg/cnb/buildpack_resolver_test.go index 044a6389..e55267b1 100644 --- a/pkg/cnb/buildpack_resolver_test.go +++ b/pkg/cnb/buildpack_resolver_test.go @@ -8,7 +8,6 @@ import ( "github.com/sclevine/spec" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -193,12 +192,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "some-store", - Kind: "ClusterStore", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds it using id and version", func() { @@ -208,26 +201,18 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "some-store", - Kind: "ClusterStore", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid id", func() { ref := makeRef("fake-buildpack", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on unknown version", func() { ref := makeRef("io.buildpack.multi", "8.0.1") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") - assert.Len(t, resolver.UsedObjects(), 0) }) }) @@ -301,13 +286,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested ids", func() { @@ -317,13 +295,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds it using id and version", func() { @@ -333,27 +304,12 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.multi-8.0.0", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) - }) - - it("fails on invalid id", func() { - ref := makeRef("fake-buildpack", "") - _, err := resolver.resolve(ref) - assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on unknown version", func() { ref := makeRef("io.buildpack.multi", "8.0.1") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") - assert.Len(t, resolver.UsedObjects(), 0) }) }) @@ -365,27 +321,18 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid kind", func() { ref := makeObjectRef("io.buildpack.meta", "FakeBuildpack", "", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "kind must be either Buildpack or ClusterBuildpack") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on object not found", func() { ref := makeObjectRef("fake-buildpack", "Buildpack", "", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "no buildpack with name 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) }) @@ -397,13 +344,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested id in resource", func() { @@ -413,13 +353,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds the correct version in resource", func() { @@ -429,34 +362,24 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.multi", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on id not found in resource", func() { ref := makeObjectRef("io.buildpack.meta", "Buildpack", "fake-buildpack", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on version not found in resource", func() { ref := makeObjectRef("io.buildpack.multi", "Buildpack", "io.buildpack.multi", "8.0.1") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on id not found in resource", func() { ref := makeObjectRef("io.buildpack.meta", "Buildpack", "fake-buildpack", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) }) }) @@ -527,12 +450,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested ids", func() { @@ -542,12 +459,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds it using id and version", func() { @@ -557,26 +468,18 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.multi-8.0.0", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid id", func() { ref := makeRef("fake-buildpack", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on unknown version", func() { ref := makeRef("io.buildpack.multi", "8.0.1") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") - assert.Len(t, resolver.UsedObjects(), 0) }) }) @@ -588,26 +491,18 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on invalid kind", func() { ref := makeObjectRef("io.buildpack.meta", "FakeClusterBuildpack", "", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "kind must be either Buildpack or ClusterBuildpack") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on object not found", func() { ref := makeObjectRef("fake-buildpack", "ClusterBuildpack", "", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "no cluster buildpack with name 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) }) @@ -619,12 +514,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds nested id in resource", func() { @@ -634,12 +523,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.meta", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("finds the correct version in resource", func() { @@ -649,33 +532,24 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.multi", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("fails on id not found in resource", func() { ref := makeObjectRef("io.buildpack.meta", "ClusterBuildpack", "fake-buildpack", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on version not found in resource", func() { ref := makeObjectRef("io.buildpack.multi", "ClusterBuildpack", "io.buildpack.multi", "8.0.1") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'io.buildpack.multi' and version '8.0.1'") - assert.Len(t, resolver.UsedObjects(), 0) }) it("fails on id not found in resource", func() { ref := makeObjectRef("io.buildpack.meta", "ClusterBuildpack", "fake-buildpack", "") _, err := resolver.resolve(ref) assert.EqualError(t, err, "could not find buildpack with id 'fake-buildpack'") - assert.Len(t, resolver.UsedObjects(), 0) }) }) }) @@ -753,23 +627,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err = resolver.resolve(makeRef("io.buildpack.multi", "9.0.0")) assert.Nil(t, err) assert.Equal(t, v9Buildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{ - { - Name: "some-store", - Kind: "ClusterStore", - }, - { - Name: "io.buildpack.multi-8.0.0", - Namespace: testNamespace, - Kind: "Buildpack", - }, - { - Name: "io.buildpack.multi-9.0.0", - Kind: "ClusterBuildpack", - }, - } - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("resolves buildpacks before anything else", func() { @@ -779,13 +636,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.multi-8.0.0", - Namespace: testNamespace, - Kind: "Buildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) it("resolves cluster buildpacks before cluster store", func() { @@ -795,12 +645,6 @@ func testBuildpackResolver(t *testing.T, when spec.G, it spec.S) { buildpack, err := resolver.resolve(ref) assert.Nil(t, err) assert.Equal(t, expectedBuildpack, buildpack.Buildpack) - - expectedUsedObjects := []corev1.ObjectReference{{ - Name: "io.buildpack.multi-9.0.0", - Kind: "ClusterBuildpack", - }} - assert.Equal(t, expectedUsedObjects, resolver.UsedObjects()) }) }) diff --git a/pkg/cnb/create_builder.go b/pkg/cnb/create_builder.go index 6c64c23f..3dbf9653 100644 --- a/pkg/cnb/create_builder.go +++ b/pkg/cnb/create_builder.go @@ -8,7 +8,6 @@ import ( buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/registry" - k8scorev1 "k8s.io/api/core/v1" ) type RegistryClient interface { @@ -32,22 +31,22 @@ func (r *RemoteBuilderCreator) CreateBuilder( builderKeychain authn.Keychain, fetcher RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec, -) ([]k8scorev1.ObjectReference, buildapi.BuilderRecord, error) { +) (buildapi.BuilderRecord, error) { buildImage, _, err := r.RegistryClient.Fetch(builderKeychain, clusterStack.Status.BuildImage.LatestImage) if err != nil { - return nil, buildapi.BuilderRecord{}, err + return buildapi.BuilderRecord{}, err } builderBldr := newBuilderBldr(r.KpackVersion) err = builderBldr.AddStack(buildImage, clusterStack) if err != nil { - return nil, buildapi.BuilderRecord{}, err + return buildapi.BuilderRecord{}, err } lifecycleLayer, lifecycleMetadata, err := r.LifecycleProvider.LayerForOS(builderBldr.os) if err != nil { - return nil, buildapi.BuilderRecord{}, err + return buildapi.BuilderRecord{}, err } builderBldr.AddLifecycle(lifecycleLayer, lifecycleMetadata) @@ -58,7 +57,7 @@ func (r *RemoteBuilderCreator) CreateBuilder( for _, buildpack := range group.Group { remoteBuildpack, err := fetcher.ResolveAndFetch(ctx, buildpack) if err != nil { - return nil, buildapi.BuilderRecord{}, err + return buildapi.BuilderRecord{}, err } buildpacks = append(buildpacks, remoteBuildpack.Optional(buildpack.Optional)) @@ -68,17 +67,17 @@ func (r *RemoteBuilderCreator) CreateBuilder( writeableImage, err := builderBldr.WriteableImage() if err != nil { - return nil, buildapi.BuilderRecord{}, err + return buildapi.BuilderRecord{}, err } identifier, err := r.RegistryClient.Save(builderKeychain, spec.Tag, writeableImage) if err != nil { - return nil, buildapi.BuilderRecord{}, err + return buildapi.BuilderRecord{}, err } config, err := writeableImage.ConfigFile() if err != nil { - return nil, buildapi.BuilderRecord{}, err + return buildapi.BuilderRecord{}, err } builder := buildapi.BuilderRecord{ @@ -94,7 +93,7 @@ func (r *RemoteBuilderCreator) CreateBuilder( OS: config.OS, } - return fetcher.UsedObjects(), builder, nil + return builder, nil } func buildpackMetadata(buildpacks []DescriptiveBuildpackInfo) corev1alpha1.BuildpackMetadataList { diff --git a/pkg/cnb/create_builder_test.go b/pkg/cnb/create_builder_test.go index b75b120a..469171be 100644 --- a/pkg/cnb/create_builder_test.go +++ b/pkg/cnb/create_builder_test.go @@ -314,7 +314,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates a custom builder", func() { - _, builderRecord, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + builderRecord, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) assert.Len(t, builderRecord.Buildpacks, 3) @@ -576,11 +576,11 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }) it("creates images deterministically ", func() { - _, original, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + original, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) for i := 1; i <= 50; i++ { - _, other, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + other, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) require.Equal(t, original.Image, other.Image) @@ -610,7 +610,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.stack@v4: stack io.buildpacks.stacks.some-stack is not supported") }) @@ -634,7 +634,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.mixin@v4: stack missing mixin(s): something-missing-mixin, something-missing-mixin2") }) @@ -679,7 +679,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.Nil(t, err) }) @@ -704,7 +704,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.Error(t, err, "validating buildpack io.buildpack.relaxed.old.mixin@v4: stack missing mixin(s): build:common-mixin, run:common-mixin, another-common-mixin") }) @@ -727,7 +727,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "validating buildpack io.buildpack.unsupported.buildpack.api@v4: unsupported buildpack api: 0.1, expecting: 0.2, 0.3") }) @@ -770,7 +770,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }}, }} - _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.NoError(t, err) }) }) @@ -797,7 +797,7 @@ func testCreateBuilderOs(os string, t *testing.T, when spec.G, it spec.S) { }, } - _, _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) + _, err := subject.CreateBuilder(ctx, keychain, fetcher, stack, clusterBuilderSpec) require.EqualError(t, err, "unsupported platform apis in kpack lifecycle: 0.1, 0.2, 0.999, expecting one of: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8") }) }) diff --git a/pkg/cnb/fakes_test.go b/pkg/cnb/fakes_test.go index f42c081e..e9763179 100644 --- a/pkg/cnb/fakes_test.go +++ b/pkg/cnb/fakes_test.go @@ -63,10 +63,6 @@ func (r *fakeResolver) resolve(ref buildapi.BuilderBuildpackRef) (K8sRemoteBuild return buildpack, nil } -func (f *fakeResolver) UsedObjects() []k8scorev1.ObjectReference { - return nil -} - func (f *fakeResolver) AddBuildpack(t *testing.T, ref buildapi.BuilderBuildpackRef, buildpack K8sRemoteBuildpack) { t.Helper() assert.NotEqual(t, ref.Id, "", "buildpack ref missing id") diff --git a/pkg/reconciler/builder/builder.go b/pkg/reconciler/builder/builder.go index fa300575..2c2fa287 100644 --- a/pkg/reconciler/builder/builder.go +++ b/pkg/reconciler/builder/builder.go @@ -4,7 +4,6 @@ import ( "context" "go.uber.org/zap" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" @@ -34,7 +33,7 @@ const ( ) type BuilderCreator interface { - CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) ([]corev1.ObjectReference, buildapi.BuilderRecord, error) + CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) } func NewController( @@ -214,7 +213,7 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Bui fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, buildpacks, clusterBuildpacks) - _, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) if err != nil { return buildapi.BuilderRecord{}, err } diff --git a/pkg/reconciler/clusterbuilder/clusterbuilder.go b/pkg/reconciler/clusterbuilder/clusterbuilder.go index 74e6ad3c..6a8ea406 100644 --- a/pkg/reconciler/clusterbuilder/clusterbuilder.go +++ b/pkg/reconciler/clusterbuilder/clusterbuilder.go @@ -34,7 +34,7 @@ const ( ) type BuilderCreator interface { - CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) ([]corev1.ObjectReference, buildapi.BuilderRecord, error) + CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, spec buildapi.BuilderSpec) (buildapi.BuilderRecord, error) } func NewController( @@ -193,7 +193,7 @@ func (c *Reconciler) reconcileBuilder(ctx context.Context, builder *buildapi.Clu fetcher := cnb.NewRemoteBuildpackFetcher(c.KeychainFactory, clusterStore, nil, clusterBuildpacks) - _, buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) + buildRecord, err := c.BuilderCreator.CreateBuilder(ctx, keychain, fetcher, clusterStack, builder.Spec.BuilderSpec) if err != nil { return buildapi.BuilderRecord{}, err } diff --git a/pkg/reconciler/testhelpers/fake_builder_creator.go b/pkg/reconciler/testhelpers/fake_builder_creator.go index 3c506233..a44bc732 100644 --- a/pkg/reconciler/testhelpers/fake_builder_creator.go +++ b/pkg/reconciler/testhelpers/fake_builder_creator.go @@ -26,7 +26,7 @@ type CreateBuilderArgs struct { BuilderSpec buildapi.BuilderSpec } -func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) ([]corev1.ObjectReference, buildapi.BuilderRecord, error) { +func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.Keychain, fetcher cnb.RemoteBuildpackFetcher, clusterStack *buildapi.ClusterStack, builder buildapi.BuilderSpec) (buildapi.BuilderRecord, error) { f.CreateBuilderCalls = append(f.CreateBuilderCalls, CreateBuilderArgs{ Context: ctx, Keychain: keychain, @@ -35,5 +35,5 @@ func (f *FakeBuilderCreator) CreateBuilder(ctx context.Context, keychain authn.K BuilderSpec: builder, }) - return f.ObjectsToTrack, f.Record, f.CreateErr + return f.Record, f.CreateErr } From a47cb27a0f002b9ce9c9d1e86669dda2483cf20d Mon Sep 17 00:00:00 2001 From: Tom Kennedy Date: Tue, 21 Mar 2023 16:29:25 -0400 Subject: [PATCH 26/39] Update openapi spec --- api/openapi-spec/swagger.json | 383 +++++++++++++--- pkg/openapi/openapi_generated.go | 754 +++++++++++++++++++++++++------ 2 files changed, 919 insertions(+), 218 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 91b146e3..36e01805 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -5121,7 +5121,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.StoreImage" + "$ref": "#/definitions/kpack.core.v1alpha1.ImageSource" }, "x-kubernetes-list-type": "" } @@ -5134,7 +5134,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.StoreBuildpack" + "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackStatus" }, "x-kubernetes-list-type": "" }, @@ -5786,6 +5786,55 @@ } } }, + "kpack.build.v1alpha2.BuilderBuildpackRef": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "apiVersion": { + "description": "API version of the referent.", + "type": "string" + }, + "fieldPath": { + "description": "If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: \"spec.containers{name}\" (where \"name\" refers to the name of the container that triggered the event) or if no container name is specified \"spec.containers[2]\" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object.", + "type": "string" + }, + "id": { + "type": "string", + "default": "" + }, + "image": { + "type": "string" + }, + "kind": { + "description": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "namespace": { + "description": "Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/", + "type": "string" + }, + "optional": { + "type": "boolean" + }, + "resourceVersion": { + "description": "Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "uid": { + "description": "UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids", + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "kpack.build.v1alpha2.BuilderList": { "type": "object", "required": [ @@ -5821,7 +5870,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.OrderEntry" + "$ref": "#/definitions/kpack.build.v1alpha2.BuilderOrderEntry" }, "x-kubernetes-list-type": "" }, @@ -5890,6 +5939,102 @@ } } }, + "kpack.build.v1alpha2.Buildpack": { + "type": "object", + "required": [ + "spec", + "status" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + }, + "spec": { + "default": {}, + "$ref": "#/definitions/kpack.build.v1alpha2.BuildpackSpec" + }, + "status": { + "default": {}, + "$ref": "#/definitions/kpack.build.v1alpha2.BuildpackStatus" + } + } + }, + "kpack.build.v1alpha2.BuildpackList": { + "type": "object", + "required": [ + "metadata", + "items" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.build.v1alpha2.Buildpack" + } + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + } + }, + "kpack.build.v1alpha2.BuildpackSpec": { + "type": "object", + "properties": { + "image": { + "type": "string" + }, + "serviceAccountName": { + "type": "string" + } + } + }, + "kpack.build.v1alpha2.BuildpackStatus": { + "type": "object", + "properties": { + "buildpacks": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackStatus" + }, + "x-kubernetes-list-type": "" + }, + "conditions": { + "description": "Conditions the latest available observations of a resource's current state.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.Condition" + }, + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge" + }, + "observedGeneration": { + "description": "ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.", + "type": "integer", + "format": "int64" + } + } + }, "kpack.build.v1alpha2.ClusterBuilder": { "type": "object", "required": [ @@ -5954,7 +6099,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.OrderEntry" + "$ref": "#/definitions/kpack.build.v1alpha2.BuilderOrderEntry" }, "x-kubernetes-list-type": "" }, @@ -5975,6 +6120,104 @@ } } }, + "kpack.build.v1alpha2.ClusterBuildpack": { + "type": "object", + "required": [ + "spec", + "status" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + }, + "spec": { + "default": {}, + "$ref": "#/definitions/kpack.build.v1alpha2.ClusterBuildpackSpec" + }, + "status": { + "default": {}, + "$ref": "#/definitions/kpack.build.v1alpha2.ClusterBuildpackStatus" + } + } + }, + "kpack.build.v1alpha2.ClusterBuildpackList": { + "type": "object", + "required": [ + "metadata", + "items" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.build.v1alpha2.ClusterBuildpack" + } + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + } + }, + "kpack.build.v1alpha2.ClusterBuildpackSpec": { + "type": "object", + "properties": { + "serviceAccountRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ObjectReference" + }, + "source": { + "default": {}, + "x-kubernetes-list-type": "", + "$ref": "#/definitions/kpack.core.v1alpha1.ImageSource" + } + } + }, + "kpack.build.v1alpha2.ClusterBuildpackStatus": { + "type": "object", + "properties": { + "buildpacks": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackStatus" + }, + "x-kubernetes-list-type": "" + }, + "conditions": { + "description": "Conditions the latest available observations of a resource's current state.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.Condition" + }, + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge" + }, + "observedGeneration": { + "description": "ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.", + "type": "integer", + "format": "int64" + } + } + }, "kpack.build.v1alpha2.ClusterStack": { "type": "object", "required": [ @@ -6184,7 +6427,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.StoreImage" + "$ref": "#/definitions/kpack.core.v1alpha1.ImageSource" }, "x-kubernetes-list-type": "" } @@ -6197,7 +6440,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.StoreBuildpack" + "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackStatus" }, "x-kubernetes-list-type": "" }, @@ -6530,7 +6773,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.OrderEntry" + "$ref": "#/definitions/kpack.build.v1alpha2.BuilderOrderEntry" }, "x-kubernetes-list-type": "" }, @@ -6810,6 +7053,61 @@ } } }, + "kpack.core.v1alpha1.BuildpackStatus": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "api": { + "type": "string" + }, + "buildpackage": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackageInfo" + }, + "diffId": { + "type": "string" + }, + "digest": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "id": { + "type": "string", + "default": "" + }, + "order": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.OrderEntry" + }, + "x-kubernetes-list-type": "" + }, + "size": { + "type": "integer", + "format": "int64" + }, + "stacks": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackStack" + }, + "x-kubernetes-list-type": "" + }, + "storeImage": { + "default": {}, + "$ref": "#/definitions/kpack.core.v1alpha1.ImageSource" + }, + "version": { + "type": "string" + } + } + }, "kpack.core.v1alpha1.BuildpackageInfo": { "type": "object", "properties": { @@ -6892,6 +7190,14 @@ } } }, + "kpack.core.v1alpha1.ImageSource": { + "type": "object", + "properties": { + "image": { + "type": "string" + } + } + }, "kpack.core.v1alpha1.NotaryConfig": { "type": "object", "properties": { @@ -7085,69 +7391,6 @@ } } }, - "kpack.core.v1alpha1.StoreBuildpack": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "api": { - "type": "string" - }, - "buildpackage": { - "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackageInfo" - }, - "diffId": { - "type": "string" - }, - "digest": { - "type": "string" - }, - "homepage": { - "type": "string" - }, - "id": { - "type": "string", - "default": "" - }, - "order": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.OrderEntry" - }, - "x-kubernetes-list-type": "" - }, - "size": { - "type": "integer", - "format": "int64" - }, - "stacks": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.BuildpackStack" - }, - "x-kubernetes-list-type": "" - }, - "storeImage": { - "default": {}, - "$ref": "#/definitions/kpack.core.v1alpha1.StoreImage" - }, - "version": { - "type": "string" - } - } - }, - "kpack.core.v1alpha1.StoreImage": { - "type": "object", - "properties": { - "image": { - "type": "string" - } - } - }, "kpack.core.v1alpha1.VolatileTime": { "description": "VolatileTime wraps metav1.Time", "type": "object", diff --git a/pkg/openapi/openapi_generated.go b/pkg/openapi/openapi_generated.go index af752e37..0b126137 100644 --- a/pkg/openapi/openapi_generated.go +++ b/pkg/openapi/openapi_generated.go @@ -73,12 +73,21 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildStack": schema_pkg_apis_build_v1alpha2_BuildStack(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildStatus": schema_pkg_apis_build_v1alpha2_BuildStatus(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.Builder": schema_pkg_apis_build_v1alpha2_Builder(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderBuildpackRef": schema_pkg_apis_build_v1alpha2_BuilderBuildpackRef(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderList": schema_pkg_apis_build_v1alpha2_BuilderList(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderSpec": schema_pkg_apis_build_v1alpha2_BuilderSpec(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderStatus": schema_pkg_apis_build_v1alpha2_BuilderStatus(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.Buildpack": schema_pkg_apis_build_v1alpha2_Buildpack(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildpackList": schema_pkg_apis_build_v1alpha2_BuildpackList(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildpackSpec": schema_pkg_apis_build_v1alpha2_BuildpackSpec(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildpackStatus": schema_pkg_apis_build_v1alpha2_BuildpackStatus(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuilder": schema_pkg_apis_build_v1alpha2_ClusterBuilder(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuilderList": schema_pkg_apis_build_v1alpha2_ClusterBuilderList(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuilderSpec": schema_pkg_apis_build_v1alpha2_ClusterBuilderSpec(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpack": schema_pkg_apis_build_v1alpha2_ClusterBuildpack(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpackList": schema_pkg_apis_build_v1alpha2_ClusterBuildpackList(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpackSpec": schema_pkg_apis_build_v1alpha2_ClusterBuildpackSpec(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpackStatus": schema_pkg_apis_build_v1alpha2_ClusterBuildpackStatus(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterStack": schema_pkg_apis_build_v1alpha2_ClusterStack(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterStackList": schema_pkg_apis_build_v1alpha2_ClusterStackList(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterStackSpec": schema_pkg_apis_build_v1alpha2_ClusterStackSpec(ref), @@ -114,10 +123,12 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackMetadata": schema_pkg_apis_core_v1alpha1_BuildpackMetadata(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackRef": schema_pkg_apis_core_v1alpha1_BuildpackRef(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStack": schema_pkg_apis_core_v1alpha1_BuildpackStack(ref), + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus": schema_pkg_apis_core_v1alpha1_BuildpackStatus(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackageInfo": schema_pkg_apis_core_v1alpha1_BuildpackageInfo(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.CNBBinding": schema_pkg_apis_core_v1alpha1_CNBBinding(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition": schema_pkg_apis_core_v1alpha1_Condition(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Git": schema_pkg_apis_core_v1alpha1_Git(ref), + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource": schema_pkg_apis_core_v1alpha1_ImageSource(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.NotaryConfig": schema_pkg_apis_core_v1alpha1_NotaryConfig(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.NotarySecretRef": schema_pkg_apis_core_v1alpha1_NotarySecretRef(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.NotaryV1Config": schema_pkg_apis_core_v1alpha1_NotaryV1Config(ref), @@ -129,8 +140,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ResolvedSourceConfig": schema_pkg_apis_core_v1alpha1_ResolvedSourceConfig(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.SourceConfig": schema_pkg_apis_core_v1alpha1_SourceConfig(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Status": schema_pkg_apis_core_v1alpha1_Status(ref), - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreBuildpack": schema_pkg_apis_core_v1alpha1_StoreBuildpack(ref), - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreImage": schema_pkg_apis_core_v1alpha1_StoreImage(ref), "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.VolatileTime": schema_pkg_apis_core_v1alpha1_VolatileTime(ref), } } @@ -1214,7 +1223,7 @@ func schema_pkg_apis_build_v1alpha1_ClusterStoreSpec(ref common.ReferenceCallbac Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreImage"), + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource"), }, }, }, @@ -1224,7 +1233,7 @@ func schema_pkg_apis_build_v1alpha1_ClusterStoreSpec(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreImage"}, + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource"}, } } @@ -1273,7 +1282,7 @@ func schema_pkg_apis_build_v1alpha1_ClusterStoreStatus(ref common.ReferenceCallb Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreBuildpack"), + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus"), }, }, }, @@ -1283,7 +1292,7 @@ func schema_pkg_apis_build_v1alpha1_ClusterStoreStatus(ref common.ReferenceCallb }, }, Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreBuildpack"}, + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition"}, } } @@ -2483,6 +2492,93 @@ func schema_pkg_apis_build_v1alpha2_Builder(ref common.ReferenceCallback) common } } +func schema_pkg_apis_build_v1alpha2_BuilderBuildpackRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "version": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "optional": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "namespace": { + SchemaProps: spec.SchemaProps{ + Description: "Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + Type: []string{"string"}, + Format: "", + }, + }, + "uid": { + SchemaProps: spec.SchemaProps{ + Description: "UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "API version of the referent.", + Type: []string{"string"}, + Format: "", + }, + }, + "resourceVersion": { + SchemaProps: spec.SchemaProps{ + Description: "Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + Type: []string{"string"}, + Format: "", + }, + }, + "fieldPath": { + SchemaProps: spec.SchemaProps{ + Description: "If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: \"spec.containers{name}\" (where \"name\" refers to the name of the container that triggered the event) or if no container name is specified \"spec.containers[2]\" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object.", + Type: []string{"string"}, + Format: "", + }, + }, + "image": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"id"}, + }, + }, + } +} + func schema_pkg_apis_build_v1alpha2_BuilderList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2567,7 +2663,7 @@ func schema_pkg_apis_build_v1alpha2_BuilderSpec(ref common.ReferenceCallback) co Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry"), + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderOrderEntry"), }, }, }, @@ -2577,7 +2673,7 @@ func schema_pkg_apis_build_v1alpha2_BuilderSpec(ref common.ReferenceCallback) co }, }, Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry", "k8s.io/api/core/v1.ObjectReference"}, + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderOrderEntry", "k8s.io/api/core/v1.ObjectReference"}, } } @@ -2678,6 +2774,184 @@ func schema_pkg_apis_build_v1alpha2_BuilderStatus(ref common.ReferenceCallback) } } +func schema_pkg_apis_build_v1alpha2_Buildpack(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildpackSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildpackStatus"), + }, + }, + }, + Required: []string{"spec", "status"}, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildpackSpec", "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuildpackStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_build_v1alpha2_BuildpackList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.Buildpack"), + }, + }, + }, + }, + }, + }, + Required: []string{"metadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.Buildpack", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_build_v1alpha2_BuildpackSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "image": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "serviceAccountName": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_build_v1alpha2_BuildpackStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "observedGeneration": { + SchemaProps: spec.SchemaProps{ + Description: "ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.", + Type: []string{"integer"}, + Format: "int64", + }, + }, + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Conditions the latest available observations of a resource's current state.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition"), + }, + }, + }, + }, + }, + "buildpacks": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition"}, + } +} + func schema_pkg_apis_build_v1alpha2_ClusterBuilder(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2797,7 +3071,197 @@ func schema_pkg_apis_build_v1alpha2_ClusterBuilderSpec(ref common.ReferenceCallb Ref: ref("k8s.io/api/core/v1.ObjectReference"), }, }, - "order": { + "order": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderOrderEntry"), + }, + }, + }, + }, + }, + "serviceAccountRef": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.ObjectReference"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderOrderEntry", "k8s.io/api/core/v1.ObjectReference"}, + } +} + +func schema_pkg_apis_build_v1alpha2_ClusterBuildpack(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpackSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpackStatus"), + }, + }, + }, + Required: []string{"spec", "status"}, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpackSpec", "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpackStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_build_v1alpha2_ClusterBuildpackList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpack"), + }, + }, + }, + }, + }, + }, + Required: []string{"metadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.ClusterBuildpack", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_build_v1alpha2_ClusterBuildpackSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "source": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "", + }, + }, + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource"), + }, + }, + "serviceAccountRef": { + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/api/core/v1.ObjectReference"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource", "k8s.io/api/core/v1.ObjectReference"}, + } +} + +func schema_pkg_apis_build_v1alpha2_ClusterBuildpackStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "observedGeneration": { + SchemaProps: spec.SchemaProps{ + Description: "ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.", + Type: []string{"integer"}, + Format: "int64", + }, + }, + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Conditions the latest available observations of a resource's current state.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition"), + }, + }, + }, + }, + }, + "buildpacks": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ "x-kubernetes-list-type": "", @@ -2809,23 +3273,17 @@ func schema_pkg_apis_build_v1alpha2_ClusterBuilderSpec(ref common.ReferenceCallb Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry"), + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus"), }, }, }, }, }, - "serviceAccountRef": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.ObjectReference"), - }, - }, }, }, }, Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry", "k8s.io/api/core/v1.ObjectReference"}, + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition"}, } } @@ -3206,7 +3664,7 @@ func schema_pkg_apis_build_v1alpha2_ClusterStoreSpec(ref common.ReferenceCallbac Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreImage"), + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource"), }, }, }, @@ -3221,7 +3679,7 @@ func schema_pkg_apis_build_v1alpha2_ClusterStoreSpec(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreImage", "k8s.io/api/core/v1.ObjectReference"}, + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource", "k8s.io/api/core/v1.ObjectReference"}, } } @@ -3270,7 +3728,7 @@ func schema_pkg_apis_build_v1alpha2_ClusterStoreStatus(ref common.ReferenceCallb Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreBuildpack"), + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus"), }, }, }, @@ -3280,7 +3738,7 @@ func schema_pkg_apis_build_v1alpha2_ClusterStoreStatus(ref common.ReferenceCallb }, }, Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreBuildpack"}, + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStatus", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.Condition"}, } } @@ -3914,7 +4372,7 @@ func schema_pkg_apis_build_v1alpha2_NamespacedBuilderSpec(ref common.ReferenceCa Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry"), + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderOrderEntry"), }, }, }, @@ -3936,7 +4394,7 @@ func schema_pkg_apis_build_v1alpha2_NamespacedBuilderSpec(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry", "k8s.io/api/core/v1.ObjectReference"}, + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderOrderEntry", "k8s.io/api/core/v1.ObjectReference"}, } } @@ -4412,6 +4870,112 @@ func schema_pkg_apis_core_v1alpha1_BuildpackStack(ref common.ReferenceCallback) } } +func schema_pkg_apis_core_v1alpha1_BuildpackStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "version": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "buildpackage": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackageInfo"), + }, + }, + "storeImage": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource"), + }, + }, + "diffId": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "digest": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "size": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + "api": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "homepage": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "order": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry"), + }, + }, + }, + }, + }, + "stacks": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStack"), + }, + }, + }, + }, + }, + }, + Required: []string{"id"}, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStack", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackageInfo", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.ImageSource", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry"}, + } +} + func schema_pkg_apis_core_v1alpha1_BuildpackageInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -4506,7 +5070,7 @@ func schema_pkg_apis_core_v1alpha1_Condition(ref common.ReferenceCallback) commo SchemaProps: spec.SchemaProps{ Description: "LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant).", Default: map[string]interface{}{}, - Type: []string{"string"}, Format: "", + Type: []string{"string"}, Format: "", }, }, "reason": { @@ -4559,6 +5123,24 @@ func schema_pkg_apis_core_v1alpha1_Git(ref common.ReferenceCallback) common.Open } } +func schema_pkg_apis_core_v1alpha1_ImageSource(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "image": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_core_v1alpha1_NotaryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -4926,130 +5508,6 @@ func schema_pkg_apis_core_v1alpha1_Status(ref common.ReferenceCallback) common.O } } -func schema_pkg_apis_core_v1alpha1_StoreBuildpack(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "id": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "version": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "buildpackage": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackageInfo"), - }, - }, - "storeImage": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreImage"), - }, - }, - "diffId": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "digest": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "size": { - SchemaProps: spec.SchemaProps{ - Type: []string{"integer"}, - Format: "int64", - }, - }, - "api": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "homepage": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "order": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry"), - }, - }, - }, - }, - }, - "stacks": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStack"), - }, - }, - }, - }, - }, - }, - Required: []string{"id"}, - }, - }, - Dependencies: []string{ - "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackStack", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.BuildpackageInfo", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.OrderEntry", "github.com/pivotal/kpack/pkg/apis/core/v1alpha1.StoreImage"}, - } -} - -func schema_pkg_apis_core_v1alpha1_StoreImage(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "image": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - func schema_pkg_apis_core_v1alpha1_VolatileTime(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ From fb53c4b90b4e98c62c4cf5c7632462c49fbc51b9 Mon Sep 17 00:00:00 2001 From: Nicholas Carlson Date: Wed, 22 Mar 2023 10:23:13 -0600 Subject: [PATCH 27/39] Write .docker config to tmp directory instead of root --- cmd/completion/main.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/cmd/completion/main.go b/cmd/completion/main.go index 059394aa..8c955743 100644 --- a/cmd/completion/main.go +++ b/cmd/completion/main.go @@ -99,16 +99,6 @@ func main() { } } - homeDir, err := os.UserHomeDir() - if err != nil { - log.Fatal(errors.Wrapf(err, "error obtaining home directory")) - } - - err = creds.Save(filepath.Join(homeDir, ".docker", "config.json")) - if err != nil { - log.Fatal(errors.Wrapf(err, "error writing docker creds")) - } - keychain := authn.NewMultiKeychain(k8sNodeKeychain, creds) metadataRetriever := cnb.RemoteMetadataRetriever{ @@ -140,6 +130,21 @@ func main() { } if hasCosign() || notaryV1URL != "" { + tempDir, err := os.MkdirTemp("", "") + if err != nil { + log.Fatal(errors.Wrapf(err, "error creating temprary directory")) + } + + err = creds.Save(filepath.Join(tempDir, ".docker", "config.json")) + if err != nil { + log.Fatal(errors.Wrapf(err, "error writing docker creds")) + } + + err = os.Setenv("DOCKER_CONFIG", filepath.Join(tempDir, ".docker")) + if err != nil { + log.Fatal(errors.Wrapf(err, "error setting DOCKER_CONFIG env")) + } + if err := signImage(report, keychain); err != nil { log.Fatal(err) } From 99d83d30adc1019f45ba97d8c3911cd576254b47 Mon Sep 17 00:00:00 2001 From: Tom Kennedy Date: Thu, 23 Mar 2023 10:19:44 -0400 Subject: [PATCH 28/39] Add codegen for BuilderOrderEntry --- api/openapi-spec/swagger.json | 13 ++++++++++ pkg/apis/build/v1alpha2/builder_types.go | 1 + pkg/openapi/openapi_generated.go | 33 ++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 36e01805..3c9f697b 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -5863,6 +5863,19 @@ } } }, + "kpack.build.v1alpha2.BuilderOrderEntry": { + "type": "object", + "properties": { + "group": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/kpack.build.v1alpha2.BuilderBuildpackRef" + }, + "x-kubernetes-list-type": "" + } + } + }, "kpack.build.v1alpha2.BuilderSpec": { "type": "object", "properties": { diff --git a/pkg/apis/build/v1alpha2/builder_types.go b/pkg/apis/build/v1alpha2/builder_types.go index 25de1b93..b81ae402 100644 --- a/pkg/apis/build/v1alpha2/builder_types.go +++ b/pkg/apis/build/v1alpha2/builder_types.go @@ -35,6 +35,7 @@ type BuilderSpec struct { Order []BuilderOrderEntry `json:"order,omitempty"` } +// +k8s:openapi-gen=true type BuilderOrderEntry struct { // +listType Group []BuilderBuildpackRef `json:"group,omitempty"` diff --git a/pkg/openapi/openapi_generated.go b/pkg/openapi/openapi_generated.go index 0b126137..34164439 100644 --- a/pkg/openapi/openapi_generated.go +++ b/pkg/openapi/openapi_generated.go @@ -75,6 +75,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.Builder": schema_pkg_apis_build_v1alpha2_Builder(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderBuildpackRef": schema_pkg_apis_build_v1alpha2_BuilderBuildpackRef(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderList": schema_pkg_apis_build_v1alpha2_BuilderList(ref), + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderOrderEntry": schema_pkg_apis_build_v1alpha2_BuilderOrderEntry(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderSpec": schema_pkg_apis_build_v1alpha2_BuilderSpec(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderStatus": schema_pkg_apis_build_v1alpha2_BuilderStatus(ref), "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.Buildpack": schema_pkg_apis_build_v1alpha2_Buildpack(ref), @@ -2627,6 +2628,38 @@ func schema_pkg_apis_build_v1alpha2_BuilderList(ref common.ReferenceCallback) co } } +func schema_pkg_apis_build_v1alpha2_BuilderOrderEntry(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "group": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderBuildpackRef"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/pivotal/kpack/pkg/apis/build/v1alpha2.BuilderBuildpackRef"}, + } +} + func schema_pkg_apis_build_v1alpha2_BuilderSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ From f6d01e59340c8773b59f19f81a60a5177edb38e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 16:18:37 +0000 Subject: [PATCH 29/39] Bump github.com/stretchr/testify from 1.8.0 to 1.8.2 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.0 to 1.8.2. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.0...v1.8.2) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index b1d0e68a..af35b9bb 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/sigstore/cosign v1.13.1 github.com/sirupsen/logrus v1.9.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.2 github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f github.com/vdemeester/k8s-pkg-credentialprovider v1.22.4 github.com/whilp/git-urls v1.0.0 diff --git a/go.sum b/go.sum index 3681d254..65a3443d 100644 --- a/go.sum +++ b/go.sum @@ -1417,6 +1417,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1426,8 +1427,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= From 77b0924bacf456dba7f946de340d69f5dbfaf409 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 19:35:14 +0000 Subject: [PATCH 30/39] Bump github.com/google/go-containerregistry from 0.12.1 to 0.14.0 Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.12.1 to 0.14.0. - [Release notes](https://github.com/google/go-containerregistry/releases) - [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml) - [Commits](https://github.com/google/go-containerregistry/compare/v0.12.1...v0.14.0) --- updated-dependencies: - dependency-name: github.com/google/go-containerregistry dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 39 ++++++++++++++++--------------- go.sum | 73 ++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/go.mod b/go.mod index af35b9bb..de829f85 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/buildpacks/lifecycle v0.14.1 github.com/ghodss/yaml v1.0.0 github.com/google/go-cmp v0.5.9 - github.com/google/go-containerregistry v0.12.1 + github.com/google/go-containerregistry v0.14.0 github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20220413173345-f1b065c6cb3d github.com/libgit2/git2go/v33 v33.0.4 github.com/matthewmcnew/archtest v0.0.0-20191014222827-a111193b50ad @@ -27,6 +27,7 @@ require ( github.com/whilp/git-urls v1.0.0 go.uber.org/zap v1.23.0 golang.org/x/crypto v0.7.0 + golang.org/x/net v0.8.0 golang.org/x/sync v0.1.0 k8s.io/api v0.24.8 k8s.io/apimachinery v0.24.8 @@ -38,7 +39,8 @@ require ( require ( bitbucket.org/creachadair/shell v0.0.7 // indirect - cloud.google.com/go/compute v1.10.0 // indirect + cloud.google.com/go/compute v1.18.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect cuelang.org/go v0.4.3 // indirect @@ -102,7 +104,7 @@ require ( github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect github.com/cockroachdb/apd/v2 v2.0.1 // indirect github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect - github.com/containerd/stargz-snapshotter/estargz v0.12.1 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect github.com/coreos/go-oidc/v3 v3.4.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect @@ -110,9 +112,9 @@ require ( github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect - github.com/docker/cli v20.10.20+incompatible // indirect + github.com/docker/cli v23.0.1+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.20+incompatible // indirect + github.com/docker/docker v23.0.1+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go-connections v0.4.0 // indirect @@ -153,7 +155,7 @@ require ( github.com/golang/glog v1.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/certificate-transparency-go v1.1.3 // indirect @@ -164,7 +166,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/trillian v1.5.0 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect @@ -177,7 +179,7 @@ require ( github.com/heroku/color v0.0.6 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect github.com/jhump/protoreflect v1.13.0 // indirect github.com/jinzhu/gorm v1.9.12 // indirect @@ -186,7 +188,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.15.11 // indirect + github.com/klauspost/compress v1.16.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/letsencrypt/boulder v0.0.0-20220929215747-76583552c2be // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -234,7 +236,7 @@ require ( github.com/soheilhy/cmux v0.1.5 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.6.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/viper v1.13.0 // indirect github.com/spiffe/go-spiffe/v2 v2.1.1 // indirect @@ -269,7 +271,7 @@ require ( go.etcd.io/etcd/tests/v3 v3.6.0-alpha.0 // indirect go.etcd.io/etcd/v3 v3.6.0-alpha.0 // indirect go.mongodb.org/mongo-driver v1.10.0 // indirect - go.opencensus.io v0.23.0 // indirect + go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 // indirect go.opentelemetry.io/otel v1.7.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect @@ -282,20 +284,19 @@ require ( go.uber.org/automaxprocs v1.5.1 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/exp v0.0.0-20220823124025-807a23277127 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/oauth2 v0.1.0 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sys v0.6.0 // indirect golang.org/x/term v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/tools v0.7.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect - google.golang.org/api v0.99.0 // indirect + google.golang.org/api v0.108.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e // indirect - google.golang.org/grpc v1.50.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2 // indirect + google.golang.org/grpc v1.51.0 // indirect + google.golang.org/protobuf v1.29.0 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 65a3443d..f7923f1d 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,10 @@ cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6m cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.5.0/go.mod h1:RGUNM0FFAVkYA94BLTxoXBgfIyY1Riq67TwaBXH0lwc= @@ -399,8 +401,8 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= -github.com/containerd/stargz-snapshotter/estargz v0.12.1 h1:+7nYmHJb0tEkcRaAW+MHqoKaJYZmkikupxCqVtmPuY0= -github.com/containerd/stargz-snapshotter/estargz v0.12.1/go.mod h1:12VUuCq3qPq4y8yUW+l5w3+oXV3cx2Po3KSe/SmPGqw= +github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= +github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -449,13 +451,13 @@ github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/docker/cli v20.10.20+incompatible h1:lWQbHSHUFs7KraSN2jOJK7zbMS2jNCHI4mt4xUFUVQ4= -github.com/docker/cli v20.10.20+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy13Ul2Q5oM= +github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.20+incompatible h1:kH9tx6XO+359d+iAkumyKDc5Q1kOwPuAUaeri48nD6E= -github.com/docker/docker v20.10.20+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= +github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= @@ -715,8 +717,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -755,8 +758,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.12.1 h1:W1mzdNUTx4Zla4JaixCRLhORcR7G6KxE5hHl5fkPsp8= -github.com/google/go-containerregistry v0.12.1/go.mod h1:sdIK+oHQO7B93xI8UweYdl887YhuIwg9vz8BSLH3+8k= +github.com/google/go-containerregistry v0.14.0 h1:z58vMqHxuwvAsVwvKEkmVBz2TlgBgH5k6koEXBtlYkw= +github.com/google/go-containerregistry v0.14.0/go.mod h1:aiJ2fp/SXvkWgmYHioXnbMdlgB8eXiiYOY55gfN91Wk= github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20220413173345-f1b065c6cb3d h1:lW/Wt1DLz5EDvR7h3+wLaE7Ug5c2SafJC9uQiAUCmoY= github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20220413173345-f1b065c6cb3d/go.mod h1:gm/Zjh0iiPBfwgDIYgHJCRxaGzBZu1njCgwX1EmC1Tw= github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20220301182634-bfe2ffc6b6bd h1:DVnBwEU/77+h/Celwk8RLwnYiuaIdBv2gguN3xHfcJM= @@ -814,8 +817,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww= github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -825,7 +828,7 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.5.1 h1:kBRZU0PSuI7PspsSb/ChWoVResUcwNVIdpB049pKTiw= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= @@ -934,8 +937,9 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add h1:DAh7mHiRT7wc6kKepYdCpH16ElPciMPQWJaJ7H3l/ng= github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add/go.mod h1:DQI8vlV6h6qSY/tCOoYKtxjWrkyiNpJ3WTV/WoBllmQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= @@ -1002,8 +1006,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -1386,8 +1390,8 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= -github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= @@ -1428,6 +1432,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -1590,8 +1595,9 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib v1.6.0/go.mod h1:FlyPNX9s4U6MCsWEc5YAK4KzKNHFDsjrDUZijJiXvy8= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= @@ -1733,8 +1739,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1840,8 +1846,8 @@ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= -golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2085,8 +2091,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2148,8 +2154,8 @@ google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69 google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.99.0 h1:tsBtOIklCE2OFxhmcYSVqGwSAN/Y897srxmcvAQnwK8= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.108.0 h1:WVBc/faN0DkKtR43Q/7+tPny9ZoLZdIiAyG5Q9vFClg= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2267,8 +2273,8 @@ google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e h1:halCgTFuLWDRD61piiNSxPsARANGD3Xl16hPrLgLiIg= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2 h1:O97sLx/Xmb/KIZHB/2/BzofxBs5QmmR0LcihPtllmbc= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -2310,8 +2316,8 @@ google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.50.0 h1:fPVVDxY9w++VjTZsYvXWqEf9Rqar/e+9zYfxKK+W+YU= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= google.golang.org/grpc/examples v0.0.0-20201130180447-c456688b1860/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= @@ -2330,8 +2336,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.0 h1:44S3JjaKmLEE4YIkjzexaP+NzZsudE3Zin5Njn/pYX0= +google.golang.org/protobuf v1.29.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc= From 5482fb0ef3ca5970f2b88bd28d0bdd7f1d12642c Mon Sep 17 00:00:00 2001 From: Nicholas Carlson Date: Fri, 3 Mar 2023 03:52:50 -0700 Subject: [PATCH 31/39] Swapping git2go for go-git - To allow for building kpack without relying on custom buildpacks to install libgit2 - Go-git now supports Azure DevOps git repos (which is why we moved from go-git to git2go previously) --- go.mod | 31 +++++-- go.sum | 94 ++++++++++++++----- pkg/git/certificate_check_callback.go | 46 ---------- pkg/git/fetch.go | 98 ++++++++++++-------- pkg/git/fetch_test.go | 95 +++++++++---------- pkg/git/git_keychain.go | 127 +++++++++++++++++--------- pkg/git/git_keychain_test.go | 33 +++---- pkg/git/k8s_git_keychain.go | 7 ++ pkg/git/k8s_git_keychain_test.go | 38 ++++---- pkg/git/remote_git_resolver.go | 89 ++++++++++++------ 10 files changed, 392 insertions(+), 266 deletions(-) delete mode 100644 pkg/git/certificate_check_callback.go diff --git a/go.mod b/go.mod index af35b9bb..dcd23245 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,11 @@ require ( github.com/buildpacks/imgutil v0.0.0-20220527150729-7a271a852e31 github.com/buildpacks/lifecycle v0.14.1 github.com/ghodss/yaml v1.0.0 + github.com/go-git/go-billy/v5 v5.4.0 + github.com/go-git/go-git/v5 v5.6.0 github.com/google/go-cmp v0.5.9 github.com/google/go-containerregistry v0.12.1 github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20220413173345-f1b065c6cb3d - github.com/libgit2/git2go/v33 v33.0.4 github.com/matthewmcnew/archtest v0.0.0-20191014222827-a111193b50ad github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b github.com/pkg/errors v0.9.1 @@ -26,7 +27,7 @@ require ( github.com/vdemeester/k8s-pkg-credentialprovider v1.22.4 github.com/whilp/git-urls v1.0.0 go.uber.org/zap v1.23.0 - golang.org/x/crypto v0.7.0 + golang.org/x/crypto v0.3.0 golang.org/x/sync v0.1.0 k8s.io/api v0.24.8 k8s.io/apimachinery v0.24.8 @@ -57,7 +58,9 @@ require ( github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect github.com/ThalesIgnite/crypto11 v1.2.5 // indirect + github.com/acomagu/bufpipe v1.0.3 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect @@ -98,6 +101,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20220327082430-c57b701bfc08 // indirect github.com/clbanning/mxj/v2 v2.5.6 // indirect + github.com/cloudflare/circl v1.1.0 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect github.com/cockroachdb/apd/v2 v2.0.1 // indirect @@ -120,6 +124,7 @@ require ( github.com/dustin/go-humanize v1.0.0 // indirect github.com/emicklei/go-restful v2.16.0+incompatible // indirect github.com/emicklei/proto v1.6.15 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect @@ -127,6 +132,7 @@ require ( github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fullstorydev/grpcurl v1.8.7 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect + github.com/go-git/gcfg v1.5.0 // indirect github.com/go-kit/log v0.2.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -175,9 +181,10 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/heroku/color v0.0.6 // indirect - github.com/imdario/mergo v0.3.12 // indirect + github.com/imdario/mergo v0.3.13 // indirect github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect github.com/jhump/protoreflect v1.13.0 // indirect github.com/jinzhu/gorm v1.9.12 // indirect @@ -186,6 +193,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.15.11 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/letsencrypt/boulder v0.0.0-20220929215747-76583552c2be // indirect @@ -213,6 +221,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.13.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect @@ -226,10 +235,12 @@ require ( github.com/sassoftware/relic v0.0.0-20210427151427-dfb082b79b74 // indirect github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect github.com/segmentio/ksuid v1.0.4 // indirect + github.com/sergi/go-diff v1.2.0 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/sigstore/fulcio v0.6.0 // indirect github.com/sigstore/rekor v0.12.1-0.20220915152154-4bb6f441c1b2 // indirect github.com/sigstore/sigstore v1.4.4 // indirect + github.com/skeema/knownhosts v1.1.0 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/spf13/afero v1.8.2 // indirect @@ -251,6 +262,7 @@ require ( github.com/urfave/cli v1.22.7 // indirect github.com/vbatts/tar-split v0.11.2 // indirect github.com/xanzy/go-gitlab v0.73.1 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect @@ -282,14 +294,14 @@ require ( go.uber.org/automaxprocs v1.5.1 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/exp v0.0.0-20220823124025-807a23277127 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/mod v0.6.0 // indirect + golang.org/x/net v0.2.0 // indirect golang.org/x/oauth2 v0.1.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.2.0 // indirect + golang.org/x/text v0.4.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/tools v0.2.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/api v0.99.0 // indirect google.golang.org/appengine v1.6.7 // indirect @@ -301,6 +313,7 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.24.4 // indirect diff --git a/go.sum b/go.sum index 65a3443d..b0148066 100644 --- a/go.sum +++ b/go.sum @@ -160,6 +160,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d h1:hi6J4K6DKrR4/ljxn6SF6nURyu785wKMuQcjt7H3VCQ= @@ -169,6 +171,8 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E= github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= @@ -218,6 +222,8 @@ github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6q github.com/aliyun/credentials-go v1.2.3 h1:Vmodnr52Rz1mcbwn0kzMhLRKb6soizewuKXdfZiNemU= github.com/aliyun/credentials-go v1.2.3/go.mod h1:/KowD1cfGSLrLsH28Jr8W+xwoId0ywIy5lNzDz6O1vw= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= @@ -240,6 +246,7 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a h1:pv34s756C4pEXnjgPfGYgdhg/ZdajGhyOvzx8k+23nw= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -340,6 +347,7 @@ github.com/buildpacks/imgutil v0.0.0-20220527150729-7a271a852e31 h1:EKj9YzFFAO5y github.com/buildpacks/imgutil v0.0.0-20220527150729-7a271a852e31/go.mod h1:SI90cWVEm7VmN9d/RLpiuchointjHNFRsQ1mFPbQVI4= github.com/buildpacks/lifecycle v0.14.1 h1:CkMsUbotZvru+VOTn08BWPbJRZnAx6Xx2yQYoqVLOW8= github.com/buildpacks/lifecycle v0.14.1/go.mod h1:l8p/hrNzwq1Dr9JEblxC8ZHOLhJPCBFOPCwyo0Z66/Y= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytecodealliance/wasmtime-go v1.0.0 h1:9u9gqaUiaJeN5IoD1L7egD8atOnTGyJcNp8BhkL9cUU= github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= @@ -373,6 +381,8 @@ github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= +github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -486,6 +496,8 @@ github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQm github.com/emicklei/proto v1.6.15 h1:XbpwxmuOPrdES97FrSfpyy67SSCV/wBIKXqgJzh6hNw= github.com/emicklei/proto v1.6.15/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -542,8 +554,19 @@ github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49P github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.4.0 h1:Vaw7LaSTRJOUric7pe4vnzBSgyuf2KrLsu2Y4ZpQBDE= +github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= +github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= +github.com/go-git/go-git/v5 v5.6.0 h1:JvBdYfcttd+0kdpuWO7KTu0FYgCf5W0t5VwkWGobaa4= +github.com/go-git/go-git/v5 v5.6.0/go.mod h1:6nmJ0tJ3N4noMV1Omv7rC5FG3/o8Cm51TB4CJp7mRmE= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -798,8 +821,6 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/trillian v1.3.14-0.20210409160123-c5ea3abd4a41/go.mod h1:1dPv0CUjNQVFEDuAUFhZql16pw/VlPgaX8qj+g5pVzQ= github.com/google/trillian v1.3.14-0.20210511103300-67b5f349eefa/go.mod h1:s4jO3Ai4NSvxucdvqUHON0bCqJyoya32eNw6XJwsmNc= @@ -929,8 +950,8 @@ github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add h1:DAh7mHiRT7wc6kKepYdCpH16ElPciMPQWJaJ7H3l/ng= github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add/go.mod h1:DQI8vlV6h6qSY/tCOoYKtxjWrkyiNpJ3WTV/WoBllmQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -938,11 +959,13 @@ github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7P github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7PDk6RgkP+A/SFfUD0ZR/AgG6SpRNEDKZy8= github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU= github.com/jellydator/ttlcache/v2 v2.11.1 h1:AZGME43Eh2Vv3giG6GeqeLeFXxwxn1/qHItqWZl6U64= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= @@ -997,6 +1020,8 @@ github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0Lh github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -1030,8 +1055,6 @@ github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTRe github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libgit2/git2go/v33 v33.0.4 h1:37xovFBzibhDEdQRLbfWwx3a44JhOIY06UICn2teenc= -github.com/libgit2/git2go/v33 v33.0.4/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linkedin/goavro v2.1.0+incompatible/go.mod h1:bBCwI2eGYpUI/4820s67MElg9tdeLbINjLjiM2xZFYM= @@ -1050,6 +1073,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matthewmcnew/archtest v0.0.0-20191014222827-a111193b50ad h1:uJ70JGeczglS1K//Rsi2+7EryfuJTEL23a5pYI6TpkA= github.com/matthewmcnew/archtest v0.0.0-20191014222827-a111193b50ad/go.mod h1:rcTN3gxjbgtNw/OIFSR8KQMx1wtwk8i1L9JmZTTjTM4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -1109,6 +1134,7 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= @@ -1218,6 +1244,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1331,6 +1359,7 @@ github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= @@ -1353,6 +1382,8 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= +github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1488,6 +1519,8 @@ github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfD github.com/xanzy/go-gitlab v0.73.1 h1:UMagqUZLJdjss1SovIC+kJCH4k2AZWXl58gJd38Y/hI= github.com/xanzy/go-gitlab v0.73.1/go.mod h1:d/a0vswScO7Agg1CZNz15Ic6SSvBG9vfw8egL99t4kA= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= @@ -1515,6 +1548,7 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.1.0/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0= github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g= github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= @@ -1653,6 +1687,7 @@ go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= +golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1678,7 +1713,6 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1689,10 +1723,13 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1733,8 +1770,9 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1810,9 +1848,11 @@ golang.org/x/net v0.0.0-20220421235706-1d1ef9303861/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1856,6 +1896,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1920,7 +1961,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1969,17 +2009,23 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1989,8 +2035,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2085,8 +2131,9 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2374,6 +2421,7 @@ gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQb gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -2389,6 +2437,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= @@ -2465,6 +2514,7 @@ knative.dev/pkg v0.0.0-20221005141429-8cacac2ea6d7 h1:HJwBicHmX0/ObW7QV6Uhx5FXeT knative.dev/pkg v0.0.0-20221005141429-8cacac2ea6d7/go.mod h1:EyxMA6/QJ4ejJ5GhWc6lx5W4bj64rPNS9LHywvHrhPI= pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= diff --git a/pkg/git/certificate_check_callback.go b/pkg/git/certificate_check_callback.go deleted file mode 100644 index 1cf3b837..00000000 --- a/pkg/git/certificate_check_callback.go +++ /dev/null @@ -1,46 +0,0 @@ -package git - -import ( - git2go "github.com/libgit2/git2go/v33" - "github.com/pkg/errors" -) - -func certificateCheckCallback() git2go.CertificateCheckCallback { - return func(cert *git2go.Certificate, valid bool, hostname string) error { - if valid { - return nil - } - - if cert.Kind == git2go.CertificateX509 { - if cert.X509 != nil { - err := cert.X509.VerifyHostname(hostname) - if err != nil { - return errors.Wrap(err, "host name could not be verified") - } - } - } else if cert.Kind == git2go.CertificateHostkey { - if cert.Hostkey.Kind == git2go.HostkeyMD5 { - if !isByteArrayEmpty(cert.Hostkey.HashMD5[:]) { - return errors.New("invalid host key MD5") - } - } else if cert.Hostkey.Kind == git2go.HostkeySHA1 { - if !isByteArrayEmpty(cert.Hostkey.HashSHA1[:]) { - return errors.New("invalid host key SHA1") - } - } - } - - return nil - } - -} - -func isByteArrayEmpty(byteArray []byte) bool { - isEmpty := true - for _, v := range byteArray { - if v != 0 { - isEmpty = false - } - } - return isEmpty -} diff --git a/pkg/git/fetch.go b/pkg/git/fetch.go index 976f4c56..84cc1c31 100644 --- a/pkg/git/fetch.go +++ b/pkg/git/fetch.go @@ -1,12 +1,16 @@ package git import ( + "github.com/BurntSushi/toml" + gogit "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "log" "os" "path" - "github.com/BurntSushi/toml" - git2go "github.com/libgit2/git2go/v33" + // import RemoteConfig + "github.com/go-git/go-git/v5/config" + "github.com/pkg/errors" ) @@ -18,56 +22,59 @@ type Fetcher struct { func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error { f.Logger.Printf("Cloning %q @ %q...", gitURL, gitRevision) - repository, err := git2go.InitRepository(dir, false) + // Initialize a repository in the directory using gogit.Init + repository, err := gogit.PlainInit(dir, false) if err != nil { return errors.Wrap(err, "initializing repo") } - defer repository.Free() - remote, err := repository.Remotes.CreateWithOptions(parseURL(gitURL), &git2go.RemoteCreateOptions{ - Name: "origin", - Flags: git2go.RemoteCreateSkipInsteadof, + remote, err := repository.CreateRemote(&config.RemoteConfig{ + Name: "origin", + URLs: []string{gitURL}, }) if err != nil { return errors.Wrap(err, "creating remote") } - defer remote.Free() - err = remote.Fetch([]string{"refs/*:refs/*"}, &git2go.FetchOptions{ - DownloadTags: git2go.DownloadTagsAll, - RemoteCallbacks: git2go.RemoteCallbacks{ - CredentialsCallback: keychainAsCredentialsCallback(f.Keychain), - CertificateCheckCallback: certificateCheckCallback(), + err = remote.Fetch(&gogit.FetchOptions{ + RefSpecs: []config.RefSpec{ + config.RefSpec("refs/*:refs/*"), }, - ProxyOptions: git2go.ProxyOptions{ - Type: git2go.ProxyTypeAuto, - }, - }, "") + Auth: nil, + Tags: gogit.AllTags, + RemoteName: defaultRemote, + }) if err != nil { return errors.Wrap(err, "fetching remote") } - oid, err := resolveRevision(repository, gitRevision) + hash, err := resolveRevision(repository, gitRevision) if err != nil { - return err + return errors.Wrap(err, "resolving revision") } - commit, err := repository.LookupCommit(oid) + // Look up the commit using the hash + commit, err := repository.CommitObject(*hash) if err != nil { return errors.Wrap(err, "looking up commit") } - err = repository.SetHeadDetached(commit.Id()) + worktree, err := repository.Worktree() if err != nil { - return errors.Wrap(err, "setting head detached") + return errors.Wrap(err, "getting worktree") } - err = repository.CheckoutHead(&git2go.CheckoutOpts{ - Strategy: git2go.CheckoutForce, - }) + + err = worktree.Checkout(&gogit.CheckoutOptions{}) if err != nil { - return errors.Wrap(err, "checkout head") + return errors.Wrap(err, "checking out blank") } + err = worktree.Checkout(&gogit.CheckoutOptions{ + Hash: plumbing.NewHash(hash.String()), + Create: false, + }) + + // Write the git revision to the metadata directory projectMetadataFile, err := os.Create(path.Join(metadataDir, "project-metadata.toml")) if err != nil { return errors.Wrapf(err, "invalid metadata destination '%s/project-metadata.toml' for git repository: %s", metadataDir, gitURL) @@ -82,7 +89,7 @@ func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error { Revision: gitRevision, }, Version: version{ - Commit: commit.Id().String(), + Commit: commit.Hash.String(), }, }, } @@ -94,23 +101,42 @@ func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error { return nil } -func resolveRevision(repository *git2go.Repository, gitRevision string) (*git2go.Oid, error) { - ref, err := repository.References.Dwim(gitRevision) +// Implement resolveRevision and return a plumbing.Hash and error +func resolveRevision(repository *gogit.Repository, gitRevision string) (*plumbing.Hash, error) { + ref, err := repository.ResolveRevision(plumbing.Revision(gitRevision)) if err != nil { return resolveCommit(gitRevision) } - - return ref.Target(), nil + return ref, nil } -func resolveCommit(gitRevision string) (*git2go.Oid, error) { - oid, err := git2go.NewOid(gitRevision) - if err != nil { - return nil, errors.Errorf("could not find reference: %s", gitRevision) //invalid oid +func resolveCommit(gitRevision string) (*plumbing.Hash, error) { + // Use plumbing.NewHash to create a new hash + hash := plumbing.NewHash(gitRevision) + // if hash is empty + if hash == plumbing.ZeroHash { + return nil, errors.Errorf("could not find reference: %s", gitRevision) //invalid hash } - return oid, nil + return &hash, nil } +//func resolveRevision(repository *git2go.Repository, gitRevision string) (*git2go.Oid, error) { +// ref, err := repository.References.Dwim(gitRevision) +// if err != nil { +// return resolveCommit(gitRevision) +// } +// +// return ref.Target(), nil +//} + +//func resolveCommit(gitRevision string) (*git2go.Oid, error) { +// oid, err := git2go.NewOid(gitRevision) +// if err != nil { +// return nil, errors.Errorf("could not find reference: %s", gitRevision) //invalid oid +// } +// return oid, nil +//} + type project struct { Source source `toml:"source"` } diff --git a/pkg/git/fetch_test.go b/pkg/git/fetch_test.go index 3b678305..f8d5bc96 100644 --- a/pkg/git/fetch_test.go +++ b/pkg/git/fetch_test.go @@ -3,17 +3,21 @@ package git import ( "bytes" "fmt" + "github.com/BurntSushi/toml" + "github.com/go-git/go-billy/v5/osfs" + gogit "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/cache" + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/storage/filesystem" + "github.com/stretchr/testify/require" "io/ioutil" "log" "os" "path" "testing" - "github.com/BurntSushi/toml" - git2go "github.com/libgit2/git2go/v33" - "github.com/pkg/errors" "github.com/sclevine/spec" - "github.com/stretchr/testify/require" ) func TestGitCheckout(t *testing.T) { @@ -49,66 +53,63 @@ func testGitCheckout(t *testing.T, when spec.G, it spec.S) { err := fetcher.Fetch(testDir, gitUrl, revision, metadataDir) require.NoError(t, err) - repository, err := git2go.InitRepository(testDir, false) - require.NoError(t, err) - defer repository.Free() - - empty, err := repository.IsEmpty() + fs := osfs.New(testDir) + storage := filesystem.NewStorage(fs, cache.NewObjectLRUDefault()) + repository, err := gogit.Init(storage, fs) + fmt.Println(outputBuffer.String()) + require.Contains(t, outputBuffer.String(), "Successfully cloned") + branches, err := repository.Branches() require.NoError(t, err) - require.False(t, empty) - - state := repository.State() - require.Equal(t, state, git2go.RepositoryStateNone) - - require.Contains(t, outputBuffer.String(), fmt.Sprintf("Successfully cloned \"%s\" @ \"%s\"", gitUrl, revision)) - - require.FileExists(t, path.Join(metadataDir, "project-metadata.toml")) + branches.ForEach(func(branch *plumbing.Reference) error { + fmt.Println("Branch name: ") + fmt.Println(branch.Name()) + return nil + }) var projectMetadata project - _, err = toml.DecodeFile(path.Join(metadataDir, "project-metadata.toml"), &projectMetadata) - require.NoError(t, err) + p := path.Join(metadataDir, "project-metadata.toml") + md, err := toml.DecodeFile(p, &projectMetadata) + for k := range md.Keys() { + fmt.Println(k) + } + require.NoError(t, err) require.Equal(t, "git", projectMetadata.Source.Type) require.Equal(t, gitUrl, projectMetadata.Source.Metadata.Repository) require.Equal(t, revision, projectMetadata.Source.Metadata.Revision) - head, err := repository.Head() + refs, err := repository.References() + refs.ForEach(func(r *plumbing.Reference) error { + fmt.Println(r.Name()) + return nil + }) + require.NoError(t, err) - defer head.Free() - require.Equal(t, head.Target().String(), projectMetadata.Source.Version.Commit) + //require.Equal(t, ref.Hash(), projectMetadata.Source.Version.Commit) } } it("fetches remote HEAD", testFetch("https://github.com/git-fixtures/basic", "master")) + }) +} - it("fetches a branch", testFetch("https://github.com/git-fixtures/basic", "branch")) - - it("fetches a tag", testFetch("https://github.com/git-fixtures/tags", "lightweight-tag")) - - it("fetches a revision", testFetch("https://github.com/git-fixtures/basic", "b029517f6300c2da0f4b651b8642506cd6aaf45d")) - - it("returns error on non-existent ref", func() { - err := fetcher.Fetch(testDir, "https://github.com/git-fixtures/basic", "doesnotexist", metadataDir) - require.EqualError(t, err, "could not find reference: doesnotexist") - }) +type fakeGitKeychain struct { +} - it("returns error from remote fetch when authentication required", func() { - err := fetcher.Fetch(testDir, "git@bitbucket.com:org/repo", "main", metadataDir) - require.EqualError(t, err, "fetching remote: no auth available") - }) +type goGitFakeCredential struct { + GoGitCredential +} - it("uses the http proxy env vars", func() { - require.NoError(t, os.Setenv("HTTPS_PROXY", "http://invalid-proxy")) - defer os.Unsetenv("HTTPS_PROXY") - err := fetcher.Fetch(testDir, "https://github.com/git-fixtures/basic", "master", metadataDir) - require.Error(t, err) - require.Contains(t, err.Error(), "fetching remote: failed to resolve address for invalid-proxy") - }) - }) +type fakeAuthMethod struct { + transport.AuthMethod } -type fakeGitKeychain struct{} +func (c *goGitFakeCredential) Cred() (transport.AuthMethod, error) { + // return fake transport.AuthMethod + return &fakeAuthMethod{}, nil +} -func (f fakeGitKeychain) Resolve(url string, usernameFromUrl string, allowedTypes git2go.CredentialType) (Git2GoCredential, error) { - return nil, errors.New("no auth available") +func (f fakeGitKeychain) Resolve(url string, usernameFromUrl string, allowedTypes CredentialType) (GoGitCredential, error) { + return &goGitFakeCredential{}, nil + //return nil, errors.New("no auth available") } diff --git a/pkg/git/git_keychain.go b/pkg/git/git_keychain.go index 6a55aafd..568b5f0f 100644 --- a/pkg/git/git_keychain.go +++ b/pkg/git/git_keychain.go @@ -1,10 +1,12 @@ package git import ( + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/http" + gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh" "sort" "strings" - git2go "github.com/libgit2/git2go/v33" "github.com/pkg/errors" giturls "github.com/whilp/git-urls" "golang.org/x/crypto/ssh" @@ -12,48 +14,79 @@ import ( "github.com/pivotal/kpack/pkg/secret" ) -type Git2GoCredential interface { - Cred() (*git2go.Credential, error) +type CredentialType string + +const ( + CredentialTypeUserpass CredentialType = "userpass" + CredentialTypeSSHKey CredentialType = "sshkey" + CredentialTypeSSHCustom CredentialType = "sshcustom" + CredentialTypeDefault CredentialType = "default" + CredentialTypeUsername CredentialType = "username" + CredentialTypeSSHMemory CredentialType = "sshmemory" +) + +type GoGitCredential interface { + Cred() (transport.AuthMethod, error) } -func keychainAsCredentialsCallback(gitKeychain GitKeychain) git2go.CredentialsCallback { - return func(url string, usernameFromUrl string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) { - cred, err := gitKeychain.Resolve(url, usernameFromUrl, allowedTypes) - if err != nil { - return nil, err - } - return cred.Cred() - } +type GoGitSshCredential struct { + GoGitCredential + User string + Signer ssh.Signer + PrivateKey []byte } -type GitKeychain interface { - Resolve(url string, usernameFromUrl string, allowedTypes git2go.CredentialType) (Git2GoCredential, error) +type GoGitHttpCredential struct { + GoGitCredential + User string + Password string } -type BasicGit2GoAuth struct { - Username, Password string +//func keychainAsCredentialsCallback(gitKeychain GitKeychain) git2go.CredentialsCallback { +// return func(url string, usernameFromUrl string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) { +// cred, err := gitKeychain.Resolve(url, usernameFromUrl, allowedTypes) +// if err != nil { +// return nil, err +// } +// return cred.Cred() +// } +//} + +type GitKeychain interface { + Resolve(url string, usernameFromUrl string, allowedTypes CredentialType) (GoGitCredential, error) + //AuthForUrl(url string) (transport.AuthMethod, error) } -func (b BasicGit2GoAuth) Cred() (*git2go.Credential, error) { - return git2go.NewCredentialUserpassPlaintext(b.Username, b.Password) +func (kc *secretGitKeychain) AuthForUrl(url string) (transport.AuthMethod, error) { + cred, err := kc.Resolve(url, "", CredentialTypeSSHKey) + if err != nil { + return nil, err + } + auth, err := cred.Cred() + if err != nil { + return nil, err + } + return auth, nil } -type SSHGit2GoAuth struct { - Username, PrivateKey string +func (c *GoGitHttpCredential) Cred() (transport.AuthMethod, error) { + return &http.BasicAuth{ + Username: c.User, + Password: c.Password, + }, nil } -func (s SSHGit2GoAuth) Cred() (*git2go.Credential, error) { - signer, err := ssh.ParsePrivateKey([]byte(s.PrivateKey)) +func (c *GoGitSshCredential) Cred() (transport.AuthMethod, error) { + signer, err := ssh.ParsePrivateKey([]byte(c.PrivateKey)) if err != nil { return nil, err } - - return git2go.NewCredentialSSHKeyFromSigner(s.Username, signer) + return &gitssh.PublicKeys{User: c.User, Signer: signer}, nil } type gitCredential interface { - match(host string, allowedTypes git2go.CredentialType) bool - git2goCredential(username string) (Git2GoCredential, error) + match(host string, allowedTypes CredentialType) bool + goGitCredential(username string) (GoGitCredential, error) name() string } @@ -67,23 +100,15 @@ type gitSshAuthCred struct { SecretName string } -func (g gitSshAuthCred) match(host string, allowedTypes git2go.CredentialType) bool { - if allowedTypes&(git2go.CredentialTypeSSHKey) == 0 { - return false - } - - return gitUrlMatch(host, g.Domain) -} - -func (g gitSshAuthCred) git2goCredential(username string) (Git2GoCredential, error) { +func (g gitSshAuthCred) goGitCredential(username string) (GoGitCredential, error) { sshSecret, err := g.fetchSecret() if err != nil { return nil, err } - return SSHGit2GoAuth{ - Username: username, - PrivateKey: sshSecret.PrivateKey, + return &GoGitSshCredential{ + User: username, + PrivateKey: []byte(sshSecret.PrivateKey), }, nil } @@ -97,21 +122,32 @@ type gitBasicAuthCred struct { SecretName string } -func (c gitBasicAuthCred) match(host string, allowedTypes git2go.CredentialType) bool { - if allowedTypes&(git2go.CredentialTypeUserpassPlaintext) == 0 { +func (g gitSshAuthCred) match(host string, allowedTypes CredentialType) bool { + if allowedTypes != CredentialTypeSSHKey { return false } + //fmt.Printf("gitSshAuthCred.match: host=%s, g.Domain=%s\n", host, g.Domain) + return gitUrlMatch(host, g.Domain) +} +func (c gitBasicAuthCred) match(host string, allowedTypes CredentialType) bool { + if allowedTypes != CredentialTypeUserpass { + return false + } + //fmt.Printf("gitSshAuthCred.match: host=%s, g.Domain=%s\n", host, c.Domain) return gitUrlMatch(host, c.Domain) } -func (c gitBasicAuthCred) git2goCredential(_ string) (Git2GoCredential, error) { +func (c gitBasicAuthCred) goGitCredential(_ string) (GoGitCredential, error) { basicAuthSecret, err := c.fetchSecret() if err != nil { return nil, err } - return BasicGit2GoAuth{Username: basicAuthSecret.Username, Password: basicAuthSecret.Password}, nil + return &GoGitHttpCredential{ + User: basicAuthSecret.Username, + Password: basicAuthSecret.Password, + }, nil } func (c gitBasicAuthCred) name() string { @@ -155,7 +191,9 @@ func NewMountedSecretGitKeychain(volumeName string, basicAuthSecrets, sshAuthSec }, nil } -func (k *secretGitKeychain) Resolve(url string, username string, allowedTypes git2go.CredentialType) (Git2GoCredential, error) { +// Resolve takes in a URL, username and allowedTypes as input and returns a GoGitCredential that matches the input +func (k *secretGitKeychain) Resolve(url string, username string, allowedTypes CredentialType) (GoGitCredential, error) { + //fmt.Printf("secretGitKeychain::Resolve url->%s, username->%s, allowedTypes->%s\n", url, username, allowedTypes) u, err := giturls.Parse(url) if err != nil { return nil, err @@ -167,10 +205,13 @@ func (k *secretGitKeychain) Resolve(url string, username string, allowedTypes gi sort.Slice(k.creds, func(i, j int) bool { return k.creds[i].name() < k.creds[j].name() }) + //fmt.Printf("secretGitKeychain::Resolve number of creds: %d\n", len(k.creds)) for _, cred := range k.creds { + //fmt.Printf("secretGitKeychain::Resolve %s\n", cred.name()) if cred.match(u.Host, allowedTypes) { - return cred.git2goCredential(username) + return cred.goGitCredential(username) } } + return nil, errors.Errorf("no credentials found for %s", url) } diff --git a/pkg/git/git_keychain_test.go b/pkg/git/git_keychain_test.go index 7c38d99f..55bae17e 100644 --- a/pkg/git/git_keychain_test.go +++ b/pkg/git/git_keychain_test.go @@ -1,15 +1,16 @@ package git import ( + "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/stretchr/testify/require" "io/ioutil" + corev1 "k8s.io/api/core/v1" "os" "path" + "reflect" "testing" - git2go "github.com/libgit2/git2go/v33" "github.com/sclevine/spec" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" ) func TestGitFileKeychain(t *testing.T) { @@ -66,41 +67,41 @@ func testGitFileKeychain(t *testing.T, when spec.G, it spec.S) { when("Resolve", func() { it("returns alphabetical first git Auth for matching basic auth secrets", func() { - cred, err := keychain.Resolve("https://github.com/org/repo", "", git2go.CredentialTypeUserpassPlaintext) + cred, err := keychain.Resolve("https://github.com/org/repo", "", CredentialTypeUserpass) require.NoError(t, err) - require.Equal(t, BasicGit2GoAuth{Username: "saved-username", Password: "saved-password"}, cred) - git2goCred, err := cred.Cred() + require.Equal(t, &GoGitHttpCredential{User: "saved-username", Password: "saved-password"}, cred) + gogitCred, err := cred.Cred() require.NoError(t, err) - require.Equal(t, git2goCred.Type(), git2go.CredentialTypeUserpassPlaintext) + require.Equal(t, reflect.TypeOf(gogitCred).Elem().String(), reflect.TypeOf(http.BasicAuth{}).String()) }) it("returns git Auth for matching secrets without scheme", func() { - cred, err := keychain.Resolve("https://noschemegit.com/org/repo", "", git2go.CredentialTypeUserpassPlaintext) + cred, err := keychain.Resolve("https://noschemegit.com/org/repo", "", CredentialTypeUserpass) require.NoError(t, err) - require.Equal(t, BasicGit2GoAuth{Username: "noschemegit-username", Password: "noschemegit-password"}, cred) + require.Equal(t, &GoGitHttpCredential{User: "noschemegit-username", Password: "noschemegit-password"}, cred) }) when("there are ssh and basic auth secret types", func() { it("returns ssh cred for requested ssh credentials", func() { - cred, err := keychain.Resolve("git@bitbucket.com:org/repo", "git", git2go.CredentialTypeSSHKey) + cred, err := keychain.Resolve("git@bitbucket.com:org/repo", "git", CredentialTypeSSHKey) require.NoError(t, err) - require.Equal(t, SSHGit2GoAuth{Username: "git", PrivateKey: "private key 1"}, cred) + require.Equal(t, &GoGitSshCredential{User: "git", PrivateKey: []byte("private key 1")}, cred) }) it("returns basic auth secret for requested basic auth credentials", func() { - cred, err := keychain.Resolve("https://bitbucket.com/org/repo", "git", git2go.CredentialTypeUserpassPlaintext) + cred, err := keychain.Resolve("https://bitbucket.com/org/repo", "git", CredentialTypeUserpass) require.NoError(t, err) - require.Equal(t, BasicGit2GoAuth{Username: "saved-username", Password: "saved-password"}, cred) + require.Equal(t, &GoGitHttpCredential{User: "saved-username", Password: "saved-password"}, cred) }) }) it("returns an error if no credentials found", func() { - _, err := keychain.Resolve("https://no-creds-github.com/org/repo", "git", git2go.CredentialTypeUserpassPlaintext) + _, err := keychain.Resolve("https://no-creds-github.com/org/repo", "git", CredentialTypeUserpass) require.EqualError(t, err, "no credentials found for https://no-creds-github.com/org/repo") }) @@ -109,10 +110,10 @@ func testGitFileKeychain(t *testing.T, when spec.G, it spec.S) { gitKeychain, err := NewMountedSecretGitKeychain(testDir, []string{}, []string{ "git-ssh-creds=git@my-git-server.com", }) - cred, err := gitKeychain.Resolve("ssh://git@my-git-server.com/my-org/my-repo.git", "", git2go.CredentialTypeSSHKey) + cred, err := gitKeychain.Resolve("ssh://git@my-git-server.com/my-org/my-repo.git", "", CredentialTypeSSHKey) require.NoError(t, err) - require.Equal(t, SSHGit2GoAuth{Username: "git", PrivateKey: "private key 3"}, cred) + require.Equal(t, &GoGitSshCredential{User: "git", PrivateKey: []byte("private key 3")}, cred) }) }) }) diff --git a/pkg/git/k8s_git_keychain.go b/pkg/git/k8s_git_keychain.go index e5acf12d..bd73f6d5 100644 --- a/pkg/git/k8s_git_keychain.go +++ b/pkg/git/k8s_git_keychain.go @@ -76,10 +76,17 @@ var matchingDomains = []string{ } func gitUrlMatch(urlMatch, annotatedUrl string) bool { + //fmt.Printf("gitUrlMatch: len(matchingDomains)->%d\n", len(matchingDomains)) for _, format := range matchingDomains { + //fmt.Printf("gitUrlMatch: urlMatch->%s, annotatedUrl->%s, format->%s\n", urlMatch, annotatedUrl, format) + //fmt.Printf("gitUrlMatch: checking match for formatted urlMatch. format->%s, urlMatch->%s, annotatedUrl->%s, Sprintf(format, urlMatch)->%s\n", format, urlMatch, annotatedUrl, fmt.Sprintf(format, urlMatch)) if fmt.Sprintf(format, urlMatch) == annotatedUrl { + // found match for formatted urlMatch + //fmt.Printf("gitUrlMatch: found match for formatted urlMatch. format->%s, urlMatch->%s, annotatedUrl->%s, Sprintf(format, urlMatch)->%s\n", format, urlMatch, annotatedUrl, fmt.Sprintf(format, urlMatch)) return true } } + // no match found for formatted urlMatch + //fmt.Printf("gitUrlMatch: no match found for formatted urlMatch. urlMatch->%s, annotatedUrl->%s\n", urlMatch, annotatedUrl) return false } diff --git a/pkg/git/k8s_git_keychain_test.go b/pkg/git/k8s_git_keychain_test.go index e17ef0e7..6c4df18d 100644 --- a/pkg/git/k8s_git_keychain_test.go +++ b/pkg/git/k8s_git_keychain_test.go @@ -6,9 +6,11 @@ import ( "crypto/rsa" "crypto/x509" "encoding/pem" + "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "reflect" "testing" - git2go "github.com/libgit2/git2go/v33" "github.com/sclevine/spec" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" @@ -157,48 +159,48 @@ func (keys gitTest) testK8sGitKeychain(t *testing.T, when spec.G, it spec.S) { }) it("returns alphabetical first git Auth for matching secrets with basic auth", func() { - cred, err := keychain.Resolve("https://github.com/org/repo", "", git2go.CredentialTypeUserpassPlaintext) + cred, err := keychain.Resolve("https://github.com/org/repo", "", CredentialTypeUserpass) require.NoError(t, err) - require.Equal(t, BasicGit2GoAuth{ - Username: "saved-username", + require.Equal(t, GoGitHttpCredential{ + User: "saved-username", Password: "saved-password", }, cred) - git2goCred, err := cred.Cred() + gogitCred, err := cred.Cred() require.NoError(t, err) - require.Equal(t, git2goCred.Type(), git2go.CredentialTypeUserpassPlaintext) + require.Equal(t, reflect.TypeOf(gogitCred).Elem().String(), reflect.TypeOf(http.BasicAuth{}).String()) }) it("returns the alphabetical first secretRef for ssh auth", func() { - cred, err := keychain.Resolve("https://gitlab.com/my-repo.git", "gituser", git2go.CredentialTypeSSHKey) + cred, err := keychain.Resolve("https://gitlab.com/my-repo.git", "gituser", CredentialTypeSSHKey) require.NoError(t, err) - require.Equal(t, SSHGit2GoAuth{ - Username: "gituser", - PrivateKey: string(keys.key1), + require.Equal(t, &GoGitSshCredential{ + User: "gituser", + PrivateKey: keys.key1, }, cred) - git2goCred, err := cred.Cred() + gogitCred, err := cred.Cred() require.NoError(t, err) - require.Equal(t, git2goCred.Type(), git2go.CredentialTypeSSHCustom) + require.Equal(t, reflect.TypeOf(gogitCred).Elem().String(), reflect.TypeOf(ssh.PublicKeys{}).String()) }) it("returns git Auth for matching secrets without scheme", func() { - cred, err := keychain.Resolve("https://noschemegit.com/org/repo", "", git2go.CredentialTypeUserpassPlaintext) + cred, err := keychain.Resolve("https://noschemegit.com/org/repo", "", CredentialTypeUserpass) require.NoError(t, err) - require.Equal(t, BasicGit2GoAuth{ - Username: "noschemegit-username", + require.Equal(t, GoGitHttpCredential{ + User: "noschemegit-username", Password: "noschemegit-password", }, cred) }) - it("returns an error if no credentials found", func() { - _, err := keychain.Resolve("https://no-creds-github.com/org/repo", "git", git2go.CredentialTypeUserpassPlaintext) - require.EqualError(t, err, "no credentials found for https://no-creds-github.com/org/repo") + it("returns an error if no credential are found", func() { + _, err := keychain.Resolve("https://notfound.com/org/repo", "git", CredentialTypeUserpass) + require.EqualError(t, err, "no credentials found for https://notfound.com/org/repo") }) }) } diff --git a/pkg/git/remote_git_resolver.go b/pkg/git/remote_git_resolver.go index 0a2d3568..7b6fa9ec 100644 --- a/pkg/git/remote_git_resolver.go +++ b/pkg/git/remote_git_resolver.go @@ -2,12 +2,14 @@ package git import ( "fmt" + gogit "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/transport" "io/ioutil" "log" "os" - "strings" - git2go "github.com/libgit2/git2go/v33" "github.com/pkg/errors" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" @@ -21,33 +23,39 @@ type remoteGitResolver struct { } func (*remoteGitResolver) Resolve(keychain GitKeychain, sourceConfig corev1alpha1.SourceConfig) (corev1alpha1.ResolvedSourceConfig, error) { - dir, err := ioutil.TempDir("", "git-resolve") + // initialize a new repository in a temporary directory + dir, err := ioutil.TempDir("", "kpack-git") if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, err + return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "creating temp dir") } defer os.RemoveAll(dir) - - repository, err := git2go.InitRepository(dir, false) + // initialize a new repository + repository, err := gogit.PlainInit(dir, false) if err != nil { return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "initializing repo") } - defer repository.Free() - - remote, err := repository.Remotes.CreateWithOptions(parseURL(sourceConfig.Git.URL), &git2go.RemoteCreateOptions{ - Name: defaultRemote, - Flags: git2go.RemoteCreateSkipInsteadof, + // create a new remote + remote, err := repository.CreateRemote(&config.RemoteConfig{ + Name: defaultRemote, + URLs: []string{sourceConfig.Git.URL}, }) + + cred, err := keychain.Resolve(sourceConfig.Git.URL, "", CredentialTypeUserpass) if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "create remote") + return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "getting auth for url") } - defer remote.Free() - err = remote.ConnectFetch( - &git2go.RemoteCallbacks{ - CredentialsCallback: keychainAsCredentialsCallback(keychain), - CertificateCheckCallback: certificateCheckCallback(), - }, - &git2go.ProxyOptions{Type: git2go.ProxyTypeAuto}, nil) + auth, err := cred.Cred() + if err != nil { + return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "getting auth for url") + } + + // fetch the remote + err = remote.Fetch(&gogit.FetchOptions{ + RemoteName: defaultRemote, + Auth: auth, + Progress: discardLogger.Writer(), + }) if err != nil { return corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ @@ -59,19 +67,25 @@ func (*remoteGitResolver) Resolve(keychain GitKeychain, sourceConfig corev1alpha }, nil } - references, err := remote.Ls() + // get the remote references + references, err := remote.List(&gogit.ListOptions{ + Auth: auth, + }) if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "remote ls") + return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "listing remote references") } - for _, ref := range references { - for _, format := range refRevParseRules { - if fmt.Sprintf(format, sourceConfig.Git.Revision) == ref.Name { + // iterate over the references + for _, reference := range references { + // iterate over the revRefParseRules + for _, revRefParseRule := range refRevParseRules { + // return ResolvedSourceConfig if the sourceConfig.Git.Revision matches the reference.Name() + if fmt.Sprintf(revRefParseRule, sourceConfig.Git.Revision) == reference.Name().String() { return corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ URL: sourceConfig.Git.URL, - Revision: ref.Id.String(), - Type: sourceType(ref), + Revision: reference.Hash().String(), + Type: referenceNameToType(reference.Name()), SubPath: sourceConfig.SubPath, }, }, nil @@ -89,11 +103,28 @@ func (*remoteGitResolver) Resolve(keychain GitKeychain, sourceConfig corev1alpha }, nil } -func sourceType(reference git2go.RemoteHead) corev1alpha1.GitSourceKind { +type transportCallbackAdapter struct { + keychain GitKeychain +} + +func keychainAsAuth(keychain GitKeychain, url string, usernameFromUrl string, allowedTypes CredentialType) (transport.AuthMethod, error) { + // Resolve(url string, usernameFromUrl string, allowedTypes CredentialType) (GoGitCredential, error) + goGitCredential, err := keychain.Resolve(url, usernameFromUrl, allowedTypes) + if err != nil { + return nil, err + } + auth, err := goGitCredential.Cred() + if err != nil { + return nil, err + } + return auth, nil +} + +func referenceNameToType(referenceName plumbing.ReferenceName) corev1alpha1.GitSourceKind { switch { - case strings.HasPrefix(reference.Name, "refs/heads"): + case referenceName.IsBranch(): return corev1alpha1.Branch - case strings.HasPrefix(reference.Name, "refs/tags"): + case referenceName.IsTag(): return corev1alpha1.Tag default: return corev1alpha1.Unknown From e6bc410aa46015b6d4a7ccbb65ebece54b5054ae Mon Sep 17 00:00:00 2001 From: Nicholas Carlson Date: Mon, 6 Mar 2023 16:28:42 -0700 Subject: [PATCH 32/39] Fixed failing tests and addressed PR feedback --- go.mod | 16 +-- go.sum | 21 ++-- hack/common.sh | 4 +- pkg/git/fetch.go | 113 ++++++++---------- pkg/git/fetch_test.go | 116 ++++++++++-------- pkg/git/git_keychain.go | 140 +++++----------------- pkg/git/git_keychain_test.go | 178 ++++++++++++++++++---------- pkg/git/k8s_git_keychain.go | 23 ++-- pkg/git/k8s_git_keychain_test.go | 108 ++++++++++------- pkg/git/remote_git_resolver.go | 115 +++++------------- pkg/git/remote_git_resolver_test.go | 37 +++--- pkg/git/resolver.go | 8 +- pkg/git/url_parser.go | 2 +- 13 files changed, 414 insertions(+), 467 deletions(-) diff --git a/go.mod b/go.mod index dcd23245..f08cb3b6 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/buildpacks/imgutil v0.0.0-20220527150729-7a271a852e31 github.com/buildpacks/lifecycle v0.14.1 github.com/ghodss/yaml v1.0.0 - github.com/go-git/go-billy/v5 v5.4.0 github.com/go-git/go-git/v5 v5.6.0 github.com/google/go-cmp v0.5.9 github.com/google/go-containerregistry v0.12.1 @@ -27,7 +26,7 @@ require ( github.com/vdemeester/k8s-pkg-credentialprovider v1.22.4 github.com/whilp/git-urls v1.0.0 go.uber.org/zap v1.23.0 - golang.org/x/crypto v0.3.0 + golang.org/x/crypto v0.7.0 golang.org/x/sync v0.1.0 k8s.io/api v0.24.8 k8s.io/apimachinery v0.24.8 @@ -133,6 +132,7 @@ require ( github.com/fullstorydev/grpcurl v1.8.7 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.4.0 // indirect github.com/go-kit/log v0.2.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -294,14 +294,14 @@ require ( go.uber.org/automaxprocs v1.5.1 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/exp v0.0.0-20220823124025-807a23277127 // indirect - golang.org/x/mod v0.6.0 // indirect - golang.org/x/net v0.2.0 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.8.0 // indirect golang.org/x/oauth2 v0.1.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/term v0.2.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.2.0 // indirect + golang.org/x/tools v0.6.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/api v0.99.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index b0148066..316d9873 100644 --- a/go.sum +++ b/go.sum @@ -1728,8 +1728,9 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1771,8 +1772,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1851,8 +1853,9 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2015,8 +2018,9 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2024,8 +2028,9 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2035,8 +2040,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2132,8 +2138,9 @@ golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpd golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/hack/common.sh b/hack/common.sh index cb953c19..3b01a2e4 100644 --- a/hack/common.sh +++ b/hack/common.sh @@ -35,7 +35,7 @@ function compile() { completion_image=${IMAGE_PREFIX}completion lifecycle_image=${IMAGE_PREFIX}lifecycle - pack_build ${controller_image} "./cmd/controller" -e BP_GIT2GO_ENABLED=true -e BP_GIT2GO_USE_LIBSSL=true + pack_build ${controller_image} "./cmd/controller" controller_image=${resolved_image_name} pack_build ${build_waiter_image} "./cmd/build-waiter" @@ -44,7 +44,7 @@ function compile() { pack_build ${webhook_image} "./cmd/webhook" webhook_image=${resolved_image_name} - pack_build ${build_init_image} "./cmd/build-init" -e BP_GIT2GO_ENABLED=true -e BP_GIT2GO_USE_LIBSSL=true + pack_build ${build_init_image} "./cmd/build-init" build_init_image=${resolved_image_name} pack_build ${rebase_image} "./cmd/rebase" diff --git a/pkg/git/fetch.go b/pkg/git/fetch.go index 84cc1c31..624ed21d 100644 --- a/pkg/git/fetch.go +++ b/pkg/git/fetch.go @@ -1,16 +1,20 @@ package git import ( - "github.com/BurntSushi/toml" - gogit "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" "log" + "net/http" + "net/url" "os" "path" + "time" - // import RemoteConfig + "github.com/BurntSushi/toml" + gogit "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" - + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/client" + githttp "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/pkg/errors" ) @@ -21,8 +25,11 @@ type Fetcher struct { func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error { f.Logger.Printf("Cloning %q @ %q...", gitURL, gitRevision) + auth, err := f.Keychain.Resolve(gitURL) + if err != nil { + return err + } - // Initialize a repository in the directory using gogit.Init repository, err := gogit.PlainInit(dir, false) if err != nil { return errors.Wrap(err, "initializing repo") @@ -36,44 +43,37 @@ func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error { return errors.Wrap(err, "creating remote") } - err = remote.Fetch(&gogit.FetchOptions{ - RefSpecs: []config.RefSpec{ - config.RefSpec("refs/*:refs/*"), - }, - Auth: nil, - Tags: gogit.AllTags, - RemoteName: defaultRemote, - }) + httpsTransport, err := getHttpsTransport() if err != nil { - return errors.Wrap(err, "fetching remote") + return err } + client.InstallProtocol("https", httpsTransport) - hash, err := resolveRevision(repository, gitRevision) - if err != nil { - return errors.Wrap(err, "resolving revision") + err = remote.Fetch(&gogit.FetchOptions{ + RefSpecs: []config.RefSpec{"refs/*:refs/*"}, + Auth: auth, + }) + if err != nil && err != transport.ErrAuthenticationRequired { + return errors.Wrapf(err, "unable to fetch references for repository") + } else if err == transport.ErrAuthenticationRequired { + return errors.Wrapf(err, "invalid credentials for repository") } - // Look up the commit using the hash - commit, err := repository.CommitObject(*hash) + worktree, err := repository.Worktree() if err != nil { - return errors.Wrap(err, "looking up commit") + return errors.Wrapf(err, "getting worktree for repository") } - worktree, err := repository.Worktree() + hash, err := repository.ResolveRevision(plumbing.Revision(gitRevision)) if err != nil { - return errors.Wrap(err, "getting worktree") + return errors.Wrapf(err, "resolving revision") } - err = worktree.Checkout(&gogit.CheckoutOptions{}) + err = worktree.Checkout(&gogit.CheckoutOptions{Hash: *hash}) if err != nil { - return errors.Wrap(err, "checking out blank") + return errors.Wrapf(err, "checking out revision") } - err = worktree.Checkout(&gogit.CheckoutOptions{ - Hash: plumbing.NewHash(hash.String()), - Create: false, - }) - // Write the git revision to the metadata directory projectMetadataFile, err := os.Create(path.Join(metadataDir, "project-metadata.toml")) if err != nil { @@ -89,7 +89,7 @@ func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error { Revision: gitRevision, }, Version: version{ - Commit: commit.Hash.String(), + Commit: hash.String(), }, }, } @@ -101,42 +101,27 @@ func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error { return nil } -// Implement resolveRevision and return a plumbing.Hash and error -func resolveRevision(repository *gogit.Repository, gitRevision string) (*plumbing.Hash, error) { - ref, err := repository.ResolveRevision(plumbing.Revision(gitRevision)) - if err != nil { - return resolveCommit(gitRevision) - } - return ref, nil -} - -func resolveCommit(gitRevision string) (*plumbing.Hash, error) { - // Use plumbing.NewHash to create a new hash - hash := plumbing.NewHash(gitRevision) - // if hash is empty - if hash == plumbing.ZeroHash { - return nil, errors.Errorf("could not find reference: %s", gitRevision) //invalid hash +func getHttpsTransport() (transport.Transport, error) { + if httpsProxy, exists := os.LookupEnv("HTTPS_PROXY"); exists { + parsedUrl, err := url.Parse(httpsProxy) + if err != nil { + return nil, errors.Wrap(err, "parsing HTTPS_PROXY url") + } + proxyClient := &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyURL(parsedUrl), + }, + Timeout: 15 * time.Second, + CheckRedirect: func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }, + } + return githttp.NewClient(proxyClient), nil + } else { + return githttp.DefaultClient, nil } - return &hash, nil } -//func resolveRevision(repository *git2go.Repository, gitRevision string) (*git2go.Oid, error) { -// ref, err := repository.References.Dwim(gitRevision) -// if err != nil { -// return resolveCommit(gitRevision) -// } -// -// return ref.Target(), nil -//} - -//func resolveCommit(gitRevision string) (*git2go.Oid, error) { -// oid, err := git2go.NewOid(gitRevision) -// if err != nil { -// return nil, errors.Errorf("could not find reference: %s", gitRevision) //invalid oid -// } -// return oid, nil -//} - type project struct { Source source `toml:"source"` } diff --git a/pkg/git/fetch_test.go b/pkg/git/fetch_test.go index f8d5bc96..eca3eaba 100644 --- a/pkg/git/fetch_test.go +++ b/pkg/git/fetch_test.go @@ -2,22 +2,16 @@ package git import ( "bytes" - "fmt" - "github.com/BurntSushi/toml" - "github.com/go-git/go-billy/v5/osfs" - gogit "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/cache" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/storage/filesystem" - "github.com/stretchr/testify/require" - "io/ioutil" "log" "os" "path" "testing" + "github.com/BurntSushi/toml" + gogit "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/transport" "github.com/sclevine/spec" + "github.com/stretchr/testify/require" ) func TestGitCheckout(t *testing.T) { @@ -36,14 +30,16 @@ func testGitCheckout(t *testing.T, when spec.G, it spec.S) { it.Before(func() { var err error - testDir, err = ioutil.TempDir("", "test-git") + testDir, err = os.MkdirTemp("", "test-git") require.NoError(t, err) - metadataDir, err = ioutil.TempDir("", "test-git") + metadataDir, err = os.MkdirTemp("", "test-git") require.NoError(t, err) + os.Unsetenv("HTTPS_PROXY") }) it.After(func() { + os.Unsetenv("HTTPS_PROXY") require.NoError(t, os.RemoveAll(testDir)) require.NoError(t, os.RemoveAll(metadataDir)) }) @@ -53,63 +49,85 @@ func testGitCheckout(t *testing.T, when spec.G, it spec.S) { err := fetcher.Fetch(testDir, gitUrl, revision, metadataDir) require.NoError(t, err) - fs := osfs.New(testDir) - storage := filesystem.NewStorage(fs, cache.NewObjectLRUDefault()) - repository, err := gogit.Init(storage, fs) - fmt.Println(outputBuffer.String()) - require.Contains(t, outputBuffer.String(), "Successfully cloned") - branches, err := repository.Branches() + repository, err := gogit.PlainOpen(testDir) require.NoError(t, err) - branches.ForEach(func(branch *plumbing.Reference) error { - fmt.Println("Branch name: ") - fmt.Println(branch.Name()) - return nil - }) + require.Contains(t, outputBuffer.String(), "Successfully cloned") - var projectMetadata project p := path.Join(metadataDir, "project-metadata.toml") - md, err := toml.DecodeFile(p, &projectMetadata) - for k := range md.Keys() { - fmt.Println(k) - } + require.FileExists(t, p) + var projectMetadata project + _, err = toml.DecodeFile(p, &projectMetadata) require.NoError(t, err) require.Equal(t, "git", projectMetadata.Source.Type) require.Equal(t, gitUrl, projectMetadata.Source.Metadata.Repository) require.Equal(t, revision, projectMetadata.Source.Metadata.Revision) - refs, err := repository.References() - refs.ForEach(func(r *plumbing.Reference) error { - fmt.Println(r.Name()) - return nil - }) - + hash, err := repository.ResolveRevision("HEAD") require.NoError(t, err) - //require.Equal(t, ref.Hash(), projectMetadata.Source.Version.Commit) + require.Equal(t, hash.String(), projectMetadata.Source.Version.Commit) } } it("fetches remote HEAD", testFetch("https://github.com/git-fixtures/basic", "master")) - }) -} -type fakeGitKeychain struct { -} + it("fetches a branch", testFetch("https://github.com/git-fixtures/basic", "branch")) + + it("fetches a tag", testFetch("https://github.com/git-fixtures/tags", "lightweight-tag")) -type goGitFakeCredential struct { - GoGitCredential + it("fetches a revision", testFetch("https://github.com/git-fixtures/basic", "b029517f6300c2da0f4b651b8642506cd6aaf45d")) + + it("returns error on non-existent ref", func() { + err := fetcher.Fetch(testDir, "https://github.com/git-fixtures/basic", "doesnotexist", metadataDir) + require.EqualError(t, err, "resolving revision: reference not found") + }) + + it("preserves symbolic links", func() { + err := fetcher.Fetch(testDir, "https://github.com/git-fixtures/symlinks", "master", metadataDir) + require.NoError(t, err) + fileInfo, err := os.Lstat(path.Join(testDir, "bar")) + isSymlink := fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink + require.True(t, isSymlink, "bar is expected to be a symbolic link") + }) + + it("preserves executable permission", func() { + err := fetcher.Fetch(testDir, "https://github.com/pivotal/kpack", "main", metadataDir) + require.NoError(t, err) + + fileInfo, err := os.Lstat(path.Join(testDir, "hack", "apply.sh")) + isExecutable := isExecutableByAll(fileInfo.Mode()) + require.True(t, isExecutable, "apply.sh is expected to be executable by owner, group, and other") + + fileInfo, err = os.Lstat(path.Join(testDir, "hack", "tools.go")) + isExecutable = isExecutableByAny(fileInfo.Mode()) + require.False(t, isExecutable, "tools.go is expected to not be executable") + }) + + it("returns invalid credentials to fetch error on authentication required", func() { + err := fetcher.Fetch(testDir, "git@bitbucket.com:org/repo", "main", metadataDir) + require.ErrorContains(t, err, "unable to fetch references for repository") + }) + + it("uses the http proxy env vars", func() { + require.NoError(t, os.Setenv("HTTPS_PROXY", "http://invalid-proxy")) + defer os.Unsetenv("HTTPS_PROXY") + err := fetcher.Fetch(testDir, "https://github.com/git-fixtures/basic", "master", metadataDir) + require.Error(t, err) + require.Contains(t, err.Error(), "no such host") + }) + }) } -type fakeAuthMethod struct { - transport.AuthMethod +func isExecutableByAny(mode os.FileMode) bool { + return mode&0111 != 0 } -func (c *goGitFakeCredential) Cred() (transport.AuthMethod, error) { - // return fake transport.AuthMethod - return &fakeAuthMethod{}, nil +func isExecutableByAll(mode os.FileMode) bool { + return mode&0111 == 0111 } -func (f fakeGitKeychain) Resolve(url string, usernameFromUrl string, allowedTypes CredentialType) (GoGitCredential, error) { - return &goGitFakeCredential{}, nil - //return nil, errors.New("no auth available") +type fakeGitKeychain struct{} + +func (f fakeGitKeychain) Resolve(gitUrl string) (transport.AuthMethod, error) { + return nil, nil } diff --git a/pkg/git/git_keychain.go b/pkg/git/git_keychain.go index 568b5f0f..b360e9e2 100644 --- a/pkg/git/git_keychain.go +++ b/pkg/git/git_keychain.go @@ -1,92 +1,26 @@ package git import ( - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/http" - gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "net/url" "sort" "strings" + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/http" + gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh" "github.com/pkg/errors" giturls "github.com/whilp/git-urls" - "golang.org/x/crypto/ssh" "github.com/pivotal/kpack/pkg/secret" ) -type CredentialType string - -const ( - CredentialTypeUserpass CredentialType = "userpass" - CredentialTypeSSHKey CredentialType = "sshkey" - CredentialTypeSSHCustom CredentialType = "sshcustom" - CredentialTypeDefault CredentialType = "default" - CredentialTypeUsername CredentialType = "username" - CredentialTypeSSHMemory CredentialType = "sshmemory" -) - -type GoGitCredential interface { - Cred() (transport.AuthMethod, error) -} - -type GoGitSshCredential struct { - GoGitCredential - User string - Signer ssh.Signer - PrivateKey []byte -} - -type GoGitHttpCredential struct { - GoGitCredential - User string - Password string -} - -//func keychainAsCredentialsCallback(gitKeychain GitKeychain) git2go.CredentialsCallback { -// return func(url string, usernameFromUrl string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) { -// cred, err := gitKeychain.Resolve(url, usernameFromUrl, allowedTypes) -// if err != nil { -// return nil, err -// } -// return cred.Cred() -// } -//} - type GitKeychain interface { - Resolve(url string, usernameFromUrl string, allowedTypes CredentialType) (GoGitCredential, error) - //AuthForUrl(url string) (transport.AuthMethod, error) -} - -func (kc *secretGitKeychain) AuthForUrl(url string) (transport.AuthMethod, error) { - cred, err := kc.Resolve(url, "", CredentialTypeSSHKey) - if err != nil { - return nil, err - } - auth, err := cred.Cred() - if err != nil { - return nil, err - } - return auth, nil -} - -func (c *GoGitHttpCredential) Cred() (transport.AuthMethod, error) { - return &http.BasicAuth{ - Username: c.User, - Password: c.Password, - }, nil -} - -func (c *GoGitSshCredential) Cred() (transport.AuthMethod, error) { - signer, err := ssh.ParsePrivateKey([]byte(c.PrivateKey)) - if err != nil { - return nil, err - } - return &gitssh.PublicKeys{User: c.User, Signer: signer}, nil + Resolve(url string) (transport.AuthMethod, error) } type gitCredential interface { - match(host string, allowedTypes CredentialType) bool - goGitCredential(username string) (GoGitCredential, error) + match(url *url.URL) bool + auth() (transport.AuthMethod, error) name() string } @@ -100,16 +34,22 @@ type gitSshAuthCred struct { SecretName string } -func (g gitSshAuthCred) goGitCredential(username string) (GoGitCredential, error) { +func (g gitSshAuthCred) auth() (transport.AuthMethod, error) { sshSecret, err := g.fetchSecret() if err != nil { return nil, err } - return &GoGitSshCredential{ - User: username, - PrivateKey: []byte(sshSecret.PrivateKey), - }, nil + keys, err := gitssh.NewPublicKeys("git", []byte(sshSecret.PrivateKey), "") + if err != nil { + return nil, err + } + + return keys, nil +} + +func (g gitSshAuthCred) match(url *url.URL) bool { + return url.Scheme == "ssh" && gitUrlMatch(url.Host, g.Domain) } func (g gitSshAuthCred) name() string { @@ -122,34 +62,22 @@ type gitBasicAuthCred struct { SecretName string } -func (g gitSshAuthCred) match(host string, allowedTypes CredentialType) bool { - if allowedTypes != CredentialTypeSSHKey { - return false - } - //fmt.Printf("gitSshAuthCred.match: host=%s, g.Domain=%s\n", host, g.Domain) - return gitUrlMatch(host, g.Domain) -} - -func (c gitBasicAuthCred) match(host string, allowedTypes CredentialType) bool { - if allowedTypes != CredentialTypeUserpass { - return false - } - //fmt.Printf("gitSshAuthCred.match: host=%s, g.Domain=%s\n", host, c.Domain) - return gitUrlMatch(host, c.Domain) -} - -func (c gitBasicAuthCred) goGitCredential(_ string) (GoGitCredential, error) { +func (c gitBasicAuthCred) auth() (transport.AuthMethod, error) { basicAuthSecret, err := c.fetchSecret() if err != nil { return nil, err } - return &GoGitHttpCredential{ - User: basicAuthSecret.Username, + return &http.BasicAuth{ + Username: basicAuthSecret.Username, Password: basicAuthSecret.Password, }, nil } +func (c gitBasicAuthCred) match(url *url.URL) bool { + return (url.Scheme == "http" || url.Scheme == "https") && gitUrlMatch(url.Host, c.Domain) +} + func (c gitBasicAuthCred) name() string { return c.SecretName } @@ -191,27 +119,19 @@ func NewMountedSecretGitKeychain(volumeName string, basicAuthSecrets, sshAuthSec }, nil } -// Resolve takes in a URL, username and allowedTypes as input and returns a GoGitCredential that matches the input -func (k *secretGitKeychain) Resolve(url string, username string, allowedTypes CredentialType) (GoGitCredential, error) { - //fmt.Printf("secretGitKeychain::Resolve url->%s, username->%s, allowedTypes->%s\n", url, username, allowedTypes) - u, err := giturls.Parse(url) +func (k *secretGitKeychain) Resolve(rawUrl string) (transport.AuthMethod, error) { + parsedUrl, err := giturls.Parse(rawUrl) if err != nil { return nil, err } - if username == "" { - username = u.User.Username() - } - sort.Slice(k.creds, func(i, j int) bool { return k.creds[i].name() < k.creds[j].name() }) - //fmt.Printf("secretGitKeychain::Resolve number of creds: %d\n", len(k.creds)) for _, cred := range k.creds { - //fmt.Printf("secretGitKeychain::Resolve %s\n", cred.name()) - if cred.match(u.Host, allowedTypes) { - return cred.goGitCredential(username) + if cred.match(parsedUrl) { + return cred.auth() } } - return nil, errors.Errorf("no credentials found for %s", url) + return anonymousAuth, nil } diff --git a/pkg/git/git_keychain_test.go b/pkg/git/git_keychain_test.go index 55bae17e..c68df21e 100644 --- a/pkg/git/git_keychain_test.go +++ b/pkg/git/git_keychain_test.go @@ -1,58 +1,82 @@ package git import ( - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/stretchr/testify/require" - "io/ioutil" - corev1 "k8s.io/api/core/v1" "os" "path" - "reflect" "testing" + "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" "github.com/sclevine/spec" + "github.com/stretchr/testify/require" + ssh2 "golang.org/x/crypto/ssh" + corev1 "k8s.io/api/core/v1" ) -func TestGitFileKeychain(t *testing.T) { - spec.Run(t, "Test Git Keychain", testGitFileKeychain) +func TestGitKeychain(t *testing.T) { + privateKeyBytes := gitTest{key1: generateRandomPrivateKey(t), key2: generateRandomPrivateKey(t)} + spec.Run(t, "Test Git Keychain", privateKeyBytes.testGitKeychain) +} + +func writeSecrets(testDir string, secrets map[string]map[string][]byte) error { + for name, creds := range secrets { + err := os.MkdirAll(path.Join(testDir, name), 0777) + if err != nil { + return err + } + for k, v := range creds { + err = os.WriteFile(path.Join(testDir, name, k), v, 0600) + if err != nil { + return err + } + } + } + return nil } -func testGitFileKeychain(t *testing.T, when spec.G, it spec.S) { +func (keys gitTest) testGitKeychain(t *testing.T, when spec.G, it spec.S) { var testDir string var keychain GitKeychain it.Before(func() { var err error - testDir, err = ioutil.TempDir("", "git-keychain") + testDir, err = os.MkdirTemp("", "git-keychain") require.NoError(t, err) - require.NoError(t, os.MkdirAll(path.Join(testDir, "github-creds"), 0777)) - require.NoError(t, os.MkdirAll(path.Join(testDir, "more-github-creds"), 0777)) - require.NoError(t, os.MkdirAll(path.Join(testDir, "bitbucket-creds"), 0777)) - require.NoError(t, os.MkdirAll(path.Join(testDir, "basic-bitbucket-creds"), 0777)) - require.NoError(t, os.MkdirAll(path.Join(testDir, "zzz-ssh-bitbucket-creds"), 0777)) - require.NoError(t, os.MkdirAll(path.Join(testDir, "noscheme-creds"), 0777)) - require.NoError(t, os.MkdirAll(path.Join(testDir, "git-ssh-creds"), 0777)) - - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "github-creds", corev1.BasicAuthUsernameKey), []byte("saved-username"), 0600)) - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "github-creds", corev1.BasicAuthPasswordKey), []byte("saved-password"), 0600)) - - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "more-github-creds", corev1.BasicAuthUsernameKey), []byte("another-saved-username"), 0600)) - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "more-github-creds", corev1.BasicAuthPasswordKey), []byte("another-saved-password"), 0600)) - - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "bitbucket-creds", corev1.SSHAuthPrivateKey), []byte("private key 1"), 0600)) - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "zzz-ssh-bitbucket-creds", corev1.SSHAuthPrivateKey), []byte("private key 2"), 0600)) - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "git-ssh-creds", corev1.SSHAuthPrivateKey), []byte("private key 3"), 0600)) - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "basic-bitbucket-creds", corev1.BasicAuthUsernameKey), []byte("saved-username"), 0600)) - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "basic-bitbucket-creds", corev1.BasicAuthPasswordKey), []byte("saved-password"), 0600)) - - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "noscheme-creds", corev1.BasicAuthUsernameKey), []byte("noschemegit-username"), 0600)) - require.NoError(t, ioutil.WriteFile(path.Join(testDir, "noscheme-creds", corev1.BasicAuthPasswordKey), []byte("noschemegit-password"), 0600)) + secrets := map[string]map[string][]byte{ + "github-creds": { + corev1.BasicAuthUsernameKey: []byte("another-saved-username"), + corev1.BasicAuthPasswordKey: []byte("another-saved-password"), + }, + "additional-github-creds": { + corev1.BasicAuthUsernameKey: []byte("saved-username"), + corev1.BasicAuthPasswordKey: []byte("saved-password"), + }, + "bitbucket-creds": { + corev1.SSHAuthPrivateKey: keys.key1, + }, + "basic-bitbucket-creds": { + corev1.BasicAuthUsernameKey: []byte("saved-username"), + corev1.BasicAuthPasswordKey: []byte("saved-password"), + }, + "zzz-ssh-bitbucket-creds": { + corev1.SSHAuthPrivateKey: []byte("private key 2"), + }, + "noscheme-creds": { + corev1.BasicAuthUsernameKey: []byte("noschemegit-username"), + corev1.BasicAuthPasswordKey: []byte("noschemegit-password"), + }, + "git-ssh-creds": { + corev1.SSHAuthPrivateKey: []byte("private key 3"), + }, + } + + require.NoError(t, writeSecrets(testDir, secrets)) keychain, err = NewMountedSecretGitKeychain(testDir, []string{ "github-creds=https://github.com", - "more-github-creds=https://github.com", + "additional-github-creds=https://github.com", "basic-bitbucket-creds=https://bitbucket.com", "noscheme-creds=noschemegit.com"}, []string{ "zzz-ssh-bitbucket-creds=https://bitbucket.com", @@ -66,55 +90,85 @@ func testGitFileKeychain(t *testing.T, when spec.G, it spec.S) { }) when("Resolve", func() { - it("returns alphabetical first git Auth for matching basic auth secrets", func() { - cred, err := keychain.Resolve("https://github.com/org/repo", "", CredentialTypeUserpass) - require.NoError(t, err) - - require.Equal(t, &GoGitHttpCredential{User: "saved-username", Password: "saved-password"}, cred) - gogitCred, err := cred.Cred() - require.NoError(t, err) + when("there are multiple secrets for the same repository", func() { + it("returns alphabetical first git Auth for matching basic auth secrets", func() { + auth, err := keychain.Resolve("https://github.com/org/repo") + require.NoError(t, err) - require.Equal(t, reflect.TypeOf(gogitCred).Elem().String(), reflect.TypeOf(http.BasicAuth{}).String()) + require.Equal(t, &http.BasicAuth{ + Username: "saved-username", + Password: "saved-password", + }, auth) + }) }) - it("returns git Auth for matching secrets without scheme", func() { - cred, err := keychain.Resolve("https://noschemegit.com/org/repo", "", CredentialTypeUserpass) - require.NoError(t, err) + when("there are ssh and basic auth secret types", func() { + it("returns ssh secret if the target is an ssh target", func() { + auth, err := keychain.Resolve("git@bitbucket.com:org/repo") + require.NoError(t, err) - require.Equal(t, &GoGitHttpCredential{User: "noschemegit-username", Password: "noschemegit-password"}, cred) - }) + publicKeys, ok := auth.(*ssh.PublicKeys) + require.True(t, ok) + + require.Equal(t, "git", publicKeys.User) + + expectedSigner, err := ssh2.ParsePrivateKey(keys.key1) + require.NoError(t, err) + require.Equal(t, expectedSigner, publicKeys.Signer) + }) - when("there are ssh and basic auth secret types", func() { it("returns ssh cred for requested ssh credentials", func() { - cred, err := keychain.Resolve("git@bitbucket.com:org/repo", "git", CredentialTypeSSHKey) + auth, err := keychain.Resolve("git@bitbucket.com:org/repo") + require.NoError(t, err) + + _, ok := auth.(*ssh.PublicKeys) + require.True(t, ok) + + signer, err := ssh2.ParsePrivateKey(keys.key1) require.NoError(t, err) - require.Equal(t, &GoGitSshCredential{User: "git", PrivateKey: []byte("private key 1")}, cred) + require.Equal(t, &ssh.PublicKeys{ + User: "git", + Signer: signer, + }, auth) }) - it("returns basic auth secret for requested basic auth credentials", func() { - cred, err := keychain.Resolve("https://bitbucket.com/org/repo", "git", CredentialTypeUserpass) + it("returns basic auth secret if the target is an https target", func() { + auth, err := keychain.Resolve("https://bitbucket.com/org/repo") require.NoError(t, err) - require.Equal(t, &GoGitHttpCredential{User: "saved-username", Password: "saved-password"}, cred) + require.NoError(t, err) + require.Equal(t, &http.BasicAuth{ + Username: "saved-username", + Password: "saved-password", + }, auth) }) }) - it("returns an error if no credentials found", func() { - _, err := keychain.Resolve("https://no-creds-github.com/org/repo", "git", CredentialTypeUserpass) - require.EqualError(t, err, "no credentials found for https://no-creds-github.com/org/repo") + it("returns git Auth for matching basic auth secrets", func() { + auth, err := keychain.Resolve("https://github.com/org/repo") + require.NoError(t, err) + + require.Equal(t, auth, &http.BasicAuth{ + Username: "saved-username", + Password: "saved-password", + }) }) - when("ssh usernameFromUrl is empty during credential callback", func() { - it("determines correct username", func() { - gitKeychain, err := NewMountedSecretGitKeychain(testDir, []string{}, []string{ - "git-ssh-creds=git@my-git-server.com", - }) - cred, err := gitKeychain.Resolve("ssh://git@my-git-server.com/my-org/my-repo.git", "", CredentialTypeSSHKey) - require.NoError(t, err) + it("returns git Auth for matching secrets without scheme", func() { + auth, err := keychain.Resolve("https://noschemegit.com/org/repo") + require.NoError(t, err) - require.Equal(t, &GoGitSshCredential{User: "git", PrivateKey: []byte("private key 3")}, cred) + require.Equal(t, auth, &http.BasicAuth{ + Username: "noschemegit-username", + Password: "noschemegit-password", }) }) + + it("returns anonymous Auth for no matching secret", func() { + auth, err := keychain.Resolve("https://no-creds-github.com/org/repo") + require.NoError(t, err) + require.Nil(t, auth) + }) }) } diff --git a/pkg/git/k8s_git_keychain.go b/pkg/git/k8s_git_keychain.go index bd73f6d5..9bc1b6dc 100644 --- a/pkg/git/k8s_git_keychain.go +++ b/pkg/git/k8s_git_keychain.go @@ -4,26 +4,32 @@ import ( "context" "fmt" + "github.com/go-git/go-git/v5/plumbing/transport" v1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" k8sclient "k8s.io/client-go/kubernetes" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" "github.com/pivotal/kpack/pkg/secret" ) -type k8sGitKeychainFactory struct { +type k8sGitKeychain struct { secretFetcher secret.Fetcher } -func newK8sGitKeychainFactory(k8sClient k8sclient.Interface) *k8sGitKeychainFactory { - return &k8sGitKeychainFactory{secretFetcher: secret.Fetcher{Client: k8sClient}} +var anonymousAuth transport.AuthMethod = nil + +func newK8sGitKeychain(k8sClient k8sclient.Interface) *k8sGitKeychain { + return &k8sGitKeychain{secretFetcher: secret.Fetcher{Client: k8sClient}} } -func (k *k8sGitKeychainFactory) KeychainForServiceAccount(ctx context.Context, namespace, serviceAccount string) (GitKeychain, error) { +func (k *k8sGitKeychain) Resolve(ctx context.Context, namespace, serviceAccount string, git corev1alpha1.Git) (transport.AuthMethod, error) { secrets, err := k.secretFetcher.SecretsForServiceAccount(ctx, serviceAccount, namespace) if err != nil && !k8serrors.IsNotFound(err) { return nil, err + } else if k8serrors.IsNotFound(err) { + return anonymousAuth, nil } var creds []gitCredential @@ -48,7 +54,7 @@ func (k *k8sGitKeychainFactory) KeychainForServiceAccount(ctx context.Context, n } } - return &secretGitKeychain{creds: creds}, nil + return (&secretGitKeychain{creds: creds}).Resolve(git.URL) } func fetchBasicAuth(s *v1.Secret) func() (secret.BasicAuth, error) { @@ -76,17 +82,10 @@ var matchingDomains = []string{ } func gitUrlMatch(urlMatch, annotatedUrl string) bool { - //fmt.Printf("gitUrlMatch: len(matchingDomains)->%d\n", len(matchingDomains)) for _, format := range matchingDomains { - //fmt.Printf("gitUrlMatch: urlMatch->%s, annotatedUrl->%s, format->%s\n", urlMatch, annotatedUrl, format) - //fmt.Printf("gitUrlMatch: checking match for formatted urlMatch. format->%s, urlMatch->%s, annotatedUrl->%s, Sprintf(format, urlMatch)->%s\n", format, urlMatch, annotatedUrl, fmt.Sprintf(format, urlMatch)) if fmt.Sprintf(format, urlMatch) == annotatedUrl { - // found match for formatted urlMatch - //fmt.Printf("gitUrlMatch: found match for formatted urlMatch. format->%s, urlMatch->%s, annotatedUrl->%s, Sprintf(format, urlMatch)->%s\n", format, urlMatch, annotatedUrl, fmt.Sprintf(format, urlMatch)) return true } } - // no match found for formatted urlMatch - //fmt.Printf("gitUrlMatch: no match found for formatted urlMatch. urlMatch->%s, annotatedUrl->%s\n", urlMatch, annotatedUrl) return false } diff --git a/pkg/git/k8s_git_keychain_test.go b/pkg/git/k8s_git_keychain_test.go index 6c4df18d..ead5b62f 100644 --- a/pkg/git/k8s_git_keychain_test.go +++ b/pkg/git/k8s_git_keychain_test.go @@ -6,21 +6,22 @@ import ( "crypto/rsa" "crypto/x509" "encoding/pem" - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/go-git/go-git/v5/plumbing/transport/ssh" - "reflect" "testing" + "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" "github.com/sclevine/spec" "github.com/stretchr/testify/require" + ssh2 "golang.org/x/crypto/ssh" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" buildapi "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" + "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" ) -func Test(t *testing.T) { +func TestK8sGitKeychain(t *testing.T) { privateKeyBytes := gitTest{key1: generateRandomPrivateKey(t), key2: generateRandomPrivateKey(t)} spec.Run(t, "Test Git Keychain", privateKeyBytes.testK8sGitKeychain) } @@ -79,34 +80,34 @@ func (keys gitTest) testK8sGitKeychain(t *testing.T, when spec.G, it spec.S) { }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: "secret-4", + Name: "secret-5", Namespace: testNamespace, Annotations: map[string]string{ buildapi.GITSecretAnnotationPrefix: "https://gitlab.com", }, }, - Type: v1.SecretTypeSSHAuth, + Type: v1.SecretTypeBasicAuth, Data: map[string][]byte{ - v1.SSHAuthPrivateKey: keys.key1, + v1.BasicAuthUsernameKey: []byte("gitlab-username"), + v1.BasicAuthPasswordKey: []byte("gitlab-password"), }, }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: "secret-5", + Name: "secret-6", Namespace: testNamespace, Annotations: map[string]string{ buildapi.GITSecretAnnotationPrefix: "https://gitlab.com", }, }, - Type: v1.SecretTypeBasicAuth, + Type: v1.SecretTypeSSHAuth, Data: map[string][]byte{ - v1.BasicAuthUsernameKey: []byte("gitlab-username"), - v1.BasicAuthPasswordKey: []byte("gitlab-password"), + v1.SSHAuthPrivateKey: keys.key2, }, }, &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: "secret-6", + Name: "secret-4", Namespace: testNamespace, Annotations: map[string]string{ buildapi.GITSecretAnnotationPrefix: "https://gitlab.com", @@ -114,7 +115,7 @@ func (keys gitTest) testK8sGitKeychain(t *testing.T, when spec.G, it spec.S) { }, Type: v1.SecretTypeSSHAuth, Data: map[string][]byte{ - v1.SSHAuthPrivateKey: keys.key2, + v1.SSHAuthPrivateKey: keys.key1, }, }, &v1.Secret{ @@ -139,68 +140,85 @@ func (keys gitTest) testK8sGitKeychain(t *testing.T, when spec.G, it spec.S) { Secrets: []v1.ObjectReference{ {Name: "secret-1"}, {Name: "secret-2"}, - {Name: "secret-3"}, {Name: "secret-4"}, {Name: "secret-5"}, + {Name: "secret-3"}, {Name: "secret-6"}, {Name: "secret-7"}, }, }) - keychainFactory = newK8sGitKeychainFactory(fakeClient) + keychain = newK8sGitKeychain(fakeClient) ) - when("Keychain resolves", func() { - var keychain GitKeychain + when("K8s Keychain resolves", func() { - it.Before(func() { - var err error - keychain, err = keychainFactory.KeychainForServiceAccount(context.Background(), testNamespace, serviceAccount) + it("returns alphabetical first git Auth for matching secrets with basic auth", func() { + auth, err := keychain.Resolve(context.Background(), testNamespace, serviceAccount, v1alpha1.Git{ + URL: "https://github.com/org/repo", + Revision: "master", + }) require.NoError(t, err) + + require.Equal(t, &http.BasicAuth{ + Username: "saved-username", + Password: "saved-password", + }, auth) }) - it("returns alphabetical first git Auth for matching secrets with basic auth", func() { - cred, err := keychain.Resolve("https://github.com/org/repo", "", CredentialTypeUserpass) + it("returns the alphabetical first secretRef for ssh auth", func() { + auth, err := keychain.Resolve(context.Background(), testNamespace, serviceAccount, v1alpha1.Git{ + URL: "git@gitlab.com:org/repo", + Revision: "master", + }) require.NoError(t, err) - require.Equal(t, GoGitHttpCredential{ - User: "saved-username", - Password: "saved-password", - }, cred) + publicKeys, ok := auth.(*ssh.PublicKeys) + require.True(t, ok) - gogitCred, err := cred.Cred() - require.NoError(t, err) + require.Equal(t, "git", publicKeys.User) - require.Equal(t, reflect.TypeOf(gogitCred).Elem().String(), reflect.TypeOf(http.BasicAuth{}).String()) + expectedSigner, err := ssh2.ParsePrivateKey(keys.key1) + require.NoError(t, err) + require.Equal(t, expectedSigner, publicKeys.Signer) }) - it("returns the alphabetical first secretRef for ssh auth", func() { - cred, err := keychain.Resolve("https://gitlab.com/my-repo.git", "gituser", CredentialTypeSSHKey) + it("returns git Auth for matching secrets with ssh auth", func() { + auth, err := keychain.Resolve(context.Background(), testNamespace, serviceAccount, v1alpha1.Git{ + URL: "git@bitbucket.com:org/repo", + Revision: "master", + }) require.NoError(t, err) - require.Equal(t, &GoGitSshCredential{ - User: "gituser", - PrivateKey: keys.key1, - }, cred) + publicKeys, ok := auth.(*ssh.PublicKeys) + require.True(t, ok) - gogitCred, err := cred.Cred() - require.NoError(t, err) + require.Equal(t, "git", publicKeys.User) - require.Equal(t, reflect.TypeOf(gogitCred).Elem().String(), reflect.TypeOf(ssh.PublicKeys{}).String()) + signer, err := ssh2.ParsePrivateKey(keys.key1) + require.NoError(t, err) + require.Equal(t, signer, publicKeys.Signer) }) it("returns git Auth for matching secrets without scheme", func() { - cred, err := keychain.Resolve("https://noschemegit.com/org/repo", "", CredentialTypeUserpass) + auth, err := keychain.Resolve(context.Background(), testNamespace, serviceAccount, v1alpha1.Git{ + URL: "https://noschemegit.com/org/repo", + Revision: "master", + }) require.NoError(t, err) - require.Equal(t, GoGitHttpCredential{ - User: "noschemegit-username", + require.Equal(t, &http.BasicAuth{ + Username: "noschemegit-username", Password: "noschemegit-password", - }, cred) + }, auth) }) - it("returns an error if no credential are found", func() { - _, err := keychain.Resolve("https://notfound.com/org/repo", "git", CredentialTypeUserpass) - require.EqualError(t, err, "no credentials found for https://notfound.com/org/repo") + it("returns anonymous Auth for no matching secret", func() { + auth, err := keychain.Resolve(context.Background(), testNamespace, serviceAccount, v1alpha1.Git{ + URL: "https://no-creds-github.com/org/repo", + Revision: "master", + }) + require.NoError(t, err) + require.Nil(t, auth) }) }) } diff --git a/pkg/git/remote_git_resolver.go b/pkg/git/remote_git_resolver.go index 7b6fa9ec..b9aad4c4 100644 --- a/pkg/git/remote_git_resolver.go +++ b/pkg/git/remote_git_resolver.go @@ -1,61 +1,27 @@ package git import ( - "fmt" gogit "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/transport" - "io/ioutil" - "log" - "os" - - "github.com/pkg/errors" + "github.com/go-git/go-git/v5/plumbing/transport/client" + "github.com/go-git/go-git/v5/storage/memory" corev1alpha1 "github.com/pivotal/kpack/pkg/apis/core/v1alpha1" ) const defaultRemote = "origin" -var discardLogger = log.New(ioutil.Discard, "", 0) - -type remoteGitResolver struct { -} +type remoteGitResolver struct{} -func (*remoteGitResolver) Resolve(keychain GitKeychain, sourceConfig corev1alpha1.SourceConfig) (corev1alpha1.ResolvedSourceConfig, error) { - // initialize a new repository in a temporary directory - dir, err := ioutil.TempDir("", "kpack-git") - if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "creating temp dir") - } - defer os.RemoveAll(dir) - // initialize a new repository - repository, err := gogit.PlainInit(dir, false) - if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "initializing repo") - } - // create a new remote - remote, err := repository.CreateRemote(&config.RemoteConfig{ +func (*remoteGitResolver) Resolve(auth transport.AuthMethod, sourceConfig corev1alpha1.SourceConfig) (corev1alpha1.ResolvedSourceConfig, error) { + remote := gogit.NewRemote(memory.NewStorage(), &config.RemoteConfig{ Name: defaultRemote, URLs: []string{sourceConfig.Git.URL}, }) - cred, err := keychain.Resolve(sourceConfig.Git.URL, "", CredentialTypeUserpass) - if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "getting auth for url") - } - - auth, err := cred.Cred() - if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "getting auth for url") - } - - // fetch the remote - err = remote.Fetch(&gogit.FetchOptions{ - RemoteName: defaultRemote, - Auth: auth, - Progress: discardLogger.Writer(), - }) + httpsTransport, err := getHttpsTransport() if err != nil { return corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ @@ -66,30 +32,32 @@ func (*remoteGitResolver) Resolve(keychain GitKeychain, sourceConfig corev1alpha }, }, nil } + client.InstallProtocol("https", httpsTransport) - // get the remote references - references, err := remote.List(&gogit.ListOptions{ + refs, err := remote.List(&gogit.ListOptions{ Auth: auth, }) if err != nil { - return corev1alpha1.ResolvedSourceConfig{}, errors.Wrap(err, "listing remote references") + return corev1alpha1.ResolvedSourceConfig{ + Git: &corev1alpha1.ResolvedGitSource{ + URL: sourceConfig.Git.URL, + Revision: sourceConfig.Git.Revision, + Type: corev1alpha1.Unknown, + SubPath: sourceConfig.SubPath, + }, + }, nil } - // iterate over the references - for _, reference := range references { - // iterate over the revRefParseRules - for _, revRefParseRule := range refRevParseRules { - // return ResolvedSourceConfig if the sourceConfig.Git.Revision matches the reference.Name() - if fmt.Sprintf(revRefParseRule, sourceConfig.Git.Revision) == reference.Name().String() { - return corev1alpha1.ResolvedSourceConfig{ - Git: &corev1alpha1.ResolvedGitSource{ - URL: sourceConfig.Git.URL, - Revision: reference.Hash().String(), - Type: referenceNameToType(reference.Name()), - SubPath: sourceConfig.SubPath, - }, - }, nil - } + for _, ref := range refs { + if ref.Name().Short() == sourceConfig.Git.Revision { + return corev1alpha1.ResolvedSourceConfig{ + Git: &corev1alpha1.ResolvedGitSource{ + URL: sourceConfig.Git.URL, + Revision: ref.Hash().String(), + Type: sourceType(ref), + SubPath: sourceConfig.SubPath, + }, + }, nil } } @@ -103,38 +71,13 @@ func (*remoteGitResolver) Resolve(keychain GitKeychain, sourceConfig corev1alpha }, nil } -type transportCallbackAdapter struct { - keychain GitKeychain -} - -func keychainAsAuth(keychain GitKeychain, url string, usernameFromUrl string, allowedTypes CredentialType) (transport.AuthMethod, error) { - // Resolve(url string, usernameFromUrl string, allowedTypes CredentialType) (GoGitCredential, error) - goGitCredential, err := keychain.Resolve(url, usernameFromUrl, allowedTypes) - if err != nil { - return nil, err - } - auth, err := goGitCredential.Cred() - if err != nil { - return nil, err - } - return auth, nil -} - -func referenceNameToType(referenceName plumbing.ReferenceName) corev1alpha1.GitSourceKind { +func sourceType(reference *plumbing.Reference) corev1alpha1.GitSourceKind { switch { - case referenceName.IsBranch(): + case reference.Name().IsBranch(): return corev1alpha1.Branch - case referenceName.IsTag(): + case reference.Name().IsTag(): return corev1alpha1.Tag default: return corev1alpha1.Unknown } } - -var refRevParseRules = []string{ - "refs/%s", - "refs/tags/%s", - "refs/heads/%s", - "refs/remotes/%s", - "refs/remotes/%s/HEAD", -} diff --git a/pkg/git/remote_git_resolver_test.go b/pkg/git/remote_git_resolver_test.go index 01af10c2..2b54fe20 100644 --- a/pkg/git/remote_git_resolver_test.go +++ b/pkg/git/remote_git_resolver_test.go @@ -3,6 +3,7 @@ package git import ( "testing" + "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/sclevine/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -26,9 +27,9 @@ func testRemoteGitResolver(t *testing.T, when spec.G, it spec.S) { when("#Resolve", func() { when("source is a commit", func() { it("returns type commit", func() { - gitResolver := &remoteGitResolver{} + gitResolver := remoteGitResolver{} - resolvedGitSource, err := gitResolver.Resolve(&fakeGitKeychain{}, corev1alpha1.SourceConfig{ + resolvedGitSource, err := gitResolver.Resolve(anonymousAuth, corev1alpha1.SourceConfig{ Git: &corev1alpha1.Git{ URL: url, Revision: nonHEADCommit, @@ -37,22 +38,22 @@ func testRemoteGitResolver(t *testing.T, when spec.G, it spec.S) { }) require.NoError(t, err) - assert.Equal(t, resolvedGitSource, corev1alpha1.ResolvedSourceConfig{ + assert.Equal(t, corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ URL: url, Revision: nonHEADCommit, SubPath: "/foo/bar", Type: corev1alpha1.Commit, }, - }) + }, resolvedGitSource) }) }) when("source is a branch", func() { it("returns branch with resolved commit", func() { - gitResolver := &remoteGitResolver{} + gitResolver := remoteGitResolver{} - resolvedGitSource, err := gitResolver.Resolve(&fakeGitKeychain{}, corev1alpha1.SourceConfig{ + resolvedGitSource, err := gitResolver.Resolve(anonymousAuth, corev1alpha1.SourceConfig{ Git: &corev1alpha1.Git{ URL: url, Revision: "master", @@ -61,14 +62,14 @@ func testRemoteGitResolver(t *testing.T, when spec.G, it spec.S) { }) require.NoError(t, err) - assert.Equal(t, resolvedGitSource, corev1alpha1.ResolvedSourceConfig{ + assert.Equal(t, corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ URL: url, Revision: fixtureHEADMasterCommit, Type: corev1alpha1.Branch, SubPath: "/foo/bar", }, - }) + }, resolvedGitSource) }) }) @@ -76,9 +77,9 @@ func testRemoteGitResolver(t *testing.T, when spec.G, it spec.S) { it("returns tag with resolved commit", func() { tagsUrl := "https://github.com/git-fixtures/tags.git" - gitResolver := &remoteGitResolver{} + gitResolver := remoteGitResolver{} - resolvedGitSource, err := gitResolver.Resolve(&fakeGitKeychain{}, corev1alpha1.SourceConfig{ + resolvedGitSource, err := gitResolver.Resolve(anonymousAuth, corev1alpha1.SourceConfig{ Git: &corev1alpha1.Git{ URL: tagsUrl, Revision: tag, @@ -87,38 +88,40 @@ func testRemoteGitResolver(t *testing.T, when spec.G, it spec.S) { }) require.NoError(t, err) - assert.Equal(t, resolvedGitSource, corev1alpha1.ResolvedSourceConfig{ + assert.Equal(t, corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ URL: tagsUrl, Revision: tagCommit, Type: corev1alpha1.Tag, SubPath: "/foo/bar", }, - }) + }, resolvedGitSource) }) }) when("authentication fails", func() { it("returns an unknown type", func() { - gitResolver := &remoteGitResolver{} + gitResolver := remoteGitResolver{} - resolvedGitSource, err := gitResolver.Resolve(&fakeGitKeychain{}, corev1alpha1.SourceConfig{ + resolvedGitSource, _ := gitResolver.Resolve(&http.BasicAuth{ + Username: "bad-username", + Password: "bad-password", + }, corev1alpha1.SourceConfig{ Git: &corev1alpha1.Git{ URL: "git@localhost:org/repo", Revision: tag, }, SubPath: "/foo/bar", }) - require.NoError(t, err) - assert.Equal(t, resolvedGitSource, corev1alpha1.ResolvedSourceConfig{ + assert.Equal(t, corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ URL: "git@localhost:org/repo", Revision: tag, Type: corev1alpha1.Unknown, SubPath: "/foo/bar", }, - }) + }, resolvedGitSource) }) }) }) diff --git a/pkg/git/resolver.go b/pkg/git/resolver.go index 948ffccb..0dc5237b 100644 --- a/pkg/git/resolver.go +++ b/pkg/git/resolver.go @@ -11,23 +11,23 @@ import ( type Resolver struct { remoteGitResolver remoteGitResolver - gitKeychain *k8sGitKeychainFactory + gitKeychain *k8sGitKeychain } func NewResolver(k8sClient k8sclient.Interface) *Resolver { return &Resolver{ remoteGitResolver: remoteGitResolver{}, - gitKeychain: newK8sGitKeychainFactory(k8sClient), + gitKeychain: newK8sGitKeychain(k8sClient), } } func (r *Resolver) Resolve(ctx context.Context, sourceResolver *buildapi.SourceResolver) (corev1alpha1.ResolvedSourceConfig, error) { - keychain, err := r.gitKeychain.KeychainForServiceAccount(ctx, sourceResolver.Namespace, sourceResolver.Spec.ServiceAccountName) + auth, err := r.gitKeychain.Resolve(ctx, sourceResolver.Namespace, sourceResolver.Spec.ServiceAccountName, *sourceResolver.Spec.Source.Git) if err != nil { return corev1alpha1.ResolvedSourceConfig{}, err } - return r.remoteGitResolver.Resolve(keychain, sourceResolver.Spec.Source) + return r.remoteGitResolver.Resolve(auth, sourceResolver.Spec.Source) } func (*Resolver) CanResolve(sourceResolver *buildapi.SourceResolver) bool { diff --git a/pkg/git/url_parser.go b/pkg/git/url_parser.go index 9e5f70dc..e0ad0e90 100644 --- a/pkg/git/url_parser.go +++ b/pkg/git/url_parser.go @@ -8,7 +8,7 @@ import ( var shortScpRegex = regexp.MustCompile(`^(ssh://)?(.*)@([[:alnum:]\.-]+):(.*)$`) // ParseURL converts a short scp-like SSH syntax to a proper SSH URL. -// Git's ssh protocol supports a url like user@hostname:path syntax, which is +// Git's ssh protocol supports a URL like user@hostname:path syntax, which is // not a valid ssh url but is inherited from scp. Because the library we // use for git relies on the Golang SSH support, we need to convert it to a // proper SSH URL. From ac7e41b4947b9066da2598dbdbdc3c9019cc4ff2 Mon Sep 17 00:00:00 2001 From: Bohan Chen Date: Tue, 28 Mar 2023 16:35:44 -0400 Subject: [PATCH 33/39] fix tests ggcr now wraps the underlying http error, so we have to unwrap and check instead of directly comparing Signed-off-by: Bohan Chen --- pkg/dockercreds/access_checker_test.go | 2 +- pkg/registry/client.go | 3 ++- pkg/registry/client_test.go | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/dockercreds/access_checker_test.go b/pkg/dockercreds/access_checker_test.go index dd1e7989..83e67fbc 100644 --- a/pkg/dockercreds/access_checker_test.go +++ b/pkg/dockercreds/access_checker_test.go @@ -84,7 +84,7 @@ func testAccessChecker(t *testing.T, when spec.G, it spec.S) { }) err := VerifyReadAccess(testKeychain{}, tagName) - assert.EqualError(t, err, fmt.Sprintf("GET %s/v2/: unexpected status code 404 Not Found", server.URL)) + assert.ErrorContains(t, err, fmt.Sprintf("GET %s/v2/: unexpected status code 404 Not Found", server.URL)) }) }) } diff --git a/pkg/registry/client.go b/pkg/registry/client.go index 0daad6ba..9fa0d615 100644 --- a/pkg/registry/client.go +++ b/pkg/registry/client.go @@ -88,7 +88,8 @@ func previousDigest(keychain authn.Keychain, ref name.Reference) string { } func handleError(err error) error { - if transportErr, ok := err.(*transport.Error); ok { + var transportErr *transport.Error + if errors.As(err, &transportErr) { if transportErr.StatusCode != http.StatusUnauthorized && transportErr.StatusCode != http.StatusForbidden { return &reconciler.NetworkError{ diff --git a/pkg/registry/client_test.go b/pkg/registry/client_test.go index 68116736..133f6f71 100644 --- a/pkg/registry/client_test.go +++ b/pkg/registry/client_test.go @@ -104,7 +104,7 @@ func testClient(t *testing.T, when spec.G, it spec.S) { when("network", func() { it.Before(func() { handler.HandleFunc("/v2/", func(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(404) + writer.WriteHeader(http.StatusNotFound) }) }) it("wraps it to NetworkError", func() { From 17703762f9da589a4561bb3676352b0a3c299e46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 20:44:13 +0000 Subject: [PATCH 34/39] Bump go.uber.org/zap from 1.23.0 to 1.24.0 Bumps [go.uber.org/zap](https://github.com/uber-go/zap) from 1.23.0 to 1.24.0. - [Release notes](https://github.com/uber-go/zap/releases) - [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md) - [Commits](https://github.com/uber-go/zap/compare/v1.23.0...v1.24.0) --- updated-dependencies: - dependency-name: go.uber.org/zap dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index de829f85..1a4ac002 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f github.com/vdemeester/k8s-pkg-credentialprovider v1.22.4 github.com/whilp/git-urls v1.0.0 - go.uber.org/zap v1.23.0 + go.uber.org/zap v1.24.0 golang.org/x/crypto v0.7.0 golang.org/x/net v0.8.0 golang.org/x/sync v0.1.0 diff --git a/go.sum b/go.sum index f7923f1d..7c729995 100644 --- a/go.sum +++ b/go.sum @@ -1656,8 +1656,8 @@ go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= From 6ee1a4ba3b46556b87e0ba7beba45f61a1ef87ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 21:09:28 +0000 Subject: [PATCH 35/39] Bump github.com/BurntSushi/toml from 1.1.0 to 1.2.1 Bumps [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) from 1.1.0 to 1.2.1. - [Release notes](https://github.com/BurntSushi/toml/releases) - [Commits](https://github.com/BurntSushi/toml/compare/v1.1.0...v1.2.1) --- updated-dependencies: - dependency-name: github.com/BurntSushi/toml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1a4ac002..caa2d0fc 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/pivotal/kpack go 1.18 require ( - github.com/BurntSushi/toml v1.1.0 + github.com/BurntSushi/toml v1.2.1 github.com/Masterminds/semver/v3 v3.1.1 github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a github.com/buildpacks/imgutil v0.0.0-20220527150729-7a271a852e31 diff --git a/go.sum b/go.sum index 7c729995..bbd53902 100644 --- a/go.sum +++ b/go.sum @@ -138,8 +138,8 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ= From 42b4aee0844537f9abd4609765702b7fa3dd8c2e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 21:16:45 +0000 Subject: [PATCH 36/39] Bump google.golang.org/protobuf from 1.29.0 to 1.29.1 Bumps google.golang.org/protobuf from 1.29.0 to 1.29.1. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index caa2d0fc..7fb58b4e 100644 --- a/go.mod +++ b/go.mod @@ -296,7 +296,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2 // indirect google.golang.org/grpc v1.51.0 // indirect - google.golang.org/protobuf v1.29.0 // indirect + google.golang.org/protobuf v1.29.1 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index bbd53902..99d4e62b 100644 --- a/go.sum +++ b/go.sum @@ -2337,8 +2337,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.29.0 h1:44S3JjaKmLEE4YIkjzexaP+NzZsudE3Zin5Njn/pYX0= -google.golang.org/protobuf v1.29.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc= From fccb5a7edae5e17b2bdefa370ff277450961a47d Mon Sep 17 00:00:00 2001 From: Nicholas Carlson Date: Wed, 29 Mar 2023 09:42:21 -0600 Subject: [PATCH 37/39] Improved readability --- pkg/git/fetch_test.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pkg/git/fetch_test.go b/pkg/git/fetch_test.go index eca3eaba..23d56101 100644 --- a/pkg/git/fetch_test.go +++ b/pkg/git/fetch_test.go @@ -35,11 +35,11 @@ func testGitCheckout(t *testing.T, when spec.G, it spec.S) { metadataDir, err = os.MkdirTemp("", "test-git") require.NoError(t, err) - os.Unsetenv("HTTPS_PROXY") + + require.NoError(t, os.Unsetenv("HTTPS_PROXY")) }) it.After(func() { - os.Unsetenv("HTTPS_PROXY") require.NoError(t, os.RemoveAll(testDir)) require.NoError(t, os.RemoveAll(metadataDir)) }) @@ -85,9 +85,10 @@ func testGitCheckout(t *testing.T, when spec.G, it spec.S) { it("preserves symbolic links", func() { err := fetcher.Fetch(testDir, "https://github.com/git-fixtures/symlinks", "master", metadataDir) require.NoError(t, err) + fileInfo, err := os.Lstat(path.Join(testDir, "bar")) - isSymlink := fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink - require.True(t, isSymlink, "bar is expected to be a symbolic link") + require.NoError(t, err) + require.Equal(t, fileInfo.Mode().Type(), os.ModeSymlink) }) it("preserves executable permission", func() { @@ -95,12 +96,12 @@ func testGitCheckout(t *testing.T, when spec.G, it spec.S) { require.NoError(t, err) fileInfo, err := os.Lstat(path.Join(testDir, "hack", "apply.sh")) - isExecutable := isExecutableByAll(fileInfo.Mode()) - require.True(t, isExecutable, "apply.sh is expected to be executable by owner, group, and other") + require.NoError(t, err) + require.True(t, isExecutableByAll(fileInfo.Mode())) fileInfo, err = os.Lstat(path.Join(testDir, "hack", "tools.go")) - isExecutable = isExecutableByAny(fileInfo.Mode()) - require.False(t, isExecutable, "tools.go is expected to not be executable") + require.NoError(t, err) + require.False(t, isExecutableByAny(fileInfo.Mode())) }) it("returns invalid credentials to fetch error on authentication required", func() { @@ -111,6 +112,7 @@ func testGitCheckout(t *testing.T, when spec.G, it spec.S) { it("uses the http proxy env vars", func() { require.NoError(t, os.Setenv("HTTPS_PROXY", "http://invalid-proxy")) defer os.Unsetenv("HTTPS_PROXY") + err := fetcher.Fetch(testDir, "https://github.com/git-fixtures/basic", "master", metadataDir) require.Error(t, err) require.Contains(t, err.Error(), "no such host") From 5d277896470da424db352e7f5fd46a475318d791 Mon Sep 17 00:00:00 2001 From: Nicholas Carlson Date: Wed, 29 Mar 2023 10:17:16 -0600 Subject: [PATCH 38/39] Bumps github.com/BurntSushi/toml from v1.1.0 to v1.2.1 Bumps github.com/go-git/go-git/v5 from v5.6.0 to v5.6.1 --- go.mod | 8 ++++---- go.sum | 26 ++++++++++++++------------ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index a3536a62..68d6e23d 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,10 @@ require ( github.com/buildpacks/imgutil v0.0.0-20220527150729-7a271a852e31 github.com/buildpacks/lifecycle v0.14.1 github.com/ghodss/yaml v1.0.0 + github.com/go-git/go-git/v5 v5.6.1 github.com/google/go-cmp v0.5.9 github.com/google/go-containerregistry v0.14.0 github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20220413173345-f1b065c6cb3d - github.com/libgit2/git2go/v33 v33.0.4 github.com/matthewmcnew/archtest v0.0.0-20191014222827-a111193b50ad github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b github.com/pkg/errors v0.9.1 @@ -59,9 +59,9 @@ require ( github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/ThalesIgnite/crypto11 v1.2.5 // indirect - github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/acomagu/bufpipe v1.0.4 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect @@ -134,7 +134,7 @@ require ( github.com/fullstorydev/grpcurl v1.8.7 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-git/gcfg v1.5.0 // indirect - github.com/go-git/go-billy/v5 v5.4.0 // indirect + github.com/go-git/go-billy/v5 v5.4.1 // indirect github.com/go-kit/log v0.2.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect diff --git a/go.sum b/go.sum index b1226b14..e998befd 100644 --- a/go.sum +++ b/go.sum @@ -162,8 +162,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= -github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d h1:hi6J4K6DKrR4/ljxn6SF6nURyu785wKMuQcjt7H3VCQ= @@ -173,8 +173,8 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E= github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= -github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= @@ -563,12 +563,12 @@ github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxm github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.4.0 h1:Vaw7LaSTRJOUric7pe4vnzBSgyuf2KrLsu2Y4ZpQBDE= -github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= +github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.6.0 h1:JvBdYfcttd+0kdpuWO7KTu0FYgCf5W0t5VwkWGobaa4= -github.com/go-git/go-git/v5 v5.6.0/go.mod h1:6nmJ0tJ3N4noMV1Omv7rC5FG3/o8Cm51TB4CJp7mRmE= +github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= +github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC2MDs4ee8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -1734,7 +1734,7 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1859,7 +1859,8 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -2023,8 +2024,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -2034,7 +2035,7 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2047,6 +2048,7 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 055789db20cdfaf67245abfb36585a1fc95cc979 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 19:12:03 +0000 Subject: [PATCH 39/39] Bump github.com/theupdateframework/notary Bumps [github.com/theupdateframework/notary](https://github.com/theupdateframework/notary) from 0.6.2-0.20200804143915-84287fd8df4f to 0.7.0. - [Release notes](https://github.com/theupdateframework/notary/releases) - [Changelog](https://github.com/notaryproject/notary/blob/master/CHANGELOG.md) - [Commits](https://github.com/theupdateframework/notary/commits/v0.7.0) --- updated-dependencies: - dependency-name: github.com/theupdateframework/notary dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 68d6e23d..3a126272 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/sirupsen/logrus v1.9.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 - github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f + github.com/theupdateframework/notary v0.7.0 github.com/vdemeester/k8s-pkg-credentialprovider v1.22.4 github.com/whilp/git-urls v1.0.0 go.uber.org/zap v1.24.0 diff --git a/go.sum b/go.sum index e998befd..85bed76c 100644 --- a/go.sum +++ b/go.sum @@ -1479,8 +1479,8 @@ github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gt github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU= github.com/theupdateframework/go-tuf v0.5.2-0.20220930112810-3890c1e7ace4 h1:1i/Afw3rmaR1gF3sfVkG2X6ldkikQwA9zY380LrR5YI= github.com/theupdateframework/go-tuf v0.5.2-0.20220930112810-3890c1e7ace4/go.mod h1:vAqWV3zEs89byeFsAYoh/Q14vJTgJkHwnnRCWBBBINY= -github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f h1:myKguilK7Xy8V5sjfJ8CYn2cD/aRlDFO4hzkqZ9HhgQ= -github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f/go.mod h1:VmySTua0RaZOe78Zx4/i3bCl9eNs0UvBOPV+1ps9t6U= +github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= +github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= @@ -1719,6 +1719,7 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=