diff --git a/go.mod b/go.mod index 70b6fdefa..73e237e0f 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,13 @@ go 1.22.4 // Kubernetes replace ( k8s.io/client-go => k8s.io/client-go v0.30.3 - k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20240726031636-6f6746feab9c k8s.io/kubectl => k8s.io/kubectl v0.30.3 ) // Openshift replace ( - github.com/openshift/api => github.com/openshift/api v0.0.0-20240722135205-ae4f370f361f + github.com/openshift/api => github.com/openshift/api v0.0.0-20240724184751-84047ef4a2ce github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20240528061634-b054aa794d87 ) @@ -19,11 +19,11 @@ require ( github.com/alexflint/go-arg v1.5.1 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/onsi/ginkgo/v2 v2.19.0 - github.com/onsi/gomega v1.33.1 + github.com/onsi/gomega v1.34.0 github.com/openshift/api v3.9.0+incompatible github.com/openshift/client-go v3.9.0+incompatible github.com/spf13/cobra v1.8.1 - github.com/tektoncd/pipeline v0.61.1 + github.com/tektoncd/pipeline v0.62.0 go.uber.org/zap v1.27.0 k8s.io/api v0.30.3 k8s.io/apimachinery v0.30.3 @@ -150,7 +150,7 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-aggregator v0.30.3 // indirect k8s.io/kube-openapi v0.30.0 // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.2.4 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.17.3 // indirect diff --git a/go.sum b/go.sum index 405aea264..5c1e49723 100644 --- a/go.sum +++ b/go.sum @@ -688,6 +688,7 @@ github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4x github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go-v2 v1.27.2 h1:pLsTXqX93rimAOZG2FIYraDQstZaaGVVN4tNw65v0h8= github.com/aws/aws-sdk-go-v2 v1.27.2/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/config v1.27.18 h1:wFvAnwOKKe7QAyIxziwSKjmer9JBMH1vzIL6W+fYuKk= @@ -1304,12 +1305,16 @@ github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKi github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= +github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/openshift/api v0.0.0-20240722135205-ae4f370f361f h1:B+uJ4LmjO+qwMTZP2YhlpMziMPD4MD1++WdCAV2y+GI= github.com/openshift/api v0.0.0-20240722135205-ae4f370f361f/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM= +github.com/openshift/api v0.0.0-20240724184751-84047ef4a2ce h1:AR9XMlwc7akIN13KDx4L0tI04zHf8jEZ1z1RMRbz1J0= +github.com/openshift/api v0.0.0-20240724184751-84047ef4a2ce/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM= github.com/openshift/client-go v0.0.0-20240528061634-b054aa794d87 h1:JtLhaGpSEconE+1IKmIgCOof/Len5ceG6H1pk43yv5U= github.com/openshift/client-go v0.0.0-20240528061634-b054aa794d87/go.mod h1:3IPD4U0qyovZS4EFady2kqY32m8lGcbs/Wx+yprg9z8= github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPfHnSOQoQf/sypqA6A4= @@ -1383,6 +1388,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1453,6 +1459,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/tektoncd/pipeline v0.61.1 h1:FB4zh6YmLshFUJ0AigJVLN8RMuVfBxuQvhqZk5ngyI8= github.com/tektoncd/pipeline v0.61.1/go.mod h1:m2zG2B124Gh7/VB4G3+NGSyyzy0q5ceNyLUqIz0cIyQ= +github.com/tektoncd/pipeline v0.62.0 h1:9qAE2ewb3X/3187e1YdrAirrsaqkQwl1u+bzp306UfM= +github.com/tektoncd/pipeline v0.62.0/go.mod h1:cYPH4n3X8t39arNMhgyU7swyv3hVeWToz1yYDRzTLT8= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -1541,6 +1549,7 @@ golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1m golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1694,6 +1703,7 @@ golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1867,10 +1877,12 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1890,6 +1902,7 @@ golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1912,6 +1925,7 @@ golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2004,6 +2018,8 @@ golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0 golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2386,12 +2402,16 @@ k8s.io/kube-aggregator v0.30.3 h1:hy5zfQ7p6BuJgc/XtGp3GBh2MPfOj6b1n3raKKMHOQE= k8s.io/kube-aggregator v0.30.3/go.mod h1:2SP0IckvQoOwwZN8lmtWUnTZTgIpwOWvidWtxyqLwuk= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6zX/gcJr22cjrsej+W784Tc= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= +k8s.io/kube-openapi v0.0.0-20240726031636-6f6746feab9c h1:CHL3IcTrTI3csK36iwYJy36uQRic+IpSoRMNH+0I8SE= +k8s.io/kube-openapi v0.0.0-20240726031636-6f6746feab9c/go.mod h1:0CVn9SVo8PeW5/JgsBZZIFmmTk5noOM8WXf2e1tCihE= k8s.io/kubectl v0.30.3 h1:YIBBvMdTW0xcDpmrOBzcpUVsn+zOgjMYIu7kAq+yqiI= k8s.io/kubectl v0.30.3/go.mod h1:IcR0I9RN2+zzTRUa1BzZCm4oM0NLOawE6RzlDvd1Fpo= k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= knative.dev/pkg v0.0.0-20240716082220-4355f0c73608 h1:BOiRzcnRS9Z5ruxlCiS/K1/Hb5bUN0X4W3xCegdcYQE= knative.dev/pkg v0.0.0-20240716082220-4355f0c73608/go.mod h1:M67lDZ4KbltYSon0Ox4/6qjlZNOIXW4Ldequ81yofbw= kubevirt.io/api v1.3.0 h1:9sGElMmnRU50pGED+MPPD2OwQl4S5lvjCUjm+t0mI90= diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 62af14ad2..9572e5fa6 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,20 @@ +## 1.34.0 + +### Features +- Add RoundTripper method to ghttp.Server [c549e0d] + +### Fixes +- fix incorrect handling of nil slices in HaveExactElements (fixes #771) [878940c] +- issue_765 - fixed bug in Hopcroft-Karp algorithm [ebadb67] + +### Maintenance +- bump ginkgo [8af2ece] +- Fix typo in docs [123a071] +- Bump github.com/onsi/ginkgo/v2 from 2.17.2 to 2.17.3 (#756) [0e69083] +- Bump google.golang.org/protobuf from 1.33.0 to 1.34.1 (#755) [2675796] +- Bump golang.org/x/net from 0.24.0 to 0.25.0 (#754) [4160c0f] +- Bump github-pages from 230 to 231 in /docs (#748) [892c303] + ## 1.33.1 ### Fixes diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index 9697d5134..650ae8672 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.33.1" +const GOMEGA_VERSION = "1.34.0" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). diff --git a/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go b/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go index dca5b9446..5a236d7d6 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go +++ b/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go @@ -30,15 +30,18 @@ func (matcher *HaveExactElementsMatcher) Match(actual interface{}) (success bool lenMatchers := len(matchers) lenValues := len(values) + success = true for i := 0; i < lenMatchers || i < lenValues; i++ { if i >= lenMatchers { matcher.extraIndex = i + success = false continue } if i >= lenValues { matcher.missingIndex = i + success = false return } @@ -49,15 +52,17 @@ func (matcher *HaveExactElementsMatcher) Match(actual interface{}) (success bool index: i, failure: err.Error(), }) + success = false } else if !match { matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ index: i, failure: elemMatcher.FailureMessage(values[i]), }) + success = false } } - return matcher.missingIndex+matcher.extraIndex+len(matcher.mismatchFailures) == 0, nil + return success, nil } func (matcher *HaveExactElementsMatcher) FailureMessage(actual interface{}) (message string) { diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go index 1c54edd8f..44aa61d4b 100644 --- a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go +++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go @@ -1,6 +1,8 @@ package bipartitegraph import ( + "slices" + . "github.com/onsi/gomega/matchers/support/goraph/edge" . "github.com/onsi/gomega/matchers/support/goraph/node" "github.com/onsi/gomega/matchers/support/goraph/util" @@ -157,6 +159,11 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [ if len(currentLayer) == 0 { return []NodeOrderedSet{} } + if done { // if last layer - into last layer must be only 'free' nodes + currentLayer = slices.DeleteFunc(currentLayer, func(in Node) bool { + return !matching.Free(in) + }) + } guideLayers = append(guideLayers, currentLayer) } diff --git a/vendor/github.com/tektoncd/pipeline/internal/artifactref/artifactref.go b/vendor/github.com/tektoncd/pipeline/internal/artifactref/artifactref.go index b5a46a730..cd8e1162c 100644 --- a/vendor/github.com/tektoncd/pipeline/internal/artifactref/artifactref.go +++ b/vendor/github.com/tektoncd/pipeline/internal/artifactref/artifactref.go @@ -2,10 +2,17 @@ package artifactref import "regexp" -// case 1: steps..inputs -// case 2: steps..outputs -// case 3: steps..inputs. -// case 4: steps..outputs. -const stepArtifactUsagePattern = `\$\(steps\.([^.]+)\.(?:inputs|outputs)(?:\.([^.^\)]+))?\)` +// case 1: steps..inputs. +// case 2: steps..outputs. +const stepArtifactUsagePattern = `\$\(steps\.([^.]+)\.(?:inputs|outputs)\.([^.)]+)\)` + +// case 1: tasks..inputs. +// case 2: tasks..outputs. +const taskArtifactUsagePattern = `\$\(tasks\.([^.]+)\.(?:inputs|outputs)\.([^.)]+)\)` + +const StepArtifactPathPattern = `step.artifacts.path` + +const TaskArtifactPathPattern = `artifacts.path` var StepArtifactRegex = regexp.MustCompile(stepArtifactUsagePattern) +var TaskArtifactRegex = regexp.MustCompile(taskArtifactUsagePattern) diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go index 6d0541b83..d0db62052 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go @@ -108,6 +108,10 @@ const ( EnableParamEnum = "enable-param-enum" // EnableConciseResolverSyntax is the flag to enable concise resolver syntax EnableConciseResolverSyntax = "enable-concise-resolver-syntax" + // EnableKubernetesSidecar is the flag to enable kubernetes sidecar support + EnableKubernetesSidecar = "enable-kubernetes-sidecar" + // DefaultEnableKubernetesSidecar is the default value for EnableKubernetesSidecar + DefaultEnableKubernetesSidecar = false // DisableInlineSpec is the flag to disable embedded spec // in Taskrun or Pipelinerun @@ -185,12 +189,12 @@ type FeatureFlags struct { RunningInEnvWithInjectedSidecars bool RequireGitSSHSecretKnownHosts bool // EnableTektonOCIBundles bool // Deprecated: this is now ignored - ScopeWhenExpressionsToTask bool - EnableAPIFields string - SendCloudEventsForRuns bool - AwaitSidecarReadiness bool - EnforceNonfalsifiability string - EnableKeepPodOnCancel bool + // ScopeWhenExpressionsToTask bool // Deprecated: this is now ignored + EnableAPIFields string + SendCloudEventsForRuns bool + AwaitSidecarReadiness bool + EnforceNonfalsifiability string + EnableKeepPodOnCancel bool // VerificationNoMatchPolicy is the feature flag for "trusted-resources-verification-no-match-policy" // VerificationNoMatchPolicy can be set to "ignore", "warn" and "fail" values. // ignore: skip trusted resources verification when no matching verification policies found @@ -208,6 +212,7 @@ type FeatureFlags struct { EnableArtifacts bool DisableInlineSpec string EnableConciseResolverSyntax bool + EnableKubernetesSidecar bool } // GetFeatureFlagsConfigName returns the name of the configmap containing all @@ -312,6 +317,9 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) { if err := setPerFeatureFlag(EnableConciseResolverSyntax, DefaultEnableConciseResolverSyntax, &tc.EnableConciseResolverSyntax); err != nil { return nil, err } + if err := setFeature(EnableKubernetesSidecar, DefaultEnableKubernetesSidecar, &tc.EnableKubernetesSidecar); err != nil { + return nil, err + } return &tc, nil } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/paths.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/paths.go index fb2b3bcf8..efb28ea90 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/paths.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/paths.go @@ -30,4 +30,6 @@ const ( StepsDir = "/tekton/steps" ScriptDir = "/tekton/scripts" + + ArtifactsDir = "/tekton/artifacts" ) diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/artifact_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/artifact_types.go index 07e43ebe1..21a0d8fc2 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/artifact_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/artifact_types.go @@ -1,13 +1,37 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package v1 +import ( + "github.com/google/go-cmp/cmp" +) + // Algorithm Standard cryptographic hash algorithm type Algorithm string // Artifact represents an artifact within a system, potentially containing multiple values // associated with it. type Artifact struct { - Name string `json:"name,omitempty"` // The artifact's identifying category name - Values []ArtifactValue `json:"values,omitempty"` // A collection of values related to the artifact + // The artifact's identifying category name + Name string `json:"name,omitempty"` + // A collection of values related to the artifact + Values []ArtifactValue `json:"values,omitempty"` + // Indicate if the artifact is a build output or a by-product + BuildOutput bool `json:"buildOutput,omitempty"` } // ArtifactValue represents a specific value or data element within an Artifact. @@ -27,3 +51,82 @@ type Artifacts struct { Inputs []Artifact `json:"inputs,omitempty"` Outputs []Artifact `json:"outputs,omitempty"` } + +func (a *Artifacts) Merge(another Artifacts) { + inputMap := make(map[string][]ArtifactValue) + var newInputs []Artifact + + for _, v := range a.Inputs { + inputMap[v.Name] = v.Values + } + + for _, v := range another.Inputs { + _, ok := inputMap[v.Name] + if !ok { + inputMap[v.Name] = []ArtifactValue{} + } + for _, vv := range v.Values { + exists := false + for _, av := range inputMap[v.Name] { + if cmp.Equal(vv, av) { + exists = true + break + } + } + if !exists { + inputMap[v.Name] = append(inputMap[v.Name], vv) + } + } + } + + for k, v := range inputMap { + newInputs = append(newInputs, Artifact{ + Name: k, + Values: v, + }) + } + + outputMap := make(map[string]Artifact) + var newOutputs []Artifact + for _, v := range a.Outputs { + outputMap[v.Name] = v + } + + for _, v := range another.Outputs { + _, ok := outputMap[v.Name] + if !ok { + outputMap[v.Name] = Artifact{Name: v.Name, Values: []ArtifactValue{}, BuildOutput: v.BuildOutput} + } + // only update buildOutput to true. + // Do not convert to false if it was true before. + if v.BuildOutput { + art := outputMap[v.Name] + art.BuildOutput = v.BuildOutput + outputMap[v.Name] = art + } + for _, vv := range v.Values { + exists := false + for _, av := range outputMap[v.Name].Values { + if cmp.Equal(vv, av) { + exists = true + break + } + } + if !exists { + art := outputMap[v.Name] + art.Values = append(art.Values, vv) + outputMap[v.Name] = art + } + } + } + + for _, v := range outputMap { + newOutputs = append(newOutputs, Artifact{ + Name: v.Name, + Values: v.Values, + BuildOutput: v.BuildOutput, + }) + } + a.Inputs = newInputs + a.Outputs = newOutputs +} diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/container_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/container_types.go index 9f0c48ae9..2dc4a8984 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/container_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/container_types.go @@ -152,6 +152,10 @@ type Step struct { // +optional // +listType=atomic Results []StepResult `json:"results,omitempty"` + + // When is a list of when expressions that need to be true for the task to run + // +optional + When StepWhenExpressions `json:"when,omitempty"` } // Ref can be used to refer to a specific instance of a StepAction. @@ -539,10 +543,43 @@ type Sidecar struct { // +optional // +listType=atomic Workspaces []WorkspaceUsage `json:"workspaces,omitempty"` + + // RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an + // initContainer and must have it's policy set to "Always". It is currently + // left optional to help support Kubernetes versions prior to 1.29 when this feature + // was introduced. + // +optional + RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"` } // ToK8sContainer converts the Sidecar to a Kubernetes Container struct func (s *Sidecar) ToK8sContainer() *corev1.Container { + if s.RestartPolicy == nil { + return &corev1.Container{ + Name: s.Name, + Image: s.Image, + Command: s.Command, + Args: s.Args, + WorkingDir: s.WorkingDir, + Ports: s.Ports, + EnvFrom: s.EnvFrom, + Env: s.Env, + Resources: s.ComputeResources, + VolumeMounts: s.VolumeMounts, + VolumeDevices: s.VolumeDevices, + LivenessProbe: s.LivenessProbe, + ReadinessProbe: s.ReadinessProbe, + StartupProbe: s.StartupProbe, + Lifecycle: s.Lifecycle, + TerminationMessagePath: s.TerminationMessagePath, + TerminationMessagePolicy: s.TerminationMessagePolicy, + ImagePullPolicy: s.ImagePullPolicy, + SecurityContext: s.SecurityContext, + Stdin: s.Stdin, + StdinOnce: s.StdinOnce, + TTY: s.TTY, + } + } return &corev1.Container{ Name: s.Name, Image: s.Image, @@ -557,6 +594,7 @@ func (s *Sidecar) ToK8sContainer() *corev1.Container { VolumeDevices: s.VolumeDevices, LivenessProbe: s.LivenessProbe, ReadinessProbe: s.ReadinessProbe, + RestartPolicy: s.RestartPolicy, StartupProbe: s.StartupProbe, Lifecycle: s.Lifecycle, TerminationMessagePath: s.TerminationMessagePath, @@ -593,6 +631,7 @@ func (s *Sidecar) SetContainerFields(c corev1.Container) { s.Stdin = c.Stdin s.StdinOnce = c.StdinOnce s.TTY = c.TTY + s.RestartPolicy = c.RestartPolicy } // GetVarSubstitutionExpressions walks all the places a substitution reference can be used diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/merge.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/merge.go index 296eaf4b1..df413a545 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/merge.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/merge.go @@ -65,7 +65,7 @@ func MergeStepsWithStepTemplate(template *StepTemplate, steps []Step) ([]Step, e amendConflictingContainerFields(&merged, s) // Pass through original step Script, for later conversion. - newStep := Step{Script: s.Script, OnError: s.OnError, Timeout: s.Timeout, StdoutConfig: s.StdoutConfig, StderrConfig: s.StderrConfig, Results: s.Results, Params: s.Params, Ref: s.Ref} + newStep := Step{Script: s.Script, OnError: s.OnError, Timeout: s.Timeout, StdoutConfig: s.StdoutConfig, StderrConfig: s.StderrConfig, Results: s.Results, Params: s.Params, Ref: s.Ref, When: s.When} newStep.SetContainerFields(merged) steps[i] = newStep } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go index 82896087a..42bf6748b 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go @@ -395,13 +395,14 @@ func schema_pkg_apis_pipeline_v1_Artifact(ref common.ReferenceCallback) common.O Properties: map[string]spec.Schema{ "name": { SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", + Description: "The artifact's identifying category name", + Type: []string{"string"}, + Format: "", }, }, "values": { SchemaProps: spec.SchemaProps{ - Description: "The artifact's identifying category name", + Description: "A collection of values related to the artifact", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -413,6 +414,13 @@ func schema_pkg_apis_pipeline_v1_Artifact(ref common.ReferenceCallback) common.O }, }, }, + "buildOutput": { + SchemaProps: spec.SchemaProps{ + Description: "Indicate if the artifact is a build output or a by-product", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, @@ -2745,6 +2753,13 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op }, }, }, + "restartPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"name"}, }, @@ -3122,12 +3137,26 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA }, }, }, + "when": { + SchemaProps: spec.SchemaProps{ + Description: "When is a list of when expressions that need to be true for the task to run", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), + }, + }, + }, + }, + }, }, Required: []string{"name"}, }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, } } @@ -3260,6 +3289,11 @@ func schema_pkg_apis_pipeline_v1_StepState(ref common.ReferenceCallback) common. }, }, }, + "provenance": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Provenance"), + }, + }, "terminationReason": { SchemaProps: spec.SchemaProps{ Type: []string{"string"}, @@ -3296,7 +3330,7 @@ func schema_pkg_apis_pipeline_v1_StepState(ref common.ReferenceCallback) common. }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult", "k8s.io/api/core/v1.ContainerStateRunning", "k8s.io/api/core/v1.ContainerStateTerminated", "k8s.io/api/core/v1.ContainerStateWaiting"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Provenance", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult", "k8s.io/api/core/v1.ContainerStateRunning", "k8s.io/api/core/v1.ContainerStateTerminated", "k8s.io/api/core/v1.ContainerStateWaiting"}, } } @@ -4172,6 +4206,18 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com }, }, }, + "artifacts": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Artifacts are the list of artifacts written out by the task's containers", + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifacts"), + }, + }, "sidecars": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -4224,7 +4270,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Provenance", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.Time", "knative.dev/pkg/apis.Condition"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifacts", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Provenance", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.Time", "knative.dev/pkg/apis.Condition"}, } } @@ -4312,6 +4358,18 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatusFields(ref common.ReferenceCallbac }, }, }, + "artifacts": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Artifacts are the list of artifacts written out by the task's containers", + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifacts"), + }, + }, "sidecars": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -4364,7 +4422,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatusFields(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Provenance", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifacts", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Provenance", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go index 43e56d102..c17293a02 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go @@ -22,6 +22,7 @@ import ( "slices" "strings" + "github.com/tektoncd/pipeline/internal/artifactref" "github.com/tektoncd/pipeline/pkg/apis/config" "github.com/tektoncd/pipeline/pkg/apis/validate" "github.com/tektoncd/pipeline/pkg/internal/resultref" @@ -89,6 +90,7 @@ func (ps *PipelineSpec) Validate(ctx context.Context) (errs *apis.FieldError) { errs = errs.Also(validateTasksAndFinallySection(ps)) errs = errs.Also(validateFinalTasks(ps.Tasks, ps.Finally)) errs = errs.Also(validateWhenExpressions(ctx, ps.Tasks, ps.Finally)) + errs = errs.Also(validateArtifactReference(ctx, ps.Tasks, ps.Finally)) errs = errs.Also(validateMatrix(ctx, ps.Tasks).ViaField("tasks")) errs = errs.Also(validateMatrix(ctx, ps.Finally).ViaField("finally")) return errs @@ -190,7 +192,7 @@ func (pt PipelineTask) Validate(ctx context.Context) (errs *apis.FieldError) { } if pt.OnError != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.AlphaAPIFields)) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.BetaAPIFields)) if pt.OnError != PipelineTaskContinue && pt.OnError != PipelineTaskStopAndFail { errs = errs.Also(apis.ErrInvalidValue(pt.OnError, "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\"")) } @@ -511,9 +513,13 @@ func (pt *PipelineTask) GetVarSubstitutionExpressions() []string { return allExpressions } +// containsExecutionStatusRef checks if a specified param has a reference to execution status or reason +// $(tasks..status), $(tasks.status), or $(tasks..reason) func containsExecutionStatusRef(p string) bool { - if strings.HasPrefix(p, "tasks.") && strings.HasSuffix(p, ".status") { - return true + if strings.HasPrefix(p, "tasks.") { + if strings.HasSuffix(p, ".status") || strings.HasSuffix(p, ".reason") { + return true + } } return false } @@ -587,7 +593,7 @@ func containsExecutionStatusReferences(expressions []string) bool { if !LooksLikeContainsResultRefs(expressions) { for _, e := range expressions { // check if it contains context variable accessing execution status - $(tasks.taskname.status) - // or an aggregate status - $(tasks.status) + // or an aggregate status - $(tasks.status) or reason - $(tasks.taskname.reason) if containsExecutionStatusRef(e) { return true } @@ -604,10 +610,17 @@ func validateExecutionStatusVariablesExpressions(expressions []string, ptNames s if expression == PipelineTasksAggregateStatus { continue } - // check if it contains context variable accessing execution status - $(tasks.taskname.status) + // check if it contains context variable accessing execution status - $(tasks.taskname.status) | $(tasks.taskname.reason) if containsExecutionStatusRef(expression) { - // strip tasks. and .status from tasks.taskname.status to further verify task name - pt := strings.TrimSuffix(strings.TrimPrefix(expression, "tasks."), ".status") + var pt string + if strings.HasSuffix(expression, ".status") { + // strip tasks. and .status from tasks.taskname.status to further verify task name + pt = strings.TrimSuffix(strings.TrimPrefix(expression, "tasks."), ".status") + } + if strings.HasSuffix(expression, ".reason") { + // strip tasks. and .reason from tasks.taskname.reason to further verify task name + pt = strings.TrimSuffix(strings.TrimPrefix(expression, "tasks."), ".reason") + } // report an error if the task name does not exist in the list of dag tasks if !ptNames.Has(pt) { errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("pipeline task %s is not defined in the pipeline", pt), fieldPath)) @@ -615,6 +628,7 @@ func validateExecutionStatusVariablesExpressions(expressions []string, ptNames s } } } + return errs } @@ -810,6 +824,10 @@ func findAndValidateResultRefsForMatrix(tasks []PipelineTask, taskMapping map[st func validateMatrixedPipelineTaskConsumed(expressions []string, taskMapping map[string]PipelineTask) (resultRefs []*ResultRef, errs *apis.FieldError) { var filteredExpressions []string for _, expression := range expressions { + // if it is not matrix result ref expression, skip + if !resultref.LooksLikeResultRef(expression) { + continue + } // ie. "tasks..results.[*]" subExpressions := strings.Split(expression, ".") pipelineTask := subExpressions[1] // pipelineTaskName @@ -882,6 +900,28 @@ func validateStringResults(results []TaskResult, resultName string) (errs *apis. return errs } +// validateArtifactReference ensure that the feature flag enableArtifacts is set to true when using artifacts +func validateArtifactReference(ctx context.Context, tasks []PipelineTask, finalTasks []PipelineTask) (errs *apis.FieldError) { + if config.FromContextOrDefaults(ctx).FeatureFlags.EnableArtifacts { + return errs + } + for i, t := range tasks { + for _, v := range t.Params.extractValues() { + if len(artifactref.TaskArtifactRegex.FindAllStringSubmatch(v, -1)) > 0 { + return errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "").ViaField("params").ViaFieldIndex("tasks", i)) + } + } + } + for i, t := range finalTasks { + for _, v := range t.Params.extractValues() { + if len(artifactref.TaskArtifactRegex.FindAllStringSubmatch(v, -1)) > 0 { + return errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "").ViaField("params").ViaFieldIndex("finally", i)) + } + } + } + return errs +} + // GetIndexingReferencesToArrayParams returns all strings referencing indices of PipelineRun array parameters // from parameters, workspaces, and when expressions defined in the Pipeline's Tasks and Finally Tasks. // For example, if a Task in the Pipeline has a parameter with a value "$(params.array-param-name[1])", diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipelinerun_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipelinerun_validation.go index d45b00ab8..16330aa21 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipelinerun_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipelinerun_validation.go @@ -27,6 +27,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/validate" "github.com/tektoncd/pipeline/pkg/internal/resultref" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" "knative.dev/pkg/webhook/resourcesemantics" @@ -55,6 +56,9 @@ func (pr *PipelineRun) Validate(ctx context.Context) *apis.FieldError { // Validate pipelinerun spec func (ps *PipelineRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { + // Validate the spec changes + errs = errs.Also(ps.ValidateUpdate(ctx)) + // Must have exactly one of pipelineRef and pipelineSpec. if ps.PipelineRef == nil && ps.PipelineSpec == nil { errs = errs.Also(apis.ErrMissingOneOf("pipelineRef", "pipelineSpec")) @@ -124,6 +128,31 @@ func (ps *PipelineRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) return errs } +// ValidateUpdate validates the update of a PipelineRunSpec +func (ps *PipelineRunSpec) ValidateUpdate(ctx context.Context) (errs *apis.FieldError) { + if !apis.IsInUpdate(ctx) { + return + } + oldObj, ok := apis.GetBaseline(ctx).(*PipelineRun) + if !ok || oldObj == nil { + return + } + old := &oldObj.Spec + + // If already in the done state, the spec cannot be modified. Otherwise, only the status field can be modified. + tips := "Once the PipelineRun is complete, no updates are allowed" + if !oldObj.IsDone() { + old = old.DeepCopy() + old.Status = ps.Status + tips = "Once the PipelineRun has started, only status updates are allowed" + } + if !equality.Semantic.DeepEqual(old, ps) { + errs = errs.Also(apis.ErrInvalidValue(tips, "")) + } + + return +} + func (ps *PipelineRunSpec) validatePipelineRunParameters(ctx context.Context) (errs *apis.FieldError) { if len(ps.Params) == 0 { return errs @@ -286,11 +315,11 @@ func (ps *PipelineRunSpec) validatePipelineTimeout(timeout time.Duration, errorM func validateTaskRunSpec(ctx context.Context, trs PipelineTaskRunSpec) (errs *apis.FieldError) { if trs.StepSpecs != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepSpecs", config.AlphaAPIFields).ViaField("stepSpecs")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepSpecs", config.BetaAPIFields).ViaField("stepSpecs")) errs = errs.Also(validateStepSpecs(trs.StepSpecs).ViaField("stepSpecs")) } if trs.SidecarSpecs != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarSpecs", config.AlphaAPIFields).ViaField("sidecarSpecs")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarSpecs", config.BetaAPIFields).ViaField("sidecarSpecs")) errs = errs.Also(validateSidecarSpecs(trs.SidecarSpecs).ViaField("sidecarSpecs")) } if trs.ComputeResources != nil { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json index be288cc97..584220d0b 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json @@ -155,11 +155,16 @@ "description": "TaskRunStepArtifact represents an artifact produced or used by a step within a task run. It directly uses the Artifact type for its structure.", "type": "object", "properties": { + "buildOutput": { + "description": "Indicate if the artifact is a build output or a by-product", + "type": "boolean" + }, "name": { + "description": "The artifact's identifying category name", "type": "string" }, "values": { - "description": "The artifact's identifying category name", + "description": "A collection of values related to the artifact", "type": "array", "items": { "default": {}, @@ -1325,6 +1330,10 @@ "description": "Periodic probe of Sidecar service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", "$ref": "#/definitions/v1.Probe" }, + "restartPolicy": { + "description": "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.", + "type": "string" + }, "script": { "description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command or Args.", "type": "string" @@ -1581,6 +1590,14 @@ "x-kubernetes-patch-merge-key": "mountPath", "x-kubernetes-patch-strategy": "merge" }, + "when": { + "description": "When is a list of when expressions that need to be true for the task to run", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.WhenExpression" + } + }, "workingDir": { "description": "Step's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", "type": "string" @@ -1663,6 +1680,9 @@ "$ref": "#/definitions/v1.Artifact" } }, + "provenance": { + "$ref": "#/definitions/v1.Provenance" + }, "results": { "type": "array", "items": { @@ -2103,6 +2123,12 @@ "default": "" } }, + "artifacts": { + "description": "Artifacts are the list of artifacts written out by the task's containers", + "default": {}, + "$ref": "#/definitions/v1.Artifacts", + "x-kubernetes-list-type": "atomic" + }, "completionTime": { "description": "CompletionTime is the time the build completed.", "$ref": "#/definitions/v1.Time" @@ -2192,6 +2218,12 @@ "podName" ], "properties": { + "artifacts": { + "description": "Artifacts are the list of artifacts written out by the task's containers", + "default": {}, + "$ref": "#/definitions/v1.Artifacts", + "x-kubernetes-list-type": "atomic" + }, "completionTime": { "description": "CompletionTime is the time the build completed.", "$ref": "#/definitions/v1.Time" diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/task_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/task_validation.go index 957085744..4232d295d 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/task_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/task_validation.go @@ -260,6 +260,9 @@ func validateSteps(ctx context.Context, steps []Step) (errs *apis.FieldError) { errs = errs.Also(ValidateStepResultsVariables(ctx, s.Results, s.Script).ViaIndex(idx)) errs = errs.Also(ValidateStepResults(ctx, s.Results).ViaIndex(idx).ViaField("results")) } + if len(s.When) > 0 { + errs = errs.Also(s.When.validate(ctx).ViaIndex(idx)) + } } return errs } @@ -312,7 +315,10 @@ func errorIfStepResultReferenceinField(value, fieldName string) (errs *apis.Fiel } func stepArtifactReferenceExists(src string) bool { - return len(artifactref.StepArtifactRegex.FindAllStringSubmatch(src, -1)) > 0 || strings.Contains(src, "$(step.artifacts.path)") + return len(artifactref.StepArtifactRegex.FindAllStringSubmatch(src, -1)) > 0 || strings.Contains(src, "$("+artifactref.StepArtifactPathPattern+")") +} +func taskArtifactReferenceExists(src string) bool { + return len(artifactref.TaskArtifactRegex.FindAllStringSubmatch(src, -1)) > 0 || strings.Contains(src, "$("+artifactref.TaskArtifactPathPattern+")") } func errorIfStepArtifactReferencedInField(value, fieldName string) (errs *apis.FieldError) { if stepArtifactReferenceExists(value) { @@ -378,17 +384,8 @@ func validateStepResultReference(s Step) (errs *apis.FieldError) { } func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.FieldError) { - if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableArtifacts { - var t []string - t = append(t, s.Script) - t = append(t, s.Command...) - t = append(t, s.Args...) - for _, e := range s.Env { - t = append(t, e.Value) - } - if slices.ContainsFunc(t, stepArtifactReferenceExists) { - return errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "")) - } + if err := validateArtifactsReferencesInStep(ctx, s); err != nil { + return err } if s.Ref != nil { @@ -456,6 +453,11 @@ func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.Fi return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true in order to use Results in Steps.", config.EnableStepActions), "") } } + if len(s.When) > 0 { + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableStepActions && isCreateOrUpdateAndDiverged(ctx, s) { + return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true in order to use When in Steps.", config.EnableStepActions), "") + } + } if s.Image == "" { errs = errs.Also(apis.ErrMissingField("Image")) } @@ -538,6 +540,22 @@ func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.Fi return errs } +func validateArtifactsReferencesInStep(ctx context.Context, s Step) *apis.FieldError { + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableArtifacts { + var t []string + t = append(t, s.Script) + t = append(t, s.Command...) + t = append(t, s.Args...) + for _, e := range s.Env { + t = append(t, e.Value) + } + if slices.ContainsFunc(t, stepArtifactReferenceExists) || slices.ContainsFunc(t, taskArtifactReferenceExists) { + return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "") + } + } + return nil +} + // ValidateParameterTypes validates all the types within a slice of ParamSpecs func ValidateParameterTypes(ctx context.Context, params []ParamSpec) (errs *apis.FieldError) { for _, p := range params { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_types.go index 615eaaa78..ea6e51764 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_types.go @@ -279,6 +279,11 @@ type TaskRunStatusFields struct { // +listType=atomic Results []TaskRunResult `json:"results,omitempty"` + // Artifacts are the list of artifacts written out by the task's containers + // +optional + // +listType=atomic + Artifacts Artifacts `json:"artifacts,omitempty"` + // The list has one entry per sidecar in the manifest. Each entry is // represents the imageid of the corresponding sidecar. // +listType=atomic @@ -359,6 +364,7 @@ type StepState struct { Container string `json:"container,omitempty"` ImageID string `json:"imageID,omitempty"` Results []TaskRunStepResult `json:"results,omitempty"` + Provenance *Provenance `json:"provenance,omitempty"` TerminationReason string `json:"terminationReason,omitempty"` Inputs []TaskRunStepArtifact `json:"inputs,omitempty"` Outputs []TaskRunStepArtifact `json:"outputs,omitempty"` diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_validation.go index 771d684d4..cfdd423e9 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/taskrun_validation.go @@ -26,6 +26,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/validate" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/strings/slices" "knative.dev/pkg/apis" @@ -50,6 +51,9 @@ func (tr *TaskRun) Validate(ctx context.Context) *apis.FieldError { // Validate taskrun spec func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { + // Validate the spec changes + errs = errs.Also(ts.ValidateUpdate(ctx)) + // Must have exactly one of taskRef and taskSpec. if ts.TaskRef == nil && ts.TaskSpec == nil { errs = errs.Also(apis.ErrMissingOneOf("taskRef", "taskSpec")) @@ -80,11 +84,11 @@ func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { errs = errs.Also(validateDebug(ts.Debug).ViaField("debug")) } if ts.StepSpecs != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepSpecs", config.AlphaAPIFields).ViaField("stepSpecs")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepSpecs", config.BetaAPIFields).ViaField("stepSpecs")) errs = errs.Also(validateStepSpecs(ts.StepSpecs).ViaField("stepSpecs")) } if ts.SidecarSpecs != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarSpecs", config.AlphaAPIFields).ViaField("sidecarSpecs")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarSpecs", config.BetaAPIFields).ViaField("sidecarSpecs")) errs = errs.Also(validateSidecarSpecs(ts.SidecarSpecs).ViaField("sidecarSpecs")) } if ts.ComputeResources != nil { @@ -118,6 +122,34 @@ func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { return errs } +// ValidateUpdate validates the update of a TaskRunSpec +func (ts *TaskRunSpec) ValidateUpdate(ctx context.Context) (errs *apis.FieldError) { + if !apis.IsInUpdate(ctx) { + return + } + oldObj, ok := apis.GetBaseline(ctx).(*TaskRun) + if !ok || oldObj == nil { + return + } + old := &oldObj.Spec + + // If already in the done state, the spec cannot be modified. + // Otherwise, only the status, statusMessage field can be modified. + tips := "Once the TaskRun is complete, no updates are allowed" + if !oldObj.IsDone() { + old = old.DeepCopy() + old.Status = ts.Status + old.StatusMessage = ts.StatusMessage + tips = "Once the TaskRun has started, only status and statusMessage updates are allowed" + } + + if !equality.Semantic.DeepEqual(old, ts) { + errs = errs.Also(apis.ErrInvalidValue(tips, "")) + } + + return +} + // validateInlineParameters validates that any parameters called in the // Task spec are declared in the TaskRun. // This is crucial for propagated parameters because the parameters could @@ -224,6 +256,11 @@ func validateDebug(db *TaskRunDebug) (errs *apis.FieldError) { if db == nil || db.Breakpoints == nil { return errs } + + if db.Breakpoints.OnFailure == "" { + errs = errs.Also(apis.ErrInvalidValue("onFailure breakpoint is empty, it is only allowed to be set as enabled", "breakpoints.onFailure")) + } + if db.Breakpoints.OnFailure != "" && db.Breakpoints.OnFailure != EnabledOnFailureBreakpoint { errs = errs.Also(apis.ErrInvalidValue(db.Breakpoints.OnFailure+" is not a valid onFailure breakpoint value, onFailure breakpoint is only allowed to be set as enabled", "breakpoints.onFailure")) } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_types.go index 66e7164a7..0a128d8f9 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_types.go @@ -98,6 +98,8 @@ func (we *WhenExpression) GetVarSubstitutionExpressions() ([]string, bool) { // All of them need to evaluate to True for a guarded Task to be executed. type WhenExpressions []WhenExpression +type StepWhenExpressions = WhenExpressions + // AllowsExecution evaluates an Input's relationship to an array of Values, based on the Operator, // to determine whether all the When Expressions are True. If they are all True, the guarded Task is // executed, otherwise it is skipped. diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go index 2a058299a..a62621a69 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go @@ -48,7 +48,7 @@ func (wes WhenExpressions) validateWhenExpressionsFields(ctx context.Context) (e func (we *WhenExpression) validateWhenExpressionFields(ctx context.Context) *apis.FieldError { if we.CEL != "" { if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableCELInWhenExpression { - return apis.ErrGeneric("feature flag %s should be set to true to use CEL: %s in WhenExpression", config.EnableCELInWhenExpression, we.CEL) + return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use CEL: %s in WhenExpression", config.EnableCELInWhenExpression, we.CEL), "") } if we.Input != "" || we.Operator != "" || len(we.Values) != 0 { return apis.ErrGeneric(fmt.Sprintf("cel and input+operator+values cannot be set in one WhenExpression: %v", we)) diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/zz_generated.deepcopy.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/zz_generated.deepcopy.go index 16e483fce..12dbe03bf 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/zz_generated.deepcopy.go @@ -1248,6 +1248,11 @@ func (in *Sidecar) DeepCopyInto(out *Sidecar) { *out = make([]WorkspaceUsage, len(*in)) copy(*out, *in) } + if in.RestartPolicy != nil { + in, out := &in.RestartPolicy, &out.RestartPolicy + *out = new(corev1.ContainerRestartPolicy) + **out = **in + } return } @@ -1385,6 +1390,13 @@ func (in *Step) DeepCopyInto(out *Step) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.When != nil { + in, out := &in.When, &out.When + *out = make(WhenExpressions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -1448,6 +1460,11 @@ func (in *StepState) DeepCopyInto(out *StepState) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Provenance != nil { + in, out := &in.Provenance, &out.Provenance + *out = new(Provenance) + (*in).DeepCopyInto(*out) + } if in.Inputs != nil { in, out := &in.Inputs, &out.Inputs *out = make([]Artifact, len(*in)) @@ -1917,6 +1934,7 @@ func (in *TaskRunStatusFields) DeepCopyInto(out *TaskRunStatusFields) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + in.Artifacts.DeepCopyInto(&out.Artifacts) if in.Sidecars != nil { in, out := &in.Sidecars, &out.Sidecars *out = make([]SidecarState, len(*in)) diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/artifact_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/artifact_types.go index ec50bde8a..23778a90b 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/artifact_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/artifact_types.go @@ -6,8 +6,12 @@ type Algorithm string // Artifact represents an artifact within a system, potentially containing multiple values // associated with it. type Artifact struct { - Name string `json:"name,omitempty"` // The artifact's identifying category name - Values []ArtifactValue `json:"values,omitempty"` // A collection of values related to the artifact + // The artifact's identifying category name + Name string `json:"name,omitempty"` + // A collection of values related to the artifact + Values []ArtifactValue `json:"values,omitempty"` + // Indicate if the artifact is a build output or a by-product + BuildOutput bool `json:"buildOutput,omitempty"` } // ArtifactValue represents a specific value or data element within an Artifact. diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_conversion.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_conversion.go index 2e828bc5a..5b61377bc 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_conversion.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_conversion.go @@ -72,6 +72,11 @@ func (s Step) convertTo(ctx context.Context, sink *v1.Step) { sink.Params = append(sink.Params, new) } sink.Results = s.Results + for _, w := range s.When { + new := v1.WhenExpression{} + w.convertTo(ctx, &new) + sink.When = append(sink.When, new) + } } func (s *Step) convertFrom(ctx context.Context, source v1.Step) { @@ -111,6 +116,11 @@ func (s *Step) convertFrom(ctx context.Context, source v1.Step) { s.Params = append(s.Params, new) } s.Results = source.Results + for _, w := range source.When { + new := WhenExpression{} + new.convertFrom(ctx, w) + s.When = append(s.When, new) + } } func (s StepTemplate) convertTo(ctx context.Context, sink *v1.StepTemplate) { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_types.go index 4494184d7..95f852bf4 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/container_types.go @@ -247,6 +247,8 @@ type Step struct { // +optional // +listType=atomic Results []v1.StepResult `json:"results,omitempty"` + + When StepWhenExpressions `json:"when,omitempty"` } // Ref can be used to refer to a specific instance of a StepAction. @@ -745,10 +747,43 @@ type Sidecar struct { // +optional // +listType=atomic Workspaces []WorkspaceUsage `json:"workspaces,omitempty"` + + // RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an + // initContainer and must have it's policy set to "Always". It is currently + // left optional to help support Kubernetes versions prior to 1.29 when this feature + // was introduced. + // +optional + RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"` } // ToK8sContainer converts the Sidecar to a Kubernetes Container struct func (s *Sidecar) ToK8sContainer() *corev1.Container { + if s.RestartPolicy == nil { + return &corev1.Container{ + Name: s.Name, + Image: s.Image, + Command: s.Command, + Args: s.Args, + WorkingDir: s.WorkingDir, + Ports: s.Ports, + EnvFrom: s.EnvFrom, + Env: s.Env, + Resources: s.Resources, + VolumeMounts: s.VolumeMounts, + VolumeDevices: s.VolumeDevices, + LivenessProbe: s.LivenessProbe, + ReadinessProbe: s.ReadinessProbe, + StartupProbe: s.StartupProbe, + Lifecycle: s.Lifecycle, + TerminationMessagePath: s.TerminationMessagePath, + TerminationMessagePolicy: s.TerminationMessagePolicy, + ImagePullPolicy: s.ImagePullPolicy, + SecurityContext: s.SecurityContext, + Stdin: s.Stdin, + StdinOnce: s.StdinOnce, + TTY: s.TTY, + } + } return &corev1.Container{ Name: s.Name, Image: s.Image, @@ -763,6 +798,7 @@ func (s *Sidecar) ToK8sContainer() *corev1.Container { VolumeDevices: s.VolumeDevices, LivenessProbe: s.LivenessProbe, ReadinessProbe: s.ReadinessProbe, + RestartPolicy: s.RestartPolicy, StartupProbe: s.StartupProbe, Lifecycle: s.Lifecycle, TerminationMessagePath: s.TerminationMessagePath, @@ -799,4 +835,5 @@ func (s *Sidecar) SetContainerFields(c corev1.Container) { s.Stdin = c.Stdin s.StdinOnce = c.StdinOnce s.TTY = c.TTY + s.RestartPolicy = c.RestartPolicy } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/merge.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/merge.go index 6d1432d46..62111ee7c 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/merge.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/merge.go @@ -66,7 +66,7 @@ func MergeStepsWithStepTemplate(template *StepTemplate, steps []Step) ([]Step, e amendConflictingContainerFields(&merged, s) // Pass through original step Script, for later conversion. - newStep := Step{Script: s.Script, OnError: s.OnError, Timeout: s.Timeout, StdoutConfig: s.StdoutConfig, StderrConfig: s.StderrConfig} + newStep := Step{Script: s.Script, OnError: s.OnError, Timeout: s.Timeout, StdoutConfig: s.StdoutConfig, StderrConfig: s.StderrConfig, When: s.When} newStep.SetContainerFields(merged) steps[i] = newStep } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go index d2c52a379..0e2f436ca 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -422,13 +422,14 @@ func schema_pkg_apis_pipeline_v1beta1_Artifact(ref common.ReferenceCallback) com Properties: map[string]spec.Schema{ "name": { SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", + Description: "The artifact's identifying category name", + Type: []string{"string"}, + Format: "", }, }, "values": { SchemaProps: spec.SchemaProps{ - Description: "The artifact's identifying category name", + Description: "A collection of values related to the artifact", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -440,6 +441,13 @@ func schema_pkg_apis_pipeline_v1beta1_Artifact(ref common.ReferenceCallback) com }, }, }, + "buildOutput": { + SchemaProps: spec.SchemaProps{ + Description: "Indicate if the artifact is a build output or a by-product", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, @@ -3616,6 +3624,13 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm }, }, }, + "restartPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"name"}, }, @@ -4077,12 +4092,25 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. }, }, }, + "when": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), + }, + }, + }, + }, + }, }, Required: []string{"name"}, }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage", "k8s.io/api/core/v1.ContainerPort", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.Lifecycle", "k8s.io/api/core/v1.Probe", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage", "k8s.io/api/core/v1.ContainerPort", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.Lifecycle", "k8s.io/api/core/v1.Probe", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, } } @@ -4422,6 +4450,11 @@ func schema_pkg_apis_pipeline_v1beta1_StepState(ref common.ReferenceCallback) co }, }, }, + "provenance": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Provenance"), + }, + }, "inputs": { SchemaProps: spec.SchemaProps{ Type: []string{"array"}, @@ -4452,7 +4485,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepState(ref common.ReferenceCallback) co }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult", "k8s.io/api/core/v1.ContainerStateRunning", "k8s.io/api/core/v1.ContainerStateTerminated", "k8s.io/api/core/v1.ContainerStateWaiting"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Provenance", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult", "k8s.io/api/core/v1.ContainerStateRunning", "k8s.io/api/core/v1.ContainerStateTerminated", "k8s.io/api/core/v1.ContainerStateWaiting"}, } } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go index 4423a9172..8f8d6a1f0 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go @@ -21,6 +21,7 @@ import ( "fmt" "strings" + "github.com/tektoncd/pipeline/internal/artifactref" "github.com/tektoncd/pipeline/pkg/apis/config" "github.com/tektoncd/pipeline/pkg/apis/validate" "github.com/tektoncd/pipeline/pkg/internal/resultref" @@ -91,6 +92,7 @@ func (ps *PipelineSpec) Validate(ctx context.Context) (errs *apis.FieldError) { errs = errs.Also(validateTasksAndFinallySection(ps)) errs = errs.Also(validateFinalTasks(ps.Tasks, ps.Finally)) errs = errs.Also(validateWhenExpressions(ctx, ps.Tasks, ps.Finally)) + errs = errs.Also(validateArtifactReference(ctx, ps.Tasks, ps.Finally)) errs = errs.Also(validateMatrix(ctx, ps.Tasks).ViaField("tasks")) errs = errs.Also(validateMatrix(ctx, ps.Finally).ViaField("finally")) return errs @@ -195,7 +197,7 @@ func (pt PipelineTask) Validate(ctx context.Context) (errs *apis.FieldError) { } if pt.OnError != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.AlphaAPIFields)) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.BetaAPIFields)) if pt.OnError != PipelineTaskContinue && pt.OnError != PipelineTaskStopAndFail { errs = errs.Also(apis.ErrInvalidValue(pt.OnError, "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\"")) } @@ -493,9 +495,13 @@ func (pt *PipelineTask) extractAllParams() Params { return allParams } +// containsExecutionStatusRef checks if a specified param has a reference to execution status or reason +// $(tasks..status), $(tasks.status), or $(tasks..reason) func containsExecutionStatusRef(p string) bool { - if strings.HasPrefix(p, "tasks.") && strings.HasSuffix(p, ".status") { - return true + if strings.HasPrefix(p, "tasks.") { + if strings.HasSuffix(p, ".status") || strings.HasSuffix(p, ".reason") { + return true + } } return false } @@ -586,10 +592,17 @@ func validateExecutionStatusVariablesExpressions(expressions []string, ptNames s if expression == PipelineTasksAggregateStatus { continue } - // check if it contains context variable accessing execution status - $(tasks.taskname.status) + // check if it contains context variable accessing execution status - $(tasks.taskname.status) | $(tasks.taskname.reason) if containsExecutionStatusRef(expression) { - // strip tasks. and .status from tasks.taskname.status to further verify task name - pt := strings.TrimSuffix(strings.TrimPrefix(expression, "tasks."), ".status") + var pt string + if strings.HasSuffix(expression, ".status") { + // strip tasks. and .status from tasks.taskname.status to further verify task name + pt = strings.TrimSuffix(strings.TrimPrefix(expression, "tasks."), ".status") + } + if strings.HasSuffix(expression, ".reason") { + // strip tasks. and .reason from tasks.taskname.reason to further verify task name + pt = strings.TrimSuffix(strings.TrimPrefix(expression, "tasks."), ".reason") + } // report an error if the task name does not exist in the list of dag tasks if !ptNames.Has(pt) { errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("pipeline task %s is not defined in the pipeline", pt), fieldPath)) @@ -866,6 +879,28 @@ func validateStringResults(results []TaskResult, resultName string) (errs *apis. return errs } +// validateArtifactReference ensure that the feature flag enableArtifacts is set to true when using artifacts +func validateArtifactReference(ctx context.Context, tasks []PipelineTask, finalTasks []PipelineTask) (errs *apis.FieldError) { + if config.FromContextOrDefaults(ctx).FeatureFlags.EnableArtifacts { + return errs + } + for i, t := range tasks { + for _, v := range t.Params.extractValues() { + if len(artifactref.TaskArtifactRegex.FindAllStringSubmatch(v, -1)) > 0 { + return errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "").ViaField("params").ViaFieldIndex("tasks", i)) + } + } + } + for i, t := range finalTasks { + for _, v := range t.Params.extractValues() { + if len(artifactref.TaskArtifactRegex.FindAllStringSubmatch(v, -1)) > 0 { + return errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "").ViaField("params").ViaFieldIndex("finally", i)) + } + } + } + return errs +} + // GetIndexingReferencesToArrayParams returns all strings referencing indices of PipelineRun array parameters // from parameters, workspaces, and when expressions defined in the Pipeline's Tasks and Finally Tasks. // For example, if a Task in the Pipeline has a parameter with a value "$(params.array-param-name[1])", diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go index 7113b6536..834c7493d 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go @@ -26,6 +26,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/validate" "github.com/tektoncd/pipeline/pkg/internal/resultref" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/strings/slices" @@ -60,6 +61,9 @@ func (pr *PipelineRun) Validate(ctx context.Context) *apis.FieldError { // Validate pipelinerun spec func (ps *PipelineRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { + // Validate the spec changes + errs = errs.Also(ps.ValidateUpdate(ctx)) + // Must have exactly one of pipelineRef and pipelineSpec. if ps.PipelineRef == nil && ps.PipelineSpec == nil { errs = errs.Also(apis.ErrMissingOneOf("pipelineRef", "pipelineSpec")) @@ -145,6 +149,31 @@ func (ps *PipelineRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) return errs } +// ValidateUpdate validates the update of a PipelineRunSpec +func (ps *PipelineRunSpec) ValidateUpdate(ctx context.Context) (errs *apis.FieldError) { + if !apis.IsInUpdate(ctx) { + return + } + oldObj, ok := apis.GetBaseline(ctx).(*PipelineRun) + if !ok || oldObj == nil { + return + } + old := &oldObj.Spec + + // If already in the done state, the spec cannot be modified. Otherwise, only the status field can be modified. + tips := "Once the PipelineRun is complete, no updates are allowed" + if !oldObj.IsDone() { + old = old.DeepCopy() + old.Status = ps.Status + tips = "Once the PipelineRun has started, only status updates are allowed" + } + if !equality.Semantic.DeepEqual(old, ps) { + errs = errs.Also(apis.ErrInvalidValue(tips, "")) + } + + return +} + func (ps *PipelineRunSpec) validatePipelineRunParameters(ctx context.Context) (errs *apis.FieldError) { if len(ps.Params) == 0 { return errs @@ -335,11 +364,11 @@ func (ps *PipelineRunSpec) validatePipelineTimeout(timeout time.Duration, errorM func validateTaskRunSpec(ctx context.Context, trs PipelineTaskRunSpec) (errs *apis.FieldError) { if trs.StepOverrides != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepOverrides", config.AlphaAPIFields).ViaField("stepOverrides")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepOverrides", config.BetaAPIFields).ViaField("stepOverrides")) errs = errs.Also(validateStepOverrides(trs.StepOverrides).ViaField("stepOverrides")) } if trs.SidecarOverrides != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarOverrides", config.AlphaAPIFields).ViaField("sidecarOverrides")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarOverrides", config.BetaAPIFields).ViaField("sidecarOverrides")) errs = errs.Also(validateSidecarOverrides(trs.SidecarOverrides).ViaField("sidecarOverrides")) } if trs.ComputeResources != nil { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json index 690ef2115..a0b5a9f9d 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json @@ -155,11 +155,16 @@ "description": "TaskRunStepArtifact represents an artifact produced or used by a step within a task run. It directly uses the Artifact type for its structure.", "type": "object", "properties": { + "buildOutput": { + "description": "Indicate if the artifact is a build output or a by-product", + "type": "boolean" + }, "name": { + "description": "The artifact's identifying category name", "type": "string" }, "values": { - "description": "The artifact's identifying category name", + "description": "A collection of values related to the artifact", "type": "array", "items": { "default": {}, @@ -1932,6 +1937,10 @@ "default": {}, "$ref": "#/definitions/v1.ResourceRequirements" }, + "restartPolicy": { + "description": "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.", + "type": "string" + }, "script": { "description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command or Args.", "type": "string" @@ -2239,6 +2248,13 @@ "x-kubernetes-patch-merge-key": "mountPath", "x-kubernetes-patch-strategy": "merge" }, + "when": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1beta1.WhenExpression" + } + }, "workingDir": { "description": "Step's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", "type": "string" @@ -2426,6 +2442,9 @@ "$ref": "#/definitions/v1beta1.Artifact" } }, + "provenance": { + "$ref": "#/definitions/v1beta1.Provenance" + }, "results": { "type": "array", "items": { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_conversion.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_conversion.go index 452fb545f..9a0d4fe50 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_conversion.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_conversion.go @@ -212,7 +212,7 @@ func serializeTaskDeprecations(meta *metav1.ObjectMeta, spec *TaskSpec, taskName existingDeprecations := taskDeprecations{} if str, ok := meta.Annotations[TaskDeprecationsAnnotationKey]; ok { if err := json.Unmarshal([]byte(str), &existingDeprecations); err != nil { - return fmt.Errorf("error deserializing key %s from metadata: %w", TaskDeprecationsAnnotationKey, err) + return fmt.Errorf("error serializing key %s from metadata: %w", TaskDeprecationsAnnotationKey, err) } } if taskDeprecation != nil { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_validation.go index 9ef0db690..4d03a9501 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_validation.go @@ -249,6 +249,9 @@ func validateSteps(ctx context.Context, steps []Step) (errs *apis.FieldError) { errs = errs.Also(v1.ValidateStepResultsVariables(ctx, s.Results, s.Script).ViaIndex(idx)) errs = errs.Also(v1.ValidateStepResults(ctx, s.Results).ViaIndex(idx).ViaField("results")) } + if len(s.When) > 0 { + errs = errs.Also(s.When.validate(ctx).ViaIndex(idx)) + } } return errs } @@ -301,7 +304,11 @@ func errorIfStepResultReferenceinField(value, fieldName string) (errs *apis.Fiel } func stepArtifactReferenceExists(src string) bool { - return len(artifactref.StepArtifactRegex.FindAllStringSubmatch(src, -1)) > 0 || strings.Contains(src, "$(step.artifacts.path)") + return len(artifactref.StepArtifactRegex.FindAllStringSubmatch(src, -1)) > 0 || strings.Contains(src, "$("+artifactref.StepArtifactPathPattern+")") +} + +func taskArtifactReferenceExists(src string) bool { + return len(artifactref.TaskArtifactRegex.FindAllStringSubmatch(src, -1)) > 0 || strings.Contains(src, "$("+artifactref.TaskArtifactPathPattern+")") } func errorIfStepArtifactReferencedInField(value, fieldName string) (errs *apis.FieldError) { @@ -368,17 +375,8 @@ func validateStepResultReference(s Step) (errs *apis.FieldError) { } func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.FieldError) { - if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableArtifacts { - var t []string - t = append(t, s.Script) - t = append(t, s.Command...) - t = append(t, s.Args...) - for _, e := range s.Env { - t = append(t, e.Value) - } - if slices.ContainsFunc(t, stepArtifactReferenceExists) { - return errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "")) - } + if err := validateArtifactsReferencesInStep(ctx, s); err != nil { + return err } if s.Ref != nil { @@ -446,6 +444,11 @@ func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.Fi return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true in order to use Results in Steps.", config.EnableStepActions), "") } } + if len(s.When) > 0 { + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableStepActions && isCreateOrUpdateAndDiverged(ctx, s) { + return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true in order to use When in Steps.", config.EnableStepActions), "") + } + } if s.Image == "" { errs = errs.Also(apis.ErrMissingField("Image")) } @@ -529,6 +532,22 @@ func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.Fi return errs } +func validateArtifactsReferencesInStep(ctx context.Context, s Step) *apis.FieldError { + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableArtifacts { + var t []string + t = append(t, s.Script) + t = append(t, s.Command...) + t = append(t, s.Args...) + for _, e := range s.Env { + t = append(t, e.Value) + } + if slices.ContainsFunc(t, stepArtifactReferenceExists) || slices.ContainsFunc(t, taskArtifactReferenceExists) { + return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use artifacts feature.", config.EnableArtifacts), "") + } + } + return nil +} + // ValidateParameterTypes validates all the types within a slice of ParamSpecs func ValidateParameterTypes(ctx context.Context, params []ParamSpec) (errs *apis.FieldError) { for _, p := range params { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_conversion.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_conversion.go index e9b1bed4f..7b749ac5a 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_conversion.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_conversion.go @@ -345,6 +345,12 @@ func (ss StepState) convertTo(ctx context.Context, sink *v1.StepState) { sink.ImageID = ss.ImageID sink.Results = nil + if ss.Provenance != nil { + new := v1.Provenance{} + ss.Provenance.convertTo(ctx, &new) + sink.Provenance = &new + } + if ss.ContainerState.Terminated != nil { sink.TerminationReason = ss.ContainerState.Terminated.Reason } @@ -379,6 +385,11 @@ func (ss *StepState) convertFrom(ctx context.Context, source v1.StepState) { new.convertFrom(ctx, r) ss.Results = append(ss.Results, new) } + if source.Provenance != nil { + new := Provenance{} + new.convertFrom(ctx, *source.Provenance) + ss.Provenance = &new + } for _, o := range source.Outputs { new := TaskRunStepArtifact{} new.convertFrom(ctx, o) diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_types.go index 551a5856e..26707ff33 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_types.go @@ -372,6 +372,7 @@ type StepState struct { ContainerName string `json:"container,omitempty"` ImageID string `json:"imageID,omitempty"` Results []TaskRunStepResult `json:"results,omitempty"` + Provenance *Provenance `json:"provenance,omitempty"` Inputs []TaskRunStepArtifact `json:"inputs,omitempty"` Outputs []TaskRunStepArtifact `json:"outputs,omitempty"` } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_validation.go index b44b3d42e..a3f37caee 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/taskrun_validation.go @@ -26,6 +26,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/validate" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/strings/slices" "knative.dev/pkg/apis" @@ -50,6 +51,9 @@ func (tr *TaskRun) Validate(ctx context.Context) *apis.FieldError { // Validate taskrun spec func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { + // Validate the spec changes + errs = errs.Also(ts.ValidateUpdate(ctx)) + // Must have exactly one of taskRef and taskSpec. if ts.TaskRef == nil && ts.TaskSpec == nil { errs = errs.Also(apis.ErrMissingOneOf("taskRef", "taskSpec")) @@ -80,11 +84,11 @@ func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { errs = errs.Also(validateDebug(ts.Debug).ViaField("debug")) } if ts.StepOverrides != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepOverrides", config.AlphaAPIFields).ViaField("stepOverrides")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "stepOverrides", config.BetaAPIFields).ViaField("stepOverrides")) errs = errs.Also(validateStepOverrides(ts.StepOverrides).ViaField("stepOverrides")) } if ts.SidecarOverrides != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarOverrides", config.AlphaAPIFields).ViaField("sidecarOverrides")) + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "sidecarOverrides", config.BetaAPIFields).ViaField("sidecarOverrides")) errs = errs.Also(validateSidecarOverrides(ts.SidecarOverrides).ViaField("sidecarOverrides")) } if ts.ComputeResources != nil { @@ -118,6 +122,34 @@ func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { return errs } +// ValidateUpdate validates the update of a TaskRunSpec +func (ts *TaskRunSpec) ValidateUpdate(ctx context.Context) (errs *apis.FieldError) { + if !apis.IsInUpdate(ctx) { + return + } + oldObj, ok := apis.GetBaseline(ctx).(*TaskRun) + if !ok || oldObj == nil { + return + } + old := &oldObj.Spec + + // If already in the done state, the spec cannot be modified. + // Otherwise, only the status, statusMessage field can be modified. + tips := "Once the TaskRun is complete, no updates are allowed" + if !oldObj.IsDone() { + old = old.DeepCopy() + old.Status = ts.Status + old.StatusMessage = ts.StatusMessage + tips = "Once the TaskRun has started, only status and statusMessage updates are allowed" + } + + if !equality.Semantic.DeepEqual(old, ts) { + errs = errs.Also(apis.ErrInvalidValue(tips, "")) + } + + return +} + // validateInlineParameters validates that any parameters called in the // Task spec are declared in the TaskRun. // This is crucial for propagated parameters because the parameters could @@ -224,6 +256,11 @@ func validateDebug(db *TaskRunDebug) (errs *apis.FieldError) { if db == nil || db.Breakpoints == nil { return errs } + + if db.Breakpoints.OnFailure == "" { + errs = errs.Also(apis.ErrInvalidValue("onFailure breakpoint is empty, it is only allowed to be set as enabled", "breakpoints.onFailure")) + } + if db.Breakpoints.OnFailure != "" && db.Breakpoints.OnFailure != EnabledOnFailureBreakpoint { errs = errs.Also(apis.ErrInvalidValue(db.Breakpoints.OnFailure+" is not a valid onFailure breakpoint value, onFailure breakpoint is only allowed to be set as enabled", "breakpoints.onFailure")) } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_types.go index f792ec199..ad24f8e62 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_types.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_types.go @@ -98,6 +98,8 @@ func (we *WhenExpression) GetVarSubstitutionExpressions() ([]string, bool) { // All of them need to evaluate to True for a guarded Task to be executed. type WhenExpressions []WhenExpression +type StepWhenExpressions = WhenExpressions + // AllowsExecution evaluates an Input's relationship to an array of Values, based on the Operator, // to determine whether all the When Expressions are True. If they are all True, the guarded Task is // executed, otherwise it is skipped. diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go index 33855040b..aa6b4b4cb 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go @@ -48,7 +48,7 @@ func (wes WhenExpressions) validateWhenExpressionsFields(ctx context.Context) (e func (we *WhenExpression) validateWhenExpressionFields(ctx context.Context) *apis.FieldError { if we.CEL != "" { if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableCELInWhenExpression { - return apis.ErrGeneric("feature flag %s should be set to true to use CEL: %s in WhenExpression", config.EnableCELInWhenExpression, we.CEL) + return apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use CEL: %s in WhenExpression", config.EnableCELInWhenExpression, we.CEL), "") } if we.Input != "" || we.Operator != "" || len(we.Values) != 0 { return apis.ErrGeneric(fmt.Sprintf("cel and input+operator+values cannot be set in one WhenExpression: %v", we)) diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go index 04d3a09ad..7852edd8c 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go @@ -1696,6 +1696,11 @@ func (in *Sidecar) DeepCopyInto(out *Sidecar) { *out = make([]WorkspaceUsage, len(*in)) copy(*out, *in) } + if in.RestartPolicy != nil { + in, out := &in.RestartPolicy, &out.RestartPolicy + *out = new(corev1.ContainerRestartPolicy) + **out = **in + } return } @@ -1858,6 +1863,13 @@ func (in *Step) DeepCopyInto(out *Step) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.When != nil { + in, out := &in.When, &out.When + *out = make(WhenExpressions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -2017,6 +2029,11 @@ func (in *StepState) DeepCopyInto(out *StepState) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Provenance != nil { + in, out := &in.Provenance, &out.Provenance + *out = new(Provenance) + (*in).DeepCopyInto(*out) + } if in.Inputs != nil { in, out := &in.Inputs, &out.Inputs *out = make([]Artifact, len(*in)) diff --git a/vendor/github.com/tektoncd/pipeline/pkg/result/result.go b/vendor/github.com/tektoncd/pipeline/pkg/result/result.go index ab52c6c82..6506074fd 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/result/result.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/result/result.go @@ -36,8 +36,11 @@ const ( // StepResultType default step result value StepResultType ResultType = 4 - // StepArtifactsResultType default artifacts result value + // StepArtifactsResultType default step artifacts result value StepArtifactsResultType ResultType = 5 + + // TaskRunArtifactsResultType default taskRun artifacts result value + TaskRunArtifactsResultType ResultType = 6 ) // RunResult is used to write key/value pairs to TaskRun pod termination messages. @@ -93,6 +96,8 @@ func (r *ResultType) UnmarshalJSON(data []byte) error { *r = InternalTektonResultType case "StepArtifactsResult": *r = StepArtifactsResultType + case "TaskRunArtifactsResult": + *r = TaskRunArtifactsResultType default: *r = UnknownResultType } diff --git a/vendor/github.com/tektoncd/pipeline/test/e2e-tests-kind-prow-alpha.env b/vendor/github.com/tektoncd/pipeline/test/e2e-tests-kind-prow-alpha.env index dfcc2e764..5ab894c2a 100644 --- a/vendor/github.com/tektoncd/pipeline/test/e2e-tests-kind-prow-alpha.env +++ b/vendor/github.com/tektoncd/pipeline/test/e2e-tests-kind-prow-alpha.env @@ -9,3 +9,4 @@ ENABLE_CEL_IN_WHENEXPRESSION=true ENABLE_PARAM_ENUM=true ENABLE_ARTIFACTS=true ENABLE_CONCISE_RESOLVER_SYNTAX=true +ENABLE_KUBERNETES_SIDECAR=true diff --git a/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh b/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh index 8a8b63a48..9d78515fd 100644 --- a/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh +++ b/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh @@ -33,6 +33,7 @@ ENABLE_CEL_IN_WHENEXPRESSION=${ENABLE_CEL_IN_WHENEXPRESSION:="false"} ENABLE_PARAM_ENUM=${ENABLE_PARAM_ENUM:="false"} ENABLE_ARTIFACTS=${ENABLE_ARTIFACTS:="false"} ENABLE_CONCISE_RESOLVER_SYNTAX=${ENABLE_CONCISE_RESOLVER_SYNTAX:="false"} +ENABLE_KUBERNETES_SIDECAR=${ENABLE_KUBERNETES_SIDECAR:="false"} failed=0 # Script entry point. @@ -143,6 +144,18 @@ function set_enable_concise_resolver_syntax() { kubectl patch configmap feature-flags -n tekton-pipelines -p "$jsonpatch" } +function set_enable_kubernetes_sidecar() { + local method="$1" + if [ "$method" != "false" ] && [ "$method" != "true" ]; then + printf "Invalid value for enable-kubernetes-sidecar %s\n" ${method} + exit 255 + fi + printf "Setting enable-kubernetes-sidecar to %s\n", ${method} + jsonpatch=$(printf "{\"data\": {\"enable-kubernetes-sidecar\": \"%s\"}}" $1) + echo "feature-flags ConfigMap patch: ${jsonpatch}" + kubectl patch configmap feature-flags -n tekton-pipelines -p "$jsonpatch" +} + function run_e2e() { # Run the integration tests header "Running Go e2e tests" @@ -171,6 +184,7 @@ set_cel_in_whenexpression "$ENABLE_CEL_IN_WHENEXPRESSION" set_enable_param_enum "$ENABLE_PARAM_ENUM" set_enable_artifacts "$ENABLE_ARTIFACTS" set_enable_concise_resolver_syntax "$ENABLE_CONCISE_RESOLVER_SYNTAX" +set_enable_kubernetes_sidecar "$ENABLE_KUBERNETES_SIDECAR" run_e2e (( failed )) && fail_test diff --git a/vendor/github.com/tektoncd/pipeline/test/featureflags.go b/vendor/github.com/tektoncd/pipeline/test/featureflags.go index 823d19b99..a6b6db071 100644 --- a/vendor/github.com/tektoncd/pipeline/test/featureflags.go +++ b/vendor/github.com/tektoncd/pipeline/test/featureflags.go @@ -119,6 +119,7 @@ func getFeatureFlagsBaseOnAPIFlag(t *testing.T) *config.FeatureFlags { "enable-param-enum": "true", "enable-artifacts": "true", "enable-concise-resolver-syntax": "true", + "enable-kubernetes-sidecar": "true", }) if err != nil { t.Fatalf("error creating alpha feature flags configmap: %v", err) diff --git a/vendor/k8s.io/utils/net/multi_listen.go b/vendor/k8s.io/utils/net/multi_listen.go new file mode 100644 index 000000000..7cb7795be --- /dev/null +++ b/vendor/k8s.io/utils/net/multi_listen.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package net + +import ( + "context" + "fmt" + "net" + "sync" +) + +// connErrPair pairs conn and error which is returned by accept on sub-listeners. +type connErrPair struct { + conn net.Conn + err error +} + +// multiListener implements net.Listener +type multiListener struct { + listeners []net.Listener + wg sync.WaitGroup + + // connCh passes accepted connections, from child listeners to parent. + connCh chan connErrPair + // stopCh communicates from parent to child listeners. + stopCh chan struct{} +} + +// compile time check to ensure *multiListener implements net.Listener +var _ net.Listener = &multiListener{} + +// MultiListen returns net.Listener which can listen on and accept connections for +// the given network on multiple addresses. Internally it uses stdlib to create +// sub-listener and multiplexes connection requests using go-routines. +// The network must be "tcp", "tcp4" or "tcp6". +// It follows the semantics of net.Listen that primarily means: +// 1. If the host is an unspecified/zero IP address with "tcp" network, MultiListen +// listens on all available unicast and anycast IP addresses of the local system. +// 2. Use "tcp4" or "tcp6" to exclusively listen on IPv4 or IPv6 family, respectively. +// 3. The host can accept names (e.g, localhost) and it will create a listener for at +// most one of the host's IP. +func MultiListen(ctx context.Context, network string, addrs ...string) (net.Listener, error) { + var lc net.ListenConfig + return multiListen( + ctx, + network, + addrs, + func(ctx context.Context, network, address string) (net.Listener, error) { + return lc.Listen(ctx, network, address) + }) +} + +// multiListen implements MultiListen by consuming stdlib functions as dependency allowing +// mocking for unit-testing. +func multiListen( + ctx context.Context, + network string, + addrs []string, + listenFunc func(ctx context.Context, network, address string) (net.Listener, error), +) (net.Listener, error) { + if !(network == "tcp" || network == "tcp4" || network == "tcp6") { + return nil, fmt.Errorf("network %q not supported", network) + } + if len(addrs) == 0 { + return nil, fmt.Errorf("no address provided to listen on") + } + + ml := &multiListener{ + connCh: make(chan connErrPair), + stopCh: make(chan struct{}), + } + for _, addr := range addrs { + l, err := listenFunc(ctx, network, addr) + if err != nil { + // close all the sub-listeners and exit + _ = ml.Close() + return nil, err + } + ml.listeners = append(ml.listeners, l) + } + + for _, l := range ml.listeners { + ml.wg.Add(1) + go func(l net.Listener) { + defer ml.wg.Done() + for { + // Accept() is blocking, unless ml.Close() is called, in which + // case it will return immediately with an error. + conn, err := l.Accept() + // This assumes that ANY error from Accept() will terminate the + // sub-listener. We could maybe be more precise, but it + // doesn't seem necessary. + terminate := err != nil + + select { + case ml.connCh <- connErrPair{conn: conn, err: err}: + case <-ml.stopCh: + // In case we accepted a connection AND were stopped, and + // this select-case was chosen, just throw away the + // connection. This avoids potentially blocking on connCh + // or leaking a connection. + if conn != nil { + _ = conn.Close() + } + terminate = true + } + // Make sure we don't loop on Accept() returning an error and + // the select choosing the channel case. + if terminate { + return + } + } + }(l) + } + return ml, nil +} + +// Accept implements net.Listener. It waits for and returns a connection from +// any of the sub-listener. +func (ml *multiListener) Accept() (net.Conn, error) { + // wait for any sub-listener to enqueue an accepted connection + connErr, ok := <-ml.connCh + if !ok { + // The channel will be closed only when Close() is called on the + // multiListener. Closing of this channel implies that all + // sub-listeners are also closed, which causes a "use of closed + // network connection" error on their Accept() calls. We return the + // same error for multiListener.Accept() if multiListener.Close() + // has already been called. + return nil, fmt.Errorf("use of closed network connection") + } + return connErr.conn, connErr.err +} + +// Close implements net.Listener. It will close all sub-listeners and wait for +// the go-routines to exit. +func (ml *multiListener) Close() error { + // Make sure this can be called repeatedly without explosions. + select { + case <-ml.stopCh: + return fmt.Errorf("use of closed network connection") + default: + } + + // Tell all sub-listeners to stop. + close(ml.stopCh) + + // Closing the listeners causes Accept() to immediately return an error in + // the sub-listener go-routines. + for _, l := range ml.listeners { + _ = l.Close() + } + + // Wait for all the sub-listener go-routines to exit. + ml.wg.Wait() + close(ml.connCh) + + // Drain any already-queued connections. + for connErr := range ml.connCh { + if connErr.conn != nil { + _ = connErr.conn.Close() + } + } + return nil +} + +// Addr is an implementation of the net.Listener interface. It always returns +// the address of the first listener. Callers should use conn.LocalAddr() to +// obtain the actual local address of the sub-listener. +func (ml *multiListener) Addr() net.Addr { + return ml.listeners[0].Addr() +} + +// Addrs is like Addr, but returns the address for all registered listeners. +func (ml *multiListener) Addrs() []net.Addr { + var ret []net.Addr + for _, l := range ml.listeners { + ret = append(ret, l.Addr()) + } + return ret +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6dd230a68..91281465e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -312,7 +312,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support github.com/onsi/ginkgo/v2/internal/testingtproxy github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/types -# github.com/onsi/gomega v1.33.1 +# github.com/onsi/gomega v1.34.0 ## explicit; go 1.20 github.com/onsi/gomega github.com/onsi/gomega/format @@ -331,7 +331,7 @@ github.com/opencontainers/go-digest ## explicit; go 1.18 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 -# github.com/openshift/api v3.9.0+incompatible => github.com/openshift/api v0.0.0-20240722135205-ae4f370f361f +# github.com/openshift/api v3.9.0+incompatible => github.com/openshift/api v0.0.0-20240724184751-84047ef4a2ce ## explicit; go 1.22.0 github.com/openshift/api/config/v1 github.com/openshift/api/pkg/serialization @@ -412,7 +412,7 @@ github.com/spf13/pflag github.com/stoewer/go-strcase # github.com/stretchr/objx v0.5.2 ## explicit; go 1.20 -# github.com/tektoncd/pipeline v0.61.1 +# github.com/tektoncd/pipeline v0.62.0 ## explicit; go 1.22 github.com/tektoncd/pipeline/internal/artifactref github.com/tektoncd/pipeline/pkg/apis/config @@ -1214,7 +1214,7 @@ k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1 k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1 -# k8s.io/kube-openapi v0.30.0 => k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f +# k8s.io/kube-openapi v0.30.0 => k8s.io/kube-openapi v0.0.0-20240726031636-6f6746feab9c ## explicit; go 1.20 k8s.io/kube-openapi/pkg/cached k8s.io/kube-openapi/pkg/common @@ -1225,7 +1225,7 @@ k8s.io/kube-openapi/pkg/schemaconv k8s.io/kube-openapi/pkg/spec3 k8s.io/kube-openapi/pkg/util/proto k8s.io/kube-openapi/pkg/validation/spec -# k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 +# k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 ## explicit; go 1.18 k8s.io/utils/buffer k8s.io/utils/clock @@ -1481,7 +1481,7 @@ sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 sigs.k8s.io/yaml/goyaml.v3 # k8s.io/client-go => k8s.io/client-go v0.30.3 -# k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f +# k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20240726031636-6f6746feab9c # k8s.io/kubectl => k8s.io/kubectl v0.30.3 -# github.com/openshift/api => github.com/openshift/api v0.0.0-20240722135205-ae4f370f361f +# github.com/openshift/api => github.com/openshift/api v0.0.0-20240724184751-84047ef4a2ce # github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20240528061634-b054aa794d87