From 706c2b478223795e374d353c0311a91178767078 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:01:47 +0100 Subject: [PATCH 01/15] update last_rebase.sh --- scripts/auto-rebase/last_rebase.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/auto-rebase/last_rebase.sh b/scripts/auto-rebase/last_rebase.sh index b0eb8ea4db..ec245165ac 100755 --- a/scripts/auto-rebase/last_rebase.sh +++ b/scripts/auto-rebase/last_rebase.sh @@ -1,2 +1,2 @@ #!/bin/bash -x -./scripts/auto-rebase/rebase.sh to "registry.ci.openshift.org/ocp/release:4.22.0-0.nightly-2026-02-05-115400" "registry.ci.openshift.org/ocp-arm64/release-arm64:4.22.0-0.nightly-arm64-2026-02-05-082424" +./scripts/auto-rebase/rebase.sh to "registry.ci.openshift.org/ocp/release:4.22.0-0.nightly-2026-02-17-112443" "registry.ci.openshift.org/ocp-arm64/release-arm64:4.22.0-0.nightly-arm64-2026-02-17-232712" From c9e94e1866bd87642ba627aa4fd228b517201411 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:01:49 +0100 Subject: [PATCH 02/15] update changelog --- scripts/auto-rebase/changelog.txt | 525 ++++++++++++++++++++++++------ scripts/auto-rebase/commits.txt | 38 +-- 2 files changed, 450 insertions(+), 113 deletions(-) diff --git a/scripts/auto-rebase/changelog.txt b/scripts/auto-rebase/changelog.txt index 8481e43f3e..db46c98cb0 100644 --- a/scripts/auto-rebase/changelog.txt +++ b/scripts/auto-rebase/changelog.txt @@ -1,95 +1,432 @@ -- api embedded-component c16ec2bcf089999a012322dbf889c632729dc80d to 81371d13d1fcad175a48627cf11524a94a80c377 - - 43dd9725 2026-02-03T15:18:57Z CodeRabbit should not be looking at openapi generated content - - b792c564 2026-02-02T12:08:34Z Remove pre 4.20 SDN feature gates - - fe0f7f81 2026-01-30T12:12:42+01:00 add suggestions - - f7f52ce3 2026-01-30T11:03:10+01:00 feat: add Insights capability to Insights CRDs - - 1d800807 2026-01-29T10:29:12-05:00 promote ManagedBootImagesCPMS fg to Default - - e73ed72f 2026-01-29T09:48:40-05:00 Add CRIOCredentialProviderConfig API - - 60662b01 2026-01-29T10:55:55Z Remove ProcMountType - - 7441eb56 2026-01-28T12:06:53+01:00 add suggestions - - f8a69ad1 2026-01-08T13:08:09+01:00 Fix documentation punctuation and regenerate files - - 66fff255 2026-01-08T12:23:59+01:00 add prometheusOperatorConfig API - -- cluster-csi-snapshot-controller-operator embedded-component 8be3728d7db58111e6efb46f6075698d6b7ec994 to 7b6335396677dfd392dc72e1f1bbb5afcfa74a44 - - f6a61f9 2026-01-27T21:59:36-08:00 Rename replacer func to more generic name - - 4b3bf71 2026-01-27T21:52:16-08:00 hypershift: Add version annotation to controller Deployments - - 4cfd73e 2026-01-27T19:40:57-08:00 Bump library-go dependency - - 90e85d2 2026-01-27T19:40:57-08:00 Add desired-version annotation to controller Deployment - -- cluster-ingress-operator embedded-component eeb7347184177d0f0855632bad82398089547e87 to 77901360f18951f2a51d38acd1a07714f9183493 - - b2c8e1c 2026-02-02T15:26:39-05:00 E2E test for internal LB creation - -- cluster-kube-apiserver-operator embedded-component 064809665fd54e4c15d3b0c2f6da9fadce715c34 to fecf00cbeaf1fc18178bffddab767ee8f3d7e36f - - f82dace 2026-01-29T12:46:58-03:00 Bump library-go to get KMS helper - - 0e25cb4 2026-01-29T12:46:58-03:00 Conditionally add the KMS plugin volume mount to the kube-apiserver container - - f6a1c91 2026-01-27T17:06:18+01:00 CNTRLPLANE-2563: update wording for major upgrades - -- cluster-kube-scheduler-operator embedded-component ed10ad69474b83c568452f59dbd3d943778799d7 to b37b73a87e7a6612f3354c2ffc134a23a0a8c13c - - d7f76dc 2026-01-27T20:23:53+05:30 Bump dependencies - - a7a7db7 2026-01-27T20:23:21+05:30 Adds openshift/cluster-kube-scheduler-operator/operator/serial suite to the test ext binary - -- cluster-network-operator embedded-component b9a777441ccdbaea524196ecd15aed7e0aa8ab5e to f0bdee37451757734c3e84cb6c0a8646290c4ffa - - d19cb3f 2026-01-28T20:28:45+01:00 Fix staticcheck QF* and ST* lint issues - - eba58e4 2026-01-28T20:28:45+01:00 Update golangci-lint config for v2 compatibility - - 46882d6 2026-01-28T15:29:08+01:00 Fix existing lint errors found by golangci-lint v1 - - 2527aec 2026-01-28T11:51:13Z Remove templating for removed feature gates - - 9f45d8d 2026-01-27T17:11:09-08:00 avoid flapping Degraded on transient failures - - ebdaccd 2026-01-27T12:15:46Z Remove references to AdminNetworkPolicy and NetworkSegmentation featuregates - - 756a7ea 2026-01-26T14:32:35+01:00 OCPBUGS-74401: Remove duplicated openssl parameter - - 5e9c628 2026-01-12T17:35:27+01:00 CNF-20883: Align templates frrk8s - -- etcd embedded-component 806f690e1f140e0aea2eb05ef5f288b756b62895 to 6a0992267004177e385e35b91e186635a644dbfe - - 4afffb4f 2025-12-18T20:05:04Z Updating ose-etcd-container image to be consistent with ART for 4.22 Reconciling with https://github.com/openshift/ocp-build-data/tree/087d1930e36b609f77d73bd8a313d85c940cff4d/images/ose-etcd.yml - -- kubernetes embedded-component e4a4167c40c9ed543c5a80f2e08cc73696f7a4f6 to 9d521311f5fb67dc43f49eeb728ee2c80976835a - - bb37a6c1a 2026-02-03T09:47:51+01:00 UPSTREAM: 136202: raise kubelet CSI init backoff to cover ~140s DNS delays - - 5579c3340 2026-01-16T14:19:18-05:00 UPSTREAM: : Added validation to check if OKD featureset is being enabled on OKD clusters - - 8504fe0c7 2026-01-13T14:38:55-05:00 UPSTREAM: : Vendored API repo - -- machine-config-operator embedded-component 1881dab7389ab49e3fbb2eaee17ea74b4f84b2ad to 067395ed863e0254c4e7ce85bf8bce7e464778bb - - df7f0605 2026-02-03T15:52:07-05:00 Fix OSImageStream validating admission policies for OKD - - 29a85663 2026-02-01T21:26:26-08:00 OKD: Pass TAGS argument to the machine-config-controller image build - - a9ea6555 2026-01-30T13:32:42-05:00 daemon: migrate legacy direct runGetOut references to use the CommandRunner interface - - 23c15b3e 2026-01-29T18:44:08Z MCO-2090: migrate nodedisruptionpolicy tests from the private repository to MCO repository - - 0b7af4aa 2026-01-29T08:36:25-05:00 AGENT-1424: Add e2e test for IRI deletion - - 56825a4f 2026-01-28T13:24:29-05:00 docs: add bootstrap e2e guide - - 64001b7a 2026-01-27T15:38:19-06:00 fixes exposure of sensitive data in log files - - e3841fb7 2026-01-27T10:34:18-05:00 add VAP for CPMS boot image updates - - 28f9c724 2026-01-27T12:44:31+01:00 MCO-2088: Remove wasm extension - - a223cc74 2026-01-23T10:15:20-05:00 add iri prefix to root certificate file - - 5b44ac92 2026-01-23T10:15:08-05:00 replaced controller clients with the related listers - - c6271f42 2026-01-12T09:44:27-05:00 controller: refactor helpers to get machines by state - -- openshift-controller-manager embedded-component aaacf2be3860ec3609e6031527a6ffca4f282ba7 to 19ac71374ea7d42957fe0eb3cc6d38679cc257e1 - - d39fedb 2026-02-02T20:41:05+01:00 CNTRLPLANE-2620: bump github.com/openshift/library-go - -- operator-framework-olm embedded-component 526cde8d70dc640972eab717f80b42b66e8dff15 to fae41b2724eeab7a0e9b1ad89408bbbb36516fe2 - - 7c903b19 2026-02-04T13:39:02+08:00 continue to adjust case per collect-profiles change - - 0fc3cdb2 2026-02-03T16:16:18+08:00 UPSTREAM: : automate OCP-87276 - - 0085e3c9 2026-02-03T00:13:13-05:00 Remove the collect-profiles job - - 04ce50ea 2026-02-03T10:45:55+08:00 UPSTREAM: : remove redhat-marketplace catalog - - ec98e0d8 2026-02-03T09:08:53+08:00 change to check collect-profile networkpolicy dynamically - - d8f66874 2026-01-28T14:38:57+08:00 Add retry logic for SNO cluster detection in leader election configuration - -- oc image-amd64 430c82293109e23f3caaf9ba60e5affd2d5356f5 to 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 - - 08d5f27a 2026-01-30T14:17:04+01:00 expose: Fix labels not being added to route - - e87384f5 2026-01-29T20:38:10-05:00 Revert "CNTRLPLANE-2656:Migrating oc cli tests to ote" - - 9619e215 2026-01-28T11:01:38-05:00 OSDOCS#18071: Updating CLI docs templates to include a required abstract/short description - - 63b9258c 2026-01-28T19:41:37+05:30 removing bindata.go - - c423f7b7 2026-01-21T12:39:18+05:30 Removed sos cases - -- kubernetes image-amd64 e4a4167c40c9ed543c5a80f2e08cc73696f7a4f6 to 9d521311f5fb67dc43f49eeb728ee2c80976835a - - bb37a6c1a 2026-02-03T09:47:51+01:00 UPSTREAM: 136202: raise kubelet CSI init backoff to cover ~140s DNS delays - - 5579c3340 2026-01-16T14:19:18-05:00 UPSTREAM: : Added validation to check if OKD featureset is being enabled on OKD clusters - - 8504fe0c7 2026-01-13T14:38:55-05:00 UPSTREAM: : Vendored API repo - -- oc image-arm64 430c82293109e23f3caaf9ba60e5affd2d5356f5 to 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 - - 08d5f27a 2026-01-30T14:17:04+01:00 expose: Fix labels not being added to route - - e87384f5 2026-01-29T20:38:10-05:00 Revert "CNTRLPLANE-2656:Migrating oc cli tests to ote" - - 9619e215 2026-01-28T11:01:38-05:00 OSDOCS#18071: Updating CLI docs templates to include a required abstract/short description - - 63b9258c 2026-01-28T19:41:37+05:30 removing bindata.go - - c423f7b7 2026-01-21T12:39:18+05:30 Removed sos cases - -- kubernetes image-arm64 0a955ccf26bb6091b9053309eb0ce0b2992fed70 to 9d521311f5fb67dc43f49eeb728ee2c80976835a - - bb37a6c1a 2026-02-03T09:47:51+01:00 UPSTREAM: 136202: raise kubelet CSI init backoff to cover ~140s DNS delays +- api embedded-component 81371d13d1fcad175a48627cf11524a94a80c377 to d34f11c515b3d00fdb3809cd59737e3bd77167c4 + - a51a8c21 2026-02-13T14:33:53-05:00 CORS-4096: Add DNS Record Type for IPv6 Domain mapping + - 164ef8ee 2026-02-11T21:51:41+01:00 make update + - 9ee7e57f 2026-02-11T21:51:40+01:00 TLSSecurityProfile: Remove go's unsupported ciphers + - 2a4d5aca 2026-02-11T16:55:12Z Synchronous review updates + - f1afd44b 2026-02-11T15:55:12Z Add ClusterAPI config + - 03090cfb 2026-02-11T15:58:03+01:00 Remove CPMSMachineNamePrefix featuregate + - 43458f18 2026-02-09T16:17:23Z Add a timeout for aysnc calls in integration tests + - 8d70004f 2026-02-09T14:04:43Z Update integration test timeout and make parallel where possible + - 49591510 2026-02-09T13:05:22Z Deploy CompatibilityRequirement from o/api repo + - 33223cf6 2026-02-09T13:01:36Z Feature gate CVO application of CompatibilityRequirement CRD + - f8283c1d 2026-02-05T11:44:39-05:00 Add link to the dynamic-config-manager EP PR + - 1fece6c0 2026-02-05T10:44:12-05:00 Add DRAPartitionableDevices to TechPreviewNoUpgrade + - 2fc32cc5 2026-02-05T08:14:06-05:00 Added support for dynamic AWS dedicated hosts + - 40188ba8 2026-02-05T01:24:01-05:00 Move DynamicConfigurationManager back to TPNU + - 3643afa3 2026-02-05T10:36:51+08:00 Graduate MutableCSINodeAllocatableCount to GA + - a47ac128 2026-02-04T04:56:57-05:00 NE-2480: Add featuregate for Gateway API without OLM + - f39c09df 2026-01-28T14:06:41+01:00 Remove VolumeAttributesClass FeatureGate + +- cluster-dns-operator embedded-component 41a53fed36e6e99c7c9ceb3a699c3547ee5d9bb9 to 5d7c973968909d4155796363222f6edc001e19a3 + - e2b909a 2026-01-15T10:37:12-05:00 Use `trafficDistribution: PreferSameNode` for openshift-dns Service + +- cluster-ingress-operator embedded-component 77901360f18951f2a51d38acd1a07714f9183493 to abfb6fa7b9c95dc54fb3988e84297912ad88e0e4 + - 15e4cae 2026-02-06T10:35:49-05:00 Fix formatting in secret_hash.go + - 900e9f0 2026-02-06T09:44:08-03:00 bump go on base image + - ff08e12 2026-02-05T17:30:47-05:00 Move CanaryServingCertHashAnnotation to daemonset.go + - 9df597d 2026-02-05T17:29:11-05:00 Address PR review comments: use CanaryCertificateName and propagate context + - 1e5f504 2026-02-05T17:22:04-05:00 OCPBUGS-58145: reload serving cert on rotation + - 9fbaa11 2026-02-05T11:34:38-03:00 bump controller-runtime + - a2e1cd1 2026-02-05T11:15:27-03:00 bump k8s libraries to v0.35.0 Update Kubernetes libraries to v0.35.0. Due to the library version update: * Indirect dependencies were also updated * Minimal go version updated to 1.25, so updating build image accordingly + - 0de9609 2026-01-22T14:59:26-03:00 NO-JIRA: Add coderabbit to CIO + +- cluster-kube-apiserver-operator embedded-component fecf00cbeaf1fc18178bffddab767ee8f3d7e36f to cee7acb6c820b707fbb1e1dc01cef6c1971f146d + - 4cf4d0b 2026-02-09T12:48:47+03:00 Test encryption provider migration + - 2a40ac5 2026-02-09T12:48:41+03:00 Bump library-go + - 436f939 2026-02-05T15:15:23+05:30 vendor: update library-go to latest + - fe307df 2026-02-04T19:05:31+05:30 CNTRLPLANE-2247: Add KMS TestKMSEncryptionOnOff e2e test + - b9d2f86 2026-01-22T11:52:23Z remove kube-apiserver user from crb + +- cluster-kube-scheduler-operator embedded-component b37b73a87e7a6612f3354c2ffc134a23a0a8c13c to 14c5fdcfc2602292e19cab8713e42accf94b593d + - 4746564 2026-02-12T15:26:40+05:30 Register preferred-host test suite in OTE and update documentation + - 6d5d557 2026-02-12T15:24:43+05:30 Refactor test utilities to eliminate code duplication + - c58aa5c 2026-02-03T20:12:57+05:30 Add Ginkgo-based e2e tests and parallel test suite + +- cluster-network-operator embedded-component f0bdee37451757734c3e84cb6c0a8646290c4ffa to 9d540eb7929f83879d3dafbcd1ae6cb1feca36b3 + - d69bd30 2025-08-04T16:54:19+02:00 silenced output of start-audit-log-rotation and made it ENV dependning instead + +- cluster-openshift-controller-manager-operator embedded-component a6ce1136e71ded4af3cb5e771435e098b5e30349 to 7634c413830a510ff942bd6886ffe5f79db707b4 + - 2e329e3 2026-02-03T12:30:47+01:00 CNTRLPLANE-2620: propagate global tls config to operand + - 5282921 2026-02-02T19:27:01+01:00 CNTRLPLANE-2620: vendor github.com/openshift/library-go/pkg/operator/configobserver + - 44f341c 2026-02-02T14:40:44+01:00 CNTRLPLANE-2620: bump github.com/openshift/library-go + +- kubernetes embedded-component 9d521311f5fb67dc43f49eeb728ee2c80976835a to 047d96223dd843e9d54bed59bc212d2e9122c56a + - bbdf0eb44 2026-02-06T13:54:27+01:00 UPSTREAM: 135629: selinux: Fix the controller to ignore finished pods + +- machine-config-operator embedded-component 067395ed863e0254c4e7ce85bf8bce7e464778bb to 7eb4793ae255b19327e781f66aaf1dbd3e5210c5 + - 64d3b69c 2026-02-13T13:16:27-05:00 bump openshift/client-go + - d98db2ff 2026-02-13T10:00:11-05:00 e2e: update boot image tests + - 604c1dae 2026-02-13T09:58:43-05:00 bootimage: enable opt-out for azure and vsphere + - 85764598 2026-02-12T10:44:04-05:00 OCPBUGS-76444: pkg/daemon/update: Remove conditional logic for kernel-rt-kvm + - a9c528d1 2026-02-12T09:00:42Z Make tls tests more stable + - 55ddcf86 2026-02-11T15:33:35-05:00 Bump openshift/api + - 5b2e93d4 2026-02-11T10:32:33-05:00 Fix cleanup verification timeouts in e2e-ocl tests + - 84eedc34 2026-02-11T09:09:01-05:00 copy binaries directly into final stage + - b8507587 2026-02-11T09:06:47-05:00 clear dnf cache to reduce image size + - 1cf8e054 2026-02-10T12:17:38-06:00 fix pull secret log spam make verify error + - b84815f0 2026-02-09T13:41:23Z Adapt boot images test cases to the new skew functionality + - 6ab5da81 2026-02-09T10:22:37Z MCO-2110: Migrate security tests + - 945c0af3 2026-02-06T14:51:16-05:00 Revert "Merge pull request #5586 from pablintino/dbus" + - 23650384 2026-02-05T15:31:31-05:00 crio: disable short_name_mode until we introduce ctrcfg api for it + - 6bde8f65 2026-02-05T13:39:36-05:00 node: add skew enforcement prometheus alert + - ed0b5ca8 2026-02-05T13:39:02-05:00 text/extended: add skew enforcement e2es + - 4d993aa6 2026-02-05T13:39:02-05:00 test/extended: refactor bootimage helpers + - b138090f 2026-02-05T12:07:53-05:00 hack: fix ami update script + - 6ef06dff 2026-02-05T00:54:41-05:00 feat: increase reserved memory for tnf masters + - 936c8e17 2026-02-04T13:15:09-05:00 hack: update ami script and list + - 24a0730d 2026-02-04T08:50:26-05:00 daemon: rewrite all systemd units when forcefile exists + - d89321d9 2026-02-02T10:51:18-05:00 Make TestImagePrunerErrors flexible to registry behavior changes + - 2277bea0 2026-01-30T14:21:59-05:00 operator: verify boot image controller state + - a16d81c4 2026-01-30T14:21:59-05:00 operator: add upgrade block unit tests + - e2b09f2a 2026-01-30T14:21:59-05:00 operator: block upgrades on skew violation + - c82370ae 2026-01-30T14:21:59-05:00 bootimage: update skew enforcement status + - 985f299c 2026-01-30T14:21:59-05:00 operator: add skew enforcement status unit tests + - 62becfc1 2026-01-30T14:21:59-05:00 operator: populate skew enforcement status + - aedd96ea 2026-01-29T23:46:05+01:00 OCPBUGS-63699: Remove MCD liveness probe + - 688d5dd1 2026-01-27T12:12:02+01:00 MCO-2065: Move systemctl execs to dbus calls + +- operator-framework-olm embedded-component fae41b2724eeab7a0e9b1ad89408bbbb36516fe2 to 811919f88bc3b8da4f97c6e6ca031258cc4fa13b + - 459f2fe9 2026-02-11T00:07:13Z :seedling: Bump go.podman.io/image/v5 from 5.38.0 to 5.39.1 (#3763) + - 81299149 2026-02-06T16:55:00-05:00 chore(deps): upgrade Go module dependencies (edge) (#473) + - 554de2ad 2026-02-06T16:55:00-05:00 Bump github.com/google/cel-go from 0.26.1 to 0.27.0 (#472) + - caa6e197 2026-02-06T16:55:00-05:00 move binary dependency management to bingo (#471) + - 9deb9d8a 2026-02-06T16:55:00-05:00 Bump sigs.k8s.io/controller-runtime (#470) + - 351eed19 2026-02-06T16:54:53-05:00 Fix k8s dependencies ci (#469) + - 5b805800 2026-02-06T16:54:38-05:00 fix(release) Issues faced with invalid latest tag after changes in goreleaser (#1901) + - 02a7f066 2026-02-06T16:54:38-05:00 fix CreateTemplateByType regression (#1899) + - 3b7ae219 2026-02-06T16:54:37-05:00 Bump github.com/operator-framework/api from 0.38.0 to 0.39.0 (#1900) + - ff328222 2026-02-06T16:54:37-05:00 chore(deps): upgrade Go module dependencies (edge) (#1897) + - 60763c02 2026-02-06T16:54:37-05:00 Bump github.com/onsi/gomega from 1.39.0 to 1.39.1 (#1895) + - 92ca3e1c 2026-02-06T16:54:37-05:00 Bump github.com/docker/cli (#1896) + - 550443d3 2026-02-06T16:54:37-05:00 Bump github.com/onsi/ginkgo/v2 from 2.27.5 to 2.28.1 (#1894) + - 5b9ccbc9 2026-02-06T16:54:36-05:00 Bump sigs.k8s.io/controller-runtime (#1893) + - bddef8d5 2026-02-06T16:54:36-05:00 Bump the k8s-dependencies with additional fixes (#1892) + - 01f01c89 2026-02-06T16:54:36-05:00 Bump github.com/docker/cli (#1890) + - 486368bc 2026-02-06T16:54:36-05:00 fix dropped :latest tag publication from migration to goreleaser v2.12 and go1.25 (#1891) + - e549c695 2026-02-06T16:54:36-05:00 upgraded github.com/operator-framework/operator-registry v1.62.0 => v1.63.0 (#3761) + - 8a49e5fd 2026-02-06T16:54:36-05:00 Add pedjak to OWNERS (#3760) + - 6c8852fe 2026-02-06T16:54:35-05:00 chore(deps): upgrade Go module dependencies (edge) (#3759) + - 275fbcf2 2026-02-06T16:54:35-05:00 fix: add OpenAPIModelName for PackageManifest to fix oc explain (#3755) + - e19d4286 2026-02-06T16:54:35-05:00 :seedling: Bump github.com/onsi/gomega from 1.39.0 to 1.39.1 (#3758) + - 561217b4 2026-02-06T16:54:35-05:00 :seedling: Bump github.com/onsi/ginkgo/v2 from 2.27.5 to 2.28.1 (#3757) + - 5d4b1b37 2026-02-06T16:54:35-05:00 fix: disable WatchListClient for envtest-based tests (#3756) + - ea7e0300 2026-02-06T16:54:34-05:00 :seedling: Bump sigs.k8s.io/controller-runtime (#3754) + - 2925d07f 2026-02-06T16:54:34-05:00 :seedling: Bump the k8s-dependencies group to 1.35 (#3743) + - 8bb814da 2026-02-06T16:54:22-05:00 fishing to see if testing explicitly for success will work for matrixed tests with fail-fast:false (#3752) + - 16ebb98d 2026-02-06T10:05:08+08:00 remove qe case of testing collect-profiles + - 82a07751 2026-02-05T18:29:54-03:00 UPSTREAM: : automate OCP-40945 + - 7b17a6ac 2026-02-05T02:30:31-03:00 tests: update OLMv0 QE cases + +- route-controller-manager embedded-component 2b9e93a5f0fc1e93090bbe34ce95f3b4ad5cff15 to 624742d93f3a7885cf7f70985f1e23ff60da580d + - 4ca0f15 2026-02-10T15:21:30-03:00 bump library-go version + - cd4fccc 2026-02-06T18:19:54-03:00 fix compilation error after bump k8s lib + - d65cfe0 2026-02-06T18:16:17-03:00 bump k8s libraries to v0.35.0 + +- oc image-amd64 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 to 8b0a043216f7ae608606afb5bdb0ce451561021e + - deaedbf2 2026-02-06T20:16:54-05:00 Revert "CNTRLPLANE-2656: Fixing oc client cases for microshift and metal ipv6 profiles" + - 82d41d0b 2026-02-05T11:33:56+05:30 CNTRLPLANE-2656: Add oc CLI e2e tests with OTE framework support + +- router image-amd64 d2db065ae452ecfdb482f0ac4c6778b0c0e48b7f to d8ed3559fd4808a4f10c927ba4a199d3fd5b84a2 + - c46d819 2026-02-11T09:03:56-03:00 update base image to OCP 4.22 + - cb8dba6 2026-02-10T09:19:25-03:00 disable WatchListClient featuregate + - b92c259 2026-02-05T11:24:23-03:00 bump k8s libraries to v0.35.0 + +- ovn-kubernetes image-amd64 1938041fd8f8c1fb5d376fa59faec1fef7614a92 to 2a9cd189db9c74dc678fcfca68473d6fdc278028 + - 7dd0e556 2026-01-27T15:00:53-08:00 skip new NetSeg Localnet test + - 245941b1 2026-01-27T20:09:36Z sync openshift/go.mod with upstream dependencies + - aaf3f757 2026-01-26T21:36:19+02:00 docs: add OVS Dynamic CPU Affinity feature documentation + - 1e68f901 2026-01-26T21:36:18+02:00 createFileWatcherFor: rename argument + - 9dccb75e 2026-01-26T21:36:18+02:00 vendor: go mod tidy && go mod vendor + - 31ea00c0 2026-01-26T21:36:18+02:00 unit-test: adjust to new logic + - da87ab85 2026-01-26T21:36:18+02:00 ovspinning: detect reservedSystemCPUs + - e6606173 2026-01-26T21:36:18+02:00 ovspinning: detect nonpinned cpus using podresourceAPI + - 23fdd5fd 2026-01-26T21:36:18+02:00 ovspinning: pass context + - 5ba2cc11 2026-01-26T21:36:18+02:00 package: podresourceAPI client + - c9a29b50 2026-01-24T17:46:28-08:00 Use promhttp handler for emitting metrics + - cbba98ef 2026-01-24T17:46:28-08:00 change from periodic interval to request-based metrics collection + - c01ff2ff 2026-01-23T11:42:00-05:00 Integrate Network Manager resolver everywhere + - 7f0a4df1 2026-01-22T18:20:05-05:00 Fixes shouldFilter with Dynamic UDN + - 64d6bc2e 2026-01-22T18:20:05-05:00 Adds support for CNC with Dynamic UDN + - 56202d01 2026-01-22T18:20:05-05:00 Fix syncNAD + - 6e8dee9a 2026-01-22T18:20:05-05:00 NodeHasNAD -> NodeHasNetwork Refactor + - 8d7a89b3 2026-01-22T18:20:05-05:00 simplify NAD controller dynamic logic + - 7daff06c 2026-01-22T18:20:05-05:00 Fixes releasing network IDs for filtered NADs + - ea687aab 2026-01-22T18:20:05-05:00 Simplify ref counting with NCC and D-UDN + - 87a20d77 2026-01-22T18:20:05-05:00 Refactor remote D-UDN handling (again) + - 1dcd01fe 2026-01-22T18:20:05-05:00 Move D-UDN status/metrics to NCC + - 998e916f 2026-01-22T18:20:05-05:00 Fix DoWithLock crash + - 3e160739 2026-01-22T18:20:05-05:00 Add better debug logging for NAD controller + - a6b34b3b 2026-01-22T18:20:05-05:00 Critical Dynamic UDN NAD controller fixes + - 4dae25a6 2026-01-22T18:20:05-05:00 Convert pod/egress ip trackers to register with nad controller + - 20411a9a 2026-01-22T18:20:05-05:00 Add .gocache to gitignore + - f9531483 2026-01-22T18:20:05-05:00 Add unit test for Dynamic UDN status update + - 09f8efbd 2026-01-22T18:20:05-05:00 Move Dynamic UDN status/metrics to nad controller + - c0add608 2026-01-22T18:20:05-05:00 Move the trackers and dynamic filtering to the nad_controller. + - c09fcf05 2026-01-22T18:20:05-05:00 Only reconcile remote nodes on start up once + - fda7f71d 2026-01-22T18:20:05-05:00 Refactor OnNetworkRefChange + - a797c8c6 2026-01-22T18:20:05-05:00 Optimize performance for tracker primary nad lookups + - 4e11aa41 2026-01-22T18:20:05-05:00 Updates unit test nodes with new transit topo anno + - 57d9cad8 2026-01-22T18:20:05-05:00 Add Dynamic UDN metrics + - a96d67b5 2026-01-22T18:20:05-05:00 Add status update for UDNs with dynamic allocation + - 70f4f131 2026-01-22T18:20:05-05:00 Change pod handling to not rely on active network + - f1ff2e7b 2026-01-22T18:20:05-05:00 Add unit test for UDN deletion grace period + - 08248fcb 2026-01-22T18:20:05-05:00 Skip service tests to "other node" + - 8725a93d 2026-01-22T18:20:05-05:00 Fixes remote node removal with UDN + - 3440f2ad 2026-01-22T18:20:05-05:00 Enable Dynamic UDN in CI for one lane + - 7abc582e 2026-01-22T17:14:12-05:00 Enable dynamic UDN allocation with kind/helm + - 950aba76 2026-01-22T17:12:59-05:00 Enable NAD on Node tracking in UDN controllers + - f841691e 2026-01-22T17:12:59-05:00 Fix UDN controller test framework + - 58a969c2 2026-01-22T17:12:59-05:00 Integrate the trackers into controller managers and nad controller + - 6e6201f0 2026-01-22T17:12:59-05:00 Adds EgressIPTracker + - 48de82d1 2026-01-22T17:12:59-05:00 Adds pod tracker controller + - db4ca916 2026-01-22T17:12:59-05:00 Move WatchFactory interface to API + - ea1d89fc 2026-01-22T17:12:58-05:00 Exposes new dynamic allocation config knobs + - 47400690 2026-01-22T11:56:47Z Add EVPN feature flag + - 4b85ee3f 2026-01-22T10:03:29+08:00 test: fix race condition in waitForRollout + - 9dd6dc8d 2026-01-20T21:14:15+09:00 add Internet Initiative Japan Inc. to ADOPTERS + - 765fbd9a 2026-01-16T13:03:26-05:00 codegen: fix script when GOPATH is not in PATH + - 19f191fc 2026-01-16T14:59:51+01:00 Move common helpers into util/network-connect + - 9ca888f5 2026-01-16T14:59:51+01:00 ci: increase network-segmentation lane timeout to 190 minutes + - 2dc80388 2026-01-16T14:59:51+01:00 e2e: support multiple CNCs with different connect subnets + - c17da56e 2026-01-16T14:59:51+01:00 e2e: add ClusterNetworkConnect OVN controller connectivity tests + - 5a69fb5e 2026-01-16T14:59:51+01:00 making the e2e utils global for reusability + - b101a3d0 2026-01-16T14:59:51+01:00 Add controller integration tests + - db5e941f 2026-01-16T14:59:51+01:00 STEP4: Add LRSRs to connect router + - 17f77b3a 2026-01-16T14:59:50+01:00 STEP3: Add routing policies to connected network routers + - 64279f6e 2026-01-16T14:59:50+01:00 Add GetNetworkScopedSwitchToRouterPortName util + - 7dc67800 2026-01-16T14:59:23+01:00 STEP2: Create patch ports to connect routers together + - e371fc55 2026-01-16T14:54:10+01:00 Add GetNetworkByID util to network manager + - 8f60a8b5 2026-01-16T14:54:10+01:00 Add static subnet and tunnel key generator helpers for CNC + - 4291607f 2026-01-16T14:54:10+01:00 Add COPP protection for connect router + - 56db7ae7 2026-01-16T14:53:01+01:00 STEP1: Create Connect Router for CNC + - c3666788 2026-01-16T12:33:21+01:00 Add network connect controller plumbing + - 622a3f23 2026-01-15T19:18:31-08:00 Skip Node Shutdown and OVN node pod restart sync tests + - 80db3f2c 2026-01-15T19:18:31-08:00 OpenShift E2E: Add deployment config timeout support + - 118948b6 2026-01-15T19:18:31-08:00 Skip net-seg overlapping CIDRs tests + - cb301f71 2026-01-15T19:18:31-08:00 skip ClusterNetworkConnect: API validations tests + - d1963911 2026-01-15T19:18:31-08:00 Bump k8s.io to v1.34.1 + - 9770e116 2026-01-15T19:18:14-08:00 infraprovider: Add openshift provider + - 40cf2ff1 2026-01-15T19:18:09-08:00 Add o/test-exts + - 34337f0a 2026-01-15T22:15:34+01:00 Add RBAC for CNCs access from ovnkube-node pod + - 1b665e97 2026-01-15T22:15:33+01:00 Add factory and clientset settings for ovnkube-controller + - cdb9e9a3 2026-01-15T21:59:47+09:00 fix golang builder image registry path in docker workflow + - 75e38626 2026-01-15T02:46:17-05:00 test: unskip Services fallback to local terminating endpoints test + - 2c3671c4 2026-01-15T02:46:17-05:00 for LGW with ETP=Local have different error code for l3 and l2 + - 0dc90599 2026-01-14T10:34:17+01:00 Use labels to skip tests + - d6501811 2026-01-13T16:13:28+01:00 Expose EVPN fields via NetInfo utils + - 6b33ee67 2026-01-13T16:13:28+01:00 Add NetConf fields for EVPN + - 13415218 2026-01-13T16:13:28+01:00 Add E2E test for VTEP API Validations + - a1fe31d9 2026-01-13T16:13:28+01:00 Add E2E test for CUDN-EVPN validation + - 69647db7 2026-01-13T16:13:28+01:00 Add VTEP API reference docs + - 9c30fc27 2026-01-13T16:13:28+01:00 Generate VTEP Yaml + - 6641c7c3 2026-01-13T16:13:28+01:00 Add VTEP CRD + - 155779fa 2026-01-13T16:13:28+01:00 Update CUDN API reference docs + - fc37829e 2026-01-13T16:13:28+01:00 Generate CUDN Yaml + - 00ed2851 2026-01-13T16:13:28+01:00 Add EVPN fields to CUDN + - ecb3b72c 2026-01-13T16:13:28+01:00 Update tests for noOverlay field + - 00f1291f 2026-01-13T16:13:28+01:00 Update API reference docs + - 2c3ab32b 2026-01-13T16:13:28+01:00 Re-generate CUDN YAML + - 953bb6ac 2026-01-13T16:13:28+01:00 Rename noOverlayOptions to noOverlay + - 06486fa7 2026-01-13T16:13:28+01:00 Cleanup codegen files before regenerating + - 5ffc1bef 2026-01-12T16:25:38-05:00 Bug fix: Skip BridgeEIPAddrManager in DPU-host mode + - 106ea801 2026-01-12T11:20:41-05:00 iprulemanager: add mark check when comparing netlink rule equality + - e60b1cdb 2026-01-12T11:20:41-05:00 iprulemanager: remove string operations from areNetlinkRulesEqual + - 10c9c2a8 2026-01-09T06:44:18-05:00 Addressing trozet feedback + - 560aee20 2026-01-08T19:26:03-05:00 Attempt to capture and store pprof data + - ac29faf5 2026-01-08T19:26:03-05:00 Adding kubelet-density-cni performance workload + - 3c1c3967 2026-01-08T18:33:55+08:00 add eip e2e case on namespace/pod labels update + - 67f9fbf8 2026-01-08T10:54:40+01:00 bump up frr-k8s and frr image versions + - 0c3604e3 2026-01-08T10:05:13+01:00 Use interface index for IPv6 zone when sending unsolicited neighbor advertisements + - 4e343bc4 2026-01-07T15:27:04-08:00 always set arp sysctl configuration for multiple same network interfaces + - e200f2d1 2026-01-07T15:10:41-08:00 docs/multi-homing: support of multiple interfaces in the same network + - 36ddd004 2026-01-06T12:44:28-08:00 e2e: add e2e test case for Pod with multiple same secondary UDN + - 76d27a29 2026-01-06T12:44:28-08:00 add ECMP pod route for multiple same secondary UDN interfaces + - d0120301 2026-01-06T08:06:51-08:00 support ipamClaim for multiple same UDN on the pod + - 1597b780 2026-01-06T08:06:51-08:00 add additional pod-if-name external-id for Pod OVS interface + - 66cf0639 2026-01-06T08:06:51-08:00 support pod with multiple same secondary UDN + - 3c0e3d2d 2026-01-06T13:38:45Z Updating ose-ovn-kubernetes-base-container image to be consistent with ART for 4.22 Reconciling with https://github.com/openshift/ocp-build-data/tree/532305ad2d84f57355ac03b308650bcc5a8d7740/images/ovn-kubernetes-base.yml + - 2ea53bd1 2026-01-06T12:10:29+08:00 node: fix DeleteEndpointSlice namespace deletion race condition + - 61cc216e 2025-12-30T07:36:52-05:00 add nodePort etp=local e2e test for UDN and default network when advertised BGP routes + - 2d4a479c 2025-12-29T15:20:13+01:00 egressip: Skip bridge configuration for secondary network IPs + - d1c55f1c 2025-12-29T11:57:24+01:00 fix(localnet, ipamless): Prevent LSP deletion on sync + - 47cecd9c 2025-12-29T10:13:56+02:00 dist, fedora: Use the right package manager + - 54bc8959 2025-12-28T12:18:46+02:00 dist: Use the project golang container image + - 7b413f85 2025-12-22T18:28:19+01:00 Re-order upgrade image step + - 542bbb37 2025-12-22T17:40:27+01:00 Allow CI workflow dispatcher on release-1.2 branch + - 0b7607fe 2025-12-22T17:40:27+01:00 Update release docs to mention new cadance + - 32287237 2025-12-22T17:40:27+01:00 Update helm-chart version to 1.2.0 + - 8571ba40 2025-12-22T17:40:26+01:00 Change OVN_DAEMONSET_VERSION to 1.2.0 + - 69e28d98 2025-12-22T16:11:30+01:00 OVN-Kubernetes 1.2 release + - 727a0e82 2025-12-22T16:11:29+01:00 Add deprecation warning signs on docs/scripts for central mode + - aa6c1c86 2025-12-22T13:42:08+01:00 Update L2 topology to reflect new TR + - c75a25a0 2025-12-22T09:19:04+08:00 Update libovsdb bindings to ovn 25.09 + - f50653ee 2025-12-21T14:45:36-08:00 minor updates on unit test cases + - 988ace17 2025-12-21T14:45:36-08:00 metrics: move OVN/OVS metrics update from periodic interval to request-based + - 9e7c7180 2025-12-19T15:27:54-05:00 Adds level-driven, UDN aware dev docs + - 5b01e17b 2025-12-19T15:27:54-05:00 Refactor NADController notifying into level driven reconciler + - e8fb693f 2025-12-19T19:29:18+01:00 Skip FRR bfdd process Coredumps + - f10deeba 2025-12-19T14:08:58+01:00 [retry] Make an exception for pods and retry them infinitely. + - 07b68bb6 2025-12-19T09:23:34+01:00 fix template referencing gatewayOps instead of gatewayOpts variable + - d22f59da 2025-12-18T17:15:49-05:00 OKEP 5674: DPU Healthcheck + - bbc03ca8 2025-12-17T17:08:11Z egressip: handle LinkNotFoundError gracefully in isEgressIPOnLink + - 8c83e326 2025-12-10T07:43:41+01:00 fix(e2e, kubevirt): Wait for IP after VM restart in ipamless localnet tests + - 5856fb09 2025-09-02T12:42:39+01:00 fix: drop prometheus operator CRDs and make CRs configurable + +- kubernetes image-amd64 9d521311f5fb67dc43f49eeb728ee2c80976835a to 047d96223dd843e9d54bed59bc212d2e9122c56a + - bbdf0eb44 2026-02-06T13:54:27+01:00 UPSTREAM: 135629: selinux: Fix the controller to ignore finished pods + +- oc image-arm64 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 to 7f88fe2132f6969e1686808e5301aa3c808d4a45 + - 1de915e0 2026-02-12T14:47:52-05:00 images/tools: Install subscription-manager + - 12d5804c 2026-02-11T13:45:48-05:00 OCPBUGS-76394: Install subscription-manager in cli image + - deaedbf2 2026-02-06T20:16:54-05:00 Revert "CNTRLPLANE-2656: Fixing oc client cases for microshift and metal ipv6 profiles" + - 82d41d0b 2026-02-05T11:33:56+05:30 CNTRLPLANE-2656: Add oc CLI e2e tests with OTE framework support + +- router image-arm64 d2db065ae452ecfdb482f0ac4c6778b0c0e48b7f to d8ed3559fd4808a4f10c927ba4a199d3fd5b84a2 + - c46d819 2026-02-11T09:03:56-03:00 update base image to OCP 4.22 + - cb8dba6 2026-02-10T09:19:25-03:00 disable WatchListClient featuregate + - b92c259 2026-02-05T11:24:23-03:00 bump k8s libraries to v0.35.0 + +- ovn-kubernetes image-arm64 1938041fd8f8c1fb5d376fa59faec1fef7614a92 to 2a9cd189db9c74dc678fcfca68473d6fdc278028 + - 7dd0e556 2026-01-27T15:00:53-08:00 skip new NetSeg Localnet test + - 245941b1 2026-01-27T20:09:36Z sync openshift/go.mod with upstream dependencies + - aaf3f757 2026-01-26T21:36:19+02:00 docs: add OVS Dynamic CPU Affinity feature documentation + - 1e68f901 2026-01-26T21:36:18+02:00 createFileWatcherFor: rename argument + - 9dccb75e 2026-01-26T21:36:18+02:00 vendor: go mod tidy && go mod vendor + - 31ea00c0 2026-01-26T21:36:18+02:00 unit-test: adjust to new logic + - da87ab85 2026-01-26T21:36:18+02:00 ovspinning: detect reservedSystemCPUs + - e6606173 2026-01-26T21:36:18+02:00 ovspinning: detect nonpinned cpus using podresourceAPI + - 23fdd5fd 2026-01-26T21:36:18+02:00 ovspinning: pass context + - 5ba2cc11 2026-01-26T21:36:18+02:00 package: podresourceAPI client + - c9a29b50 2026-01-24T17:46:28-08:00 Use promhttp handler for emitting metrics + - cbba98ef 2026-01-24T17:46:28-08:00 change from periodic interval to request-based metrics collection + - c01ff2ff 2026-01-23T11:42:00-05:00 Integrate Network Manager resolver everywhere + - 7f0a4df1 2026-01-22T18:20:05-05:00 Fixes shouldFilter with Dynamic UDN + - 64d6bc2e 2026-01-22T18:20:05-05:00 Adds support for CNC with Dynamic UDN + - 56202d01 2026-01-22T18:20:05-05:00 Fix syncNAD + - 6e8dee9a 2026-01-22T18:20:05-05:00 NodeHasNAD -> NodeHasNetwork Refactor + - 8d7a89b3 2026-01-22T18:20:05-05:00 simplify NAD controller dynamic logic + - 7daff06c 2026-01-22T18:20:05-05:00 Fixes releasing network IDs for filtered NADs + - ea687aab 2026-01-22T18:20:05-05:00 Simplify ref counting with NCC and D-UDN + - 87a20d77 2026-01-22T18:20:05-05:00 Refactor remote D-UDN handling (again) + - 1dcd01fe 2026-01-22T18:20:05-05:00 Move D-UDN status/metrics to NCC + - 998e916f 2026-01-22T18:20:05-05:00 Fix DoWithLock crash + - 3e160739 2026-01-22T18:20:05-05:00 Add better debug logging for NAD controller + - a6b34b3b 2026-01-22T18:20:05-05:00 Critical Dynamic UDN NAD controller fixes + - 4dae25a6 2026-01-22T18:20:05-05:00 Convert pod/egress ip trackers to register with nad controller + - 20411a9a 2026-01-22T18:20:05-05:00 Add .gocache to gitignore + - f9531483 2026-01-22T18:20:05-05:00 Add unit test for Dynamic UDN status update + - 09f8efbd 2026-01-22T18:20:05-05:00 Move Dynamic UDN status/metrics to nad controller + - c0add608 2026-01-22T18:20:05-05:00 Move the trackers and dynamic filtering to the nad_controller. + - c09fcf05 2026-01-22T18:20:05-05:00 Only reconcile remote nodes on start up once + - fda7f71d 2026-01-22T18:20:05-05:00 Refactor OnNetworkRefChange + - a797c8c6 2026-01-22T18:20:05-05:00 Optimize performance for tracker primary nad lookups + - 4e11aa41 2026-01-22T18:20:05-05:00 Updates unit test nodes with new transit topo anno + - 57d9cad8 2026-01-22T18:20:05-05:00 Add Dynamic UDN metrics + - a96d67b5 2026-01-22T18:20:05-05:00 Add status update for UDNs with dynamic allocation + - 70f4f131 2026-01-22T18:20:05-05:00 Change pod handling to not rely on active network + - f1ff2e7b 2026-01-22T18:20:05-05:00 Add unit test for UDN deletion grace period + - 08248fcb 2026-01-22T18:20:05-05:00 Skip service tests to "other node" + - 8725a93d 2026-01-22T18:20:05-05:00 Fixes remote node removal with UDN + - 3440f2ad 2026-01-22T18:20:05-05:00 Enable Dynamic UDN in CI for one lane + - 7abc582e 2026-01-22T17:14:12-05:00 Enable dynamic UDN allocation with kind/helm + - 950aba76 2026-01-22T17:12:59-05:00 Enable NAD on Node tracking in UDN controllers + - f841691e 2026-01-22T17:12:59-05:00 Fix UDN controller test framework + - 58a969c2 2026-01-22T17:12:59-05:00 Integrate the trackers into controller managers and nad controller + - 6e6201f0 2026-01-22T17:12:59-05:00 Adds EgressIPTracker + - 48de82d1 2026-01-22T17:12:59-05:00 Adds pod tracker controller + - db4ca916 2026-01-22T17:12:59-05:00 Move WatchFactory interface to API + - ea1d89fc 2026-01-22T17:12:58-05:00 Exposes new dynamic allocation config knobs + - 47400690 2026-01-22T11:56:47Z Add EVPN feature flag + - 4b85ee3f 2026-01-22T10:03:29+08:00 test: fix race condition in waitForRollout + - 9dd6dc8d 2026-01-20T21:14:15+09:00 add Internet Initiative Japan Inc. to ADOPTERS + - 765fbd9a 2026-01-16T13:03:26-05:00 codegen: fix script when GOPATH is not in PATH + - 19f191fc 2026-01-16T14:59:51+01:00 Move common helpers into util/network-connect + - 9ca888f5 2026-01-16T14:59:51+01:00 ci: increase network-segmentation lane timeout to 190 minutes + - 2dc80388 2026-01-16T14:59:51+01:00 e2e: support multiple CNCs with different connect subnets + - c17da56e 2026-01-16T14:59:51+01:00 e2e: add ClusterNetworkConnect OVN controller connectivity tests + - 5a69fb5e 2026-01-16T14:59:51+01:00 making the e2e utils global for reusability + - b101a3d0 2026-01-16T14:59:51+01:00 Add controller integration tests + - db5e941f 2026-01-16T14:59:51+01:00 STEP4: Add LRSRs to connect router + - 17f77b3a 2026-01-16T14:59:50+01:00 STEP3: Add routing policies to connected network routers + - 64279f6e 2026-01-16T14:59:50+01:00 Add GetNetworkScopedSwitchToRouterPortName util + - 7dc67800 2026-01-16T14:59:23+01:00 STEP2: Create patch ports to connect routers together + - e371fc55 2026-01-16T14:54:10+01:00 Add GetNetworkByID util to network manager + - 8f60a8b5 2026-01-16T14:54:10+01:00 Add static subnet and tunnel key generator helpers for CNC + - 4291607f 2026-01-16T14:54:10+01:00 Add COPP protection for connect router + - 56db7ae7 2026-01-16T14:53:01+01:00 STEP1: Create Connect Router for CNC + - c3666788 2026-01-16T12:33:21+01:00 Add network connect controller plumbing + - 622a3f23 2026-01-15T19:18:31-08:00 Skip Node Shutdown and OVN node pod restart sync tests + - 80db3f2c 2026-01-15T19:18:31-08:00 OpenShift E2E: Add deployment config timeout support + - 118948b6 2026-01-15T19:18:31-08:00 Skip net-seg overlapping CIDRs tests + - cb301f71 2026-01-15T19:18:31-08:00 skip ClusterNetworkConnect: API validations tests + - d1963911 2026-01-15T19:18:31-08:00 Bump k8s.io to v1.34.1 + - 9770e116 2026-01-15T19:18:14-08:00 infraprovider: Add openshift provider + - 40cf2ff1 2026-01-15T19:18:09-08:00 Add o/test-exts + - 34337f0a 2026-01-15T22:15:34+01:00 Add RBAC for CNCs access from ovnkube-node pod + - 1b665e97 2026-01-15T22:15:33+01:00 Add factory and clientset settings for ovnkube-controller + - cdb9e9a3 2026-01-15T21:59:47+09:00 fix golang builder image registry path in docker workflow + - 75e38626 2026-01-15T02:46:17-05:00 test: unskip Services fallback to local terminating endpoints test + - 2c3671c4 2026-01-15T02:46:17-05:00 for LGW with ETP=Local have different error code for l3 and l2 + - 0dc90599 2026-01-14T10:34:17+01:00 Use labels to skip tests + - d6501811 2026-01-13T16:13:28+01:00 Expose EVPN fields via NetInfo utils + - 6b33ee67 2026-01-13T16:13:28+01:00 Add NetConf fields for EVPN + - 13415218 2026-01-13T16:13:28+01:00 Add E2E test for VTEP API Validations + - a1fe31d9 2026-01-13T16:13:28+01:00 Add E2E test for CUDN-EVPN validation + - 69647db7 2026-01-13T16:13:28+01:00 Add VTEP API reference docs + - 9c30fc27 2026-01-13T16:13:28+01:00 Generate VTEP Yaml + - 6641c7c3 2026-01-13T16:13:28+01:00 Add VTEP CRD + - 155779fa 2026-01-13T16:13:28+01:00 Update CUDN API reference docs + - fc37829e 2026-01-13T16:13:28+01:00 Generate CUDN Yaml + - 00ed2851 2026-01-13T16:13:28+01:00 Add EVPN fields to CUDN + - ecb3b72c 2026-01-13T16:13:28+01:00 Update tests for noOverlay field + - 00f1291f 2026-01-13T16:13:28+01:00 Update API reference docs + - 2c3ab32b 2026-01-13T16:13:28+01:00 Re-generate CUDN YAML + - 953bb6ac 2026-01-13T16:13:28+01:00 Rename noOverlayOptions to noOverlay + - 06486fa7 2026-01-13T16:13:28+01:00 Cleanup codegen files before regenerating + - 5ffc1bef 2026-01-12T16:25:38-05:00 Bug fix: Skip BridgeEIPAddrManager in DPU-host mode + - 106ea801 2026-01-12T11:20:41-05:00 iprulemanager: add mark check when comparing netlink rule equality + - e60b1cdb 2026-01-12T11:20:41-05:00 iprulemanager: remove string operations from areNetlinkRulesEqual + - 10c9c2a8 2026-01-09T06:44:18-05:00 Addressing trozet feedback + - 560aee20 2026-01-08T19:26:03-05:00 Attempt to capture and store pprof data + - ac29faf5 2026-01-08T19:26:03-05:00 Adding kubelet-density-cni performance workload + - 3c1c3967 2026-01-08T18:33:55+08:00 add eip e2e case on namespace/pod labels update + - 67f9fbf8 2026-01-08T10:54:40+01:00 bump up frr-k8s and frr image versions + - 0c3604e3 2026-01-08T10:05:13+01:00 Use interface index for IPv6 zone when sending unsolicited neighbor advertisements + - 4e343bc4 2026-01-07T15:27:04-08:00 always set arp sysctl configuration for multiple same network interfaces + - e200f2d1 2026-01-07T15:10:41-08:00 docs/multi-homing: support of multiple interfaces in the same network + - 36ddd004 2026-01-06T12:44:28-08:00 e2e: add e2e test case for Pod with multiple same secondary UDN + - 76d27a29 2026-01-06T12:44:28-08:00 add ECMP pod route for multiple same secondary UDN interfaces + - d0120301 2026-01-06T08:06:51-08:00 support ipamClaim for multiple same UDN on the pod + - 1597b780 2026-01-06T08:06:51-08:00 add additional pod-if-name external-id for Pod OVS interface + - 66cf0639 2026-01-06T08:06:51-08:00 support pod with multiple same secondary UDN + - 3c0e3d2d 2026-01-06T13:38:45Z Updating ose-ovn-kubernetes-base-container image to be consistent with ART for 4.22 Reconciling with https://github.com/openshift/ocp-build-data/tree/532305ad2d84f57355ac03b308650bcc5a8d7740/images/ovn-kubernetes-base.yml + - 2ea53bd1 2026-01-06T12:10:29+08:00 node: fix DeleteEndpointSlice namespace deletion race condition + - 61cc216e 2025-12-30T07:36:52-05:00 add nodePort etp=local e2e test for UDN and default network when advertised BGP routes + - 2d4a479c 2025-12-29T15:20:13+01:00 egressip: Skip bridge configuration for secondary network IPs + - d1c55f1c 2025-12-29T11:57:24+01:00 fix(localnet, ipamless): Prevent LSP deletion on sync + - 47cecd9c 2025-12-29T10:13:56+02:00 dist, fedora: Use the right package manager + - 54bc8959 2025-12-28T12:18:46+02:00 dist: Use the project golang container image + - 7b413f85 2025-12-22T18:28:19+01:00 Re-order upgrade image step + - 542bbb37 2025-12-22T17:40:27+01:00 Allow CI workflow dispatcher on release-1.2 branch + - 0b7607fe 2025-12-22T17:40:27+01:00 Update release docs to mention new cadance + - 32287237 2025-12-22T17:40:27+01:00 Update helm-chart version to 1.2.0 + - 8571ba40 2025-12-22T17:40:26+01:00 Change OVN_DAEMONSET_VERSION to 1.2.0 + - 69e28d98 2025-12-22T16:11:30+01:00 OVN-Kubernetes 1.2 release + - 727a0e82 2025-12-22T16:11:29+01:00 Add deprecation warning signs on docs/scripts for central mode + - aa6c1c86 2025-12-22T13:42:08+01:00 Update L2 topology to reflect new TR + - c75a25a0 2025-12-22T09:19:04+08:00 Update libovsdb bindings to ovn 25.09 + - f50653ee 2025-12-21T14:45:36-08:00 minor updates on unit test cases + - 988ace17 2025-12-21T14:45:36-08:00 metrics: move OVN/OVS metrics update from periodic interval to request-based + - 9e7c7180 2025-12-19T15:27:54-05:00 Adds level-driven, UDN aware dev docs + - 5b01e17b 2025-12-19T15:27:54-05:00 Refactor NADController notifying into level driven reconciler + - e8fb693f 2025-12-19T19:29:18+01:00 Skip FRR bfdd process Coredumps + - f10deeba 2025-12-19T14:08:58+01:00 [retry] Make an exception for pods and retry them infinitely. + - 07b68bb6 2025-12-19T09:23:34+01:00 fix template referencing gatewayOps instead of gatewayOpts variable + - d22f59da 2025-12-18T17:15:49-05:00 OKEP 5674: DPU Healthcheck + - bbc03ca8 2025-12-17T17:08:11Z egressip: handle LinkNotFoundError gracefully in isEgressIPOnLink + - 8c83e326 2025-12-10T07:43:41+01:00 fix(e2e, kubevirt): Wait for IP after VM restart in ipamless localnet tests + - 5856fb09 2025-09-02T12:42:39+01:00 fix: drop prometheus operator CRDs and make CRs configurable + +- kubernetes image-arm64 9d521311f5fb67dc43f49eeb728ee2c80976835a to 047d96223dd843e9d54bed59bc212d2e9122c56a + - bbdf0eb44 2026-02-06T13:54:27+01:00 UPSTREAM: 135629: selinux: Fix the controller to ignore finished pods diff --git a/scripts/auto-rebase/commits.txt b/scripts/auto-rebase/commits.txt index e594e8cae6..4ed5fd8759 100644 --- a/scripts/auto-rebase/commits.txt +++ b/scripts/auto-rebase/commits.txt @@ -1,35 +1,35 @@ -https://github.com/openshift/api embedded-component 81371d13d1fcad175a48627cf11524a94a80c377 +https://github.com/openshift/api embedded-component d34f11c515b3d00fdb3809cd59737e3bd77167c4 https://github.com/openshift/cluster-csi-snapshot-controller-operator embedded-component 7b6335396677dfd392dc72e1f1bbb5afcfa74a44 -https://github.com/openshift/cluster-dns-operator embedded-component 41a53fed36e6e99c7c9ceb3a699c3547ee5d9bb9 -https://github.com/openshift/cluster-ingress-operator embedded-component 77901360f18951f2a51d38acd1a07714f9183493 -https://github.com/openshift/cluster-kube-apiserver-operator embedded-component fecf00cbeaf1fc18178bffddab767ee8f3d7e36f +https://github.com/openshift/cluster-dns-operator embedded-component 5d7c973968909d4155796363222f6edc001e19a3 +https://github.com/openshift/cluster-ingress-operator embedded-component abfb6fa7b9c95dc54fb3988e84297912ad88e0e4 +https://github.com/openshift/cluster-kube-apiserver-operator embedded-component cee7acb6c820b707fbb1e1dc01cef6c1971f146d https://github.com/openshift/cluster-kube-controller-manager-operator embedded-component a6a751080c9b2bdd3a721851b206cf2f7c8bbc41 -https://github.com/openshift/cluster-kube-scheduler-operator embedded-component b37b73a87e7a6612f3354c2ffc134a23a0a8c13c -https://github.com/openshift/cluster-network-operator embedded-component f0bdee37451757734c3e84cb6c0a8646290c4ffa -https://github.com/openshift/cluster-openshift-controller-manager-operator embedded-component a6ce1136e71ded4af3cb5e771435e098b5e30349 +https://github.com/openshift/cluster-kube-scheduler-operator embedded-component 14c5fdcfc2602292e19cab8713e42accf94b593d +https://github.com/openshift/cluster-network-operator embedded-component 9d540eb7929f83879d3dafbcd1ae6cb1feca36b3 +https://github.com/openshift/cluster-openshift-controller-manager-operator embedded-component 7634c413830a510ff942bd6886ffe5f79db707b4 https://github.com/openshift/cluster-policy-controller embedded-component 8b775487512fb543bff470ff1042bd3ac31b29be https://github.com/openshift/csi-external-snapshotter embedded-component d20b90a92cd7d77166319f5bc2feb80623747d28 https://github.com/openshift/etcd embedded-component 6a0992267004177e385e35b91e186635a644dbfe -https://github.com/openshift/kubernetes embedded-component 9d521311f5fb67dc43f49eeb728ee2c80976835a +https://github.com/openshift/kubernetes embedded-component 047d96223dd843e9d54bed59bc212d2e9122c56a https://github.com/openshift/kubernetes-kube-storage-version-migrator embedded-component 73b468abf83d3d5894534f5d5cc42d1cad2a9045 -https://github.com/openshift/machine-config-operator embedded-component 067395ed863e0254c4e7ce85bf8bce7e464778bb +https://github.com/openshift/machine-config-operator embedded-component 7eb4793ae255b19327e781f66aaf1dbd3e5210c5 https://github.com/openshift/openshift-controller-manager embedded-component 19ac71374ea7d42957fe0eb3cc6d38679cc257e1 -https://github.com/openshift/operator-framework-olm embedded-component fae41b2724eeab7a0e9b1ad89408bbbb36516fe2 -https://github.com/openshift/route-controller-manager embedded-component 2b9e93a5f0fc1e93090bbe34ce95f3b4ad5cff15 +https://github.com/openshift/operator-framework-olm embedded-component 811919f88bc3b8da4f97c6e6ca031258cc4fa13b +https://github.com/openshift/route-controller-manager embedded-component 624742d93f3a7885cf7f70985f1e23ff60da580d https://github.com/openshift/service-ca-operator embedded-component 503e4f5f4c74fd095a8dca385541125f3c9ee28b -https://github.com/openshift/oc image-amd64 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 +https://github.com/openshift/oc image-amd64 8b0a043216f7ae608606afb5bdb0ce451561021e https://github.com/openshift/coredns image-amd64 9798af8539c27ad02bd376006cd3a9a7b23e5966 https://github.com/openshift/csi-external-snapshotter image-amd64 d20b90a92cd7d77166319f5bc2feb80623747d28 -https://github.com/openshift/router image-amd64 d2db065ae452ecfdb482f0ac4c6778b0c0e48b7f +https://github.com/openshift/router image-amd64 d8ed3559fd4808a4f10c927ba4a199d3fd5b84a2 https://github.com/openshift/kube-rbac-proxy image-amd64 c7ab76fd6fdf651d5022db8946c35b158ecc2396 -https://github.com/openshift/ovn-kubernetes image-amd64 1938041fd8f8c1fb5d376fa59faec1fef7614a92 -https://github.com/openshift/kubernetes image-amd64 9d521311f5fb67dc43f49eeb728ee2c80976835a +https://github.com/openshift/ovn-kubernetes image-amd64 2a9cd189db9c74dc678fcfca68473d6fdc278028 +https://github.com/openshift/kubernetes image-amd64 047d96223dd843e9d54bed59bc212d2e9122c56a https://github.com/openshift/service-ca-operator image-amd64 503e4f5f4c74fd095a8dca385541125f3c9ee28b -https://github.com/openshift/oc image-arm64 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 +https://github.com/openshift/oc image-arm64 7f88fe2132f6969e1686808e5301aa3c808d4a45 https://github.com/openshift/coredns image-arm64 9798af8539c27ad02bd376006cd3a9a7b23e5966 https://github.com/openshift/csi-external-snapshotter image-arm64 d20b90a92cd7d77166319f5bc2feb80623747d28 -https://github.com/openshift/router image-arm64 d2db065ae452ecfdb482f0ac4c6778b0c0e48b7f +https://github.com/openshift/router image-arm64 d8ed3559fd4808a4f10c927ba4a199d3fd5b84a2 https://github.com/openshift/kube-rbac-proxy image-arm64 c7ab76fd6fdf651d5022db8946c35b158ecc2396 -https://github.com/openshift/ovn-kubernetes image-arm64 1938041fd8f8c1fb5d376fa59faec1fef7614a92 -https://github.com/openshift/kubernetes image-arm64 9d521311f5fb67dc43f49eeb728ee2c80976835a +https://github.com/openshift/ovn-kubernetes image-arm64 2a9cd189db9c74dc678fcfca68473d6fdc278028 +https://github.com/openshift/kubernetes image-arm64 047d96223dd843e9d54bed59bc212d2e9122c56a https://github.com/openshift/service-ca-operator image-arm64 503e4f5f4c74fd095a8dca385541125f3c9ee28b From ba6e71582a0d67e6691510bedbcc0c3acae9faab Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:03:13 +0100 Subject: [PATCH 03/15] update microshift/go.mod --- go.mod | 49 +++++++++++++++--------------- go.sum | 96 ++++++++++++++++++++++++++++++---------------------------- 2 files changed, 74 insertions(+), 71 deletions(-) diff --git a/go.mod b/go.mod index d9ee75e293..c1aa920ad9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/openshift/microshift -go 1.24.0 +go 1.25.0 require ( github.com/apparentlymart/go-cidr v1.1.0 @@ -10,17 +10,17 @@ require ( github.com/openshift/api v0.0.0-20251214014457-bfa868a22401 github.com/openshift/build-machinery-go v0.0.0-20251023084048-5d77c1a5e5af github.com/openshift/client-go v0.0.0-20251205093018-96a6cbc1420c - github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f + github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/cobra v1.9.1 + github.com/spf13/cobra v1.10.0 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 github.com/vishvananda/netlink v1.3.1 - go.etcd.io/etcd/client/pkg/v3 v3.6.4 - go.etcd.io/etcd/client/v3 v3.6.4 - golang.org/x/sys v0.36.0 + go.etcd.io/etcd/client/pkg/v3 v3.6.5 + go.etcd.io/etcd/client/v3 v3.6.5 + golang.org/x/sys v0.38.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 sigs.k8s.io/yaml v1.6.0 ) @@ -32,7 +32,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/golang/snappy v0.0.4 github.com/openshift/cluster-policy-controller v0.0.0-20251120141414-8b775487512f - github.com/openshift/route-controller-manager v0.0.0-20260127173744-2b9e93a5f0fc + github.com/openshift/route-controller-manager v0.0.0-20260211095309-624742d93f3a github.com/prometheus/client_model v0.6.2 github.com/prometheus/common v0.66.1 github.com/prometheus/prometheus v0.302.1 @@ -57,6 +57,7 @@ require ( require ( cel.dev/expr v0.24.0 // indirect + cyphar.com/go-pathrs v0.2.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab // indirect @@ -76,7 +77,7 @@ require ( github.com/containerd/ttrpc v1.2.6 // indirect github.com/containerd/typeurl/v2 v2.2.2 // indirect github.com/coreos/go-oidc v2.3.0+incompatible // indirect - github.com/cyphar/filepath-securejoin v0.5.1 // indirect + github.com/cyphar/filepath-securejoin v0.6.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect @@ -100,7 +101,7 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/cadvisor v0.52.1 // indirect github.com/google/cel-go v0.26.0 // indirect - github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect + github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect @@ -126,7 +127,7 @@ require ( github.com/opencontainers/image-spec v1.1.1 // indirect github.com/opencontainers/runc v1.2.8 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect - github.com/opencontainers/selinux v1.12.0 // indirect + github.com/opencontainers/selinux v1.13.0 // indirect github.com/openshift/apiserver-library-go v0.0.0-20251015164739-79d04067059d // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect @@ -141,7 +142,7 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel v1.37.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect @@ -150,14 +151,14 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.42.0 // indirect + golang.org/x/crypto v0.45.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/term v0.35.0 // indirect + golang.org/x/term v0.37.0 // indirect golang.org/x/time v0.9.0 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect @@ -177,7 +178,7 @@ require ( k8s.io/mount-utils v1.34.2 // indirect k8s.io/pod-security-admission v1.34.2 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect ) @@ -203,21 +204,21 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/vishvananda/netns v0.0.5 // indirect - go.etcd.io/etcd/api/v3 v3.6.4 // indirect + go.etcd.io/etcd/api/v3 v3.6.5 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/text v0.29.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/tools v0.38.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect google.golang.org/grpc v1.76.0 // indirect google.golang.org/protobuf v1.36.8 // indirect k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect k8s.io/klog/v2 v2.130.1 - k8s.io/kubernetes v1.34.2 + k8s.io/kubernetes v1.35.0 ) replace ( diff --git a/go.sum b/go.sum index 8dd726435d..76a141d650 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= +cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= @@ -68,8 +70,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48= -github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is= +github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -159,8 +161,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= @@ -267,8 +269,8 @@ github.com/opencontainers/runc v1.2.8 h1:RnEICeDReapbZ5lZEgHvj7E9Q3Eex9toYmaGBsb github.com/opencontainers/runc v1.2.8/go.mod h1:cC0YkmZcuvr+rtBZ6T7NBoVbMGNAdLa/21vIElJDOzI= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8= -github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U= +github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+LGaWfbL84= +github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s= github.com/openshift/api v0.0.0-20251214014457-bfa868a22401 h1:goMf6pBtRFSQaVElFk6K+GIAqnv7O84p7PJHH6pDz/E= github.com/openshift/api v0.0.0-20251214014457-bfa868a22401/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY= github.com/openshift/apiserver-library-go v0.0.0-20251015164739-79d04067059d h1:Mfya3RxHWvidOrKyHj3bmFn5x2B89DLZIvDAhwm+C2s= @@ -281,12 +283,12 @@ github.com/openshift/cluster-policy-controller v0.0.0-20251120141414-8b775487512 github.com/openshift/cluster-policy-controller v0.0.0-20251120141414-8b775487512f/go.mod h1:LXi/198uMe/91uydJ/yHz+jS66JCP1DtSonVDFhVVPs= github.com/openshift/kubernetes-kube-storage-version-migrator v0.0.3-0.20260105155255-73b468abf83d h1:BlRqHWLT8GtikpEbhReHR+EgZIJ9o/wo+JDP7XC1qis= github.com/openshift/kubernetes-kube-storage-version-migrator v0.0.3-0.20260105155255-73b468abf83d/go.mod h1:o5cKv/pQ+exEYKq97WapNa5cxSPxuwBezHZHNW5RNRo= -github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f h1:r1pLosA7z3+t+lzW29FU54sg4/pAWu+lsKD0L5Gx3wg= -github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f/go.mod h1:ErDfiIrPHH+menTP/B4LKd0nxFDdvCbTamAc6SWMIh8= +github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 h1:Fm9C8pT4l6VjpdqdhI1cBX9Y3D3S+rFxptVhCPBbMAI= +github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04/go.mod h1:nIzWQQE49XbiKizVnVOip9CEB7HJ0hoJwNi3g3YKnKc= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/openshift/route-controller-manager v0.0.0-20260127173744-2b9e93a5f0fc h1:Dt1sz1Dthy5bRMNin/URQ8NJKLU36D3Qn1l/XJu6pLY= -github.com/openshift/route-controller-manager v0.0.0-20260127173744-2b9e93a5f0fc/go.mod h1:/tw1PYHkUdzPG+EuC+ANJdDD81Ik2pPzYjLBZhyzyME= +github.com/openshift/route-controller-manager v0.0.0-20260211095309-624742d93f3a h1:jBmugEVHpoRmyNBFb7ZBLeurE5+snu9NXS6bf57iiqA= +github.com/openshift/route-controller-manager v0.0.0-20260211095309-624742d93f3a/go.mod h1:KNxrLlGIh4j2iUAOax5Y9f5rN3vIo8w9QTGKHEQlvFo= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -315,8 +317,8 @@ github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= @@ -325,9 +327,9 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.0 h1:a5/WeUlSDCvV5a45ljW2ZFtV0bTDpkfSAj3uqB6Sc+0= +github.com/spf13/cobra v1.10.0/go.mod h1:9dhySC7dnTtEiqzmqfkLj47BslqLCUPMXjG2lj/NgoE= +github.com/spf13/pflag v1.0.8/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/squat/generic-device-plugin v0.0.0-20251019101956-043a51e18f31 h1:wPJNupO/W9VJkwf/5vVnEReuS3pf5u+V+RGv6TOPrLM= @@ -363,12 +365,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/api/v3 v3.6.5 h1:pMMc42276sgR1j1raO/Qv3QI9Af/AuyQUW6CBAWuntA= +go.etcd.io/etcd/api/v3 v3.6.5/go.mod h1:ob0/oWA/UQQlT1BmaEkWQzI0sJ1M0Et0mMpaABxguOQ= +go.etcd.io/etcd/client/pkg/v3 v3.6.5 h1:Duz9fAzIZFhYWgRjp/FgNq2gO1jId9Yae/rLn3RrBP8= +go.etcd.io/etcd/client/pkg/v3 v3.6.5/go.mod h1:8Wx3eGRPiy0qOFMZT/hfvdos+DjEaPxdIDiCDUv/FQk= +go.etcd.io/etcd/client/v3 v3.6.5 h1:yRwZNFBx/35VKHTcLDeO7XVLbCBFbPi+XV4OC3QJf2U= +go.etcd.io/etcd/client/v3 v3.6.5/go.mod h1:ZqwG/7TAFZ0BJ0jXRPoJjKQJtbFo/9NIY8uoFFKcCyo= go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA= go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE= go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU= @@ -381,8 +383,8 @@ go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelr go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0/go.mod h1:uq8DrRaen3suIWTpdR/JNHCGpurSvMv9D5Nr5CU5TXc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/contrib/propagators/b3 v1.19.0 h1:ulz44cpm6V5oAeg5Aw9HyqGFMS6XM7untlMEhD7YzzA= go.opentelemetry.io/contrib/propagators/b3 v1.19.0/go.mod h1:OzCmE2IVS+asTI+odXQstRGVfXQ4bXv9nMBRK0nNyqQ= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= @@ -409,34 +411,34 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -447,22 +449,22 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= @@ -484,8 +486,8 @@ google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXn gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -499,14 +501,14 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f h1:SLb+kxmzfA87x4E4brQzB33VBbT2+x7Zq9ROIHmGn9Q= k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78= From 77ac65f856ace4062c21ca93a765bba4f9ec1e8d Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:03:14 +0100 Subject: [PATCH 04/15] update microshift/deps --- .../selinuxwarning/cache/volumecache.go | 12 +- .../selinux_warning_controller.go | 55 ++- .../selinux_warning_controller_test.go | 318 +++++++++++++----- .../test/e2e/storage/csimock/base.go | 32 +- .../e2e/storage/csimock/csi_selinux_mount.go | 141 +++++++- 5 files changed, 450 insertions(+), 108 deletions(-) diff --git a/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go b/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go index dfa129dae9..4b19c985c8 100644 --- a/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go +++ b/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go @@ -114,11 +114,19 @@ func (c *volumeCache) AddVolume(logger klog.Logger, volumeName v1.UniqueVolumeNa } // The volume is already known - // Add the pod to the cache or update its properties - volume.pods[podKey] = podInfo{ + podInfo := podInfo{ seLinuxLabel: label, changePolicy: changePolicy, } + oldPodInfo, found := volume.pods[podKey] + if found && oldPodInfo == podInfo { + // The Pod is already known too and nothing changed since the last update. + // All conflicts were already reported when the Pod was added / updated in the cache last time. + return conflicts + } + + // Add the updated pod info to the cache + volume.pods[podKey] = podInfo // Emit conflicts for the pod for otherPodKey, otherPodInfo := range volume.pods { diff --git a/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go b/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go index e5049e05ab..d373eeabf5 100644 --- a/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go +++ b/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go @@ -140,9 +140,9 @@ func NewController( logger := klog.FromContext(ctx) _, err = podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { c.addPod(logger, obj) }, - DeleteFunc: func(obj interface{}) { c.deletePod(logger, obj) }, - // Not watching updates: Pod volumes and SecurityContext are immutable after creation + AddFunc: func(obj interface{}) { c.enqueuePod(logger, obj) }, + UpdateFunc: func(oldObj, newObj interface{}) { c.updatePod(logger, oldObj, newObj) }, + DeleteFunc: func(obj interface{}) { c.enqueuePod(logger, obj) }, }) if err != nil { return nil, err @@ -178,7 +178,7 @@ func NewController( return c, nil } -func (c *Controller) addPod(_ klog.Logger, obj interface{}) { +func (c *Controller) enqueuePod(_ klog.Logger, obj interface{}) { podRef, err := cache.DeletionHandlingObjectToName(obj) if err != nil { utilruntime.HandleError(fmt.Errorf("couldn't get key for pod %#v: %w", obj, err)) @@ -186,12 +186,29 @@ func (c *Controller) addPod(_ klog.Logger, obj interface{}) { c.queue.Add(podRef) } -func (c *Controller) deletePod(_ klog.Logger, obj interface{}) { - podRef, err := cache.DeletionHandlingObjectToName(obj) - if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for pod %#v: %w", obj, err)) +func (c *Controller) updatePod(logger klog.Logger, oldObj, newObj interface{}) { + // Pod.Spec fields that are relevant to this controller are immutable after creation (i.e. + // pod volumes, SELinux labels, privileged flag). React to update only when the Pod + // reaches its final state - kubelet will unmount the Pod volumes and the controller should + // therefore remove them from the cache. + oldPod, ok := oldObj.(*v1.Pod) + if !ok { + return } - c.queue.Add(podRef) + newPod, ok := newObj.(*v1.Pod) + if !ok { + return + } + + // This is an optimization. In theory, passing most pod updates to the controller queue should lead to noop. + // To save some CPU, pass only pod updates that can cause any action in the controller + if oldPod.Status.Phase == newPod.Status.Phase { + return + } + if newPod.Status.Phase != v1.PodFailed && newPod.Status.Phase != v1.PodSucceeded { + return + } + c.enqueuePod(logger, newObj) } func (c *Controller) addPVC(logger klog.Logger, obj interface{}) { @@ -277,11 +294,7 @@ func (c *Controller) enqueueAllPodsForPVC(logger klog.Logger, namespace, name st return } for _, obj := range objs { - podRef, err := cache.DeletionHandlingObjectToName(obj) - if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for pod %#v: %w", obj, err)) - } - c.queue.Add(podRef) + c.enqueuePod(logger, obj) } } @@ -401,6 +414,11 @@ func (c *Controller) sync(ctx context.Context, podRef cache.ObjectName) error { logger.V(5).Info("Error getting pod from informer", "pod", klog.KObj(pod), "podUID", pod.UID, "err", err) return err } + if pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded { + // The pod has reached its final state and kubelet is unmounting is volumes. + // Remove them from the cache. + return c.syncPodDelete(ctx, podRef) + } return c.syncPod(ctx, pod) } @@ -481,8 +499,15 @@ func (c *Controller) syncVolume(logger klog.Logger, pod *v1.Pod, spec *volume.Sp changePolicy := v1.SELinuxChangePolicyMountOption if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxChangePolicy != nil { changePolicy = *pod.Spec.SecurityContext.SELinuxChangePolicy + logger.V(5).Info("Using Pod SELinux change policy", "pod", klog.KObj(pod), "changePolicy", changePolicy) } - if !pluginSupportsSELinuxContextMount { + if !pluginSupportsSELinuxContextMount && changePolicy != v1.SELinuxChangePolicyRecursive { + logger.V(5).Info("Volume does not support SELinux context mount, setting changePolicy to Recursive", "pod", klog.KObj(pod), "volume", spec.Name()) + changePolicy = v1.SELinuxChangePolicyRecursive + } + + if seLinuxLabel == "" && changePolicy != v1.SELinuxChangePolicyRecursive { + logger.V(5).Info("Pod has empty SELinux label, setting changePolicy to Recursive", "pod", klog.KObj(pod)) changePolicy = v1.SELinuxChangePolicyRecursive } diff --git a/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go b/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go index 3f863cac8a..8cc6c6d585 100644 --- a/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go +++ b/deps/github.com/openshift/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go @@ -54,31 +54,34 @@ func TestSELinuxWarningController_Sync(t *testing.T) { existingCSIDrivers []*storagev1.CSIDriver existingPods []*v1.Pod - pod cache.ObjectName - conflicts []volumecache.Conflict - expectError bool - expectedAddedVolumes []addedVolume - expectedEvents []string - expectedDeletedPods []cache.ObjectName + pod cache.ObjectName + csiDriverSELinuxEnabled bool + conflicts []volumecache.Conflict + expectError bool + expectedAddedVolumes []addedVolume + expectedEvents []string + expectedDeletedPods []cache.ObjectName }{ { name: "existing pod with no volumes", existingPods: []*v1.Pod{ - pod("pod1", "s0:c1,c2", nil), + pod("pod1", "s0:c1,c2", nil).build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - expectedEvents: nil, - expectedAddedVolumes: nil, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, + expectedAddedVolumes: nil, }, { name: "existing pod with unbound PVC", existingPods: []*v1.Pod{ - podWithPVC("pod1", "s0:c1,c2", nil, "non-existing-pvc", "vol1"), + pod("pod1", "s0:c1,c2", nil).withPVC("non-existing-pvc", "vol1").build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - expectError: true, // PVC is missing, add back to queue with exp. backoff - expectedEvents: nil, - expectedAddedVolumes: nil, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectError: true, // PVC is missing, add back to queue with exp. backoff + expectedEvents: nil, + expectedAddedVolumes: nil, }, { name: "existing pod with fully bound PVC", @@ -89,10 +92,11 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - podWithPVC("pod1", "s0:c1,c2", nil, "pvc1", "vol1"), + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - expectedEvents: nil, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, expectedAddedVolumes: []addedVolume{ { volumeName: "fake-plugin/pv1", @@ -112,10 +116,11 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - podWithPVC("pod1", "s0:c1,c2", ptr.To(v1.SELinuxChangePolicyRecursive), "pvc1", "vol1"), + pod("pod1", "s0:c1,c2", ptr.To(v1.SELinuxChangePolicyRecursive)).withPVC("pvc1", "vol1").build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - expectedEvents: nil, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, expectedAddedVolumes: []addedVolume{ { volumeName: "fake-plugin/pv1", @@ -135,10 +140,11 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - addInlineVolume(pod("pod1", "s0:c1,c2", nil)), + pod("pod1", "s0:c1,c2", nil).withInlineVolume().build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - expectedEvents: nil, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, expectedAddedVolumes: []addedVolume{ { volumeName: "fake-plugin/ebs.csi.aws.com-inlinevol1", @@ -158,10 +164,11 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - addInlineVolume(podWithPVC("pod1", "s0:c1,c2", nil, "pvc1", "vol1")), + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").withInlineVolume().build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - expectedEvents: nil, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, expectedAddedVolumes: []addedVolume{ { volumeName: "fake-plugin/pv1", @@ -188,10 +195,11 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - podWithPVC("pod1", "s0:c1,c2", nil, "pvc1", "vol1"), - pod("pod2", "s0:c98,c99", nil), + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").build(), + pod("pod2", "s0:c98,c99", nil).build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, conflicts: []volumecache.Conflict{ { PropertyName: "SELinuxLabel", @@ -233,11 +241,12 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - podWithPVC("pod1", "s0:c1,c2", ptr.To(v1.SELinuxChangePolicyRecursive), "pvc1", "vol1"), - pod("pod2", "s0:c98,c99", ptr.To(v1.SELinuxChangePolicyRecursive)), + pod("pod1", "s0:c1,c2", ptr.To(v1.SELinuxChangePolicyRecursive)).withPVC("pvc1", "vol1").build(), + pod("pod2", "s0:c98,c99", ptr.To(v1.SELinuxChangePolicyRecursive)).build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - conflicts: []volumecache.Conflict{}, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + conflicts: []volumecache.Conflict{}, expectedAddedVolumes: []addedVolume{ { volumeName: "fake-plugin/pv1", @@ -257,10 +266,11 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - podWithPVC("pod1", "s0:c1,c2", ptr.To(v1.SELinuxChangePolicyRecursive), "pvc1", "vol1"), - podWithPVC("pod2", "s0:c98,c99", ptr.To(v1.SELinuxChangePolicyMountOption), "pvc1", "vol1"), + pod("pod1", "s0:c1,c2", ptr.To(v1.SELinuxChangePolicyRecursive)).withPVC("pvc1", "vol1").build(), + pod("pod2", "s0:c98,c99", ptr.To(v1.SELinuxChangePolicyMountOption)).withPVC("pvc1", "vol1").build(), }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, conflicts: []volumecache.Conflict{ { PropertyName: "SELinuxChangePolicy", @@ -302,10 +312,11 @@ func TestSELinuxWarningController_Sync(t *testing.T) { pvBoundToPVC("pv1", "pvc1"), }, existingPods: []*v1.Pod{ - podWithPVC("pod1", "s0:c1,c2", nil, "pvc1", "vol1"), + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").build(), // "pod2" does not exist }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, conflicts: []volumecache.Conflict{ { PropertyName: "SELinuxLabel", @@ -338,16 +349,147 @@ func TestSELinuxWarningController_Sync(t *testing.T) { `Normal SELinuxLabelConflict SELinuxLabel ":::s0:c1,c2" conflicts with pod pod2 that uses the same volume as this pod with SELinuxLabel ":::s0:c98,c99". If both pods land on the same node, only one of them may access the volume.`, }, }, + { + name: "empty label implies Recursive policy", + existingPVCs: []*v1.PersistentVolumeClaim{ + pvcBoundToPV("pv1", "pvc1"), + }, + existingPVs: []*v1.PersistentVolume{ + pvBoundToPVC("pv1", "pvc1"), + }, + existingPods: []*v1.Pod{ + pod("pod1", "", ptr.To(v1.SELinuxChangePolicyMountOption)).withPVC("pvc1", "vol1").build(), + }, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + conflicts: []volumecache.Conflict{}, + expectedAddedVolumes: []addedVolume{ + { + volumeName: "fake-plugin/pv1", + podKey: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + label: "", + changePolicy: v1.SELinuxChangePolicyRecursive, // Reset to Recursive when the label is empty + csiDriver: "ebs.csi.aws.com", + }, + }, + }, + { + name: "pending pod is processed", + existingPVCs: []*v1.PersistentVolumeClaim{ + pvcBoundToPV("pv1", "pvc1"), + }, + existingPVs: []*v1.PersistentVolume{ + pvBoundToPVC("pv1", "pvc1"), + }, + existingPods: []*v1.Pod{ + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").withPhase(v1.PodPending).build(), + }, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, + expectedAddedVolumes: []addedVolume{ + { + volumeName: "fake-plugin/pv1", + podKey: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + label: ":::s0:c1,c2", + changePolicy: v1.SELinuxChangePolicyMountOption, + csiDriver: "ebs.csi.aws.com", + }, + }, + }, + { + name: "unknown pod is processed", + existingPVCs: []*v1.PersistentVolumeClaim{ + pvcBoundToPV("pv1", "pvc1"), + }, + existingPVs: []*v1.PersistentVolume{ + pvBoundToPVC("pv1", "pvc1"), + }, + existingPods: []*v1.Pod{ + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").withPhase(v1.PodUnknown).build(), + }, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, + expectedAddedVolumes: []addedVolume{ + { + volumeName: "fake-plugin/pv1", + podKey: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + label: ":::s0:c1,c2", + changePolicy: v1.SELinuxChangePolicyMountOption, + csiDriver: "ebs.csi.aws.com", + }, + }, + }, + { + name: "succeeded pod is removed from the cache", + existingPVCs: []*v1.PersistentVolumeClaim{ + pvcBoundToPV("pv1", "pvc1"), + }, + existingPVs: []*v1.PersistentVolume{ + pvBoundToPVC("pv1", "pvc1"), + }, + existingPods: []*v1.Pod{ + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").withPhase(v1.PodSucceeded).build(), + }, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, + expectedAddedVolumes: nil, + expectedDeletedPods: []cache.ObjectName{{Namespace: namespace, Name: "pod1"}}, + }, + { + name: "failed pod is removed from the cache", + existingPVCs: []*v1.PersistentVolumeClaim{ + pvcBoundToPV("pv1", "pvc1"), + }, + existingPVs: []*v1.PersistentVolume{ + pvBoundToPVC("pv1", "pvc1"), + }, + existingPods: []*v1.Pod{ + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").withPhase(v1.PodFailed).build(), + }, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectedEvents: nil, + expectedAddedVolumes: nil, + expectedDeletedPods: []cache.ObjectName{{Namespace: namespace, Name: "pod1"}}, + }, { name: "deleted pod", existingPods: []*v1.Pod{ // "pod1" does not exist in the informer }, - pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, - expectError: false, - expectedEvents: nil, - expectedAddedVolumes: nil, - expectedDeletedPods: []cache.ObjectName{{Namespace: namespace, Name: "pod1"}}, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: true, + expectError: false, + expectedEvents: nil, + expectedAddedVolumes: nil, + expectedDeletedPods: []cache.ObjectName{{Namespace: namespace, Name: "pod1"}}, + }, + { + name: "existing pod with fully bound PVC and CSIDriver.SELinuxMount disabled", + existingPVCs: []*v1.PersistentVolumeClaim{ + pvcBoundToPV("pv1", "pvc1"), + }, + existingPVs: []*v1.PersistentVolume{ + pvBoundToPVC("pv1", "pvc1"), + }, + existingPods: []*v1.Pod{ + pod("pod1", "s0:c1,c2", nil).withPVC("pvc1", "vol1").build(), + }, + pod: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + csiDriverSELinuxEnabled: false, + expectedEvents: nil, + expectedAddedVolumes: []addedVolume{ + { + volumeName: "fake-plugin/pv1", + podKey: cache.ObjectName{Namespace: namespace, Name: "pod1"}, + label: "", // Label is cleared when the CSI driver does not support SELinuxMount + changePolicy: v1.SELinuxChangePolicyRecursive, // Reset to Recursive when the CSI driver does not support SELinuxMount + csiDriver: "ebs.csi.aws.com", // The PV is a fake EBS volume + }, + }, }, } @@ -357,7 +499,7 @@ func TestSELinuxWarningController_Sync(t *testing.T) { _, ctx := ktesting.NewTestContext(t) _, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t) - plugin.SupportsSELinux = true + plugin.SupportsSELinux = tt.csiDriverSELinuxEnabled fakeClient := fake.NewClientset() fakeInformerFactory := informers.NewSharedInformerFactory(fakeClient, controller.NoResyncPeriodFunc()) @@ -490,49 +632,63 @@ func pvcBoundToPV(pvName, pvcName string) *v1.PersistentVolumeClaim { return pvc } -func pod(podName, level string, changePolicy *v1.PodSELinuxChangePolicy) *v1.Pod { +type podBuilder struct { + pod *v1.Pod +} + +func pod(podName, level string, changePolicy *v1.PodSELinuxChangePolicy) *podBuilder { var opts *v1.SELinuxOptions if level != "" { opts = &v1.SELinuxOptions{ Level: level, } } - return &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "ns1", - Name: podName, - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: "container1", - Image: "image1", - VolumeMounts: []v1.VolumeMount{ - { - Name: "vol1", - MountPath: "/mnt", + return &podBuilder{ + pod: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns1", + Name: podName, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "container1", + Image: "image1", + VolumeMounts: []v1.VolumeMount{ + { + Name: "vol1", + MountPath: "/mnt", + }, }, }, }, - }, - SecurityContext: &v1.PodSecurityContext{ - SELinuxChangePolicy: changePolicy, - SELinuxOptions: opts, - }, - Volumes: []v1.Volume{ - { - Name: "emptyDir1", - VolumeSource: v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{}, + SecurityContext: &v1.PodSecurityContext{ + SELinuxChangePolicy: changePolicy, + SELinuxOptions: opts, + }, + Volumes: []v1.Volume{ + { + Name: "emptyDir1", + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, }, }, }, + Status: v1.PodStatus{ + Phase: v1.PodRunning, + }, }, } } -func addInlineVolume(pod *v1.Pod) *v1.Pod { - pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{ +func (b *podBuilder) withPhase(phase v1.PodPhase) *podBuilder { + b.pod.Status.Phase = phase + return b +} + +func (b *podBuilder) withInlineVolume() *podBuilder { + b.pod.Spec.Volumes = append(b.pod.Spec.Volumes, v1.Volume{ Name: "inlineVolume", VolumeSource: v1.VolumeSource{ AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ @@ -540,17 +696,15 @@ func addInlineVolume(pod *v1.Pod) *v1.Pod { }, }, }) - pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ + b.pod.Spec.Containers[0].VolumeMounts = append(b.pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ Name: "inlineVolume", MountPath: "/mnt", }) - - return pod + return b } -func podWithPVC(podName, label string, changePolicy *v1.PodSELinuxChangePolicy, pvcName, volumeName string) *v1.Pod { - pod := pod(podName, label, changePolicy) - pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{ +func (b *podBuilder) withPVC(pvcName, volumeName string) *podBuilder { + b.pod.Spec.Volumes = append(b.pod.Spec.Volumes, v1.Volume{ Name: volumeName, VolumeSource: v1.VolumeSource{ PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ @@ -558,11 +712,15 @@ func podWithPVC(podName, label string, changePolicy *v1.PodSELinuxChangePolicy, }, }, }) - pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ + b.pod.Spec.Containers[0].VolumeMounts = append(b.pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ Name: volumeName, MountPath: "/mnt", }) - return pod + return b +} + +func (b *podBuilder) build() *v1.Pod { + return b.pod } type addedVolume struct { diff --git a/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/base.go b/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/base.go index 4c51a11a31..86c75e4850 100644 --- a/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/base.go +++ b/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/base.go @@ -149,6 +149,7 @@ const ( var ( errPodCompleted = fmt.Errorf("pod ran to completion") errNotEnoughSpace = errors.New(errReasonNotEnoughSpace) + sleepCommand = []string{"sleep", "infinity"} ) func newMockDriverSetup(f *framework.Framework) *mockDriverSetup { @@ -474,7 +475,15 @@ func (m *mockDriverSetup) createPodWithFSGroup(ctx context.Context, fsGroup *int return class, claim, pod } -func (m *mockDriverSetup) createPodWithSELinux(ctx context.Context, accessModes []v1.PersistentVolumeAccessMode, mountOptions []string, seLinuxOpts *v1.SELinuxOptions, policy *v1.PodSELinuxChangePolicy, privileged bool) (*storagev1.StorageClass, *v1.PersistentVolumeClaim, *v1.Pod) { +func (m *mockDriverSetup) createPodWithSELinux( + ctx context.Context, + accessModes []v1.PersistentVolumeAccessMode, + mountOptions []string, + seLinuxOpts *v1.SELinuxOptions, + policy *v1.PodSELinuxChangePolicy, + privileged bool, + command []string) (*storagev1.StorageClass, *v1.PersistentVolumeClaim, *v1.Pod) { + ginkgo.By("Creating pod with SELinux context") f := m.f nodeSelection := m.config.ClientNodeSelection @@ -491,7 +500,7 @@ func (m *mockDriverSetup) createPodWithSELinux(ctx context.Context, accessModes ReclaimPolicy: m.tp.reclaimPolicy, } class, claim := createClaim(ctx, f.ClientSet, scTest, nodeSelection, m.tp.scName, f.Namespace.Name, accessModes) - pod, err := startPausePodWithSELinuxOptions(f.ClientSet, claim, nodeSelection, f.Namespace.Name, seLinuxOpts, policy, privileged) + pod, err := startPausePodWithSELinuxOptions(f.ClientSet, claim, nodeSelection, f.Namespace.Name, seLinuxOpts, policy, privileged, command) framework.ExpectNoError(err, "Failed to create pause pod with SELinux context %s: %v", seLinuxOpts, err) if class != nil { @@ -866,7 +875,19 @@ func startBusyBoxPodWithVolumeSource(cs clientset.Interface, volumeSource v1.Vol return cs.CoreV1().Pods(ns).Create(context.TODO(), pod, metav1.CreateOptions{}) } -func startPausePodWithSELinuxOptions(cs clientset.Interface, pvc *v1.PersistentVolumeClaim, node e2epod.NodeSelection, ns string, seLinuxOpts *v1.SELinuxOptions, policy *v1.PodSELinuxChangePolicy, privileged bool) (*v1.Pod, error) { +func startPausePodWithSELinuxOptions( + cs clientset.Interface, + pvc *v1.PersistentVolumeClaim, + node e2epod.NodeSelection, + ns string, + seLinuxOpts *v1.SELinuxOptions, + policy *v1.PodSELinuxChangePolicy, + privileged bool, + command []string) (*v1.Pod, error) { + + if len(command) == 0 { + command = sleepCommand + } pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ GenerateName: "pvc-volume-tester-", @@ -878,8 +899,9 @@ func startPausePodWithSELinuxOptions(cs clientset.Interface, pvc *v1.PersistentV }, Containers: []v1.Container{ { - Name: "volume-tester", - Image: imageutils.GetE2EImage(imageutils.Pause), + Name: "volume-tester", + Image: e2epod.GetDefaultTestImage(), + Command: command, SecurityContext: &v1.SecurityContext{ Privileged: &privileged, }, diff --git a/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/csi_selinux_mount.go b/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/csi_selinux_mount.go index 3a7045cbaf..08c0e54857 100644 --- a/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/csi_selinux_mount.go +++ b/deps/github.com/openshift/kubernetes/test/e2e/storage/csimock/csi_selinux_mount.go @@ -298,7 +298,7 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount", func() { // Act ginkgo.By("Starting the initial pod") accessModes := []v1.PersistentVolumeAccessMode{t.volumeMode} - _, claim, pod := m.createPodWithSELinux(ctx, accessModes, t.mountOptions, t.firstPodSELinuxOpts, t.firstPodChangePolicy, false /* privileged */) + _, claim, pod := m.createPodWithSELinux(ctx, accessModes, t.mountOptions, t.firstPodSELinuxOpts, t.firstPodChangePolicy, false /* privileged */, sleepCommand) err := e2epod.WaitForPodNameRunningInNamespace(ctx, m.cs, pod.Name, pod.Namespace) framework.ExpectNoError(err, "starting the initial pod") @@ -331,7 +331,15 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount", func() { pod, err = m.cs.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) framework.ExpectNoError(err, "getting the initial pod") nodeSelection := e2epod.NodeSelection{Name: pod.Spec.NodeName} - pod2, err := startPausePodWithSELinuxOptions(f.ClientSet, claim, nodeSelection, f.Namespace.Name, t.secondPodSELinuxOpts, t.secondPodChangePolicy, false /* privileged */) + pod2, err := startPausePodWithSELinuxOptions( + f.ClientSet, + claim, + nodeSelection, + f.Namespace.Name, + t.secondPodSELinuxOpts, + t.secondPodChangePolicy, + false, /* privileged */ + sleepCommand) framework.ExpectNoError(err, "creating second pod with SELinux context %s", t.secondPodSELinuxOpts) m.pods = append(m.pods, pod2) @@ -454,6 +462,7 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount metrics and SELinuxWarningC firstPodSELinuxOpts *v1.SELinuxOptions firstPodChangePolicy *v1.PodSELinuxChangePolicy firstPodPrivileged bool + firstPodTargetPhase v1.PodPhase // Phase the first pod should reach before the second pod is created. Empty value means Running secondPodSELinuxOpts *v1.SELinuxOptions secondPodChangePolicy *v1.PodSELinuxChangePolicy secondPodPrivileged bool @@ -719,6 +728,74 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount metrics and SELinuxWarningC expectControllerConflictProperty: "SELinuxLabel", testTags: []interface{}{framework.WithFeatureGate(features.SELinuxMount)}, }, + { + name: "error is not bumped on a finished Pod with a different context on RWO volume and SELinuxMount enabled", + csiDriverSELinuxEnabled: true, + firstPodSELinuxOpts: &seLinuxOpts1, + firstPodTargetPhase: v1.PodSucceeded, + secondPodSELinuxOpts: &seLinuxOpts2, + volumeMode: v1.ReadWriteOnce, + waitForSecondPodStart: true, + // The volume is unmounted between the first and the second Pod, so admitted_total increases, + expectNodeIncreases: sets.New[string]("volume_manager_selinux_volumes_admitted_total"), + testTags: []interface{}{framework.WithFeatureGate(features.SELinuxMount)}, + }, + { + name: "error is not bumped on a failed Pod with a different context on RWO volume and SELinuxMount enabled", + csiDriverSELinuxEnabled: true, + firstPodSELinuxOpts: &seLinuxOpts1, + firstPodTargetPhase: v1.PodFailed, + secondPodSELinuxOpts: &seLinuxOpts2, + volumeMode: v1.ReadWriteOnce, + waitForSecondPodStart: true, + // The volume is unmounted between the first and the second Pod, so admitted_total increases, + expectNodeIncreases: sets.New[string]("volume_manager_selinux_volumes_admitted_total"), + testTags: []interface{}{framework.WithFeatureGate(features.SELinuxMount)}, + }, + { + name: "warning is not bumped on RWO volume with CSIDriver.SELinuxMount disabled and mismatched labels", + csiDriverSELinuxEnabled: false, + firstPodSELinuxOpts: &seLinuxOpts1, + secondPodSELinuxOpts: &seLinuxOpts2, + volumeMode: v1.ReadWriteOnce, + waitForSecondPodStart: true, + expectNodeIncreases: sets.New[string]( /* no metric is increased, admitted_total was already increased when the first pod started */ ), + testTags: []interface{}{framework.WithFeatureGate(features.SELinuxMount)}, + }, + { + name: "warning is not bumped on RWX volume with CSIDriver.SELinuxMount disabled and mismatched labels", + csiDriverSELinuxEnabled: false, + firstPodSELinuxOpts: &seLinuxOpts1, + secondPodSELinuxOpts: &seLinuxOpts2, + volumeMode: v1.ReadWriteMany, + waitForSecondPodStart: true, + expectNodeIncreases: sets.New[string]( /* no metric is increased, admitted_total was already increased when the first pod started */ ), + testTags: []interface{}{framework.WithFeatureGate(features.SELinuxMount)}, + }, + { + name: "warning is not bumped on RWO volume with CSIDriver.SELinuxMount disabled and mismatched policies", + csiDriverSELinuxEnabled: false, + firstPodSELinuxOpts: &seLinuxOpts1, + firstPodChangePolicy: &recursive, + secondPodSELinuxOpts: &seLinuxOpts1, + secondPodChangePolicy: &mount, + volumeMode: v1.ReadWriteOnce, + waitForSecondPodStart: true, + expectNodeIncreases: sets.New[string]( /* no metric is increased, admitted_total was already increased when the first pod started */ ), + testTags: []interface{}{framework.WithFeatureGate(features.SELinuxMount)}, + }, + { + name: "warning is not bumped on RWX volume with CSIDriver.SELinuxMount disabled and mismatched policies", + csiDriverSELinuxEnabled: false, + firstPodSELinuxOpts: &seLinuxOpts1, + firstPodChangePolicy: &recursive, + secondPodSELinuxOpts: &seLinuxOpts1, + secondPodChangePolicy: &mount, + volumeMode: v1.ReadWriteMany, + waitForSecondPodStart: true, + expectNodeIncreases: sets.New[string]( /* no metric is increased, admitted_total was already increased when the first pod started */ ), + testTags: []interface{}{framework.WithFeatureGate(features.SELinuxMount)}, + }, } for _, t := range tests { t := t @@ -726,6 +803,9 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount metrics and SELinuxWarningC if processLabel == "" { e2eskipper.Skipf("SELinux tests are supported only on %+v", getSupportedSELinuxDistros()) } + if t.firstPodTargetPhase == "" { + t.firstPodTargetPhase = v1.PodRunning + } // Some metrics use CSI driver name as a label, which is "csi-mock-" + the namespace name. volumePluginLabel := "volume_plugin=\"kubernetes.io/csi/csi-mock-" + f.Namespace.Name + "\"" @@ -744,9 +824,24 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount metrics and SELinuxWarningC ginkgo.By("Starting the first pod") accessModes := []v1.PersistentVolumeAccessMode{t.volumeMode} - _, claim, pod := m.createPodWithSELinux(ctx, accessModes, []string{}, t.firstPodSELinuxOpts, t.firstPodChangePolicy, t.firstPodPrivileged) - err = e2epod.WaitForPodNameRunningInNamespace(ctx, m.cs, pod.Name, pod.Namespace) - framework.ExpectNoError(err, "starting the initial pod") + command := sleepCommand + switch t.firstPodTargetPhase { + case v1.PodSucceeded: + command = []string{"/bin/true"} + case v1.PodFailed: + command = []string{"/bin/false"} + } + _, claim, pod := m.createPodWithSELinux(ctx, accessModes, []string{}, t.firstPodSELinuxOpts, t.firstPodChangePolicy, t.firstPodPrivileged, command) + + switch t.firstPodTargetPhase { + case v1.PodRunning: + err = e2epod.WaitForPodNameRunningInNamespace(ctx, m.cs, pod.Name, pod.Namespace) + framework.ExpectNoError(err, "starting the initial pod") + case v1.PodSucceeded, v1.PodFailed: + ginkgo.By("Waiting for the first pod to complete") + err = e2epod.WaitForPodNoLongerRunningInNamespace(ctx, m.cs, pod.Name, pod.Namespace) + framework.ExpectNoError(err, "starting and completing the initial pod") + } ginkgo.By("Grabbing initial metrics") pod, err = m.cs.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) @@ -759,7 +854,15 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount metrics and SELinuxWarningC ginkgo.By("Starting the second pod") // Skip scheduler, it would block scheduling the second pod with ReadWriteOncePod PV. nodeSelection := e2epod.NodeSelection{Name: pod.Spec.NodeName} - pod2, err := startPausePodWithSELinuxOptions(f.ClientSet, claim, nodeSelection, f.Namespace.Name, t.secondPodSELinuxOpts, t.secondPodChangePolicy, t.secondPodPrivileged) + pod2, err := startPausePodWithSELinuxOptions( + f.ClientSet, + claim, + nodeSelection, + f.Namespace.Name, + t.secondPodSELinuxOpts, + t.secondPodChangePolicy, + t.secondPodPrivileged, + sleepCommand) framework.ExpectNoError(err, "creating second pod with SELinux context %s", t.secondPodSELinuxOpts) m.pods = append(m.pods, pod2) @@ -795,6 +898,9 @@ var _ = utils.SIGDescribe("CSI Mock selinux on mount metrics and SELinuxWarningC // Check the controler generated event on the second pod err = waitForConflictEvent(ctx, m.cs, pod2, pod, t.expectControllerConflictProperty, f.Timeouts.PodStart) framework.ExpectNoError(err, "while waiting for an event on the second pod") + } else { + err := checkForNoConflictEvents(ctx, m.cs, pod, pod2) + framework.ExpectNoError(err, "ensuring there are no SELinux conflict events") } } // t.testTags is array and it's not possible to use It("name", func(){xxx}, t.testTags...) @@ -974,6 +1080,29 @@ func waitForConflictEvent(ctx context.Context, cs clientset.Interface, pod, othe return e2eevents.WaitTimeoutForEvent(ctx, cs, pod.Namespace, eventSelector, msg, timeout) } +func checkForNoConflictEvents(ctx context.Context, cs clientset.Interface, pod, otherPod *v1.Pod) error { + eventSelector := fields.Set{ + "involvedObject.kind": "Pod", + "involvedObject.name": pod.Name, + "involvedObject.namespace": pod.Namespace, + }.AsSelector().String() + options := metav1.ListOptions{FieldSelector: eventSelector} + + events, err := cs.CoreV1().Events(pod.Namespace).List(ctx, options) + if err != nil { + return fmt.Errorf("error getting events: %w", err) + } + + msg := fmt.Sprintf("conflicts with pod %s that uses the same volume as this pod", otherPod.Name) + ginkgo.By(fmt.Sprintf("Checking for the SELinux controller events on pod %q: %q", pod.Name, msg)) + for _, event := range events.Items { + if strings.Contains(event.Message, msg) { + return fmt.Errorf("conflict event found: %s", event.Message) + } + } + return nil +} + func dumpMetrics(metrics map[string]float64) { // Print the metrics sorted by metric name for better readability keys := make([]string, 0, len(metrics)) From f842a513df3d469d6279dc339cdd7c4b91115d53 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:03:30 +0100 Subject: [PATCH 05/15] update microshift/vendor --- vendor/cyphar.com/go-pathrs/.golangci.yml | 43 ++ vendor/cyphar.com/go-pathrs/COPYING | 373 +++++++++++ vendor/cyphar.com/go-pathrs/doc.go | 14 + vendor/cyphar.com/go-pathrs/handle_linux.go | 114 ++++ .../go-pathrs/internal/fdutils/fd_linux.go | 75 +++ .../internal/libpathrs/error_unix.go | 40 ++ .../internal/libpathrs/libpathrs_linux.go | 337 ++++++++++ .../go-pathrs/procfs/procfs_linux.go | 246 ++++++++ vendor/cyphar.com/go-pathrs/root_linux.go | 367 +++++++++++ vendor/cyphar.com/go-pathrs/utils_linux.go | 56 ++ .../cyphar/filepath-securejoin/.golangci.yml | 4 + .../cyphar/filepath-securejoin/CHANGELOG.md | 62 +- .../cyphar/filepath-securejoin/VERSION | 2 +- .../filepath-securejoin/deprecated_linux.go | 48 -- .../filepath-securejoin/pathrs-lite/README.md | 12 +- .../filepath-securejoin/pathrs-lite/doc.go | 2 + .../pathrs-lite/internal/gopathrs/doc.go | 16 + .../{ => internal/gopathrs}/lookup_linux.go | 6 +- .../{ => internal/gopathrs}/mkdir_linux.go | 54 +- .../internal/gopathrs/open_linux.go | 26 + .../{ => internal/gopathrs}/openat2_linux.go | 2 +- .../filepath-securejoin/pathrs-lite/mkdir.go | 55 ++ .../pathrs-lite/mkdir_libpathrs.go | 52 ++ .../pathrs-lite/mkdir_purego.go | 42 ++ .../pathrs-lite/{open_linux.go => open.go} | 29 - .../pathrs-lite/open_libpathrs.go | 57 ++ .../pathrs-lite/open_purego.go | 42 ++ .../pathrs-lite/procfs/procfs_libpathrs.go | 161 +++++ .../{procfs_linux.go => procfs_purego.go} | 2 +- .../selinux/go-selinux/label/label_linux.go | 6 +- .../selinux/go-selinux/selinux.go | 10 +- .../selinux/go-selinux/selinux_linux.go | 268 +++++--- .../selinux/go-selinux/selinux_stub.go | 12 +- .../openshift/library-go/pkg/crypto/crypto.go | 50 +- .../pkg/operator/certrotation/signer.go | 2 +- vendor/github.com/spf13/cobra/.golangci.yml | 28 +- vendor/github.com/spf13/cobra/README.md | 24 +- vendor/github.com/spf13/cobra/SECURITY.md | 105 +++ vendor/github.com/spf13/cobra/command.go | 11 +- vendor/github.com/spf13/cobra/completions.go | 19 +- .../go.etcd.io/etcd/api/v3/version/version.go | 2 +- .../etcd/client/v3/retry_interceptor.go | 6 +- .../net/http/otelhttp/config.go | 4 + .../net/http/otelhttp/handler.go | 9 +- .../otelhttp/internal/request/body_wrapper.go | 7 +- .../net/http/otelhttp/internal/request/gen.go | 10 + .../internal/request/resp_writer_wrapper.go | 5 +- .../net/http/otelhttp/internal/semconv/env.go | 121 ++-- .../net/http/otelhttp/internal/semconv/gen.go | 16 +- .../otelhttp/internal/semconv/httpconv.go | 76 ++- .../http/otelhttp/internal/semconv/util.go | 28 +- .../http/otelhttp/internal/semconv/v1.20.0.go | 27 +- .../otelhttp/internal/semconvutil/httpconv.go | 53 +- .../otelhttp/internal/semconvutil/netconv.go | 13 +- .../net/http/otelhttp/labeler.go | 6 +- .../net/http/otelhttp/version.go | 9 +- vendor/golang.org/x/crypto/ed25519/ed25519.go | 11 +- .../x/crypto/salsa20/salsa/hsalsa20.go | 4 + vendor/golang.org/x/net/context/context.go | 70 +- vendor/golang.org/x/net/html/escape.go | 2 +- vendor/golang.org/x/net/html/parse.go | 57 +- vendor/golang.org/x/net/html/render.go | 2 +- vendor/golang.org/x/net/http2/config.go | 63 +- vendor/golang.org/x/net/http2/config_go124.go | 61 -- vendor/golang.org/x/net/http2/config_go125.go | 15 + vendor/golang.org/x/net/http2/config_go126.go | 15 + .../x/net/http2/config_pre_go124.go | 16 - vendor/golang.org/x/net/http2/frame.go | 101 ++- vendor/golang.org/x/net/http2/gotrack.go | 17 +- vendor/golang.org/x/net/http2/http2.go | 35 +- vendor/golang.org/x/net/http2/server.go | 143 ++--- vendor/golang.org/x/net/http2/timer.go | 20 - vendor/golang.org/x/net/http2/transport.go | 196 +++--- vendor/golang.org/x/net/http2/writesched.go | 67 +- ...rity.go => writesched_priority_rfc7540.go} | 109 ++-- .../net/http2/writesched_priority_rfc9218.go | 209 ++++++ .../x/net/http2/writesched_roundrobin.go | 2 +- .../x/net/internal/httpcommon/request.go | 4 +- .../golang.org/x/net/internal/socks/socks.go | 2 +- vendor/golang.org/x/sync/errgroup/errgroup.go | 2 +- vendor/golang.org/x/sys/cpu/cpu.go | 3 + vendor/golang.org/x/sys/cpu/cpu_arm64.go | 20 +- vendor/golang.org/x/sys/cpu/cpu_arm64.s | 19 +- vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go | 1 + .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 1 + .../golang.org/x/sys/cpu/cpu_netbsd_arm64.go | 2 +- .../golang.org/x/sys/cpu/cpu_openbsd_arm64.go | 2 +- .../golang.org/x/sys/unix/affinity_linux.go | 9 + vendor/golang.org/x/sys/unix/fdset.go | 4 +- vendor/golang.org/x/sys/unix/ifreq_linux.go | 4 +- vendor/golang.org/x/sys/unix/mkall.sh | 1 + vendor/golang.org/x/sys/unix/mkerrors.sh | 2 + vendor/golang.org/x/sys/unix/syscall_linux.go | 10 +- .../golang.org/x/sys/unix/syscall_netbsd.go | 17 + vendor/golang.org/x/sys/unix/zerrors_linux.go | 359 +++++++++++ .../golang.org/x/sys/unix/zsyscall_linux.go | 10 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 31 + .../x/sys/windows/syscall_windows.go | 17 + .../golang.org/x/sys/windows/types_windows.go | 92 +++ .../x/sys/windows/zsyscall_windows.go | 55 ++ vendor/golang.org/x/term/terminal.go | 6 +- vendor/golang.org/x/text/unicode/bidi/core.go | 11 +- .../x/tools/go/ast/astutil/imports.go | 67 +- vendor/golang.org/x/tools/go/ast/edge/edge.go | 295 +++++++++ .../x/tools/go/ast/inspector/cursor.go | 502 +++++++++++++++ .../x/tools/go/ast/inspector/inspector.go | 311 +++++++++ .../x/tools/go/ast/inspector/iter.go | 85 +++ .../x/tools/go/ast/inspector/typeof.go | 227 +++++++ .../x/tools/go/ast/inspector/walk.go | 341 ++++++++++ .../golang.org/x/tools/go/packages/golist.go | 6 - .../golang.org/x/tools/go/packages/visit.go | 85 ++- .../x/tools/go/types/objectpath/objectpath.go | 5 +- .../x/tools/go/types/typeutil/map.go | 19 +- vendor/golang.org/x/tools/imports/forward.go | 6 - .../x/tools/internal/event/core/event.go | 5 - .../x/tools/internal/gcimporter/iexport.go | 1 - .../internal/gcimporter/iimport_go122.go | 53 -- .../x/tools/internal/imports/fix.go | 6 +- .../x/tools/internal/modindex/symbols.go | 3 +- .../x/tools/internal/stdlib/deps.go | 596 +++++++++--------- .../x/tools/internal/stdlib/manifest.go | 58 +- .../x/tools/internal/typesinternal/fx.go | 49 ++ .../x/tools/internal/typesinternal/isnamed.go | 71 +++ .../tools/internal/typesinternal/qualifier.go | 8 + .../x/tools/internal/typesinternal/types.go | 48 +- .../tools/internal/typesinternal/zerovalue.go | 17 +- .../gopkg.in/evanphx/json-patch.v4/README.md | 8 +- .../gopkg.in/evanphx/json-patch.v4/patch.go | 105 ++- .../kube-openapi/cmd/openapi-gen/args/args.go | 13 + .../cmd/openapi-gen/openapi-gen.go | 27 +- .../kube-openapi/pkg/generators/config.go | 62 +- .../pkg/generators/model_names.go | 177 ++++++ .../kube-openapi/pkg/generators/openapi.go | 66 +- vendor/k8s.io/kube-openapi/pkg/util/util.go | 13 +- .../pkg/validation/strfmt/default.go | 290 --------- .../pkg/validation/strfmt/duration.go | 17 - .../pkg/validation/strfmt/time.go | 20 - .../selinuxwarning/cache/volumecache.go | 12 +- .../selinux_warning_controller.go | 55 +- vendor/modules.txt | 75 ++- .../internal/golang/encoding/json/decode.go | 43 +- .../internal/golang/encoding/json/encode.go | 63 +- .../internal/golang/encoding/json/stream.go | 4 +- 143 files changed, 7245 insertions(+), 1834 deletions(-) create mode 100644 vendor/cyphar.com/go-pathrs/.golangci.yml create mode 100644 vendor/cyphar.com/go-pathrs/COPYING create mode 100644 vendor/cyphar.com/go-pathrs/doc.go create mode 100644 vendor/cyphar.com/go-pathrs/handle_linux.go create mode 100644 vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go create mode 100644 vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go create mode 100644 vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go create mode 100644 vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go create mode 100644 vendor/cyphar.com/go-pathrs/root_linux.go create mode 100644 vendor/cyphar.com/go-pathrs/utils_linux.go delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/deprecated_linux.go create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/doc.go rename vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/{ => internal/gopathrs}/lookup_linux.go (98%) rename vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/{ => internal/gopathrs}/mkdir_linux.go (81%) create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/open_linux.go rename vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/{ => internal/gopathrs}/openat2_linux.go (99%) create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir.go create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_libpathrs.go create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_purego.go rename vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/{open_linux.go => open.go} (57%) create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_libpathrs.go create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_purego.go create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_libpathrs.go rename vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/{procfs_linux.go => procfs_purego.go} (99%) create mode 100644 vendor/github.com/spf13/cobra/SECURITY.md create mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go delete mode 100644 vendor/golang.org/x/net/http2/config_go124.go create mode 100644 vendor/golang.org/x/net/http2/config_go125.go create mode 100644 vendor/golang.org/x/net/http2/config_go126.go delete mode 100644 vendor/golang.org/x/net/http2/config_pre_go124.go delete mode 100644 vendor/golang.org/x/net/http2/timer.go rename vendor/golang.org/x/net/http2/{writesched_priority.go => writesched_priority_rfc7540.go} (77%) create mode 100644 vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go create mode 100644 vendor/golang.org/x/tools/go/ast/edge/edge.go create mode 100644 vendor/golang.org/x/tools/go/ast/inspector/cursor.go create mode 100644 vendor/golang.org/x/tools/go/ast/inspector/inspector.go create mode 100644 vendor/golang.org/x/tools/go/ast/inspector/iter.go create mode 100644 vendor/golang.org/x/tools/go/ast/inspector/typeof.go create mode 100644 vendor/golang.org/x/tools/go/ast/inspector/walk.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/fx.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/isnamed.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/model_names.go diff --git a/vendor/cyphar.com/go-pathrs/.golangci.yml b/vendor/cyphar.com/go-pathrs/.golangci.yml new file mode 100644 index 0000000000..2778a3268e --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/.golangci.yml @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: MPL-2.0 +# +# libpathrs: safe path resolution on Linux +# Copyright (C) 2019-2025 Aleksa Sarai +# Copyright (C) 2019-2025 SUSE LLC +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. + +version: "2" +linters: + enable: + - bidichk + - cyclop + - errname + - errorlint + - exhaustive + - goconst + - godot + - gomoddirectives + - gosec + - mirror + - misspell + - mnd + - nilerr + - nilnil + - perfsprint + - prealloc + - reassign + - revive + - unconvert + - unparam + - usestdlibvars + - wastedassign +formatters: + enable: + - gofumpt + - goimports + settings: + goimports: + local-prefixes: + - cyphar.com/go-pathrs diff --git a/vendor/cyphar.com/go-pathrs/COPYING b/vendor/cyphar.com/go-pathrs/COPYING new file mode 100644 index 0000000000..d0a1fa1482 --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/COPYING @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at https://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/cyphar.com/go-pathrs/doc.go b/vendor/cyphar.com/go-pathrs/doc.go new file mode 100644 index 0000000000..a7ee4bc487 --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/doc.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +// Package pathrs provides bindings for libpathrs, a library for safe path +// resolution on Linux. +package pathrs diff --git a/vendor/cyphar.com/go-pathrs/handle_linux.go b/vendor/cyphar.com/go-pathrs/handle_linux.go new file mode 100644 index 0000000000..3221ef6738 --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/handle_linux.go @@ -0,0 +1,114 @@ +//go:build linux + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package pathrs + +import ( + "fmt" + "os" + + "cyphar.com/go-pathrs/internal/fdutils" + "cyphar.com/go-pathrs/internal/libpathrs" +) + +// Handle is a handle for a path within a given [Root]. This handle references +// an already-resolved path which can be used for only one purpose -- to +// "re-open" the handle and get an actual [os.File] which can be used for +// ordinary operations. +// +// If you wish to open a file without having an intermediate [Handle] object, +// you can try to use [Root.Open] or [Root.OpenFile]. +// +// It is critical that perform all relevant operations through this [Handle] +// (rather than fetching the file descriptor yourself with [Handle.IntoRaw]), +// because the security properties of libpathrs depend on users doing all +// relevant filesystem operations through libpathrs. +// +// [os.File]: https://pkg.go.dev/os#File +type Handle struct { + inner *os.File +} + +// HandleFromFile creates a new [Handle] from an existing file handle. The +// handle will be copied by this method, so the original handle should still be +// freed by the caller. +// +// This is effectively the inverse operation of [Handle.IntoRaw], and is used +// for "deserialising" pathrs root handles. +func HandleFromFile(file *os.File) (*Handle, error) { + newFile, err := fdutils.DupFile(file) + if err != nil { + return nil, fmt.Errorf("duplicate handle fd: %w", err) + } + return &Handle{inner: newFile}, nil +} + +// Open creates an "upgraded" file handle to the file referenced by the +// [Handle]. Note that the original [Handle] is not consumed by this operation, +// and can be opened multiple times. +// +// The handle returned is only usable for reading, and this is method is +// shorthand for [Handle.OpenFile] with os.O_RDONLY. +// +// TODO: Rename these to "Reopen" or something. +func (h *Handle) Open() (*os.File, error) { + return h.OpenFile(os.O_RDONLY) +} + +// OpenFile creates an "upgraded" file handle to the file referenced by the +// [Handle]. Note that the original [Handle] is not consumed by this operation, +// and can be opened multiple times. +// +// The provided flags indicate which open(2) flags are used to create the new +// handle. +// +// TODO: Rename these to "Reopen" or something. +func (h *Handle) OpenFile(flags int) (*os.File, error) { + return fdutils.WithFileFd(h.inner, func(fd uintptr) (*os.File, error) { + newFd, err := libpathrs.Reopen(fd, flags) + if err != nil { + return nil, err + } + return os.NewFile(newFd, h.inner.Name()), nil + }) +} + +// IntoFile unwraps the [Handle] into its underlying [os.File]. +// +// You almost certainly want to use [Handle.OpenFile] to get a non-O_PATH +// version of this [Handle]. +// +// This operation returns the internal [os.File] of the [Handle] directly, so +// calling [Handle.Close] will also close any copies of the returned [os.File]. +// If you want to get an independent copy, use [Handle.Clone] followed by +// [Handle.IntoFile] on the cloned [Handle]. +// +// [os.File]: https://pkg.go.dev/os#File +func (h *Handle) IntoFile() *os.File { + // TODO: Figure out if we really don't want to make a copy. + // TODO: We almost certainly want to clear r.inner here, but we can't do + // that easily atomically (we could use atomic.Value but that'll make + // things quite a bit uglier). + return h.inner +} + +// Clone creates a copy of a [Handle], such that it has a separate lifetime to +// the original (while referring to the same underlying file). +func (h *Handle) Clone() (*Handle, error) { + return HandleFromFile(h.inner) +} + +// Close frees all of the resources used by the [Handle]. +func (h *Handle) Close() error { + return h.inner.Close() +} diff --git a/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go b/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go new file mode 100644 index 0000000000..41aea3e4b3 --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go @@ -0,0 +1,75 @@ +//go:build linux + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +// Package fdutils contains a few helper methods when dealing with *os.File and +// file descriptors. +package fdutils + +import ( + "fmt" + "os" + + "golang.org/x/sys/unix" + + "cyphar.com/go-pathrs/internal/libpathrs" +) + +// DupFd makes a duplicate of the given fd. +func DupFd(fd uintptr, name string) (*os.File, error) { + newFd, err := unix.FcntlInt(fd, unix.F_DUPFD_CLOEXEC, 0) + if err != nil { + return nil, fmt.Errorf("fcntl(F_DUPFD_CLOEXEC): %w", err) + } + return os.NewFile(uintptr(newFd), name), nil +} + +// WithFileFd is a more ergonomic wrapper around file.SyscallConn().Control(). +func WithFileFd[T any](file *os.File, fn func(fd uintptr) (T, error)) (T, error) { + conn, err := file.SyscallConn() + if err != nil { + return *new(T), err + } + var ( + ret T + innerErr error + ) + if err := conn.Control(func(fd uintptr) { + ret, innerErr = fn(fd) + }); err != nil { + return *new(T), err + } + return ret, innerErr +} + +// DupFile makes a duplicate of the given file. +func DupFile(file *os.File) (*os.File, error) { + return WithFileFd(file, func(fd uintptr) (*os.File, error) { + return DupFd(fd, file.Name()) + }) +} + +// MkFile creates a new *os.File from the provided file descriptor. However, +// unlike os.NewFile, the file's Name is based on the real path (provided by +// /proc/self/fd/$n). +func MkFile(fd uintptr) (*os.File, error) { + fdPath := fmt.Sprintf("fd/%d", fd) + fdName, err := libpathrs.ProcReadlinkat(libpathrs.ProcDefaultRootFd, libpathrs.ProcThreadSelf, fdPath) + if err != nil { + _ = unix.Close(int(fd)) + return nil, fmt.Errorf("failed to fetch real name of fd %d: %w", fd, err) + } + // TODO: Maybe we should prefix this name with something to indicate to + // users that they must not use this path as a "safe" path. Something like + // "//pathrs-handle:/foo/bar"? + return os.NewFile(fd, fdName), nil +} diff --git a/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go b/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go new file mode 100644 index 0000000000..c9f416de01 --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go @@ -0,0 +1,40 @@ +//go:build linux + +// TODO: Use "go:build unix" once we bump the minimum Go version 1.19. + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package libpathrs + +import ( + "syscall" +) + +// Error represents an underlying libpathrs error. +type Error struct { + description string + errno syscall.Errno +} + +// Error returns a textual description of the error. +func (err *Error) Error() string { + return err.description +} + +// Unwrap returns the underlying error which was wrapped by this error (if +// applicable). +func (err *Error) Unwrap() error { + if err.errno != 0 { + return err.errno + } + return nil +} diff --git a/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go b/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go new file mode 100644 index 0000000000..c07b80e307 --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go @@ -0,0 +1,337 @@ +//go:build linux + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +// Package libpathrs is an internal thin wrapper around the libpathrs C API. +package libpathrs + +import ( + "fmt" + "syscall" + "unsafe" +) + +/* +// TODO: Figure out if we need to add support for linking against libpathrs +// statically even if in dynamically linked builds in order to make +// packaging a bit easier (using "-Wl,-Bstatic -lpathrs -Wl,-Bdynamic" or +// "-l:pathrs.a"). +#cgo pkg-config: pathrs +#include + +// This is a workaround for unsafe.Pointer() not working for non-void pointers. +char *cast_ptr(void *ptr) { return ptr; } +*/ +import "C" + +func fetchError(errID C.int) error { + if errID >= C.__PATHRS_MAX_ERR_VALUE { + return nil + } + cErr := C.pathrs_errorinfo(errID) + defer C.pathrs_errorinfo_free(cErr) + + var err error + if cErr != nil { + err = &Error{ + errno: syscall.Errno(cErr.saved_errno), + description: C.GoString(cErr.description), + } + } + return err +} + +// OpenRoot wraps pathrs_open_root. +func OpenRoot(path string) (uintptr, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + fd := C.pathrs_open_root(cPath) + return uintptr(fd), fetchError(fd) +} + +// Reopen wraps pathrs_reopen. +func Reopen(fd uintptr, flags int) (uintptr, error) { + newFd := C.pathrs_reopen(C.int(fd), C.int(flags)) + return uintptr(newFd), fetchError(newFd) +} + +// InRootResolve wraps pathrs_inroot_resolve. +func InRootResolve(rootFd uintptr, path string) (uintptr, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + fd := C.pathrs_inroot_resolve(C.int(rootFd), cPath) + return uintptr(fd), fetchError(fd) +} + +// InRootResolveNoFollow wraps pathrs_inroot_resolve_nofollow. +func InRootResolveNoFollow(rootFd uintptr, path string) (uintptr, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + fd := C.pathrs_inroot_resolve_nofollow(C.int(rootFd), cPath) + return uintptr(fd), fetchError(fd) +} + +// InRootOpen wraps pathrs_inroot_open. +func InRootOpen(rootFd uintptr, path string, flags int) (uintptr, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + fd := C.pathrs_inroot_open(C.int(rootFd), cPath, C.int(flags)) + return uintptr(fd), fetchError(fd) +} + +// InRootReadlink wraps pathrs_inroot_readlink. +func InRootReadlink(rootFd uintptr, path string) (string, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + size := 128 + for { + linkBuf := make([]byte, size) + n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf))) + switch { + case int(n) < C.__PATHRS_MAX_ERR_VALUE: + return "", fetchError(n) + case int(n) <= len(linkBuf): + return string(linkBuf[:int(n)]), nil + default: + // The contents were truncated. Unlike readlinkat, pathrs returns + // the size of the link when it checked. So use the returned size + // as a basis for the reallocated size (but in order to avoid a DoS + // where a magic-link is growing by a single byte each iteration, + // make sure we are a fair bit larger). + size += int(n) + } + } +} + +// InRootRmdir wraps pathrs_inroot_rmdir. +func InRootRmdir(rootFd uintptr, path string) error { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + err := C.pathrs_inroot_rmdir(C.int(rootFd), cPath) + return fetchError(err) +} + +// InRootUnlink wraps pathrs_inroot_unlink. +func InRootUnlink(rootFd uintptr, path string) error { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + err := C.pathrs_inroot_unlink(C.int(rootFd), cPath) + return fetchError(err) +} + +// InRootRemoveAll wraps pathrs_inroot_remove_all. +func InRootRemoveAll(rootFd uintptr, path string) error { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + err := C.pathrs_inroot_remove_all(C.int(rootFd), cPath) + return fetchError(err) +} + +// InRootCreat wraps pathrs_inroot_creat. +func InRootCreat(rootFd uintptr, path string, flags int, mode uint32) (uintptr, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + fd := C.pathrs_inroot_creat(C.int(rootFd), cPath, C.int(flags), C.uint(mode)) + return uintptr(fd), fetchError(fd) +} + +// InRootRename wraps pathrs_inroot_rename. +func InRootRename(rootFd uintptr, src, dst string, flags uint) error { + cSrc := C.CString(src) + defer C.free(unsafe.Pointer(cSrc)) + + cDst := C.CString(dst) + defer C.free(unsafe.Pointer(cDst)) + + err := C.pathrs_inroot_rename(C.int(rootFd), cSrc, cDst, C.uint(flags)) + return fetchError(err) +} + +// InRootMkdir wraps pathrs_inroot_mkdir. +func InRootMkdir(rootFd uintptr, path string, mode uint32) error { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + err := C.pathrs_inroot_mkdir(C.int(rootFd), cPath, C.uint(mode)) + return fetchError(err) +} + +// InRootMkdirAll wraps pathrs_inroot_mkdir_all. +func InRootMkdirAll(rootFd uintptr, path string, mode uint32) (uintptr, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + fd := C.pathrs_inroot_mkdir_all(C.int(rootFd), cPath, C.uint(mode)) + return uintptr(fd), fetchError(fd) +} + +// InRootMknod wraps pathrs_inroot_mknod. +func InRootMknod(rootFd uintptr, path string, mode uint32, dev uint64) error { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + err := C.pathrs_inroot_mknod(C.int(rootFd), cPath, C.uint(mode), C.dev_t(dev)) + return fetchError(err) +} + +// InRootSymlink wraps pathrs_inroot_symlink. +func InRootSymlink(rootFd uintptr, path, target string) error { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + cTarget := C.CString(target) + defer C.free(unsafe.Pointer(cTarget)) + + err := C.pathrs_inroot_symlink(C.int(rootFd), cPath, cTarget) + return fetchError(err) +} + +// InRootHardlink wraps pathrs_inroot_hardlink. +func InRootHardlink(rootFd uintptr, path, target string) error { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + cTarget := C.CString(target) + defer C.free(unsafe.Pointer(cTarget)) + + err := C.pathrs_inroot_hardlink(C.int(rootFd), cPath, cTarget) + return fetchError(err) +} + +// ProcBase is pathrs_proc_base_t (uint64_t). +type ProcBase C.pathrs_proc_base_t + +// FIXME: We need to open-code the constants because CGo unfortunately will +// implicitly convert any non-literal constants (i.e. those resolved using gcc) +// to signed integers. See for some +// more information on the underlying issue (though. +const ( + // ProcRoot is PATHRS_PROC_ROOT. + ProcRoot ProcBase = 0xFFFF_FFFE_7072_6F63 // C.PATHRS_PROC_ROOT + // ProcSelf is PATHRS_PROC_SELF. + ProcSelf ProcBase = 0xFFFF_FFFE_091D_5E1F // C.PATHRS_PROC_SELF + // ProcThreadSelf is PATHRS_PROC_THREAD_SELF. + ProcThreadSelf ProcBase = 0xFFFF_FFFE_3EAD_5E1F // C.PATHRS_PROC_THREAD_SELF + + // ProcBaseTypeMask is __PATHRS_PROC_TYPE_MASK. + ProcBaseTypeMask ProcBase = 0xFFFF_FFFF_0000_0000 // C.__PATHRS_PROC_TYPE_MASK + // ProcBaseTypePid is __PATHRS_PROC_TYPE_PID. + ProcBaseTypePid ProcBase = 0x8000_0000_0000_0000 // C.__PATHRS_PROC_TYPE_PID + + // ProcDefaultRootFd is PATHRS_PROC_DEFAULT_ROOTFD. + ProcDefaultRootFd = -int(syscall.EBADF) // C.PATHRS_PROC_DEFAULT_ROOTFD +) + +func assertEqual[T comparable](a, b T, msg string) { + if a != b { + panic(fmt.Sprintf("%s ((%T) %#v != (%T) %#v)", msg, a, a, b, b)) + } +} + +// Verify that the values above match the actual C values. Unfortunately, Go +// only allows us to forcefully cast int64 to uint64 if you use a temporary +// variable, which means we cannot do it in a const context and thus need to do +// it at runtime (even though it is a check that fundamentally could be done at +// compile-time)... +func init() { + var ( + actualProcRoot int64 = C.PATHRS_PROC_ROOT + actualProcSelf int64 = C.PATHRS_PROC_SELF + actualProcThreadSelf int64 = C.PATHRS_PROC_THREAD_SELF + ) + + assertEqual(ProcRoot, ProcBase(actualProcRoot), "PATHRS_PROC_ROOT") + assertEqual(ProcSelf, ProcBase(actualProcSelf), "PATHRS_PROC_SELF") + assertEqual(ProcThreadSelf, ProcBase(actualProcThreadSelf), "PATHRS_PROC_THREAD_SELF") + + var ( + actualProcBaseTypeMask uint64 = C.__PATHRS_PROC_TYPE_MASK + actualProcBaseTypePid uint64 = C.__PATHRS_PROC_TYPE_PID + ) + + assertEqual(ProcBaseTypeMask, ProcBase(actualProcBaseTypeMask), "__PATHRS_PROC_TYPE_MASK") + assertEqual(ProcBaseTypePid, ProcBase(actualProcBaseTypePid), "__PATHRS_PROC_TYPE_PID") + + assertEqual(ProcDefaultRootFd, int(C.PATHRS_PROC_DEFAULT_ROOTFD), "PATHRS_PROC_DEFAULT_ROOTFD") +} + +// ProcPid reimplements the PROC_PID(x) conversion. +func ProcPid(pid uint32) ProcBase { return ProcBaseTypePid | ProcBase(pid) } + +// ProcOpenat wraps pathrs_proc_openat. +func ProcOpenat(procRootFd int, base ProcBase, path string, flags int) (uintptr, error) { + cBase := C.pathrs_proc_base_t(base) + + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + fd := C.pathrs_proc_openat(C.int(procRootFd), cBase, cPath, C.int(flags)) + return uintptr(fd), fetchError(fd) +} + +// ProcReadlinkat wraps pathrs_proc_readlinkat. +func ProcReadlinkat(procRootFd int, base ProcBase, path string) (string, error) { + // TODO: See if we can unify this code with InRootReadlink. + + cBase := C.pathrs_proc_base_t(base) + + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + size := 128 + for { + linkBuf := make([]byte, size) + n := C.pathrs_proc_readlinkat( + C.int(procRootFd), cBase, cPath, + C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf))) + switch { + case int(n) < C.__PATHRS_MAX_ERR_VALUE: + return "", fetchError(n) + case int(n) <= len(linkBuf): + return string(linkBuf[:int(n)]), nil + default: + // The contents were truncated. Unlike readlinkat, pathrs returns + // the size of the link when it checked. So use the returned size + // as a basis for the reallocated size (but in order to avoid a DoS + // where a magic-link is growing by a single byte each iteration, + // make sure we are a fair bit larger). + size += int(n) + } + } +} + +// ProcfsOpenHow is pathrs_procfs_open_how (struct). +type ProcfsOpenHow C.pathrs_procfs_open_how + +const ( + // ProcfsNewUnmasked is PATHRS_PROCFS_NEW_UNMASKED. + ProcfsNewUnmasked = C.PATHRS_PROCFS_NEW_UNMASKED +) + +// Flags returns a pointer to the internal flags field to allow other packages +// to modify structure fields that are internal due to Go's visibility model. +func (how *ProcfsOpenHow) Flags() *C.uint64_t { return &how.flags } + +// ProcfsOpen is pathrs_procfs_open (sizeof(*how) is passed automatically). +func ProcfsOpen(how *ProcfsOpenHow) (uintptr, error) { + fd := C.pathrs_procfs_open((*C.pathrs_procfs_open_how)(how), C.size_t(unsafe.Sizeof(*how))) + return uintptr(fd), fetchError(fd) +} diff --git a/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go b/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go new file mode 100644 index 0000000000..5533c427cb --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go @@ -0,0 +1,246 @@ +//go:build linux + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +// Package procfs provides a safe API for operating on /proc on Linux. +package procfs + +import ( + "os" + "runtime" + + "cyphar.com/go-pathrs/internal/fdutils" + "cyphar.com/go-pathrs/internal/libpathrs" +) + +// ProcBase is used with [ProcReadlink] and related functions to indicate what +// /proc subpath path operations should be done relative to. +type ProcBase struct { + inner libpathrs.ProcBase +} + +var ( + // ProcRoot indicates to use /proc. Note that this mode may be more + // expensive because we have to take steps to try to avoid leaking unmasked + // procfs handles, so you should use [ProcBaseSelf] if you can. + ProcRoot = ProcBase{inner: libpathrs.ProcRoot} + // ProcSelf indicates to use /proc/self. For most programs, this is the + // standard choice. + ProcSelf = ProcBase{inner: libpathrs.ProcSelf} + // ProcThreadSelf indicates to use /proc/thread-self. In multi-threaded + // programs where one thread has a different CLONE_FS, it is possible for + // /proc/self to point the wrong thread and so /proc/thread-self may be + // necessary. + ProcThreadSelf = ProcBase{inner: libpathrs.ProcThreadSelf} +) + +// ProcPid returns a ProcBase which indicates to use /proc/$pid for the given +// PID (or TID). Be aware that due to PID recycling, using this is generally +// not safe except in certain circumstances. Namely: +// +// - PID 1 (the init process), as that PID cannot ever get recycled. +// - Your current PID (though you should just use [ProcBaseSelf]). +// - Your current TID if you have used [runtime.LockOSThread] (though you +// should just use [ProcBaseThreadSelf]). +// - PIDs of child processes (as long as you are sure that no other part of +// your program incorrectly catches or ignores SIGCHLD, and that you do it +// *before* you call wait(2)or any equivalent method that could reap +// zombies). +func ProcPid(pid int) ProcBase { + if pid < 0 || pid >= 1<<31 { + panic("invalid ProcBasePid value") // TODO: should this be an error? + } + return ProcBase{inner: libpathrs.ProcPid(uint32(pid))} +} + +// ThreadCloser is a callback that needs to be called when you are done +// operating on an [os.File] fetched using [Handle.OpenThreadSelf]. +// +// [os.File]: https://pkg.go.dev/os#File +type ThreadCloser func() + +// Handle is a wrapper around an *os.File handle to "/proc", which can be +// used to do further procfs-related operations in a safe way. +type Handle struct { + inner *os.File +} + +// Close releases all internal resources for this [Handle]. +// +// Note that if the handle is actually the global cached handle, this operation +// is a no-op. +func (proc *Handle) Close() error { + var err error + if proc.inner != nil { + err = proc.inner.Close() + } + return err +} + +// OpenOption is a configuration function passed as an argument to [Open]. +type OpenOption func(*libpathrs.ProcfsOpenHow) error + +// UnmaskedProcRoot can be passed to [Open] to request an unmasked procfs +// handle be created. +// +// procfs, err := procfs.OpenRoot(procfs.UnmaskedProcRoot) +func UnmaskedProcRoot(how *libpathrs.ProcfsOpenHow) error { + *how.Flags() |= libpathrs.ProcfsNewUnmasked + return nil +} + +// Open creates a new [Handle] to a safe "/proc", based on the passed +// configuration options (in the form of a series of [OpenOption]s). +func Open(opts ...OpenOption) (*Handle, error) { + var how libpathrs.ProcfsOpenHow + for _, opt := range opts { + if err := opt(&how); err != nil { + return nil, err + } + } + fd, err := libpathrs.ProcfsOpen(&how) + if err != nil { + return nil, err + } + var procFile *os.File + if int(fd) >= 0 { + procFile = os.NewFile(fd, "/proc") + } + // TODO: Check that fd == PATHRS_PROC_DEFAULT_ROOTFD in the <0 case? + return &Handle{inner: procFile}, nil +} + +// TODO: Switch to something fdutils.WithFileFd-like. +func (proc *Handle) fd() int { + if proc.inner != nil { + return int(proc.inner.Fd()) + } + return libpathrs.ProcDefaultRootFd +} + +// TODO: Should we expose open? +func (proc *Handle) open(base ProcBase, path string, flags int) (_ *os.File, Closer ThreadCloser, Err error) { + var closer ThreadCloser + if base == ProcThreadSelf { + runtime.LockOSThread() + closer = runtime.UnlockOSThread + } + defer func() { + if closer != nil && Err != nil { + closer() + Closer = nil + } + }() + + fd, err := libpathrs.ProcOpenat(proc.fd(), base.inner, path, flags) + if err != nil { + return nil, nil, err + } + file, err := fdutils.MkFile(fd) + return file, closer, err +} + +// OpenRoot safely opens a given path from inside /proc/. +// +// This function must only be used for accessing global information from procfs +// (such as /proc/cpuinfo) or information about other processes (such as +// /proc/1). Accessing your own process information should be done using +// [Handle.OpenSelf] or [Handle.OpenThreadSelf]. +func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) { + file, closer, err := proc.open(ProcRoot, path, flags) + if closer != nil { + // should not happen + panic("non-zero closer returned from procOpen(ProcRoot)") + } + return file, err +} + +// OpenSelf safely opens a given path from inside /proc/self/. +// +// This method is recommend for getting process information about the current +// process for almost all Go processes *except* for cases where there are +// [runtime.LockOSThread] threads that have changed some aspect of their state +// (such as through unshare(CLONE_FS) or changing namespaces). +// +// For such non-heterogeneous processes, /proc/self may reference to a task +// that has different state from the current goroutine and so it may be +// preferable to use [Handle.OpenThreadSelf]. The same is true if a user +// really wants to inspect the current OS thread's information (such as +// /proc/thread-self/stack or /proc/thread-self/status which is always uniquely +// per-thread). +// +// Unlike [Handle.OpenThreadSelf], this method does not involve locking +// the goroutine to the current OS thread and so is simpler to use and +// theoretically has slightly less overhead. +// +// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread +func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) { + file, closer, err := proc.open(ProcSelf, path, flags) + if closer != nil { + // should not happen + panic("non-zero closer returned from procOpen(ProcSelf)") + } + return file, err +} + +// OpenPid safely opens a given path from inside /proc/$pid/, where pid can be +// either a PID or TID. +// +// This is effectively equivalent to calling [Handle.OpenRoot] with the +// pid prefixed to the subpath. +// +// Be aware that due to PID recycling, using this is generally not safe except +// in certain circumstances. See the documentation of [ProcPid] for more +// details. +func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) { + file, closer, err := proc.open(ProcPid(pid), path, flags) + if closer != nil { + // should not happen + panic("non-zero closer returned from procOpen(ProcPidOpen)") + } + return file, err +} + +// OpenThreadSelf safely opens a given path from inside /proc/thread-self/. +// +// Most Go processes have heterogeneous threads (all threads have most of the +// same kernel state such as CLONE_FS) and so [Handle.OpenSelf] is +// preferable for most users. +// +// For non-heterogeneous threads, or users that actually want thread-specific +// information (such as /proc/thread-self/stack or /proc/thread-self/status), +// this method is necessary. +// +// Because Go can change the running OS thread of your goroutine without notice +// (and then subsequently kill the old thread), this method will lock the +// current goroutine to the OS thread (with [runtime.LockOSThread]) and the +// caller is responsible for unlocking the the OS thread with the +// [ThreadCloser] callback once they are done using the returned file. This +// callback MUST be called AFTER you have finished using the returned +// [os.File]. This callback is completely separate to [os.File.Close], so it +// must be called regardless of how you close the handle. +// +// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread +// [os.File]: https://pkg.go.dev/os#File +// [os.File.Close]: https://pkg.go.dev/os#File.Close +func (proc *Handle) OpenThreadSelf(path string, flags int) (*os.File, ThreadCloser, error) { + return proc.open(ProcThreadSelf, path, flags) +} + +// Readlink safely reads the contents of a symlink from the given procfs base. +// +// This is effectively equivalent to doing an Open*(O_PATH|O_NOFOLLOW) of the +// path and then doing unix.Readlinkat(fd, ""), but with the benefit that +// thread locking is not necessary for [ProcThreadSelf]. +func (proc *Handle) Readlink(base ProcBase, path string) (string, error) { + return libpathrs.ProcReadlinkat(proc.fd(), base.inner, path) +} diff --git a/vendor/cyphar.com/go-pathrs/root_linux.go b/vendor/cyphar.com/go-pathrs/root_linux.go new file mode 100644 index 0000000000..edc9e4c87f --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/root_linux.go @@ -0,0 +1,367 @@ +//go:build linux + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package pathrs + +import ( + "errors" + "fmt" + "os" + "syscall" + + "cyphar.com/go-pathrs/internal/fdutils" + "cyphar.com/go-pathrs/internal/libpathrs" +) + +// Root is a handle to the root of a directory tree to resolve within. The only +// purpose of this "root handle" is to perform operations within the directory +// tree, or to get a [Handle] to inodes within the directory tree. +// +// At time of writing, it is considered a *VERY BAD IDEA* to open a [Root] +// inside a possibly-attacker-controlled directory tree. While we do have +// protections that should defend against it, it's far more dangerous than just +// opening a directory tree which is not inside a potentially-untrusted +// directory. +type Root struct { + inner *os.File +} + +// OpenRoot creates a new [Root] handle to the directory at the given path. +func OpenRoot(path string) (*Root, error) { + fd, err := libpathrs.OpenRoot(path) + if err != nil { + return nil, err + } + file, err := fdutils.MkFile(fd) + if err != nil { + return nil, err + } + return &Root{inner: file}, nil +} + +// RootFromFile creates a new [Root] handle from an [os.File] referencing a +// directory. The provided file will be duplicated, so the original file should +// still be closed by the caller. +// +// This is effectively the inverse operation of [Root.IntoFile]. +// +// [os.File]: https://pkg.go.dev/os#File +func RootFromFile(file *os.File) (*Root, error) { + newFile, err := fdutils.DupFile(file) + if err != nil { + return nil, fmt.Errorf("duplicate root fd: %w", err) + } + return &Root{inner: newFile}, nil +} + +// Resolve resolves the given path within the [Root]'s directory tree, and +// returns a [Handle] to the resolved path. The path must already exist, +// otherwise an error will occur. +// +// All symlinks (including trailing symlinks) are followed, but they are +// resolved within the rootfs. If you wish to open a handle to the symlink +// itself, use [ResolveNoFollow]. +func (r *Root) Resolve(path string) (*Handle, error) { + return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { + handleFd, err := libpathrs.InRootResolve(rootFd, path) + if err != nil { + return nil, err + } + handleFile, err := fdutils.MkFile(handleFd) + if err != nil { + return nil, err + } + return &Handle{inner: handleFile}, nil + }) +} + +// ResolveNoFollow is effectively an O_NOFOLLOW version of [Resolve]. Their +// behaviour is identical, except that *trailing* symlinks will not be +// followed. If the final component is a trailing symlink, an O_PATH|O_NOFOLLOW +// handle to the symlink itself is returned. +func (r *Root) ResolveNoFollow(path string) (*Handle, error) { + return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { + handleFd, err := libpathrs.InRootResolveNoFollow(rootFd, path) + if err != nil { + return nil, err + } + handleFile, err := fdutils.MkFile(handleFd) + if err != nil { + return nil, err + } + return &Handle{inner: handleFile}, nil + }) +} + +// Open is effectively shorthand for [Resolve] followed by [Handle.Open], but +// can be slightly more efficient (it reduces CGo overhead and the number of +// syscalls used when using the openat2-based resolver) and is arguably more +// ergonomic to use. +// +// This is effectively equivalent to [os.Open]. +// +// [os.Open]: https://pkg.go.dev/os#Open +func (r *Root) Open(path string) (*os.File, error) { + return r.OpenFile(path, os.O_RDONLY) +} + +// OpenFile is effectively shorthand for [Resolve] followed by +// [Handle.OpenFile], but can be slightly more efficient (it reduces CGo +// overhead and the number of syscalls used when using the openat2-based +// resolver) and is arguably more ergonomic to use. +// +// However, if flags contains os.O_NOFOLLOW and the path is a symlink, then +// OpenFile's behaviour will match that of openat2. In most cases an error will +// be returned, but if os.O_PATH is provided along with os.O_NOFOLLOW then a +// file equivalent to [ResolveNoFollow] will be returned instead. +// +// This is effectively equivalent to [os.OpenFile], except that os.O_CREAT is +// not supported. +// +// [os.OpenFile]: https://pkg.go.dev/os#OpenFile +func (r *Root) OpenFile(path string, flags int) (*os.File, error) { + return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) { + fd, err := libpathrs.InRootOpen(rootFd, path, flags) + if err != nil { + return nil, err + } + return fdutils.MkFile(fd) + }) +} + +// Create creates a file within the [Root]'s directory tree at the given path, +// and returns a handle to the file. The provided mode is used for the new file +// (the process's umask applies). +// +// Unlike [os.Create], if the file already exists an error is created rather +// than the file being opened and truncated. +// +// [os.Create]: https://pkg.go.dev/os#Create +func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error) { + unixMode, err := toUnixMode(mode, false) + if err != nil { + return nil, err + } + return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) { + handleFd, err := libpathrs.InRootCreat(rootFd, path, flags, unixMode) + if err != nil { + return nil, err + } + return fdutils.MkFile(handleFd) + }) +} + +// Rename two paths within a [Root]'s directory tree. The flags argument is +// identical to the RENAME_* flags to the renameat2(2) system call. +func (r *Root) Rename(src, dst string, flags uint) error { + _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootRename(rootFd, src, dst, flags) + return struct{}{}, err + }) + return err +} + +// RemoveDir removes the named empty directory within a [Root]'s directory +// tree. +func (r *Root) RemoveDir(path string) error { + _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootRmdir(rootFd, path) + return struct{}{}, err + }) + return err +} + +// RemoveFile removes the named file within a [Root]'s directory tree. +func (r *Root) RemoveFile(path string) error { + _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootUnlink(rootFd, path) + return struct{}{}, err + }) + return err +} + +// Remove removes the named file or (empty) directory within a [Root]'s +// directory tree. +// +// This is effectively equivalent to [os.Remove]. +// +// [os.Remove]: https://pkg.go.dev/os#Remove +func (r *Root) Remove(path string) error { + // In order to match os.Remove's implementation we need to also do both + // syscalls unconditionally and adjust the error based on whether + // pathrs_inroot_rmdir() returned ENOTDIR. + unlinkErr := r.RemoveFile(path) + if unlinkErr == nil { + return nil + } + rmdirErr := r.RemoveDir(path) + if rmdirErr == nil { + return nil + } + // Both failed, adjust the error in the same way that os.Remove does. + err := rmdirErr + if errors.Is(err, syscall.ENOTDIR) { + err = unlinkErr + } + return err +} + +// RemoveAll recursively deletes a path and all of its children. +// +// This is effectively equivalent to [os.RemoveAll]. +// +// [os.RemoveAll]: https://pkg.go.dev/os#RemoveAll +func (r *Root) RemoveAll(path string) error { + _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootRemoveAll(rootFd, path) + return struct{}{}, err + }) + return err +} + +// Mkdir creates a directory within a [Root]'s directory tree. The provided +// mode is used for the new directory (the process's umask applies). +// +// This is effectively equivalent to [os.Mkdir]. +// +// [os.Mkdir]: https://pkg.go.dev/os#Mkdir +func (r *Root) Mkdir(path string, mode os.FileMode) error { + unixMode, err := toUnixMode(mode, false) + if err != nil { + return err + } + + _, err = fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootMkdir(rootFd, path, unixMode) + return struct{}{}, err + }) + return err +} + +// MkdirAll creates a directory (and any parent path components if they don't +// exist) within a [Root]'s directory tree. The provided mode is used for any +// directories created by this function (the process's umask applies). +// +// This is effectively equivalent to [os.MkdirAll]. +// +// [os.MkdirAll]: https://pkg.go.dev/os#MkdirAll +func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) { + unixMode, err := toUnixMode(mode, false) + if err != nil { + return nil, err + } + + return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { + handleFd, err := libpathrs.InRootMkdirAll(rootFd, path, unixMode) + if err != nil { + return nil, err + } + handleFile, err := fdutils.MkFile(handleFd) + if err != nil { + return nil, err + } + return &Handle{inner: handleFile}, err + }) +} + +// Mknod creates a new device inode of the given type within a [Root]'s +// directory tree. The provided mode is used for the new directory (the +// process's umask applies). +// +// This is effectively equivalent to [unix.Mknod]. +// +// [unix.Mknod]: https://pkg.go.dev/golang.org/x/sys/unix#Mknod +func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error { + unixMode, err := toUnixMode(mode, true) + if err != nil { + return err + } + + _, err = fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootMknod(rootFd, path, unixMode, dev) + return struct{}{}, err + }) + return err +} + +// Symlink creates a symlink within a [Root]'s directory tree. The symlink is +// created at path and is a link to target. +// +// This is effectively equivalent to [os.Symlink]. +// +// [os.Symlink]: https://pkg.go.dev/os#Symlink +func (r *Root) Symlink(path, target string) error { + _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootSymlink(rootFd, path, target) + return struct{}{}, err + }) + return err +} + +// Hardlink creates a hardlink within a [Root]'s directory tree. The hardlink +// is created at path and is a link to target. Both paths are within the +// [Root]'s directory tree (you cannot hardlink to a different [Root] or the +// host). +// +// This is effectively equivalent to [os.Link]. +// +// [os.Link]: https://pkg.go.dev/os#Link +func (r *Root) Hardlink(path, target string) error { + _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { + err := libpathrs.InRootHardlink(rootFd, path, target) + return struct{}{}, err + }) + return err +} + +// Readlink returns the target of a symlink with a [Root]'s directory tree. +// +// This is effectively equivalent to [os.Readlink]. +// +// [os.Readlink]: https://pkg.go.dev/os#Readlink +func (r *Root) Readlink(path string) (string, error) { + return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) { + return libpathrs.InRootReadlink(rootFd, path) + }) +} + +// IntoFile unwraps the [Root] into its underlying [os.File]. +// +// It is critical that you do not operate on this file descriptor yourself, +// because the security properties of libpathrs depend on users doing all +// relevant filesystem operations through libpathrs. +// +// This operation returns the internal [os.File] of the [Root] directly, so +// calling [Root.Close] will also close any copies of the returned [os.File]. +// If you want to get an independent copy, use [Root.Clone] followed by +// [Root.IntoFile] on the cloned [Root]. +// +// [os.File]: https://pkg.go.dev/os#File +func (r *Root) IntoFile() *os.File { + // TODO: Figure out if we really don't want to make a copy. + // TODO: We almost certainly want to clear r.inner here, but we can't do + // that easily atomically (we could use atomic.Value but that'll make + // things quite a bit uglier). + return r.inner +} + +// Clone creates a copy of a [Root] handle, such that it has a separate +// lifetime to the original (while referring to the same underlying directory). +func (r *Root) Clone() (*Root, error) { + return RootFromFile(r.inner) +} + +// Close frees all of the resources used by the [Root] handle. +func (r *Root) Close() error { + return r.inner.Close() +} diff --git a/vendor/cyphar.com/go-pathrs/utils_linux.go b/vendor/cyphar.com/go-pathrs/utils_linux.go new file mode 100644 index 0000000000..2208d608f8 --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/utils_linux.go @@ -0,0 +1,56 @@ +//go:build linux + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2019-2025 Aleksa Sarai + * Copyright (C) 2019-2025 SUSE LLC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package pathrs + +import ( + "fmt" + "os" + + "golang.org/x/sys/unix" +) + +//nolint:cyclop // this function needs to handle a lot of cases +func toUnixMode(mode os.FileMode, needsType bool) (uint32, error) { + sysMode := uint32(mode.Perm()) + switch mode & os.ModeType { //nolint:exhaustive // we only care about ModeType bits + case 0: + if needsType { + sysMode |= unix.S_IFREG + } + case os.ModeDir: + sysMode |= unix.S_IFDIR + case os.ModeSymlink: + sysMode |= unix.S_IFLNK + case os.ModeCharDevice | os.ModeDevice: + sysMode |= unix.S_IFCHR + case os.ModeDevice: + sysMode |= unix.S_IFBLK + case os.ModeNamedPipe: + sysMode |= unix.S_IFIFO + case os.ModeSocket: + sysMode |= unix.S_IFSOCK + default: + return 0, fmt.Errorf("invalid mode filetype %+o", mode) + } + if mode&os.ModeSetuid != 0 { + sysMode |= unix.S_ISUID + } + if mode&os.ModeSetgid != 0 { + sysMode |= unix.S_ISGID + } + if mode&os.ModeSticky != 0 { + sysMode |= unix.S_ISVTX + } + return sysMode, nil +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml b/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml index e965034ed3..3e8dd99bd7 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml +++ b/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml @@ -9,6 +9,10 @@ version: "2" +run: + build-tags: + - libpathrs + linters: enable: - asasalint diff --git a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md index 3faee0bc55..734cf61e32 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md +++ b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md @@ -4,7 +4,64 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased 0.5.z] ## +## [Unreleased] ## + +## [0.6.0] - 2025-11-03 ## + +> By the Power of Greyskull! + +While quite small code-wise, this release marks a very key point in the +development of filepath-securejoin. + +filepath-securejoin was originally intended (back in 2017) to simply be a +single-purpose library that would take some common code used in container +runtimes (specifically, Docker's `FollowSymlinksInScope`) and make it more +general-purpose (with the eventual goals of it ending up in the Go stdlib). + +Of course, I quickly discovered that this problem was actually far more +complicated to solve when dealing with racing attackers, which lead to me +developing `openat2(2)` and [libpathrs][]. I had originally planned for +libpathrs to completely replace filepath-securejoin "once it was ready" but in +the interim we needed to fix several race attacks in runc as part of security +advisories. Obviously we couldn't require the usage of a pre-0.1 Rust library +in runc so it was necessary to port bits of libpathrs into filepath-securejoin. +(Ironically the first prototypes of libpathrs were originally written in Go and +then rewritten to Rust, so the code in filepath-securejoin is actually Go code +that was rewritten to Rust then re-rewritten to Go.) + +It then became clear that pure-Go libraries will likely not be willing to +require CGo for all of their builds, so it was necessary to accept that +filepath-securejoin will need to stay. As such, in v0.5.0 we provided more +pure-Go implementations of features from libpathrs but moved them into +`pathrs-lite` subpackage to clarify what purpose these helpers serve. + +This release finally closes the loop and makes it so that pathrs-lite can +transparently use libpathrs (via a `libpathrs` build-tag). This means that +upstream libraries can use the pure Go version if they prefer, but downstreams +(either downstream library users or even downstream distributions) are able to +migrate to libpathrs for all usages of pathrs-lite in an entire Go binary. + +I should make it clear that I do not plan to port the rest of libpathrs to Go, +as I do not wish to maintain two copies of the same codebase. pathrs-lite +already provides the core essentials necessary to operate on paths safely for +most modern systems. Users who want additional hardening or more ergonomic APIs +are free to use [`cyphar.com/go-pathrs`][go-pathrs] (libpathrs's Go bindings). + +[libpathrs]: https://github.com/cyphar/libpathrs +[go-pathrs]: https://cyphar.com/go-pathrs + +### Breaking ### +- The deprecated `MkdirAll`, `MkdirAllHandle`, `OpenInRoot`, `OpenatInRoot` and + `Reopen` wrappers have been removed. Please switch to using `pathrs-lite` + directly. + +### Added ### +- `pathrs-lite` now has support for using [libpathrs][libpathrs] as a backend. + This is opt-in and can be enabled at build time with the `libpathrs` build + tag. The intention is to allow for downstream libraries and other projects to + make use of the pure-Go `github.com/cyphar/filepath-securejoin/pathrs-lite` + package and distributors can then opt-in to using `libpathrs` for the entire + binary if they wish. ## [0.5.1] - 2025-10-31 ## @@ -383,7 +440,8 @@ This is our first release of `github.com/cyphar/filepath-securejoin`, containing a full implementation with a coverage of 93.5% (the only missing cases are the error cases, which are hard to mocktest at the moment). -[Unreleased 0.5.z]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.1...release-0.5 +[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.6.0...HEAD +[0.6.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.1...v0.6.0 [0.5.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.0...v0.5.1 [0.5.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.1...v0.5.0 [0.4.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.0...v0.4.1 diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION index 4b9fcbec10..a918a2aa18 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/VERSION +++ b/vendor/github.com/cyphar/filepath-securejoin/VERSION @@ -1 +1 @@ -0.5.1 +0.6.0 diff --git a/vendor/github.com/cyphar/filepath-securejoin/deprecated_linux.go b/vendor/github.com/cyphar/filepath-securejoin/deprecated_linux.go deleted file mode 100644 index 3e427b1640..0000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/deprecated_linux.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package securejoin - -import ( - "github.com/cyphar/filepath-securejoin/pathrs-lite" -) - -var ( - // MkdirAll is a wrapper around [pathrs.MkdirAll]. - // - // Deprecated: You should use [pathrs.MkdirAll] directly instead. This - // wrapper will be removed in filepath-securejoin v0.6. - MkdirAll = pathrs.MkdirAll - - // MkdirAllHandle is a wrapper around [pathrs.MkdirAllHandle]. - // - // Deprecated: You should use [pathrs.MkdirAllHandle] directly instead. - // This wrapper will be removed in filepath-securejoin v0.6. - MkdirAllHandle = pathrs.MkdirAllHandle - - // OpenInRoot is a wrapper around [pathrs.OpenInRoot]. - // - // Deprecated: You should use [pathrs.OpenInRoot] directly instead. This - // wrapper will be removed in filepath-securejoin v0.6. - OpenInRoot = pathrs.OpenInRoot - - // OpenatInRoot is a wrapper around [pathrs.OpenatInRoot]. - // - // Deprecated: You should use [pathrs.OpenatInRoot] directly instead. This - // wrapper will be removed in filepath-securejoin v0.6. - OpenatInRoot = pathrs.OpenatInRoot - - // Reopen is a wrapper around [pathrs.Reopen]. - // - // Deprecated: You should use [pathrs.Reopen] directly instead. This - // wrapper will be removed in filepath-securejoin v0.6. - Reopen = pathrs.Reopen -) diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md index 1be727e75b..bb95b028c6 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md @@ -5,11 +5,13 @@ Go** implementation of the core bits of [libpathrs][]. This is not intended to be a complete replacement for libpathrs, instead it is mainly intended to be useful as a transition tool for existing Go projects. -The long-term plan for `pathrs-lite` is to provide a build tag that will cause -all `pathrs-lite` operations to call into libpathrs directly, thus removing -code duplication for projects that wish to make use of libpathrs (and providing -the ability for software packagers to opt-in to libpathrs support without -needing to patch upstream). +`pathrs-lite` also provides a very easy way to switch to `libpathrs` (even for +downstreams where `pathrs-lite` is being used in a third-party package and is +not interested in using CGo). At build time, if you use the `libpathrs` build +tag then `pathrs-lite` will use `libpathrs` directly instead of the pure Go +implementation. The two backends are functionally equivalent (and we have +integration tests to verify this), so this migration should be very easy with +no user-visible impact. [libpathrs]: https://github.com/cyphar/libpathrs diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/doc.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/doc.go index d3d7451750..61411da37a 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/doc.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/doc.go @@ -11,4 +11,6 @@ // Package pathrs (pathrs-lite) is a less complete pure Go implementation of // some of the APIs provided by [libpathrs]. +// +// [libpathrs]: https://github.com/cyphar/libpathrs package pathrs diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/doc.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/doc.go new file mode 100644 index 0000000000..2ddb71e844 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/doc.go @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build linux + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// Package gopathrs is a less complete pure Go implementation of some of the +// APIs provided by [libpathrs]. +// +// [libpathrs]: https://github.com/cyphar/libpathrs +package gopathrs diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/lookup_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go similarity index 98% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/lookup_linux.go rename to vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go index f47504e663..56480f0cee 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/lookup_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go @@ -9,7 +9,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -package pathrs +package gopathrs import ( "errors" @@ -166,11 +166,11 @@ func (s *symlinkStack) PopTopSymlink() (*os.File, string, bool) { return tailEntry.dir, tailEntry.remainingPath, true } -// partialLookupInRoot tries to lookup as much of the request path as possible +// PartialLookupInRoot tries to lookup as much of the request path as possible // within the provided root (a-la RESOLVE_IN_ROOT) and opens the final existing // component of the requested path, returning a file handle to the final // existing component and a string containing the remaining path components. -func partialLookupInRoot(root fd.Fd, unsafePath string) (*os.File, string, error) { +func PartialLookupInRoot(root fd.Fd, unsafePath string) (*os.File, string, error) { return lookupInRoot(root, unsafePath, true) } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/mkdir_linux.go similarity index 81% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_linux.go rename to vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/mkdir_linux.go index f3c62b0dac..21a5593f44 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/mkdir_linux.go @@ -9,7 +9,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -package pathrs +package gopathrs import ( "errors" @@ -23,9 +23,12 @@ import ( "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd" "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux" + "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs" ) -var errInvalidMode = errors.New("invalid permission mode") +// ErrInvalidMode is returned from [MkdirAll] when the requested mode is +// invalid. +var ErrInvalidMode = errors.New("invalid permission mode") // modePermExt is like os.ModePerm except that it also includes the set[ug]id // and sticky bits. @@ -45,11 +48,11 @@ func toUnixMode(mode os.FileMode) (uint32, error) { } // We don't allow file type bits. if mode&os.ModeType != 0 { - return 0, fmt.Errorf("%w %+.3o (%s): type bits not permitted", errInvalidMode, mode, mode) + return 0, fmt.Errorf("%w %+.3o (%s): type bits not permitted", ErrInvalidMode, mode, mode) } // We don't allow other unknown modes. if mode&^modePermExt != 0 || sysMode&unix.S_IFMT != 0 { - return 0, fmt.Errorf("%w %+.3o (%s): unknown mode bits", errInvalidMode, mode, mode) + return 0, fmt.Errorf("%w %+.3o (%s): unknown mode bits", ErrInvalidMode, mode, mode) } return sysMode, nil } @@ -84,11 +87,11 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F // users it seems more prudent to return an error so users notice that // these bits will not be set. if unixMode&^0o1777 != 0 { - return nil, fmt.Errorf("%w for mkdir %+.3o: suid and sgid are ignored by mkdir", errInvalidMode, mode) + return nil, fmt.Errorf("%w for mkdir %+.3o: suid and sgid are ignored by mkdir", ErrInvalidMode, mode) } // Try to open as much of the path as possible. - currentDir, remainingPath, err := partialLookupInRoot(root, unsafePath) + currentDir, remainingPath, err := PartialLookupInRoot(root, unsafePath) defer func() { if Err != nil { _ = currentDir.Close() @@ -117,7 +120,7 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F // Re-open the path to match the O_DIRECTORY reopen loop later (so that we // always return a non-O_PATH handle). We also check that we actually got a // directory. - if reopenDir, err := Reopen(currentDir, unix.O_DIRECTORY|unix.O_CLOEXEC); errors.Is(err, unix.ENOTDIR) { + if reopenDir, err := procfs.ReopenFd(currentDir, unix.O_DIRECTORY|unix.O_CLOEXEC); errors.Is(err, unix.ENOTDIR) { return nil, fmt.Errorf("cannot create subdirectories in %q: %w", currentDir.Name(), unix.ENOTDIR) } else if err != nil { return nil, fmt.Errorf("re-opening handle to %q: %w", currentDir.Name(), err) @@ -207,40 +210,3 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F } return currentDir, nil } - -// MkdirAll is a race-safe alternative to the [os.MkdirAll] function, -// where the new directory is guaranteed to be within the root directory (if an -// attacker can move directories from inside the root to outside the root, the -// created directory tree might be outside of the root but the key constraint -// is that at no point will we walk outside of the directory tree we are -// creating). -// -// Effectively, MkdirAll(root, unsafePath, mode) is equivalent to -// -// path, _ := securejoin.SecureJoin(root, unsafePath) -// err := os.MkdirAll(path, mode) -// -// But is much safer. The above implementation is unsafe because if an attacker -// can modify the filesystem tree between [SecureJoin] and [os.MkdirAll], it is -// possible for MkdirAll to resolve unsafe symlink components and create -// directories outside of the root. -// -// If you plan to open the directory after you have created it or want to use -// an open directory handle as the root, you should use [MkdirAllHandle] instead. -// This function is a wrapper around [MkdirAllHandle]. -// -// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin -func MkdirAll(root, unsafePath string, mode os.FileMode) error { - rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) - if err != nil { - return err - } - defer rootDir.Close() //nolint:errcheck // close failures aren't critical here - - f, err := MkdirAllHandle(rootDir, unsafePath, mode) - if err != nil { - return err - } - _ = f.Close() - return nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/open_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/open_linux.go new file mode 100644 index 0000000000..cd9632a958 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/open_linux.go @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build linux + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +package gopathrs + +import ( + "os" +) + +// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided +// using an *[os.File] handle, to ensure that the correct root directory is used. +func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { + handle, err := completeLookupInRoot(root, unsafePath) + if err != nil { + return nil, &os.PathError{Op: "securejoin.OpenInRoot", Path: unsafePath, Err: err} + } + return handle, nil +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go similarity index 99% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/openat2_linux.go rename to vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go index 937bc435f2..b80ecd0895 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/openat2_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go @@ -9,7 +9,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -package pathrs +package gopathrs import ( "errors" diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir.go new file mode 100644 index 0000000000..b43169564a --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir.go @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build linux + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +package pathrs + +import ( + "os" + + "golang.org/x/sys/unix" +) + +// MkdirAll is a race-safe alternative to the [os.MkdirAll] function, +// where the new directory is guaranteed to be within the root directory (if an +// attacker can move directories from inside the root to outside the root, the +// created directory tree might be outside of the root but the key constraint +// is that at no point will we walk outside of the directory tree we are +// creating). +// +// Effectively, MkdirAll(root, unsafePath, mode) is equivalent to +// +// path, _ := securejoin.SecureJoin(root, unsafePath) +// err := os.MkdirAll(path, mode) +// +// But is much safer. The above implementation is unsafe because if an attacker +// can modify the filesystem tree between [SecureJoin] and [os.MkdirAll], it is +// possible for MkdirAll to resolve unsafe symlink components and create +// directories outside of the root. +// +// If you plan to open the directory after you have created it or want to use +// an open directory handle as the root, you should use [MkdirAllHandle] instead. +// This function is a wrapper around [MkdirAllHandle]. +// +// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin +func MkdirAll(root, unsafePath string, mode os.FileMode) error { + rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) + if err != nil { + return err + } + defer rootDir.Close() //nolint:errcheck // close failures aren't critical here + + f, err := MkdirAllHandle(rootDir, unsafePath, mode) + if err != nil { + return err + } + _ = f.Close() + return nil +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_libpathrs.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_libpathrs.go new file mode 100644 index 0000000000..f864dbc8f3 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_libpathrs.go @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build libpathrs + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +package pathrs + +import ( + "os" + + "cyphar.com/go-pathrs" +) + +// MkdirAllHandle is equivalent to [MkdirAll], except that it is safer to use +// in two respects: +// +// - The caller provides the root directory as an *[os.File] (preferably O_PATH) +// handle. This means that the caller can be sure which root directory is +// being used. Note that this can be emulated by using /proc/self/fd/... as +// the root path with [os.MkdirAll]. +// +// - Once all of the directories have been created, an *[os.File] O_PATH handle +// to the directory at unsafePath is returned to the caller. This is done in +// an effectively-race-free way (an attacker would only be able to swap the +// final directory component), which is not possible to emulate with +// [MkdirAll]. +// +// In addition, the returned handle is obtained far more efficiently than doing +// a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after +// doing [MkdirAll]. If you intend to open the directory after creating it, you +// should use MkdirAllHandle. +// +// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin +func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (*os.File, error) { + rootRef, err := pathrs.RootFromFile(root) + if err != nil { + return nil, err + } + defer rootRef.Close() //nolint:errcheck // close failures aren't critical here + + handle, err := rootRef.MkdirAll(unsafePath, mode) + if err != nil { + return nil, err + } + return handle.IntoFile(), nil +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_purego.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_purego.go new file mode 100644 index 0000000000..0369dfe7e6 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_purego.go @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build linux && !libpathrs + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +package pathrs + +import ( + "os" + + "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs" +) + +// MkdirAllHandle is equivalent to [MkdirAll], except that it is safer to use +// in two respects: +// +// - The caller provides the root directory as an *[os.File] (preferably O_PATH) +// handle. This means that the caller can be sure which root directory is +// being used. Note that this can be emulated by using /proc/self/fd/... as +// the root path with [os.MkdirAll]. +// +// - Once all of the directories have been created, an *[os.File] O_PATH handle +// to the directory at unsafePath is returned to the caller. This is done in +// an effectively-race-free way (an attacker would only be able to swap the +// final directory component), which is not possible to emulate with +// [MkdirAll]. +// +// In addition, the returned handle is obtained far more efficiently than doing +// a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after +// doing [MkdirAll]. If you intend to open the directory after creating it, you +// should use MkdirAllHandle. +// +// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin +func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (*os.File, error) { + return gopathrs.MkdirAllHandle(root, unsafePath, mode) +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open.go similarity index 57% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_linux.go rename to vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open.go index 7492d8cfa0..41b628907e 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open.go @@ -15,20 +15,8 @@ import ( "os" "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs" ) -// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided -// using an *[os.File] handle, to ensure that the correct root directory is used. -func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { - handle, err := completeLookupInRoot(root, unsafePath) - if err != nil { - return nil, &os.PathError{Op: "securejoin.OpenInRoot", Path: unsafePath, Err: err} - } - return handle, nil -} - // OpenInRoot safely opens the provided unsafePath within the root. // Effectively, OpenInRoot(root, unsafePath) is equivalent to // @@ -55,20 +43,3 @@ func OpenInRoot(root, unsafePath string) (*os.File, error) { defer rootDir.Close() //nolint:errcheck // close failures aren't critical here return OpenatInRoot(rootDir, unsafePath) } - -// Reopen takes an *[os.File] handle and re-opens it through /proc/self/fd. -// Reopen(file, flags) is effectively equivalent to -// -// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd()) -// os.OpenFile(fdPath, flags|unix.O_CLOEXEC) -// -// But with some extra hardenings to ensure that we are not tricked by a -// maliciously-configured /proc mount. While this attack scenario is not -// common, in container runtimes it is possible for higher-level runtimes to be -// tricked into configuring an unsafe /proc that can be used to attack file -// operations. See [CVE-2019-19921] for more details. -// -// [CVE-2019-19921]: https://github.com/advisories/GHSA-fh74-hm69-rqjw -func Reopen(handle *os.File, flags int) (*os.File, error) { - return procfs.ReopenFd(handle, flags) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_libpathrs.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_libpathrs.go new file mode 100644 index 0000000000..53352000e6 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_libpathrs.go @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build libpathrs + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +package pathrs + +import ( + "os" + + "cyphar.com/go-pathrs" +) + +// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided +// using an *[os.File] handle, to ensure that the correct root directory is used. +func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { + rootRef, err := pathrs.RootFromFile(root) + if err != nil { + return nil, err + } + defer rootRef.Close() //nolint:errcheck // close failures aren't critical here + + handle, err := rootRef.Resolve(unsafePath) + if err != nil { + return nil, err + } + return handle.IntoFile(), nil +} + +// Reopen takes an *[os.File] handle and re-opens it through /proc/self/fd. +// Reopen(file, flags) is effectively equivalent to +// +// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd()) +// os.OpenFile(fdPath, flags|unix.O_CLOEXEC) +// +// But with some extra hardenings to ensure that we are not tricked by a +// maliciously-configured /proc mount. While this attack scenario is not +// common, in container runtimes it is possible for higher-level runtimes to be +// tricked into configuring an unsafe /proc that can be used to attack file +// operations. See [CVE-2019-19921] for more details. +// +// [CVE-2019-19921]: https://github.com/advisories/GHSA-fh74-hm69-rqjw +func Reopen(file *os.File, flags int) (*os.File, error) { + handle, err := pathrs.HandleFromFile(file) + if err != nil { + return nil, err + } + defer handle.Close() //nolint:errcheck // close failures aren't critical here + + return handle.OpenFile(flags) +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_purego.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_purego.go new file mode 100644 index 0000000000..6d1be12ce5 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_purego.go @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build linux && !libpathrs + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +package pathrs + +import ( + "os" + + "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs" + "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs" +) + +// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided +// using an *[os.File] handle, to ensure that the correct root directory is used. +func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { + return gopathrs.OpenatInRoot(root, unsafePath) +} + +// Reopen takes an *[os.File] handle and re-opens it through /proc/self/fd. +// Reopen(file, flags) is effectively equivalent to +// +// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd()) +// os.OpenFile(fdPath, flags|unix.O_CLOEXEC) +// +// But with some extra hardenings to ensure that we are not tricked by a +// maliciously-configured /proc mount. While this attack scenario is not +// common, in container runtimes it is possible for higher-level runtimes to be +// tricked into configuring an unsafe /proc that can be used to attack file +// operations. See [CVE-2019-19921] for more details. +// +// [CVE-2019-19921]: https://github.com/advisories/GHSA-fh74-hm69-rqjw +func Reopen(handle *os.File, flags int) (*os.File, error) { + return procfs.ReopenFd(handle, flags) +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_libpathrs.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_libpathrs.go new file mode 100644 index 0000000000..6c4df3763b --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_libpathrs.go @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MPL-2.0 + +//go:build libpathrs + +// Copyright (C) 2024-2025 Aleksa Sarai +// Copyright (C) 2024-2025 SUSE LLC +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// Package procfs provides a safe API for operating on /proc on Linux. +package procfs + +import ( + "os" + "strconv" + + "cyphar.com/go-pathrs/procfs" + "golang.org/x/sys/unix" +) + +// ProcThreadSelfCloser is a callback that needs to be called when you are done +// operating on an [os.File] fetched using [Handle.OpenThreadSelf]. +// +// [os.File]: https://pkg.go.dev/os#File +type ProcThreadSelfCloser = procfs.ThreadCloser + +// Handle is a wrapper around an *os.File handle to "/proc", which can be used +// to do further procfs-related operations in a safe way. +type Handle struct { + inner *procfs.Handle +} + +// Close close the resources associated with this [Handle]. Note that if this +// [Handle] was created with [OpenProcRoot], on some kernels the underlying +// procfs handle is cached and so this Close operation may be a no-op. However, +// you should always call Close on [Handle]s once you are done with them. +func (proc *Handle) Close() error { return proc.inner.Close() } + +// OpenProcRoot tries to open a "safer" handle to "/proc" (i.e., one with the +// "subset=pid" mount option applied, available from Linux 5.8). Unless you +// plan to do many [Handle.OpenRoot] operations, users should prefer to use +// this over [OpenUnsafeProcRoot] which is far more dangerous to keep open. +// +// If a safe handle cannot be opened, OpenProcRoot will fall back to opening a +// regular "/proc" handle. +// +// Note that using [Handle.OpenRoot] will still work with handles returned by +// this function. If a subpath cannot be operated on with a safe "/proc" +// handle, then [OpenUnsafeProcRoot] will be called internally and a temporary +// unsafe handle will be used. +func OpenProcRoot() (*Handle, error) { + proc, err := procfs.Open() + if err != nil { + return nil, err + } + return &Handle{inner: proc}, nil +} + +// OpenUnsafeProcRoot opens a handle to "/proc" without any overmounts or +// masked paths. You must be extremely careful to make sure this handle is +// never leaked to a container and that you program cannot be tricked into +// writing to arbitrary paths within it. +// +// This is not necessary if you just wish to use [Handle.OpenRoot], as handles +// returned by [OpenProcRoot] will fall back to using a *temporary* unsafe +// handle in that case. You should only really use this if you need to do many +// operations with [Handle.OpenRoot] and the performance overhead of making +// many procfs handles is an issue. If you do use OpenUnsafeProcRoot, you +// should make sure to close the handle as soon as possible to avoid +// known-fd-number attacks. +func OpenUnsafeProcRoot() (*Handle, error) { + proc, err := procfs.Open(procfs.UnmaskedProcRoot) + if err != nil { + return nil, err + } + return &Handle{inner: proc}, nil +} + +// OpenThreadSelf returns a handle to "/proc/thread-self/" (or an +// equivalent handle on older kernels where "/proc/thread-self" doesn't exist). +// Once finished with the handle, you must call the returned closer function +// ([runtime.UnlockOSThread]). You must not pass the returned *os.File to other +// Go threads or use the handle after calling the closer. +// +// [runtime.UnlockOSThread]: https://pkg.go.dev/runtime#UnlockOSThread +func (proc *Handle) OpenThreadSelf(subpath string) (*os.File, ProcThreadSelfCloser, error) { + return proc.inner.OpenThreadSelf(subpath, unix.O_PATH|unix.O_NOFOLLOW) +} + +// OpenSelf returns a handle to /proc/self/. +// +// Note that in Go programs with non-homogenous threads, this may result in +// spurious errors. If you are monkeying around with APIs that are +// thread-specific, you probably want to use [Handle.OpenThreadSelf] instead +// which will guarantee that the handle refers to the same thread as the caller +// is executing on. +func (proc *Handle) OpenSelf(subpath string) (*os.File, error) { + return proc.inner.OpenSelf(subpath, unix.O_PATH|unix.O_NOFOLLOW) +} + +// OpenRoot returns a handle to /proc/. +// +// You should only use this when you need to operate on global procfs files +// (such as sysctls in /proc/sys). Unlike [Handle.OpenThreadSelf], +// [Handle.OpenSelf], and [Handle.OpenPid], the procfs handle used internally +// for this operation will never use "subset=pid", which makes it a more juicy +// target for [CVE-2024-21626]-style attacks (and doing something like opening +// a directory with OpenRoot effectively leaks [OpenUnsafeProcRoot] as long as +// the file descriptor is open). +// +// [CVE-2024-21626]: https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv +func (proc *Handle) OpenRoot(subpath string) (*os.File, error) { + return proc.inner.OpenRoot(subpath, unix.O_PATH|unix.O_NOFOLLOW) +} + +// OpenPid returns a handle to /proc/$pid/ (pid can be a pid or tid). +// This is mainly intended for usage when operating on other processes. +// +// You should not use this for the current thread, as special handling is +// needed for /proc/thread-self (or /proc/self/task/) when dealing with +// goroutine scheduling -- use [Handle.OpenThreadSelf] instead. +// +// To refer to the current thread-group, you should use prefer +// [Handle.OpenSelf] to passing os.Getpid as the pid argument. +func (proc *Handle) OpenPid(pid int, subpath string) (*os.File, error) { + return proc.inner.OpenPid(pid, subpath, unix.O_PATH|unix.O_NOFOLLOW) +} + +// ProcSelfFdReadlink gets the real path of the given file by looking at +// /proc/self/fd/ with [readlink]. It is effectively just shorthand for +// something along the lines of: +// +// proc, err := procfs.OpenProcRoot() +// if err != nil { +// return err +// } +// link, err := proc.OpenThreadSelf(fmt.Sprintf("fd/%d", f.Fd())) +// if err != nil { +// return err +// } +// defer link.Close() +// var buf [4096]byte +// n, err := unix.Readlinkat(int(link.Fd()), "", buf[:]) +// if err != nil { +// return err +// } +// pathname := buf[:n] +// +// [readlink]: https://pkg.go.dev/golang.org/x/sys/unix#Readlinkat +func ProcSelfFdReadlink(f *os.File) (string, error) { + proc, err := procfs.Open() + if err != nil { + return "", err + } + defer proc.Close() //nolint:errcheck // close failures aren't critical here + + fdPath := "fd/" + strconv.Itoa(int(f.Fd())) + return proc.Readlink(procfs.ProcThreadSelf, fdPath) +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_purego.go similarity index 99% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_linux.go rename to vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_purego.go index ec187a414c..9383002f9a 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_purego.go @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -//go:build linux +//go:build linux && !libpathrs // Copyright (C) 2024-2025 Aleksa Sarai // Copyright (C) 2024-2025 SUSE LLC diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go index 1258c98ce7..95f29e21f4 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -18,7 +18,7 @@ var validOptions = map[string]bool{ "level": true, } -var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be used together") +var ErrIncompatibleLabel = errors.New("bad SELinux option: z and Z can not be used together") // InitLabels returns the process label and file labels to be used within // the container. A list of options can be passed into this function to alter @@ -52,11 +52,11 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { return "", selinux.PrivContainerMountLabel(), nil } if i := strings.Index(opt, ":"); i == -1 { - return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) + return "", "", fmt.Errorf("bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) } con := strings.SplitN(opt, ":", 2) if !validOptions[con[0]] { - return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0]) + return "", "", fmt.Errorf("bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0]) } if con[0] == "filetype" { mcon["type"] = con[1] diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index 9f0740ef6f..15150d4752 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -153,7 +153,7 @@ func CalculateGlbLub(sourceRange, targetRange string) (string, error) { // of the program is finished to guarantee another goroutine does not migrate to the current // thread before execution is complete. func SetExecLabel(label string) error { - return writeCon(attrPath("exec"), label) + return writeConThreadSelf("attr/exec", label) } // SetTaskLabel sets the SELinux label for the current thread, or an error. @@ -161,7 +161,7 @@ func SetExecLabel(label string) error { // be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() to guarantee // the current thread does not run in a new mislabeled thread. func SetTaskLabel(label string) error { - return writeCon(attrPath("current"), label) + return writeConThreadSelf("attr/current", label) } // SetSocketLabel takes a process label and tells the kernel to assign the @@ -170,12 +170,12 @@ func SetTaskLabel(label string) error { // the socket is created to guarantee another goroutine does not migrate // to the current thread before execution is complete. func SetSocketLabel(label string) error { - return writeCon(attrPath("sockcreate"), label) + return writeConThreadSelf("attr/sockcreate", label) } // SocketLabel retrieves the current socket label setting func SocketLabel() (string, error) { - return readCon(attrPath("sockcreate")) + return readConThreadSelf("attr/sockcreate") } // PeerLabel retrieves the label of the client on the other side of a socket @@ -198,7 +198,7 @@ func SetKeyLabel(label string) error { // KeyLabel retrieves the current kernel keyring label setting func KeyLabel() (string, error) { - return readCon("/proc/self/attr/keycreate") + return keyLabel() } // Get returns the Context as a string diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index a607980724..6d7f8e270b 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -17,8 +17,11 @@ import ( "strings" "sync" - "github.com/opencontainers/selinux/pkg/pwalkdir" + "github.com/cyphar/filepath-securejoin/pathrs-lite" + "github.com/cyphar/filepath-securejoin/pathrs-lite/procfs" "golang.org/x/sys/unix" + + "github.com/opencontainers/selinux/pkg/pwalkdir" ) const ( @@ -73,10 +76,6 @@ var ( mcsList: make(map[string]bool), } - // for attrPath() - attrPathOnce sync.Once - haveThreadSelf bool - // for policyRoot() policyRootOnce sync.Once policyRootVal string @@ -256,48 +255,183 @@ func readConfig(target string) string { return "" } -func isProcHandle(fh *os.File) error { - var buf unix.Statfs_t +func readConFd(in *os.File) (string, error) { + data, err := io.ReadAll(in) + if err != nil { + return "", err + } + return string(bytes.TrimSuffix(data, []byte{0})), nil +} - for { - err := unix.Fstatfs(int(fh.Fd()), &buf) - if err == nil { - break - } - if err != unix.EINTR { - return &os.PathError{Op: "fstatfs", Path: fh.Name(), Err: err} - } +func writeConFd(out *os.File, val string) error { + var err error + if val != "" { + _, err = out.Write([]byte(val)) + } else { + _, err = out.Write(nil) } - if buf.Type != unix.PROC_SUPER_MAGIC { - return fmt.Errorf("file %q is not on procfs", fh.Name()) + return err +} + +// openProcThreadSelf is a small wrapper around [procfs.Handle.OpenThreadSelf] +// and [pathrs.Reopen] to make "one-shot opens" slightly more ergonomic. The +// provided mode must be os.O_* flags to indicate what mode the returned file +// should be opened with (flags like os.O_CREAT and os.O_EXCL are not +// supported). +// +// If no error occurred, the returned handle is guaranteed to be exactly +// /proc/thread-self/ with no tricky mounts or symlinks causing you to +// operate on an unexpected path (with some caveats on pre-openat2 or +// pre-fsopen kernels). +func openProcThreadSelf(subpath string, mode int) (*os.File, procfs.ProcThreadSelfCloser, error) { + if subpath == "" { + return nil, nil, ErrEmptyPath } - return nil -} + proc, err := procfs.OpenProcRoot() + if err != nil { + return nil, nil, err + } + defer proc.Close() -func readCon(fpath string) (string, error) { - if fpath == "" { - return "", ErrEmptyPath + handle, closer, err := proc.OpenThreadSelf(subpath) + if err != nil { + return nil, nil, fmt.Errorf("open /proc/thread-self/%s handle: %w", subpath, err) + } + defer handle.Close() // we will return a re-opened handle + + file, err := pathrs.Reopen(handle, mode) + if err != nil { + closer() + return nil, nil, fmt.Errorf("reopen /proc/thread-self/%s handle (%#x): %w", subpath, mode, err) } + return file, closer, nil +} - in, err := os.Open(fpath) +// Read the contents of /proc/thread-self/. +func readConThreadSelf(fpath string) (string, error) { + in, closer, err := openProcThreadSelf(fpath, os.O_RDONLY|unix.O_CLOEXEC) if err != nil { return "", err } + defer closer() defer in.Close() - if err := isProcHandle(in); err != nil { + return readConFd(in) +} + +// Write to /proc/thread-self/. +func writeConThreadSelf(fpath, val string) error { + if val == "" { + if !getEnabled() { + return nil + } + } + + out, closer, err := openProcThreadSelf(fpath, os.O_WRONLY|unix.O_CLOEXEC) + if err != nil { + return err + } + defer closer() + defer out.Close() + + return writeConFd(out, val) +} + +// openProcSelf is a small wrapper around [procfs.Handle.OpenSelf] and +// [pathrs.Reopen] to make "one-shot opens" slightly more ergonomic. The +// provided mode must be os.O_* flags to indicate what mode the returned file +// should be opened with (flags like os.O_CREAT and os.O_EXCL are not +// supported). +// +// If no error occurred, the returned handle is guaranteed to be exactly +// /proc/self/ with no tricky mounts or symlinks causing you to +// operate on an unexpected path (with some caveats on pre-openat2 or +// pre-fsopen kernels). +func openProcSelf(subpath string, mode int) (*os.File, error) { + if subpath == "" { + return nil, ErrEmptyPath + } + + proc, err := procfs.OpenProcRoot() + if err != nil { + return nil, err + } + defer proc.Close() + + handle, err := proc.OpenSelf(subpath) + if err != nil { + return nil, fmt.Errorf("open /proc/self/%s handle: %w", subpath, err) + } + defer handle.Close() // we will return a re-opened handle + + file, err := pathrs.Reopen(handle, mode) + if err != nil { + return nil, fmt.Errorf("reopen /proc/self/%s handle (%#x): %w", subpath, mode, err) + } + return file, nil +} + +// Read the contents of /proc/self/. +func readConSelf(fpath string) (string, error) { + in, err := openProcSelf(fpath, os.O_RDONLY|unix.O_CLOEXEC) + if err != nil { return "", err } + defer in.Close() + return readConFd(in) } -func readConFd(in *os.File) (string, error) { - data, err := io.ReadAll(in) +// Write to /proc/self/. +func writeConSelf(fpath, val string) error { + if val == "" { + if !getEnabled() { + return nil + } + } + + out, err := openProcSelf(fpath, os.O_WRONLY|unix.O_CLOEXEC) if err != nil { - return "", err + return err } - return string(bytes.TrimSuffix(data, []byte{0})), nil + defer out.Close() + + return writeConFd(out, val) +} + +// openProcPid is a small wrapper around [procfs.Handle.OpenPid] and +// [pathrs.Reopen] to make "one-shot opens" slightly more ergonomic. The +// provided mode must be os.O_* flags to indicate what mode the returned file +// should be opened with (flags like os.O_CREAT and os.O_EXCL are not +// supported). +// +// If no error occurred, the returned handle is guaranteed to be exactly +// /proc/self/ with no tricky mounts or symlinks causing you to +// operate on an unexpected path (with some caveats on pre-openat2 or +// pre-fsopen kernels). +func openProcPid(pid int, subpath string, mode int) (*os.File, error) { + if subpath == "" { + return nil, ErrEmptyPath + } + + proc, err := procfs.OpenProcRoot() + if err != nil { + return nil, err + } + defer proc.Close() + + handle, err := proc.OpenPid(pid, subpath) + if err != nil { + return nil, fmt.Errorf("open /proc/%d/%s handle: %w", pid, subpath, err) + } + defer handle.Close() // we will return a re-opened handle + + file, err := pathrs.Reopen(handle, mode) + if err != nil { + return nil, fmt.Errorf("reopen /proc/%d/%s handle (%#x): %w", pid, subpath, mode, err) + } + return file, nil } // classIndex returns the int index for an object class in the loaded policy, @@ -393,78 +527,34 @@ func lFileLabel(fpath string) (string, error) { } func setFSCreateLabel(label string) error { - return writeCon(attrPath("fscreate"), label) + return writeConThreadSelf("attr/fscreate", label) } // fsCreateLabel returns the default label the kernel which the kernel is using // for file system objects created by this task. "" indicates default. func fsCreateLabel() (string, error) { - return readCon(attrPath("fscreate")) + return readConThreadSelf("attr/fscreate") } // currentLabel returns the SELinux label of the current process thread, or an error. func currentLabel() (string, error) { - return readCon(attrPath("current")) + return readConThreadSelf("attr/current") } // pidLabel returns the SELinux label of the given pid, or an error. func pidLabel(pid int) (string, error) { - return readCon(fmt.Sprintf("/proc/%d/attr/current", pid)) + it, err := openProcPid(pid, "attr/current", os.O_RDONLY|unix.O_CLOEXEC) + if err != nil { + return "", nil + } + defer it.Close() + return readConFd(it) } // ExecLabel returns the SELinux label that the kernel will use for any programs // that are executed by the current process thread, or an error. func execLabel() (string, error) { - return readCon(attrPath("exec")) -} - -func writeCon(fpath, val string) error { - if fpath == "" { - return ErrEmptyPath - } - if val == "" { - if !getEnabled() { - return nil - } - } - - out, err := os.OpenFile(fpath, os.O_WRONLY, 0) - if err != nil { - return err - } - defer out.Close() - - if err := isProcHandle(out); err != nil { - return err - } - - if val != "" { - _, err = out.Write([]byte(val)) - } else { - _, err = out.Write(nil) - } - if err != nil { - return err - } - return nil -} - -func attrPath(attr string) string { - // Linux >= 3.17 provides this - const threadSelfPrefix = "/proc/thread-self/attr" - - attrPathOnce.Do(func() { - st, err := os.Stat(threadSelfPrefix) - if err == nil && st.Mode().IsDir() { - haveThreadSelf = true - } - }) - - if haveThreadSelf { - return filepath.Join(threadSelfPrefix, attr) - } - - return filepath.Join("/proc/self/task", strconv.Itoa(unix.Gettid()), "attr", attr) + return readConThreadSelf("exec") } // canonicalizeContext takes a context string and writes it to the kernel @@ -728,19 +818,29 @@ func peerLabel(fd uintptr) (string, error) { // setKeyLabel takes a process label and tells the kernel to assign the // label to the next kernel keyring that gets created func setKeyLabel(label string) error { - err := writeCon("/proc/self/attr/keycreate", label) + // Rather than using /proc/thread-self, we want to use /proc/self to + // operate on the thread-group leader. + err := writeConSelf("attr/keycreate", label) if errors.Is(err, os.ErrNotExist) { return nil } if label == "" && errors.Is(err, os.ErrPermission) { return nil } - if errors.Is(err, unix.EACCES) && unix.Getuid() != unix.Gettid() { + if errors.Is(err, unix.EACCES) && unix.Getpid() != unix.Gettid() { return ErrNotTGLeader } return err } +// KeyLabel retrieves the current kernel keyring label setting for this +// thread-group. +func keyLabel() (string, error) { + // Rather than using /proc/thread-self, we want to use /proc/self to + // operate on the thread-group leader. + return readConSelf("attr/keycreate") +} + // get returns the Context as a string func (c Context) get() string { if l := c["level"]; l != "" { diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 0889fbe0e0..382244e503 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -3,15 +3,11 @@ package selinux -func attrPath(string) string { - return "" -} - -func readCon(string) (string, error) { +func readConThreadSelf(string) (string, error) { return "", nil } -func writeCon(string, string) error { +func writeConThreadSelf(string, string) error { return nil } @@ -81,6 +77,10 @@ func setKeyLabel(string) error { return nil } +func keyLabel() (string, error) { + return "", nil +} + func (c Context) get() string { return "" } diff --git a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go index 33a09ae16e..bff6155c2f 100644 --- a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go +++ b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go @@ -242,35 +242,41 @@ func ValidCipherSuites() []string { sort.Strings(validCipherSuites) return validCipherSuites } + +// DefaultCiphers returns the default cipher suites for TLS connections. +// +// RECOMMENDATION: Instead of relying on this function directly, consumers should respect +// TLSSecurityProfile settings from one of the OpenShift API configuration resources: +// - For API servers: Use apiserver.config.openshift.io/cluster Spec.TLSSecurityProfile +// - For ingress controllers: Use operator.openshift.io/v1 IngressController Spec.TLSSecurityProfile +// - For kubelet: Use machineconfiguration.openshift.io/v1 KubeletConfig Spec.TLSSecurityProfile +// +// These API resources allow cluster administrators to choose between Old, Intermediate, +// Modern, or Custom TLS profiles. Components should observe these settings. func DefaultCiphers() []uint16 { - // HTTP/2 mandates TLS 1.2 or higher with an AEAD cipher - // suite (GCM, Poly1305) and ephemeral key exchange (ECDHE, DHE) for - // perfect forward secrecy. Servers may provide additional cipher - // suites for backwards compatibility with HTTP/1.1 clients. - // See RFC7540, section 9.2 (Use of TLS Features) and Appendix A - // (TLS 1.2 Cipher Suite Black List). + // Aligned with intermediate profile of the 5.7 version of the Mozilla Server + // Side TLS guidelines found at: https://ssl-config.mozilla.org/guidelines/5.7.json + // + // Latest guidelines: https://ssl-config.mozilla.org/guidelines/latest.json + // + // This profile provides strong security with wide compatibility. + // It requires TLS 1.2+ and uses only AEAD cipher suites (GCM, ChaCha20-Poly1305) + // with ECDHE key exchange for perfect forward secrecy. + // + // All CBC-mode ciphers have been removed due to padding oracle vulnerabilities. + // All RSA key exchange ciphers have been removed due to lack of perfect forward secrecy. + // + // HTTP/2 compliance: All ciphers are compliant with RFC7540, section 9.2. return []uint16{ + // TLS 1.2 cipher suites with ECDHE + AEAD tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // required by http/2 + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // required by HTTP/2 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // forbidden by http/2, not flagged by http2isBadCipher() in go1.8 - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // forbidden by http/2, not flagged by http2isBadCipher() in go1.8 - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 - tls.TLS_RSA_WITH_AES_128_GCM_SHA256, // forbidden by http/2 - tls.TLS_RSA_WITH_AES_256_GCM_SHA384, // forbidden by http/2 - // the next one is in the intermediate suite, but go1.8 http2isBadCipher() complains when it is included at the recommended index - // because it comes after ciphers forbidden by the http/2 spec - // tls.TLS_RSA_WITH_AES_128_CBC_SHA256, - // tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, // forbidden by http/2, disabled to mitigate SWEET32 attack - // tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, // forbidden by http/2, disabled to mitigate SWEET32 attack - tls.TLS_RSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 - tls.TLS_RSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 + + // TLS 1.3 cipher suites (negotiated automatically, not configurable) tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384, tls.TLS_CHACHA20_POLY1305_SHA256, diff --git a/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go b/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go index 1cb4e55542..c2c8b8368f 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go @@ -188,7 +188,7 @@ func getValidityFromAnnotations(annotations map[string]string) (notBefore time.T return notBefore, notAfter, fmt.Sprintf("bad expiry: %q", notAfterString) } notBeforeString := annotations[CertificateNotBeforeAnnotation] - if len(notAfterString) == 0 { + if len(notBeforeString) == 0 { return notBefore, notAfter, "missing notBefore" } notBefore, err = time.Parse(time.RFC3339, notBeforeString) diff --git a/vendor/github.com/spf13/cobra/.golangci.yml b/vendor/github.com/spf13/cobra/.golangci.yml index 2c8f4808c1..6acf8ab1ea 100644 --- a/vendor/github.com/spf13/cobra/.golangci.yml +++ b/vendor/github.com/spf13/cobra/.golangci.yml @@ -12,14 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. +version: "2" + run: - deadline: 5m + timeout: 5m + +formatters: + enable: + - gofmt + - goimports linters: - disable-all: true + default: none enable: #- bodyclose - # - deadcode ! deprecated since v1.49.0; replaced by 'unused' #- depguard #- dogsled #- dupl @@ -30,28 +36,24 @@ linters: - goconst - gocritic #- gocyclo - - gofmt - - goimports - #- gomnd #- goprintffuncname - gosec - - gosimple - govet - ineffassign #- lll - misspell + #- mnd #- nakedret #- noctx - nolintlint #- rowserrcheck - #- scopelint - staticcheck - #- structcheck ! deprecated since v1.49.0; replaced by 'unused' - - stylecheck - #- typecheck - unconvert #- unparam - unused - # - varcheck ! deprecated since v1.49.0; replaced by 'unused' #- whitespace - fast: false + exclusions: + presets: + - common-false-positives + - legacy + - std-error-handling diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md index 71757151c3..8416275f48 100644 --- a/vendor/github.com/spf13/cobra/README.md +++ b/vendor/github.com/spf13/cobra/README.md @@ -1,8 +1,14 @@ - -![cobra logo](https://github.com/user-attachments/assets/cbc3adf8-0dff-46e9-a88d-5e2d971c169e) +
+ +cobra-logo + +
Cobra is a library for creating powerful modern CLI applications. +Visit Cobra.dev for extensive documentation + + Cobra is used in many Go projects such as [Kubernetes](https://kubernetes.io/), [Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to name a few. [This list](site/content/projects_using_cobra.md) contains a more extensive list of projects using Cobra. @@ -11,6 +17,20 @@ name a few. [This list](site/content/projects_using_cobra.md) contains a more ex [![Go Reference](https://pkg.go.dev/badge/github.com/spf13/cobra.svg)](https://pkg.go.dev/github.com/spf13/cobra) [![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra) [![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199) +
+
+ Supported by: +
+
+ + Warp sponsorship + + +### [Warp, the AI terminal for devs](https://www.warp.dev/cobra) +[Try Cobra in Warp today](https://www.warp.dev/cobra)
+ +
+
# Overview diff --git a/vendor/github.com/spf13/cobra/SECURITY.md b/vendor/github.com/spf13/cobra/SECURITY.md new file mode 100644 index 0000000000..54e60c28c1 --- /dev/null +++ b/vendor/github.com/spf13/cobra/SECURITY.md @@ -0,0 +1,105 @@ +# Security Policy + +## Reporting a Vulnerability + +The `cobra` maintainers take security issues seriously and +we appreciate your efforts to _**responsibly**_ disclose your findings. +We will make every effort to swiftly respond and address concerns. + +To report a security vulnerability: + +1. **DO NOT** create a public GitHub issue for the vulnerability! +2. **DO NOT** create a public GitHub Pull Request with a fix for the vulnerability! +3. Send an email to `cobra-security@googlegroups.com`. +4. Include the following details in your report: + - Description of the vulnerability + - Steps to reproduce + - Potential impact of the vulnerability (to your downstream project, to the Go ecosystem, etc.) + - Any potential mitigations you've already identified +5. Allow up to 7 days for an initial response. + You should receive an acknowledgment of your report and an estimated timeline for a fix. +6. (Optional) If you have a fix and would like to contribute your patch, please work + directly with the maintainers via `cobra-security@googlegroups.com` to + coordinate pushing the patch to GitHub, cutting a new release, and disclosing the change. + +## Response Process + +When a security vulnerability report is received, the `cobra` maintainers will: + +1. Confirm receipt of the vulnerability report within 7 days. +2. Assess the report to determine if it constitutes a security vulnerability. +3. If confirmed, assign the vulnerability a severity level and create a timeline for addressing it. +4. Develop and test a fix. +5. Patch the vulnerability and make a new GitHub release: the maintainers will coordinate disclosure with the reporter. +6. Create a new GitHub Security Advisory to inform the broader Go ecosystem + +## Disclosure Policy + +The `cobra` maintainers follow a coordinated disclosure process: + +1. Security vulnerabilities will be addressed as quickly as possible. +2. A CVE (Common Vulnerabilities and Exposures) identifier will be requested for significant vulnerabilities + that are within `cobra` itself. +3. Once a fix is ready, the maintainers will: + - Release a new version containing the fix. + - Update the security advisory with details about the vulnerability. + - Credit the reporter (unless they wish to remain anonymous). + - Credit the fixer (unless they wish to remain anonymous, this may be the same as the reporter). + - Announce the vulnerability through appropriate channels + (GitHub Security Advisory, mailing lists, GitHub Releases, etc.) + +## Supported Versions + +Security fixes will typically only be released for the most recent major release. + +## Upstream Security Issues + +`cobra` generally will not accept vulnerability reports that originate in upstream +dependencies. I.e., if there is a problem in Go code that `cobra` depends on, +it is best to engage that project's maintainers and owners. + +This security policy primarily pertains only to `cobra` itself but if you believe you've +identified a problem that originates in an upstream dependency and is being widely +distributed by `cobra`, please follow the disclosure procedure above: the `cobra` +maintainers will work with you to determine the severity and ecosystem impact. + +## Security Updates and CVEs + +Information about known security vulnerabilities and CVEs affecting `cobra` will +be published as GitHub Security Advisories at +https://github.com/spf13/cobra/security/advisories. + +All users are encouraged to watch the repository and upgrade promptly when +security releases are published. + +## `cobra` Security Best Practices for Users + +When using `cobra` in your CLIs, the `cobra` maintainers recommend the following: + +1. Always use the latest version of `cobra`. +2. [Use Go modules](https://go.dev/blog/using-go-modules) for dependency management. +3. Always use the latest possible version of Go. + +## Security Best Practices for Contributors + +When contributing to `cobra`: + +1. Be mindful of security implications when adding new features or modifying existing ones. +2. Be aware of `cobra`'s extremely large reach: it is used in nearly every Go CLI + (like Kubernetes, Docker, Prometheus, etc. etc.) +3. Write tests that explicitly cover edge cases and potential issues. +4. If you discover a security issue while working on `cobra`, please report it + following the process above rather than opening a public pull request or issue that + addresses the vulnerability. +5. Take personal sec-ops seriously and secure your GitHub account: use [two-factor authentication](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa), + [sign your commits with a GPG or SSH key](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification), + etc. + +## Acknowledgments + +The `cobra` maintainers would like to thank all security researchers and +community members who help keep cobra, its users, and the entire Go ecosystem secure through responsible disclosures!! + +--- + +*This security policy is inspired by the [Open Web Application Security Project (OWASP)](https://owasp.org/) guidelines and security best practices.* diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index dbb2c298ba..78088db69c 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -39,7 +39,7 @@ const ( ) // FParseErrWhitelist configures Flag parse errors to be ignored -type FParseErrWhitelist flag.ParseErrorsWhitelist +type FParseErrWhitelist flag.ParseErrorsAllowlist // Group Structure to manage groups for commands type Group struct { @@ -1296,6 +1296,11 @@ Simply type ` + c.DisplayName() + ` help [path to command] for full details.`, c.Printf("Unknown help topic %#q\n", args) CheckErr(c.Root().Usage()) } else { + // FLow the context down to be used in help text + if cmd.ctx == nil { + cmd.ctx = c.ctx + } + cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown cmd.InitDefaultVersionFlag() // make possible 'version' flag to be shown CheckErr(cmd.Help()) @@ -1872,7 +1877,7 @@ func (c *Command) ParseFlags(args []string) error { c.mergePersistentFlags() // do it here after merging all flags and just before parse - c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist) + c.Flags().ParseErrorsAllowlist = flag.ParseErrorsAllowlist(c.FParseErrWhitelist) err := c.Flags().Parse(args) // Print warnings if they occurred (e.g. deprecated flag messages). @@ -2020,7 +2025,7 @@ func defaultUsageFunc(w io.Writer, in interface{}) error { fmt.Fprint(w, trimRightSpace(c.InheritedFlags().FlagUsages())) } if c.HasHelpSubCommands() { - fmt.Fprintf(w, "\n\nAdditional help topcis:") + fmt.Fprintf(w, "\n\nAdditional help topics:") for _, subcmd := range c.Commands() { if subcmd.IsAdditionalHelpTopicCommand() { fmt.Fprintf(w, "\n %s %s", rpad(subcmd.CommandPath(), subcmd.CommandPathPadding()), subcmd.Short) diff --git a/vendor/github.com/spf13/cobra/completions.go b/vendor/github.com/spf13/cobra/completions.go index a1752f7631..d3607c2d2f 100644 --- a/vendor/github.com/spf13/cobra/completions.go +++ b/vendor/github.com/spf13/cobra/completions.go @@ -115,6 +115,13 @@ type CompletionOptions struct { DisableDescriptions bool // HiddenDefaultCmd makes the default 'completion' command hidden HiddenDefaultCmd bool + // DefaultShellCompDirective sets the ShellCompDirective that is returned + // if no special directive can be determined + DefaultShellCompDirective *ShellCompDirective +} + +func (receiver *CompletionOptions) SetDefaultShellCompDirective(directive ShellCompDirective) { + receiver.DefaultShellCompDirective = &directive } // Completion is a string that can be used for completions @@ -375,7 +382,7 @@ func (c *Command) getCompletions(args []string) (*Command, []Completion, ShellCo // Error while attempting to parse flags if flagErr != nil { // If error type is flagCompError and we don't want flagCompletion we should ignore the error - if _, ok := flagErr.(*flagCompError); !(ok && !flagCompletion) { + if _, ok := flagErr.(*flagCompError); !ok || flagCompletion { return finalCmd, []Completion{}, ShellCompDirectiveDefault, flagErr } } @@ -480,6 +487,14 @@ func (c *Command) getCompletions(args []string) (*Command, []Completion, ShellCo } } else { directive = ShellCompDirectiveDefault + // check current and parent commands for a custom DefaultShellCompDirective + for cmd := finalCmd; cmd != nil; cmd = cmd.parent { + if cmd.CompletionOptions.DefaultShellCompDirective != nil { + directive = *cmd.CompletionOptions.DefaultShellCompDirective + break + } + } + if flag == nil { foundLocalNonPersistentFlag := false // If TraverseChildren is true on the root command we don't check for @@ -773,7 +788,7 @@ See each sub-command's help for details on how to use the generated script. // shell completion for it (prog __complete completion '') subCmd, cmdArgs, err := c.Find(args) if err != nil || subCmd.Name() != compCmdName && - !(subCmd.Name() == ShellCompRequestCmd && len(cmdArgs) > 1 && cmdArgs[0] == compCmdName) { + (subCmd.Name() != ShellCompRequestCmd || len(cmdArgs) <= 1 || cmdArgs[0] != compCmdName) { // The completion command is not being called or being completed so we remove it. c.RemoveCommand(completionCmd) return diff --git a/vendor/go.etcd.io/etcd/api/v3/version/version.go b/vendor/go.etcd.io/etcd/api/v3/version/version.go index d77e31a972..9e7bc64c17 100644 --- a/vendor/go.etcd.io/etcd/api/v3/version/version.go +++ b/vendor/go.etcd.io/etcd/api/v3/version/version.go @@ -26,7 +26,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "3.0.0" - Version = "3.6.4" + Version = "3.6.5" APIVersion = "unknown" // Git SHA Value will be set during build diff --git a/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go b/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go index 2b9301a580..7703e673b0 100644 --- a/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go +++ b/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go @@ -351,11 +351,11 @@ func isContextError(err error) bool { func contextErrToGRPCErr(err error) error { switch { case errors.Is(err, context.DeadlineExceeded): - return status.Errorf(codes.DeadlineExceeded, err.Error()) + return status.Error(codes.DeadlineExceeded, err.Error()) case errors.Is(err, context.Canceled): - return status.Errorf(codes.Canceled, err.Error()) + return status.Error(codes.Canceled, err.Error()) default: - return status.Errorf(codes.Unknown, err.Error()) + return status.Error(codes.Unknown, err.Error()) } } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go index a01bfafbe0..6bd50d4c9b 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go @@ -176,6 +176,10 @@ func WithMessageEvents(events ...event) Option { // WithSpanNameFormatter takes a function that will be called on every // request and the returned string will become the Span Name. +// +// When using [http.ServeMux] (or any middleware that sets the Pattern of [http.Request]), +// the span name formatter will run twice. Once when the span is created, and +// second time after the middleware, so the pattern can be used. func WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option { return optionFunc(func(c *config) { c.SpanNameFormatter = f diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go index 3ea05d0199..937f9b4e73 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go @@ -98,7 +98,7 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http ctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header)) opts := []trace.SpanStartOption{ - trace.WithAttributes(h.semconv.RequestTraceAttrs(h.server, r)...), + trace.WithAttributes(h.semconv.RequestTraceAttrs(h.server, r, semconv.RequestTraceAttrsOpts{})...), } opts = append(opts, h.spanStartOptions...) @@ -176,7 +176,12 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http ctx = ContextWithLabeler(ctx, labeler) } - next.ServeHTTP(w, r.WithContext(ctx)) + r = r.WithContext(ctx) + next.ServeHTTP(w, r) + + if r.Pattern != "" { + span.SetName(h.spanNameFormatter(h.operation, r)) + } statusCode := rww.StatusCode() bytesWritten := rww.BytesWritten() diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go index a945f55661..d032aa841b 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go @@ -1,6 +1,11 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/request/body_wrapper.go.tmpl + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// Package request provides types and functionality to handle HTTP request +// handling. package request // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request" import ( @@ -53,7 +58,7 @@ func (w *BodyWrapper) updateReadData(n int64, err error) { } } -// Closes closes the io.ReadCloser. +// Close closes the io.ReadCloser. func (w *BodyWrapper) Close() error { return w.ReadCloser.Close() } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go new file mode 100644 index 0000000000..9e00dd2fce --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package request // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request" + +// Generate request package: +//go:generate gotmpl --body=../../../../../../internal/shared/request/body_wrapper.go.tmpl "--data={}" --out=body_wrapper.go +//go:generate gotmpl --body=../../../../../../internal/shared/request/body_wrapper_test.go.tmpl "--data={}" --out=body_wrapper_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/request/resp_writer_wrapper.go.tmpl "--data={}" --out=resp_writer_wrapper.go +//go:generate gotmpl --body=../../../../../../internal/shared/request/resp_writer_wrapper_test.go.tmpl "--data={}" --out=resp_writer_wrapper_test.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go index fbc344cbdd..ca2e4c14c7 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go @@ -1,3 +1,6 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/request/resp_writer_wrapper.go.tmpl + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 @@ -102,7 +105,7 @@ func (w *RespWriterWrapper) BytesWritten() int64 { return w.written } -// BytesWritten returns the HTTP status code that was sent. +// StatusCode returns the HTTP status code that was sent. func (w *RespWriterWrapper) StatusCode() int { w.mu.RLock() defer w.mu.RUnlock() diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go index eaf4c37967..7cb9693d98 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go @@ -1,4 +1,4 @@ -// Code created by gotmpl. DO NOT MODIFY. +// Code generated by gotmpl. DO NOT MODIFY. // source: internal/shared/semconv/env.go.tmpl // Copyright The OpenTelemetry Authors @@ -20,7 +20,7 @@ import ( ) // OTelSemConvStabilityOptIn is an environment variable. -// That can be set to "old" or "http/dup" to opt into the new HTTP semantic conventions. +// That can be set to "http/dup" to keep getting the old HTTP semantic conventions. const OTelSemConvStabilityOptIn = "OTEL_SEMCONV_STABILITY_OPT_IN" type ResponseTelemetry struct { @@ -61,26 +61,40 @@ type HTTPServer struct { // // If the primary server name is not known, server should be an empty string. // The req Host will be used to determine the server instead. -func (s HTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue { +func (s HTTPServer) RequestTraceAttrs(server string, req *http.Request, opts RequestTraceAttrsOpts) []attribute.KeyValue { + attrs := CurrentHTTPServer{}.RequestTraceAttrs(server, req, opts) if s.duplicate { - return append(OldHTTPServer{}.RequestTraceAttrs(server, req), CurrentHTTPServer{}.RequestTraceAttrs(server, req)...) + return OldHTTPServer{}.RequestTraceAttrs(server, req, attrs) + } + return attrs +} + +func (s HTTPServer) NetworkTransportAttr(network string) []attribute.KeyValue { + if s.duplicate { + return []attribute.KeyValue{ + OldHTTPServer{}.NetworkTransportAttr(network), + CurrentHTTPServer{}.NetworkTransportAttr(network), + } + } + return []attribute.KeyValue{ + CurrentHTTPServer{}.NetworkTransportAttr(network), } - return OldHTTPServer{}.RequestTraceAttrs(server, req) } // ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response. // // If any of the fields in the ResponseTelemetry are not set the attribute will be omitted. func (s HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { + attrs := CurrentHTTPServer{}.ResponseTraceAttrs(resp) if s.duplicate { - return append(OldHTTPServer{}.ResponseTraceAttrs(resp), CurrentHTTPServer{}.ResponseTraceAttrs(resp)...) + return OldHTTPServer{}.ResponseTraceAttrs(resp, attrs) } - return OldHTTPServer{}.ResponseTraceAttrs(resp) + return attrs } // Route returns the attribute for the route. func (s HTTPServer) Route(route string) attribute.KeyValue { - return OldHTTPServer{}.Route(route) + return CurrentHTTPServer{}.Route(route) } // Status returns a span status code and message for an HTTP status code @@ -112,6 +126,8 @@ type MetricAttributes struct { type MetricData struct { RequestSize int64 + + // The request duration, in milliseconds ElapsedTime float64 } @@ -130,7 +146,19 @@ var ( ) func (s HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { - if s.requestBytesCounter != nil && s.responseBytesCounter != nil && s.serverLatencyMeasure != nil { + if s.requestDurationHistogram != nil && s.requestBodySizeHistogram != nil && s.responseBodySizeHistogram != nil { + attributes := CurrentHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes) + o := metric.WithAttributeSet(attribute.NewSet(attributes...)) + recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption) + *recordOpts = append(*recordOpts, o) + s.requestBodySizeHistogram.Record(ctx, md.RequestSize, *recordOpts...) + s.responseBodySizeHistogram.Record(ctx, md.ResponseSize, *recordOpts...) + s.requestDurationHistogram.Record(ctx, md.ElapsedTime/1000.0, o) + *recordOpts = (*recordOpts)[:0] + metricRecordOptionPool.Put(recordOpts) + } + + if s.duplicate && s.requestBytesCounter != nil && s.responseBytesCounter != nil && s.serverLatencyMeasure != nil { attributes := OldHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes) o := metric.WithAttributeSet(attribute.NewSet(attributes...)) addOpts := metricAddOptionPool.Get().(*[]metric.AddOption) @@ -141,29 +169,28 @@ func (s HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { *addOpts = (*addOpts)[:0] metricAddOptionPool.Put(addOpts) } +} - if s.duplicate && s.requestDurationHistogram != nil && s.requestBodySizeHistogram != nil && s.responseBodySizeHistogram != nil { - attributes := CurrentHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes) - o := metric.WithAttributeSet(attribute.NewSet(attributes...)) - recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption) - *recordOpts = append(*recordOpts, o) - s.requestBodySizeHistogram.Record(ctx, md.RequestSize, *recordOpts...) - s.responseBodySizeHistogram.Record(ctx, md.ResponseSize, *recordOpts...) - s.requestDurationHistogram.Record(ctx, md.ElapsedTime, o) - *recordOpts = (*recordOpts)[:0] - metricRecordOptionPool.Put(recordOpts) +// hasOptIn returns true if the comma-separated version string contains the +// exact optIn value. +func hasOptIn(version, optIn string) bool { + for _, v := range strings.Split(version, ",") { + if strings.TrimSpace(v) == optIn { + return true + } } + return false } func NewHTTPServer(meter metric.Meter) HTTPServer { env := strings.ToLower(os.Getenv(OTelSemConvStabilityOptIn)) - duplicate := env == "http/dup" + duplicate := hasOptIn(env, "http/dup") server := HTTPServer{ duplicate: duplicate, } - server.requestBytesCounter, server.responseBytesCounter, server.serverLatencyMeasure = OldHTTPServer{}.createMeasures(meter) + server.requestBodySizeHistogram, server.responseBodySizeHistogram, server.requestDurationHistogram = CurrentHTTPServer{}.createMeasures(meter) if duplicate { - server.requestBodySizeHistogram, server.responseBodySizeHistogram, server.requestDurationHistogram = CurrentHTTPServer{}.createMeasures(meter) + server.requestBytesCounter, server.responseBytesCounter, server.serverLatencyMeasure = OldHTTPServer{}.createMeasures(meter) } return server } @@ -183,13 +210,13 @@ type HTTPClient struct { func NewHTTPClient(meter metric.Meter) HTTPClient { env := strings.ToLower(os.Getenv(OTelSemConvStabilityOptIn)) - duplicate := env == "http/dup" + duplicate := hasOptIn(env, "http/dup") client := HTTPClient{ duplicate: duplicate, } - client.requestBytesCounter, client.responseBytesCounter, client.latencyMeasure = OldHTTPClient{}.createMeasures(meter) + client.requestBodySize, client.requestDuration = CurrentHTTPClient{}.createMeasures(meter) if duplicate { - client.requestBodySize, client.requestDuration = CurrentHTTPClient{}.createMeasures(meter) + client.requestBytesCounter, client.responseBytesCounter, client.latencyMeasure = OldHTTPClient{}.createMeasures(meter) } return client @@ -197,19 +224,20 @@ func NewHTTPClient(meter metric.Meter) HTTPClient { // RequestTraceAttrs returns attributes for an HTTP request made by a client. func (c HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { + attrs := CurrentHTTPClient{}.RequestTraceAttrs(req) if c.duplicate { - return append(OldHTTPClient{}.RequestTraceAttrs(req), CurrentHTTPClient{}.RequestTraceAttrs(req)...) + return OldHTTPClient{}.RequestTraceAttrs(req, attrs) } - return OldHTTPClient{}.RequestTraceAttrs(req) + return attrs } // ResponseTraceAttrs returns metric attributes for an HTTP request made by a client. func (c HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { + attrs := CurrentHTTPClient{}.ResponseTraceAttrs(resp) if c.duplicate { - return append(OldHTTPClient{}.ResponseTraceAttrs(resp), CurrentHTTPClient{}.ResponseTraceAttrs(resp)...) + return OldHTTPClient{}.ResponseTraceAttrs(resp, attrs) } - - return OldHTTPClient{}.ResponseTraceAttrs(resp) + return attrs } func (c HTTPClient) Status(code int) (codes.Code, string) { @@ -223,11 +251,7 @@ func (c HTTPClient) Status(code int) (codes.Code, string) { } func (c HTTPClient) ErrorType(err error) attribute.KeyValue { - if c.duplicate { - return CurrentHTTPClient{}.ErrorType(err) - } - - return attribute.KeyValue{} + return CurrentHTTPClient{}.ErrorType(err) } type MetricOpts struct { @@ -246,17 +270,17 @@ func (o MetricOpts) AddOptions() metric.AddOption { func (c HTTPClient) MetricOptions(ma MetricAttributes) map[string]MetricOpts { opts := map[string]MetricOpts{} - attributes := OldHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) + attributes := CurrentHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) set := metric.WithAttributeSet(attribute.NewSet(attributes...)) - opts["old"] = MetricOpts{ + opts["new"] = MetricOpts{ measurement: set, addOptions: set, } if c.duplicate { - attributes := CurrentHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) + attributes := OldHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) set := metric.WithAttributeSet(attribute.NewSet(attributes...)) - opts["new"] = MetricOpts{ + opts["old"] = MetricOpts{ measurement: set, addOptions: set, } @@ -266,17 +290,17 @@ func (c HTTPClient) MetricOptions(ma MetricAttributes) map[string]MetricOpts { } func (s HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts map[string]MetricOpts) { - if s.requestBytesCounter == nil || s.latencyMeasure == nil { + if s.requestBodySize == nil || s.requestDuration == nil { // This will happen if an HTTPClient{} is used instead of NewHTTPClient(). return } - s.requestBytesCounter.Add(ctx, md.RequestSize, opts["old"].AddOptions()) - s.latencyMeasure.Record(ctx, md.ElapsedTime, opts["old"].MeasurementOption()) + s.requestBodySize.Record(ctx, md.RequestSize, opts["new"].MeasurementOption()) + s.requestDuration.Record(ctx, md.ElapsedTime/1000, opts["new"].MeasurementOption()) if s.duplicate { - s.requestBodySize.Record(ctx, md.RequestSize, opts["new"].MeasurementOption()) - s.requestDuration.Record(ctx, md.ElapsedTime, opts["new"].MeasurementOption()) + s.requestBytesCounter.Add(ctx, md.RequestSize, opts["old"].AddOptions()) + s.latencyMeasure.Record(ctx, md.ElapsedTime, opts["old"].MeasurementOption()) } } @@ -288,3 +312,12 @@ func (s HTTPClient) RecordResponseSize(ctx context.Context, responseData int64, s.responseBytesCounter.Add(ctx, responseData, opts["old"].AddOptions()) } + +func (s HTTPClient) TraceAttributes(host string) []attribute.KeyValue { + attrs := CurrentHTTPClient{}.TraceAttributes(host) + if s.duplicate { + return OldHTTPClient{}.TraceAttributes(host, attrs) + } + + return attrs +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go index 32630864bf..f2cf8a152d 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go @@ -4,11 +4,11 @@ package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" // Generate semconv package: -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/bench_test.go.tmpl "--data={}" --out=bench_test.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env.go.tmpl "--data={}" --out=env.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env_test.go.tmpl "--data={}" --out=env_test.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv.go.tmpl "--data={}" --out=httpconv.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv_test.go.tmpl "--data={}" --out=httpconv_test.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/util.go.tmpl "--data={}" --out=util.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/util_test.go.tmpl "--data={}" --out=util_test.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/v1.20.0.go.tmpl "--data={}" --out=v1.20.0.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/bench_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=bench_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=env.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=env_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=httpconv.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=httpconv_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/util.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=util.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/util_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=util_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/v1.20.0.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=v1.20.0.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go index 8c3c627513..53976b0d5a 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go @@ -1,9 +1,11 @@ -// Code created by gotmpl. DO NOT MODIFY. +// Code generated by gotmpl. DO NOT MODIFY. // source: internal/shared/semconv/httpconv.go.tmpl // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// Package semconv provides OpenTelemetry semantic convention types and +// functionality. package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" import ( @@ -20,9 +22,14 @@ import ( semconvNew "go.opentelemetry.io/otel/semconv/v1.26.0" ) +type RequestTraceAttrsOpts struct { + // If set, this is used as value for the "http.client_ip" attribute. + HTTPClientIP string +} + type CurrentHTTPServer struct{} -// TraceRequest returns trace attributes for an HTTP request received by a +// RequestTraceAttrs returns trace attributes for an HTTP request received by a // server. // // The server must be the primary server name if it is known. For example this @@ -38,7 +45,7 @@ type CurrentHTTPServer struct{} // // If the primary server name is not known, server should be an empty string. // The req Host will be used to determine the server instead. -func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue { +func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request, opts RequestTraceAttrsOpts) []attribute.KeyValue { count := 3 // ServerAddress, Method, Scheme var host string @@ -65,7 +72,8 @@ func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request) [ scheme := n.scheme(req.TLS != nil) - if peer, peerPort := SplitHostPort(req.RemoteAddr); peer != "" { + peer, peerPort := SplitHostPort(req.RemoteAddr) + if peer != "" { // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a // file-path that would be interpreted with a sock family. count++ @@ -79,7 +87,17 @@ func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request) [ count++ } - clientIP := serverClientIP(req.Header.Get("X-Forwarded-For")) + // For client IP, use, in order: + // 1. The value passed in the options + // 2. The value in the X-Forwarded-For header + // 3. The peer address + clientIP := opts.HTTPClientIP + if clientIP == "" { + clientIP = serverClientIP(req.Header.Get("X-Forwarded-For")) + if clientIP == "" { + clientIP = peer + } + } if clientIP != "" { count++ } @@ -96,6 +114,11 @@ func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request) [ count++ } + route := httpRoute(req.Pattern) + if route != "" { + count++ + } + attrs := make([]attribute.KeyValue, 0, count) attrs = append(attrs, semconvNew.ServerAddress(host), @@ -119,7 +142,7 @@ func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request) [ } } - if useragent := req.UserAgent(); useragent != "" { + if useragent != "" { attrs = append(attrs, semconvNew.UserAgentOriginal(useragent)) } @@ -138,9 +161,26 @@ func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request) [ attrs = append(attrs, semconvNew.NetworkProtocolVersion(protoVersion)) } + if route != "" { + attrs = append(attrs, n.Route(route)) + } + return attrs } +func (n CurrentHTTPServer) NetworkTransportAttr(network string) attribute.KeyValue { + switch network { + case "tcp", "tcp4", "tcp6": + return semconvNew.NetworkTransportTCP + case "udp", "udp4", "udp6": + return semconvNew.NetworkTransportUDP + case "unix", "unixgram", "unixpacket": + return semconvNew.NetworkTransportUnix + default: + return semconvNew.NetworkTransportPipe + } +} + func (n CurrentHTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { if method == "" { return semconvNew.HTTPRequestMethodGet, attribute.KeyValue{} @@ -163,9 +203,11 @@ func (n CurrentHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:rev return semconvNew.URLScheme("http") } -// TraceResponse returns trace attributes for telemetry from an HTTP response. +// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP +// response. // -// If any of the fields in the ResponseTelemetry are not set the attribute will be omitted. +// If any of the fields in the ResponseTelemetry are not set the attribute will +// be omitted. func (n CurrentHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { var count int @@ -228,6 +270,7 @@ func (n CurrentHTTPServer) createMeasures(meter metric.Meter) (metric.Int64Histo semconvNew.HTTPServerRequestDurationName, metric.WithUnit(semconvNew.HTTPServerRequestDurationUnit), metric.WithDescription(semconvNew.HTTPServerRequestDurationDescription), + metric.WithExplicitBucketBoundaries(0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10), ) handleErr(err) @@ -446,6 +489,7 @@ func (n CurrentHTTPClient) createMeasures(meter metric.Meter) (metric.Int64Histo semconvNew.HTTPClientRequestDurationName, metric.WithUnit(semconvNew.HTTPClientRequestDurationUnit), metric.WithDescription(semconvNew.HTTPClientRequestDurationDescription), + metric.WithExplicitBucketBoundaries(0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10), ) handleErr(err) @@ -488,7 +532,7 @@ func (n CurrentHTTPClient) MetricAttributes(req *http.Request, statusCode int, a attributes = append(attributes, semconvNew.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), semconvNew.ServerAddress(requestHost), - n.scheme(req.TLS != nil), + n.scheme(req), ) if port > 0 { @@ -507,8 +551,18 @@ func (n CurrentHTTPClient) MetricAttributes(req *http.Request, statusCode int, a return attributes } -func (n CurrentHTTPClient) scheme(https bool) attribute.KeyValue { // nolint:revive - if https { +// TraceAttributes returns attributes for httptrace. +func (n CurrentHTTPClient) TraceAttributes(host string) []attribute.KeyValue { + return []attribute.KeyValue{ + semconvNew.ServerAddress(host), + } +} + +func (n CurrentHTTPClient) scheme(req *http.Request) attribute.KeyValue { + if req.URL != nil && req.URL.Scheme != "" { + return semconvNew.URLScheme(req.URL.Scheme) + } + if req.TLS != nil { return semconvNew.URLScheme("https") } return semconvNew.URLScheme("http") diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go index 558efd0594..bc1f7751db 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go @@ -1,4 +1,4 @@ -// Code created by gotmpl. DO NOT MODIFY. +// Code generated by gotmpl. DO NOT MODIFY. // source: internal/shared/semconv/util.go.tmpl // Copyright The OpenTelemetry Authors @@ -28,17 +28,17 @@ func SplitHostPort(hostport string) (host string, port int) { port = -1 if strings.HasPrefix(hostport, "[") { - addrEnd := strings.LastIndex(hostport, "]") + addrEnd := strings.LastIndexByte(hostport, ']') if addrEnd < 0 { // Invalid hostport. return } - if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 { + if i := strings.LastIndexByte(hostport[addrEnd:], ':'); i < 0 { host = hostport[1:addrEnd] return } } else { - if i := strings.LastIndex(hostport, ":"); i < 0 { + if i := strings.LastIndexByte(hostport, ':'); i < 0 { host = hostport return } @@ -70,15 +70,31 @@ func requiredHTTPPort(https bool, port int) int { // nolint:revive } func serverClientIP(xForwardedFor string) string { - if idx := strings.Index(xForwardedFor, ","); idx >= 0 { + if idx := strings.IndexByte(xForwardedFor, ','); idx >= 0 { xForwardedFor = xForwardedFor[:idx] } return xForwardedFor } +func httpRoute(pattern string) string { + if idx := strings.IndexByte(pattern, '/'); idx >= 0 { + return pattern[idx:] + } + return "" +} + func netProtocol(proto string) (name string, version string) { name, version, _ = strings.Cut(proto, "/") - name = strings.ToLower(name) + switch name { + case "HTTP": + name = "http" + case "QUIC": + name = "quic" + case "SPDY": + name = "spdy" + default: + name = strings.ToLower(name) + } return name, version } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go index 57d1507b62..ba7fccf1ef 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go @@ -1,4 +1,4 @@ -// Code created by gotmpl. DO NOT MODIFY. +// Code generated by gotmpl. DO NOT MODIFY. // source: internal/shared/semconv/v120.0.go.tmpl // Copyright The OpenTelemetry Authors @@ -37,16 +37,18 @@ type OldHTTPServer struct{} // // If the primary server name is not known, server should be an empty string. // The req Host will be used to determine the server instead. -func (o OldHTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue { - return semconvutil.HTTPServerRequest(server, req) +func (o OldHTTPServer) RequestTraceAttrs(server string, req *http.Request, attrs []attribute.KeyValue) []attribute.KeyValue { + return semconvutil.HTTPServerRequest(server, req, semconvutil.HTTPServerRequestOptions{}, attrs) +} + +func (o OldHTTPServer) NetworkTransportAttr(network string) attribute.KeyValue { + return semconvutil.NetTransport(network) } // ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response. // // If any of the fields in the ResponseTelemetry are not set the attribute will be omitted. -func (o OldHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { - attributes := []attribute.KeyValue{} - +func (o OldHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry, attributes []attribute.KeyValue) []attribute.KeyValue { if resp.ReadBytes > 0 { attributes = append(attributes, semconv.HTTPRequestContentLength(int(resp.ReadBytes))) } @@ -175,12 +177,12 @@ func (o OldHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive type OldHTTPClient struct{} -func (o OldHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { - return semconvutil.HTTPClientRequest(req) +func (o OldHTTPClient) RequestTraceAttrs(req *http.Request, attrs []attribute.KeyValue) []attribute.KeyValue { + return semconvutil.HTTPClientRequest(req, attrs) } -func (o OldHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { - return semconvutil.HTTPClientResponse(resp) +func (o OldHTTPClient) ResponseTraceAttrs(resp *http.Response, attrs []attribute.KeyValue) []attribute.KeyValue { + return semconvutil.HTTPClientResponse(resp, attrs) } func (o OldHTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { @@ -264,3 +266,8 @@ func (o OldHTTPClient) createMeasures(meter metric.Meter) (metric.Int64Counter, return requestBytesCounter, responseBytesCounter, latencyMeasure } + +// TraceAttributes returns attributes for httptrace. +func (c OldHTTPClient) TraceAttributes(host string, attrs []attribute.KeyValue) []attribute.KeyValue { + return append(attrs, semconv.NetHostName(host)) +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go index a73bb06e90..b997354793 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go @@ -1,14 +1,16 @@ -// Code created by gotmpl. DO NOT MODIFY. +// Code generated by gotmpl. DO NOT MODIFY. // source: internal/shared/semconvutil/httpconv.go.tmpl // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// Package semconvutil provides OpenTelemetry semantic convention utilities. package semconvutil // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil" import ( "fmt" "net/http" + "slices" "strings" "go.opentelemetry.io/otel/attribute" @@ -16,6 +18,11 @@ import ( semconv "go.opentelemetry.io/otel/semconv/v1.20.0" ) +type HTTPServerRequestOptions struct { + // If set, this is used as value for the "http.client_ip" attribute. + HTTPClientIP string +} + // HTTPClientResponse returns trace attributes for an HTTP response received by a // client from a server. It will return the following attributes if the related // values are defined in resp: "http.status.code", @@ -26,9 +33,9 @@ import ( // attributes. If a complete set of attributes can be generated using the // request contained in resp. For example: // -// append(HTTPClientResponse(resp), ClientRequest(resp.Request)...) -func HTTPClientResponse(resp *http.Response) []attribute.KeyValue { - return hc.ClientResponse(resp) +// HTTPClientResponse(resp, ClientRequest(resp.Request))) +func HTTPClientResponse(resp *http.Response, attrs []attribute.KeyValue) []attribute.KeyValue { + return hc.ClientResponse(resp, attrs) } // HTTPClientRequest returns trace attributes for an HTTP request made by a client. @@ -36,8 +43,8 @@ func HTTPClientResponse(resp *http.Response) []attribute.KeyValue { // "net.peer.name". The following attributes are returned if the related values // are defined in req: "net.peer.port", "user_agent.original", // "http.request_content_length". -func HTTPClientRequest(req *http.Request) []attribute.KeyValue { - return hc.ClientRequest(req) +func HTTPClientRequest(req *http.Request, attrs []attribute.KeyValue) []attribute.KeyValue { + return hc.ClientRequest(req, attrs) } // HTTPClientRequestMetrics returns metric attributes for an HTTP request made by a client. @@ -75,8 +82,8 @@ func HTTPClientStatus(code int) (codes.Code, string) { // "http.target", "net.host.name". The following attributes are returned if // they related values are defined in req: "net.host.port", "net.sock.peer.addr", // "net.sock.peer.port", "user_agent.original", "http.client_ip". -func HTTPServerRequest(server string, req *http.Request) []attribute.KeyValue { - return hc.ServerRequest(server, req) +func HTTPServerRequest(server string, req *http.Request, opts HTTPServerRequestOptions, attrs []attribute.KeyValue) []attribute.KeyValue { + return hc.ServerRequest(server, req, opts, attrs) } // HTTPServerRequestMetrics returns metric attributes for an HTTP request received by a @@ -153,8 +160,8 @@ var hc = &httpConv{ // attributes. If a complete set of attributes can be generated using the // request contained in resp. For example: // -// append(ClientResponse(resp), ClientRequest(resp.Request)...) -func (c *httpConv) ClientResponse(resp *http.Response) []attribute.KeyValue { +// ClientResponse(resp, ClientRequest(resp.Request)) +func (c *httpConv) ClientResponse(resp *http.Response, attrs []attribute.KeyValue) []attribute.KeyValue { /* The following semantic conventions are returned if present: http.status_code int http.response_content_length int @@ -166,8 +173,11 @@ func (c *httpConv) ClientResponse(resp *http.Response) []attribute.KeyValue { if resp.ContentLength > 0 { n++ } + if n == 0 { + return attrs + } - attrs := make([]attribute.KeyValue, 0, n) + attrs = slices.Grow(attrs, n) if resp.StatusCode > 0 { attrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode)) } @@ -182,7 +192,7 @@ func (c *httpConv) ClientResponse(resp *http.Response) []attribute.KeyValue { // "net.peer.name". The following attributes are returned if the related values // are defined in req: "net.peer.port", "user_agent.original", // "http.request_content_length", "user_agent.original". -func (c *httpConv) ClientRequest(req *http.Request) []attribute.KeyValue { +func (c *httpConv) ClientRequest(req *http.Request, attrs []attribute.KeyValue) []attribute.KeyValue { /* The following semantic conventions are returned if present: http.method string user_agent.original string @@ -221,8 +231,7 @@ func (c *httpConv) ClientRequest(req *http.Request) []attribute.KeyValue { n++ } - attrs := make([]attribute.KeyValue, 0, n) - + attrs = slices.Grow(attrs, n) attrs = append(attrs, c.method(req.Method)) var u string @@ -305,7 +314,7 @@ func (c *httpConv) ClientRequestMetrics(req *http.Request) []attribute.KeyValue // related values are defined in req: "net.host.port", "net.sock.peer.addr", // "net.sock.peer.port", "user_agent.original", "http.client_ip", // "net.protocol.name", "net.protocol.version". -func (c *httpConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue { +func (c *httpConv) ServerRequest(server string, req *http.Request, opts HTTPServerRequestOptions, attrs []attribute.KeyValue) []attribute.KeyValue { /* The following semantic conventions are returned if present: http.method string http.scheme string @@ -358,7 +367,17 @@ func (c *httpConv) ServerRequest(server string, req *http.Request) []attribute.K n++ } - clientIP := serverClientIP(req.Header.Get("X-Forwarded-For")) + // For client IP, use, in order: + // 1. The value passed in the options + // 2. The value in the X-Forwarded-For header + // 3. The peer address + clientIP := opts.HTTPClientIP + if clientIP == "" { + clientIP = serverClientIP(req.Header.Get("X-Forwarded-For")) + if clientIP == "" { + clientIP = peer + } + } if clientIP != "" { n++ } @@ -378,7 +397,7 @@ func (c *httpConv) ServerRequest(server string, req *http.Request) []attribute.K n++ } - attrs := make([]attribute.KeyValue, 0, n) + attrs = slices.Grow(attrs, n) attrs = append(attrs, c.method(req.Method)) attrs = append(attrs, c.scheme(req.TLS != nil)) diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go index b80a1db61f..df97255e41 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go @@ -1,4 +1,4 @@ -// Code created by gotmpl. DO NOT MODIFY. +// Code generated by gotmpl. DO NOT MODIFY. // source: internal/shared/semconvutil/netconv.go.tmpl // Copyright The OpenTelemetry Authors @@ -200,6 +200,15 @@ func splitHostPort(hostport string) (host string, port int) { func netProtocol(proto string) (name string, version string) { name, version, _ = strings.Cut(proto, "/") - name = strings.ToLower(name) + switch name { + case "HTTP": + name = "http" + case "QUIC": + name = "quic" + case "SPDY": + name = "spdy" + default: + name = strings.ToLower(name) + } return name, version } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go index ea504e396f..d62ce44b00 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go @@ -35,14 +35,14 @@ func (l *Labeler) Get() []attribute.KeyValue { type labelerContextKeyType int -const lablelerContextKey labelerContextKeyType = 0 +const labelerContextKey labelerContextKeyType = 0 // ContextWithLabeler returns a new context with the provided Labeler instance. // Attributes added to the specified labeler will be injected into metrics // emitted by the instrumentation. Only one labeller can be injected into the // context. Injecting it multiple times will override the previous calls. func ContextWithLabeler(parent context.Context, l *Labeler) context.Context { - return context.WithValue(parent, lablelerContextKey, l) + return context.WithValue(parent, labelerContextKey, l) } // LabelerFromContext retrieves a Labeler instance from the provided context if @@ -50,7 +50,7 @@ func ContextWithLabeler(parent context.Context, l *Labeler) context.Context { // Labeler is returned and the second return value is false. In this case it is // safe to use the Labeler but any attributes added to it will not be used. func LabelerFromContext(ctx context.Context) (*Labeler, bool) { - l, ok := ctx.Value(lablelerContextKey).(*Labeler) + l, ok := ctx.Value(labelerContextKey).(*Labeler) if !ok { l = &Labeler{} } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go index 386f09e1b7..6be4c1fde2 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go @@ -5,13 +5,6 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http // Version is the current release version of the otelhttp instrumentation. func Version() string { - return "0.59.0" + return "0.61.0" // This string is updated by the pre_release.sh script during release } - -// SemVersion is the semantic version to be supplied to tracer/meter creation. -// -// Deprecated: Use [Version] instead. -func SemVersion() string { - return Version() -} diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go index 59b3a95a7d..df453dcce0 100644 --- a/vendor/golang.org/x/crypto/ed25519/ed25519.go +++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go @@ -2,16 +2,19 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package ed25519 implements the Ed25519 signature algorithm. See -// https://ed25519.cr.yp.to/. +// Package ed25519 implements the Ed25519 signature algorithm. // // These functions are also compatible with the “Ed25519” function defined in -// RFC 8032. However, unlike RFC 8032's formulation, this package's private key +// [RFC 8032]. However, unlike RFC 8032's formulation, this package's private key // representation includes a public key suffix to make multiple signing // operations with the same key more efficient. This package refers to the RFC // 8032 private key as the “seed”. // -// This package is a wrapper around the standard library crypto/ed25519 package. +// The ed25519 package is a wrapper for the Ed25519 implementation in the +// crypto/ed25519 package. It is [frozen] and is not accepting new features. +// +// [RFC 8032]: https://datatracker.ietf.org/doc/html/rfc8032 +// [frozen]: https://go.dev/wiki/Frozen package ed25519 import ( diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go index 3685b34458..75df77406d 100644 --- a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go +++ b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go @@ -3,6 +3,10 @@ // license that can be found in the LICENSE file. // Package salsa provides low-level access to functions in the Salsa family. +// +// Deprecated: this package exposes unsafe low-level operations. New applications +// should consider using the AEAD construction in golang.org/x/crypto/chacha20poly1305 +// instead. Existing users should migrate to golang.org/x/crypto/salsa20. package salsa import "math/bits" diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go index db1c95fab1..24cea68820 100644 --- a/vendor/golang.org/x/net/context/context.go +++ b/vendor/golang.org/x/net/context/context.go @@ -2,44 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package context defines the Context type, which carries deadlines, -// cancellation signals, and other request-scoped values across API boundaries -// and between processes. -// As of Go 1.7 this package is available in the standard library under the -// name [context], and migrating to it can be done automatically with [go fix]. -// -// Incoming requests to a server should create a [Context], and outgoing -// calls to servers should accept a Context. The chain of function -// calls between them must propagate the Context, optionally replacing -// it with a derived Context created using [WithCancel], [WithDeadline], -// [WithTimeout], or [WithValue]. -// -// Programs that use Contexts should follow these rules to keep interfaces -// consistent across packages and enable static analysis tools to check context -// propagation: -// -// Do not store Contexts inside a struct type; instead, pass a Context -// explicitly to each function that needs it. This is discussed further in -// https://go.dev/blog/context-and-structs. The Context should be the first -// parameter, typically named ctx: -// -// func DoSomething(ctx context.Context, arg Arg) error { -// // ... use ctx ... -// } -// -// Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] -// if you are unsure about which Context to use. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. +// Package context has been superseded by the standard library [context] package. // -// The same Context may be passed to functions running in different goroutines; -// Contexts are safe for simultaneous use by multiple goroutines. -// -// See https://go.dev/blog/context for example code for a server that uses -// Contexts. -// -// [go fix]: https://go.dev/cmd/go#hdr-Update_packages_to_use_new_APIs +// Deprecated: Use the standard library context package instead. package context import ( @@ -51,36 +16,37 @@ import ( // API boundaries. // // Context's methods may be called by multiple goroutines simultaneously. +// +//go:fix inline type Context = context.Context // Canceled is the error returned by [Context.Err] when the context is canceled // for some reason other than its deadline passing. +// +//go:fix inline var Canceled = context.Canceled // DeadlineExceeded is the error returned by [Context.Err] when the context is canceled // due to its deadline passing. +// +//go:fix inline var DeadlineExceeded = context.DeadlineExceeded // Background returns a non-nil, empty Context. It is never canceled, has no // values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming // requests. -func Background() Context { - return background -} +// +//go:fix inline +func Background() Context { return context.Background() } // TODO returns a non-nil, empty Context. Code should use context.TODO when // it's unclear which Context to use or it is not yet available (because the // surrounding function has not yet been extended to accept a Context // parameter). -func TODO() Context { - return todo -} - -var ( - background = context.Background() - todo = context.TODO() -) +// +//go:fix inline +func TODO() Context { return context.TODO() } // A CancelFunc tells an operation to abandon its work. // A CancelFunc does not wait for the work to stop. @@ -95,6 +61,8 @@ type CancelFunc = context.CancelFunc // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this [Context] complete. +// +//go:fix inline func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { return context.WithCancel(parent) } @@ -108,6 +76,8 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this [Context] complete. +// +//go:fix inline func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { return context.WithDeadline(parent, d) } @@ -122,6 +92,8 @@ func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { // defer cancel() // releases resources if slowOperation completes before timeout elapses // return slowOperation(ctx) // } +// +//go:fix inline func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { return context.WithTimeout(parent, timeout) } @@ -139,6 +111,8 @@ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { // interface{}, context keys often have concrete type // struct{}. Alternatively, exported context key variables' static // type should be a pointer or interface. +// +//go:fix inline func WithValue(parent Context, key, val interface{}) Context { return context.WithValue(parent, key, val) } diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go index 04c6bec210..12f2273706 100644 --- a/vendor/golang.org/x/net/html/escape.go +++ b/vendor/golang.org/x/net/html/escape.go @@ -299,7 +299,7 @@ func escape(w writer, s string) error { case '\r': esc = " " default: - panic("unrecognized escape character") + panic("html: unrecognized escape character") } s = s[i+1:] if _, err := w.WriteString(esc); err != nil { diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go index 518ee4c94e..88fc0056a3 100644 --- a/vendor/golang.org/x/net/html/parse.go +++ b/vendor/golang.org/x/net/html/parse.go @@ -136,7 +136,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { return -1 } default: - panic("unreachable") + panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s)) } } switch s { @@ -179,7 +179,7 @@ func (p *parser) clearStackToContext(s scope) { return } default: - panic("unreachable") + panic(fmt.Sprintf("html: internal error: clearStackToContext unknown scope: %d", s)) } } } @@ -231,7 +231,14 @@ func (p *parser) addChild(n *Node) { } if n.Type == ElementNode { - p.oe = append(p.oe, n) + p.insertOpenElement(n) + } +} + +func (p *parser) insertOpenElement(n *Node) { + p.oe = append(p.oe, n) + if len(p.oe) > 512 { + panic("html: open stack of elements exceeds 512 nodes") } } @@ -810,7 +817,7 @@ func afterHeadIM(p *parser) bool { p.im = inFramesetIM return true case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title: - p.oe = append(p.oe, p.head) + p.insertOpenElement(p.head) defer p.oe.remove(p.head) return inHeadIM(p) case a.Head: @@ -1678,7 +1685,7 @@ func inTableBodyIM(p *parser) bool { return inTableIM(p) } -// Section 12.2.6.4.14. +// Section 13.2.6.4.14. func inRowIM(p *parser) bool { switch p.tok.Type { case StartTagToken: @@ -1690,7 +1697,9 @@ func inRowIM(p *parser) bool { p.im = inCellIM return true case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr: - if p.popUntil(tableScope, a.Tr) { + if p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() p.im = inTableBodyIM return false } @@ -1700,22 +1709,28 @@ func inRowIM(p *parser) bool { case EndTagToken: switch p.tok.DataAtom { case a.Tr: - if p.popUntil(tableScope, a.Tr) { + if p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() p.im = inTableBodyIM return true } // Ignore the token. return true case a.Table: - if p.popUntil(tableScope, a.Tr) { + if p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() p.im = inTableBodyIM return false } // Ignore the token. return true case a.Tbody, a.Tfoot, a.Thead: - if p.elementInScope(tableScope, p.tok.DataAtom) { - p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String()) + if p.elementInScope(tableScope, p.tok.DataAtom) && p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() + p.im = inTableBodyIM return false } // Ignore the token. @@ -2222,16 +2237,20 @@ func parseForeignContent(p *parser) bool { p.acknowledgeSelfClosingTag() } case EndTagToken: + if strings.EqualFold(p.oe[len(p.oe)-1].Data, p.tok.Data) { + p.oe = p.oe[:len(p.oe)-1] + return true + } for i := len(p.oe) - 1; i >= 0; i-- { - if p.oe[i].Namespace == "" { - return p.im(p) - } if strings.EqualFold(p.oe[i].Data, p.tok.Data) { p.oe = p.oe[:i] + return true + } + if i > 0 && p.oe[i-1].Namespace == "" { break } } - return true + return p.im(p) default: // Ignore the token. } @@ -2312,9 +2331,13 @@ func (p *parser) parseCurrentToken() { } } -func (p *parser) parse() error { +func (p *parser) parse() (err error) { + defer func() { + if panicErr := recover(); panicErr != nil { + err = fmt.Errorf("%s", panicErr) + } + }() // Iterate until EOF. Any other error will cause an early return. - var err error for err != io.EOF { // CDATA sections are allowed only in foreign content. n := p.oe.top() @@ -2343,6 +2366,8 @@ func (p *parser) parse() error { // s. Conversely, explicit s in r's data can be silently dropped, // with no corresponding node in the resulting tree. // +// Parse will reject HTML that is nested deeper than 512 elements. +// // The input is assumed to be UTF-8 encoded. func Parse(r io.Reader) (*Node, error) { return ParseWithOptions(r) diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go index e8c1233455..0157d89e1f 100644 --- a/vendor/golang.org/x/net/html/render.go +++ b/vendor/golang.org/x/net/html/render.go @@ -184,7 +184,7 @@ func render1(w writer, n *Node) error { return err } - // Add initial newline where there is danger of a newline beging ignored. + // Add initial newline where there is danger of a newline being ignored. if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") { switch n.Data { case "pre", "listing", "textarea": diff --git a/vendor/golang.org/x/net/http2/config.go b/vendor/golang.org/x/net/http2/config.go index ca645d9a1a..8a7a89d016 100644 --- a/vendor/golang.org/x/net/http2/config.go +++ b/vendor/golang.org/x/net/http2/config.go @@ -27,6 +27,7 @@ import ( // - If the resulting value is zero or out of range, use a default. type http2Config struct { MaxConcurrentStreams uint32 + StrictMaxConcurrentRequests bool MaxDecoderHeaderTableSize uint32 MaxEncoderHeaderTableSize uint32 MaxReadFrameSize uint32 @@ -55,7 +56,7 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config { PermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites, CountError: h2.CountError, } - fillNetHTTPServerConfig(&conf, h1) + fillNetHTTPConfig(&conf, h1.HTTP2) setConfigDefaults(&conf, true) return conf } @@ -64,12 +65,13 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config { // (the net/http Transport). func configFromTransport(h2 *Transport) http2Config { conf := http2Config{ - MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, - MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, - MaxReadFrameSize: h2.MaxReadFrameSize, - SendPingTimeout: h2.ReadIdleTimeout, - PingTimeout: h2.PingTimeout, - WriteByteTimeout: h2.WriteByteTimeout, + StrictMaxConcurrentRequests: h2.StrictMaxConcurrentStreams, + MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, + MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, + MaxReadFrameSize: h2.MaxReadFrameSize, + SendPingTimeout: h2.ReadIdleTimeout, + PingTimeout: h2.PingTimeout, + WriteByteTimeout: h2.WriteByteTimeout, } // Unlike most config fields, where out-of-range values revert to the default, @@ -81,7 +83,7 @@ func configFromTransport(h2 *Transport) http2Config { } if h2.t1 != nil { - fillNetHTTPTransportConfig(&conf, h2.t1) + fillNetHTTPConfig(&conf, h2.t1.HTTP2) } setConfigDefaults(&conf, false) return conf @@ -120,3 +122,48 @@ func adjustHTTP1MaxHeaderSize(n int64) int64 { const typicalHeaders = 10 // conservative return n + typicalHeaders*perFieldOverhead } + +func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { + if h2 == nil { + return + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if http2ConfigStrictMaxConcurrentRequests(h2) { + conf.StrictMaxConcurrentRequests = true + } + if h2.MaxEncoderHeaderTableSize != 0 { + conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) + } + if h2.MaxDecoderHeaderTableSize != 0 { + conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if h2.MaxReadFrameSize != 0 { + conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) + } + if h2.MaxReceiveBufferPerConnection != 0 { + conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) + } + if h2.MaxReceiveBufferPerStream != 0 { + conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) + } + if h2.SendPingTimeout != 0 { + conf.SendPingTimeout = h2.SendPingTimeout + } + if h2.PingTimeout != 0 { + conf.PingTimeout = h2.PingTimeout + } + if h2.WriteByteTimeout != 0 { + conf.WriteByteTimeout = h2.WriteByteTimeout + } + if h2.PermitProhibitedCipherSuites { + conf.PermitProhibitedCipherSuites = true + } + if h2.CountError != nil { + conf.CountError = h2.CountError + } +} diff --git a/vendor/golang.org/x/net/http2/config_go124.go b/vendor/golang.org/x/net/http2/config_go124.go deleted file mode 100644 index 5b516c55ff..0000000000 --- a/vendor/golang.org/x/net/http2/config_go124.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.24 - -package http2 - -import "net/http" - -// fillNetHTTPServerConfig sets fields in conf from srv.HTTP2. -func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) { - fillNetHTTPConfig(conf, srv.HTTP2) -} - -// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. -func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { - fillNetHTTPConfig(conf, tr.HTTP2) -} - -func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { - if h2 == nil { - return - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if h2.MaxEncoderHeaderTableSize != 0 { - conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) - } - if h2.MaxDecoderHeaderTableSize != 0 { - conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if h2.MaxReadFrameSize != 0 { - conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) - } - if h2.MaxReceiveBufferPerConnection != 0 { - conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) - } - if h2.MaxReceiveBufferPerStream != 0 { - conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) - } - if h2.SendPingTimeout != 0 { - conf.SendPingTimeout = h2.SendPingTimeout - } - if h2.PingTimeout != 0 { - conf.PingTimeout = h2.PingTimeout - } - if h2.WriteByteTimeout != 0 { - conf.WriteByteTimeout = h2.WriteByteTimeout - } - if h2.PermitProhibitedCipherSuites { - conf.PermitProhibitedCipherSuites = true - } - if h2.CountError != nil { - conf.CountError = h2.CountError - } -} diff --git a/vendor/golang.org/x/net/http2/config_go125.go b/vendor/golang.org/x/net/http2/config_go125.go new file mode 100644 index 0000000000..b4373fe33c --- /dev/null +++ b/vendor/golang.org/x/net/http2/config_go125.go @@ -0,0 +1,15 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.26 + +package http2 + +import ( + "net/http" +) + +func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool { + return false +} diff --git a/vendor/golang.org/x/net/http2/config_go126.go b/vendor/golang.org/x/net/http2/config_go126.go new file mode 100644 index 0000000000..6b071c149d --- /dev/null +++ b/vendor/golang.org/x/net/http2/config_go126.go @@ -0,0 +1,15 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.26 + +package http2 + +import ( + "net/http" +) + +func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool { + return h2.StrictMaxConcurrentRequests +} diff --git a/vendor/golang.org/x/net/http2/config_pre_go124.go b/vendor/golang.org/x/net/http2/config_pre_go124.go deleted file mode 100644 index 060fd6c64c..0000000000 --- a/vendor/golang.org/x/net/http2/config_pre_go124.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.24 - -package http2 - -import "net/http" - -// Pre-Go 1.24 fallback. -// The Server.HTTP2 and Transport.HTTP2 config fields were added in Go 1.24. - -func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {} - -func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {} diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index db3264da8c..9a4bd123c9 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -280,6 +280,8 @@ type Framer struct { // lastHeaderStream is non-zero if the last frame was an // unfinished HEADERS/CONTINUATION. lastHeaderStream uint32 + // lastFrameType holds the type of the last frame for verifying frame order. + lastFrameType FrameType maxReadSize uint32 headerBuf [frameHeaderLen]byte @@ -347,7 +349,7 @@ func (fr *Framer) maxHeaderListSize() uint32 { func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) { // Write the FrameHeader. f.wbuf = append(f.wbuf[:0], - 0, // 3 bytes of length, filled in in endWrite + 0, // 3 bytes of length, filled in endWrite 0, 0, byte(ftype), @@ -488,30 +490,41 @@ func terminalReadFrameError(err error) bool { return err != nil } -// ReadFrame reads a single frame. The returned Frame is only valid -// until the next call to ReadFrame. +// ReadFrameHeader reads the header of the next frame. +// It reads the 9-byte fixed frame header, and does not read any portion of the +// frame payload. The caller is responsible for consuming the payload, either +// with ReadFrameForHeader or directly from the Framer's io.Reader. // -// If the frame is larger than previously set with SetMaxReadFrameSize, the -// returned error is ErrFrameTooLarge. Other errors may be of type -// ConnectionError, StreamError, or anything else from the underlying -// reader. +// If the frame is larger than previously set with SetMaxReadFrameSize, it +// returns the frame header and ErrFrameTooLarge. // -// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID -// indicates the stream responsible for the error. -func (fr *Framer) ReadFrame() (Frame, error) { +// If the returned FrameHeader.StreamID is non-zero, it indicates the stream +// responsible for the error. +func (fr *Framer) ReadFrameHeader() (FrameHeader, error) { fr.errDetail = nil - if fr.lastFrame != nil { - fr.lastFrame.invalidate() - } fh, err := readFrameHeader(fr.headerBuf[:], fr.r) if err != nil { - return nil, err + return fh, err } if fh.Length > fr.maxReadSize { if fh == invalidHTTP1LookingFrameHeader() { - return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge) + return fh, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge) } - return nil, ErrFrameTooLarge + return fh, ErrFrameTooLarge + } + if err := fr.checkFrameOrder(fh); err != nil { + return fh, err + } + return fh, nil +} + +// ReadFrameForHeader reads the payload for the frame with the given FrameHeader. +// +// It behaves identically to ReadFrame, other than not checking the maximum +// frame size. +func (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error) { + if fr.lastFrame != nil { + fr.lastFrame.invalidate() } payload := fr.getReadBuf(fh.Length) if _, err := io.ReadFull(fr.r, payload); err != nil { @@ -527,9 +540,7 @@ func (fr *Framer) ReadFrame() (Frame, error) { } return nil, err } - if err := fr.checkFrameOrder(f); err != nil { - return nil, err - } + fr.lastFrame = f if fr.logReads { fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) } @@ -539,6 +550,24 @@ func (fr *Framer) ReadFrame() (Frame, error) { return f, nil } +// ReadFrame reads a single frame. The returned Frame is only valid +// until the next call to ReadFrame or ReadFrameBodyForHeader. +// +// If the frame is larger than previously set with SetMaxReadFrameSize, the +// returned error is ErrFrameTooLarge. Other errors may be of type +// ConnectionError, StreamError, or anything else from the underlying +// reader. +// +// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID +// indicates the stream responsible for the error. +func (fr *Framer) ReadFrame() (Frame, error) { + fh, err := fr.ReadFrameHeader() + if err != nil { + return nil, err + } + return fr.ReadFrameForHeader(fh) +} + // connError returns ConnectionError(code) but first // stashes away a public reason to the caller can optionally relay it // to the peer before hanging up on them. This might help others debug @@ -551,20 +580,19 @@ func (fr *Framer) connError(code ErrCode, reason string) error { // checkFrameOrder reports an error if f is an invalid frame to return // next from ReadFrame. Mostly it checks whether HEADERS and // CONTINUATION frames are contiguous. -func (fr *Framer) checkFrameOrder(f Frame) error { - last := fr.lastFrame - fr.lastFrame = f +func (fr *Framer) checkFrameOrder(fh FrameHeader) error { + lastType := fr.lastFrameType + fr.lastFrameType = fh.Type if fr.AllowIllegalReads { return nil } - fh := f.Header() if fr.lastHeaderStream != 0 { if fh.Type != FrameContinuation { return fr.connError(ErrCodeProtocol, fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", fh.Type, fh.StreamID, - last.Header().Type, fr.lastHeaderStream)) + lastType, fr.lastHeaderStream)) } if fh.StreamID != fr.lastHeaderStream { return fr.connError(ErrCodeProtocol, @@ -1152,7 +1180,16 @@ type PriorityFrame struct { PriorityParam } -// PriorityParam are the stream prioritzation parameters. +var defaultRFC9218Priority = PriorityParam{ + incremental: 0, + urgency: 3, +} + +// Note that HTTP/2 has had two different prioritization schemes, and +// PriorityParam struct below is a superset of both schemes. The exported +// symbols are from RFC 7540 and the non-exported ones are from RFC 9218. + +// PriorityParam are the stream prioritization parameters. type PriorityParam struct { // StreamDep is a 31-bit stream identifier for the // stream that this stream depends on. Zero means no @@ -1167,6 +1204,20 @@ type PriorityParam struct { // the spec, "Add one to the value to obtain a weight between // 1 and 256." Weight uint8 + + // "The urgency (u) parameter value is Integer (see Section 3.3.1 of + // [STRUCTURED-FIELDS]), between 0 and 7 inclusive, in descending order of + // priority. The default is 3." + urgency uint8 + + // "The incremental (i) parameter value is Boolean (see Section 3.3.6 of + // [STRUCTURED-FIELDS]). It indicates if an HTTP response can be processed + // incrementally, i.e., provide some meaningful output as chunks of the + // response arrive." + // + // We use uint8 (i.e. 0 is false, 1 is true) instead of bool so we can + // avoid unnecessary type conversions and because either type takes 1 byte. + incremental uint8 } func (p PriorityParam) IsZero() bool { diff --git a/vendor/golang.org/x/net/http2/gotrack.go b/vendor/golang.org/x/net/http2/gotrack.go index 9933c9f8c7..9921ca096d 100644 --- a/vendor/golang.org/x/net/http2/gotrack.go +++ b/vendor/golang.org/x/net/http2/gotrack.go @@ -15,21 +15,32 @@ import ( "runtime" "strconv" "sync" + "sync/atomic" ) var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" +// Setting DebugGoroutines to false during a test to disable goroutine debugging +// results in race detector complaints when a test leaves goroutines running before +// returning. Tests shouldn't do this, of course, but when they do it generally shows +// up as infrequent, hard-to-debug flakes. (See #66519.) +// +// Disable goroutine debugging during individual tests with an atomic bool. +// (Note that it's safe to enable/disable debugging mid-test, so the actual race condition +// here is harmless.) +var disableDebugGoroutines atomic.Bool + type goroutineLock uint64 func newGoroutineLock() goroutineLock { - if !DebugGoroutines { + if !DebugGoroutines || disableDebugGoroutines.Load() { return 0 } return goroutineLock(curGoroutineID()) } func (g goroutineLock) check() { - if !DebugGoroutines { + if !DebugGoroutines || disableDebugGoroutines.Load() { return } if curGoroutineID() != uint64(g) { @@ -38,7 +49,7 @@ func (g goroutineLock) check() { } func (g goroutineLock) checkNotOn() { - if !DebugGoroutines { + if !DebugGoroutines || disableDebugGoroutines.Load() { return } if curGoroutineID() == uint64(g) { diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index ea5ae629fd..105fe12fef 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -15,7 +15,6 @@ package http2 // import "golang.org/x/net/http2" import ( "bufio" - "context" "crypto/tls" "errors" "fmt" @@ -35,7 +34,6 @@ var ( VerboseLogs bool logFrameWrites bool logFrameReads bool - inTests bool // Enabling extended CONNECT by causes browsers to attempt to use // WebSockets-over-HTTP/2. This results in problems when the server's websocket @@ -255,15 +253,13 @@ func (cw closeWaiter) Wait() { // idle memory usage with many connections. type bufferedWriter struct { _ incomparable - group synctestGroupInterface // immutable - conn net.Conn // immutable - bw *bufio.Writer // non-nil when data is buffered - byteTimeout time.Duration // immutable, WriteByteTimeout + conn net.Conn // immutable + bw *bufio.Writer // non-nil when data is buffered + byteTimeout time.Duration // immutable, WriteByteTimeout } -func newBufferedWriter(group synctestGroupInterface, conn net.Conn, timeout time.Duration) *bufferedWriter { +func newBufferedWriter(conn net.Conn, timeout time.Duration) *bufferedWriter { return &bufferedWriter{ - group: group, conn: conn, byteTimeout: timeout, } @@ -314,24 +310,18 @@ func (w *bufferedWriter) Flush() error { type bufferedWriterTimeoutWriter bufferedWriter func (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) { - return writeWithByteTimeout(w.group, w.conn, w.byteTimeout, p) + return writeWithByteTimeout(w.conn, w.byteTimeout, p) } // writeWithByteTimeout writes to conn. // If more than timeout passes without any bytes being written to the connection, // the write fails. -func writeWithByteTimeout(group synctestGroupInterface, conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { +func writeWithByteTimeout(conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { if timeout <= 0 { return conn.Write(p) } for { - var now time.Time - if group == nil { - now = time.Now() - } else { - now = group.Now() - } - conn.SetWriteDeadline(now.Add(timeout)) + conn.SetWriteDeadline(time.Now().Add(timeout)) nn, err := conn.Write(p[n:]) n += nn if n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) { @@ -417,14 +407,3 @@ func (s *sorter) SortStrings(ss []string) { // makes that struct also non-comparable, and generally doesn't add // any size (as long as it's first). type incomparable [0]func() - -// synctestGroupInterface is the methods of synctestGroup used by Server and Transport. -// It's defined as an interface here to let us keep synctestGroup entirely test-only -// and not a part of non-test builds. -type synctestGroupInterface interface { - Join() - Now() time.Time - NewTimer(d time.Duration) timer - AfterFunc(d time.Duration, f func()) timer - ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) -} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 51fca38f61..bdc5520ebd 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -176,44 +176,15 @@ type Server struct { // so that we don't embed a Mutex in this struct, which will make the // struct non-copyable, which might break some callers. state *serverInternalState - - // Synchronization group used for testing. - // Outside of tests, this is nil. - group synctestGroupInterface -} - -func (s *Server) markNewGoroutine() { - if s.group != nil { - s.group.Join() - } -} - -func (s *Server) now() time.Time { - if s.group != nil { - return s.group.Now() - } - return time.Now() -} - -// newTimer creates a new time.Timer, or a synthetic timer in tests. -func (s *Server) newTimer(d time.Duration) timer { - if s.group != nil { - return s.group.NewTimer(d) - } - return timeTimer{time.NewTimer(d)} -} - -// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. -func (s *Server) afterFunc(d time.Duration, f func()) timer { - if s.group != nil { - return s.group.AfterFunc(d, f) - } - return timeTimer{time.AfterFunc(d, f)} } type serverInternalState struct { mu sync.Mutex activeConns map[*serverConn]struct{} + + // Pool of error channels. This is per-Server rather than global + // because channels can't be reused across synctest bubbles. + errChanPool sync.Pool } func (s *serverInternalState) registerConn(sc *serverConn) { @@ -245,6 +216,27 @@ func (s *serverInternalState) startGracefulShutdown() { s.mu.Unlock() } +// Global error channel pool used for uninitialized Servers. +// We use a per-Server pool when possible to avoid using channels across synctest bubbles. +var errChanPool = sync.Pool{ + New: func() any { return make(chan error, 1) }, +} + +func (s *serverInternalState) getErrChan() chan error { + if s == nil { + return errChanPool.Get().(chan error) // Server used without calling ConfigureServer + } + return s.errChanPool.Get().(chan error) +} + +func (s *serverInternalState) putErrChan(ch chan error) { + if s == nil { + errChanPool.Put(ch) // Server used without calling ConfigureServer + return + } + s.errChanPool.Put(ch) +} + // ConfigureServer adds HTTP/2 support to a net/http Server. // // The configuration conf may be nil. @@ -257,7 +249,10 @@ func ConfigureServer(s *http.Server, conf *Server) error { if conf == nil { conf = new(Server) } - conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} + conf.state = &serverInternalState{ + activeConns: make(map[*serverConn]struct{}), + errChanPool: sync.Pool{New: func() any { return make(chan error, 1) }}, + } if h1, h2 := s, conf; h2.IdleTimeout == 0 { if h1.IdleTimeout != 0 { h2.IdleTimeout = h1.IdleTimeout @@ -423,6 +418,9 @@ func (o *ServeConnOpts) handler() http.Handler { // // The opts parameter is optional. If nil, default values are used. func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { + if opts == nil { + opts = &ServeConnOpts{} + } s.serveConn(c, opts, nil) } @@ -438,7 +436,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon conn: c, baseCtx: baseCtx, remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(s.group, c, conf.WriteByteTimeout), + bw: newBufferedWriter(c, conf.WriteByteTimeout), handler: opts.handler(), streams: make(map[uint32]*stream), readFrameCh: make(chan readFrameResult), @@ -638,11 +636,11 @@ type serverConn struct { pingSent bool sentPingData [8]byte goAwayCode ErrCode - shutdownTimer timer // nil until used - idleTimer timer // nil if unused + shutdownTimer *time.Timer // nil until used + idleTimer *time.Timer // nil if unused readIdleTimeout time.Duration pingTimeout time.Duration - readIdleTimer timer // nil if unused + readIdleTimer *time.Timer // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer @@ -687,12 +685,12 @@ type stream struct { flow outflow // limits writing from Handler to client inflow inflow // what the client is allowed to POST/etc to us state streamState - resetQueued bool // RST_STREAM queued for write; set by sc.resetStream - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - readDeadline timer // nil if unused - writeDeadline timer // nil if unused - closeErr error // set before cw is closed + resetQueued bool // RST_STREAM queued for write; set by sc.resetStream + gotTrailerHeader bool // HEADER frame for trailers was seen + wroteHeaders bool // whether we wrote headers (not status 100) + readDeadline *time.Timer // nil if unused + writeDeadline *time.Timer // nil if unused + closeErr error // set before cw is closed trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -848,7 +846,6 @@ type readFrameResult struct { // consumer is done with the frame. // It's run on its own goroutine. func (sc *serverConn) readFrames() { - sc.srv.markNewGoroutine() gate := make(chan struct{}) gateDone := func() { gate <- struct{}{} } for { @@ -881,7 +878,6 @@ type frameWriteResult struct { // At most one goroutine can be running writeFrameAsync at a time per // serverConn. func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) { - sc.srv.markNewGoroutine() var err error if wd == nil { err = wr.write.writeFrame(sc) @@ -965,22 +961,22 @@ func (sc *serverConn) serve(conf http2Config) { sc.setConnState(http.StateIdle) if sc.srv.IdleTimeout > 0 { - sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) + sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } if conf.SendPingTimeout > 0 { sc.readIdleTimeout = conf.SendPingTimeout - sc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) + sc.readIdleTimer = time.AfterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) defer sc.readIdleTimer.Stop() } go sc.readFrames() // closed by defer sc.conn.Close above - settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer) + settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer) defer settingsTimer.Stop() - lastFrameTime := sc.srv.now() + lastFrameTime := time.Now() loopNum := 0 for { loopNum++ @@ -994,7 +990,7 @@ func (sc *serverConn) serve(conf http2Config) { case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: - lastFrameTime = sc.srv.now() + lastFrameTime = time.Now() // Process any written frames before reading new frames from the client since a // written frame could have triggered a new stream to be started. if sc.writingFrameAsync { @@ -1077,7 +1073,7 @@ func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) { } pingAt := lastFrameReadTime.Add(sc.readIdleTimeout) - now := sc.srv.now() + now := time.Now() if pingAt.After(now) { // We received frames since arming the ping timer. // Reset it for the next possible timeout. @@ -1141,10 +1137,10 @@ func (sc *serverConn) readPreface() error { errc <- nil } }() - timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server? + timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server? defer timer.Stop() select { - case <-timer.C(): + case <-timer.C: return errPrefaceTimeout case err := <-errc: if err == nil { @@ -1156,10 +1152,6 @@ func (sc *serverConn) readPreface() error { } } -var errChanPool = sync.Pool{ - New: func() interface{} { return make(chan error, 1) }, -} - var writeDataPool = sync.Pool{ New: func() interface{} { return new(writeData) }, } @@ -1167,7 +1159,7 @@ var writeDataPool = sync.Pool{ // writeDataFromHandler writes DATA response frames from a handler on // the given stream. func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error { - ch := errChanPool.Get().(chan error) + ch := sc.srv.state.getErrChan() writeArg := writeDataPool.Get().(*writeData) *writeArg = writeData{stream.id, data, endStream} err := sc.writeFrameFromHandler(FrameWriteRequest{ @@ -1199,7 +1191,7 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea return errStreamClosed } } - errChanPool.Put(ch) + sc.srv.state.putErrChan(ch) if frameWriteDone { writeDataPool.Put(writeArg) } @@ -1513,7 +1505,7 @@ func (sc *serverConn) goAway(code ErrCode) { func (sc *serverConn) shutDownIn(d time.Duration) { sc.serveG.check() - sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer) + sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer) } func (sc *serverConn) resetStream(se StreamError) { @@ -2118,7 +2110,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // (in Go 1.8), though. That's a more sane option anyway. if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) - st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout) + st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } return sc.scheduleHandler(id, rw, req, handler) @@ -2216,7 +2208,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.initialStreamRecvWindowSize) if sc.hs.WriteTimeout > 0 { - st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) + st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } sc.streams[id] = st @@ -2405,7 +2397,6 @@ func (sc *serverConn) handlerDone() { // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { - sc.srv.markNewGoroutine() defer sc.sendServeMsg(handlerDoneMsg) didPanic := true defer func() { @@ -2454,7 +2445,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro // waiting for this frame to be written, so an http.Flush mid-handler // writes out the correct value of keys, before a handler later potentially // mutates it. - errc = errChanPool.Get().(chan error) + errc = sc.srv.state.getErrChan() } if err := sc.writeFrameFromHandler(FrameWriteRequest{ write: headerData, @@ -2466,7 +2457,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro if errc != nil { select { case err := <-errc: - errChanPool.Put(errc) + sc.srv.state.putErrChan(errc) return err case <-sc.doneServing: return errClientDisconnected @@ -2573,7 +2564,7 @@ func (b *requestBody) Read(p []byte) (n int, err error) { if err == io.EOF { b.sawEOF = true } - if b.conn == nil && inTests { + if b.conn == nil { return } b.conn.noteBodyReadFromHandler(b.stream, n, err) @@ -2702,7 +2693,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { var date string if _, ok := rws.snapHeader["Date"]; !ok { // TODO(bradfitz): be faster here, like net/http? measure. - date = rws.conn.srv.now().UTC().Format(http.TimeFormat) + date = time.Now().UTC().Format(http.TimeFormat) } for _, v := range rws.snapHeader["Trailer"] { @@ -2824,7 +2815,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() { func (w *responseWriter) SetReadDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { + if !deadline.IsZero() && deadline.Before(time.Now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onReadTimeout() @@ -2840,9 +2831,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { if deadline.IsZero() { st.readDeadline = nil } else if st.readDeadline == nil { - st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout) + st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout) } else { - st.readDeadline.Reset(deadline.Sub(sc.srv.now())) + st.readDeadline.Reset(deadline.Sub(time.Now())) } }) return nil @@ -2850,7 +2841,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { + if !deadline.IsZero() && deadline.Before(time.Now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onWriteTimeout() @@ -2866,9 +2857,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { if deadline.IsZero() { st.writeDeadline = nil } else if st.writeDeadline == nil { - st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout) + st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout) } else { - st.writeDeadline.Reset(deadline.Sub(sc.srv.now())) + st.writeDeadline.Reset(deadline.Sub(time.Now())) } }) return nil @@ -3147,7 +3138,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error { method: opts.Method, url: u, header: cloneHeader(opts.Header), - done: errChanPool.Get().(chan error), + done: sc.srv.state.getErrChan(), } select { @@ -3164,7 +3155,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error { case <-st.cw: return errStreamClosed case err := <-msg.done: - errChanPool.Put(msg.done) + sc.srv.state.putErrChan(msg.done) return err } } diff --git a/vendor/golang.org/x/net/http2/timer.go b/vendor/golang.org/x/net/http2/timer.go deleted file mode 100644 index 0b1c17b812..0000000000 --- a/vendor/golang.org/x/net/http2/timer.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package http2 - -import "time" - -// A timer is a time.Timer, as an interface which can be replaced in tests. -type timer = interface { - C() <-chan time.Time - Reset(d time.Duration) bool - Stop() bool -} - -// timeTimer adapts a time.Timer to the timer interface. -type timeTimer struct { - *time.Timer -} - -func (t timeTimer) C() <-chan time.Time { return t.Timer.C } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index f26356b9cd..1965913e54 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -9,6 +9,7 @@ package http2 import ( "bufio" "bytes" + "compress/flate" "compress/gzip" "context" "crypto/rand" @@ -193,50 +194,6 @@ type Transport struct { type transportTestHooks struct { newclientconn func(*ClientConn) - group synctestGroupInterface -} - -func (t *Transport) markNewGoroutine() { - if t != nil && t.transportTestHooks != nil { - t.transportTestHooks.group.Join() - } -} - -func (t *Transport) now() time.Time { - if t != nil && t.transportTestHooks != nil { - return t.transportTestHooks.group.Now() - } - return time.Now() -} - -func (t *Transport) timeSince(when time.Time) time.Duration { - if t != nil && t.transportTestHooks != nil { - return t.now().Sub(when) - } - return time.Since(when) -} - -// newTimer creates a new time.Timer, or a synthetic timer in tests. -func (t *Transport) newTimer(d time.Duration) timer { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.NewTimer(d) - } - return timeTimer{time.NewTimer(d)} -} - -// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. -func (t *Transport) afterFunc(d time.Duration, f func()) timer { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.AfterFunc(d, f) - } - return timeTimer{time.AfterFunc(d, f)} -} - -func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.ContextWithTimeout(ctx, d) - } - return context.WithTimeout(ctx, d) } func (t *Transport) maxHeaderListSize() uint32 { @@ -366,7 +323,7 @@ type ClientConn struct { readerErr error // set before readerDone is closed idleTimeout time.Duration // or 0 for never - idleTimer timer + idleTimer *time.Timer mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes @@ -399,6 +356,7 @@ type ClientConn struct { readIdleTimeout time.Duration pingTimeout time.Duration extendedConnectAllowed bool + strictMaxConcurrentStreams bool // rstStreamPingsBlocked works around an unfortunate gRPC behavior. // gRPC strictly limits the number of PING frames that it will receive. @@ -534,14 +492,12 @@ func (cs *clientStream) closeReqBodyLocked() { cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed go func() { - cs.cc.t.markNewGoroutine() cs.reqBody.Close() close(reqBodyClosed) }() } type stickyErrWriter struct { - group synctestGroupInterface conn net.Conn timeout time.Duration err *error @@ -551,7 +507,7 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { if *sew.err != nil { return 0, *sew.err } - n, err = writeWithByteTimeout(sew.group, sew.conn, sew.timeout, p) + n, err = writeWithByteTimeout(sew.conn, sew.timeout, p) *sew.err = err return n, err } @@ -650,9 +606,9 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - tm := t.newTimer(d) + tm := time.NewTimer(d) select { - case <-tm.C(): + case <-tm.C: t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) continue case <-req.Context().Done(): @@ -699,6 +655,7 @@ var ( errClientConnUnusable = errors.New("http2: client conn not usable") errClientConnNotEstablished = errors.New("http2: client conn could not be established") errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") + errClientConnForceClosed = errors.New("http2: client connection force closed via ClientConn.Close") ) // shouldRetryRequest is called by RoundTrip when a request fails to get @@ -829,7 +786,8 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro initialWindowSize: 65535, // spec default initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream, maxConcurrentStreams: initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings. - peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. + strictMaxConcurrentStreams: conf.StrictMaxConcurrentRequests, + peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. streams: make(map[uint32]*clientStream), singleUse: singleUse, seenSettingsChan: make(chan struct{}), @@ -838,14 +796,11 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro pingTimeout: conf.PingTimeout, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), - lastActive: t.now(), + lastActive: time.Now(), } - var group synctestGroupInterface if t.transportTestHooks != nil { - t.markNewGoroutine() t.transportTestHooks.newclientconn(cc) c = cc.tconn - group = t.group } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -857,7 +812,6 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // TODO: adjust this writer size to account for frame size + // MTU + crypto/tls record padding. cc.bw = bufio.NewWriter(stickyErrWriter{ - group: group, conn: c, timeout: conf.WriteByteTimeout, err: &cc.werr, @@ -906,7 +860,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // Start the idle timer after the connection is fully initialized. if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d - cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout) + cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) } go cc.readLoop() @@ -917,7 +871,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.pingTimeout // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout) + ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1067,7 +1021,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { return } var maxConcurrentOkay bool - if cc.t.StrictMaxConcurrentStreams { + if cc.strictMaxConcurrentStreams { // We'll tell the caller we can take a new request to // prevent the caller from dialing a new TCP // connection, but then we'll block later before @@ -1120,7 +1074,7 @@ func (cc *ClientConn) tooIdleLocked() bool { // times are compared based on their wall time. We don't want // to reuse a connection that's been sitting idle during // VM/laptop suspend if monotonic time was also frozen. - return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout + return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout } // onIdleTimeout is called from a time.AfterFunc goroutine. It will @@ -1186,7 +1140,6 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { done := make(chan struct{}) cancelled := false // guarded by cc.mu go func() { - cc.t.markNewGoroutine() cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1257,8 +1210,7 @@ func (cc *ClientConn) closeForError(err error) { // // In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. func (cc *ClientConn) Close() error { - err := errors.New("http2: client connection force closed via ClientConn.Close") - cc.closeForError(err) + cc.closeForError(errClientConnForceClosed) return nil } @@ -1427,7 +1379,6 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) // // It sends the request and performs post-request cleanup (closing Request.Body, etc.). func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) { - cs.cc.t.markNewGoroutine() err := cs.writeRequest(req, streamf) cs.cleanupWriteRequest(err) } @@ -1558,9 +1509,9 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := cc.t.newTimer(d) + timer := time.NewTimer(d) defer timer.Stop() - respHeaderTimer = timer.C() + respHeaderTimer = timer.C respHeaderRecv = cs.respHeaderRecv } // Wait until the peer half-closes its end of the stream, @@ -1753,7 +1704,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { // Return a fatal error which aborts the retry loop. return errClientConnNotEstablished } - cc.lastActive = cc.t.now() + cc.lastActive = time.Now() if cc.closed || !cc.canTakeNewRequestLocked() { return errClientConnUnusable } @@ -2092,10 +2043,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) { if len(cc.streams) != slen-1 { panic("forgetting unknown stream id") } - cc.lastActive = cc.t.now() + cc.lastActive = time.Now() if len(cc.streams) == 0 && cc.idleTimer != nil { cc.idleTimer.Reset(cc.idleTimeout) - cc.lastIdle = cc.t.now() + cc.lastIdle = time.Now() } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. @@ -2121,7 +2072,6 @@ type clientConnReadLoop struct { // readLoop runs in its own goroutine and reads and dispatches frames. func (cc *ClientConn) readLoop() { - cc.t.markNewGoroutine() rl := &clientConnReadLoop{cc: cc} defer rl.cleanup() cc.readerErr = rl.run() @@ -2188,9 +2138,9 @@ func (rl *clientConnReadLoop) cleanup() { if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { unusedWaitTime = cc.idleTimeout } - idleTime := cc.t.now().Sub(cc.lastActive) + idleTime := time.Now().Sub(cc.lastActive) if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { - cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { + cc.idleTimer = time.AfterFunc(unusedWaitTime-idleTime, func() { cc.t.connPool().MarkDead(cc) }) } else { @@ -2250,9 +2200,9 @@ func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false readIdleTimeout := cc.readIdleTimeout - var t timer + var t *time.Timer if readIdleTimeout != 0 { - t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck) + t = time.AfterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -2998,7 +2948,6 @@ func (cc *ClientConn) Ping(ctx context.Context) error { var pingError error errc := make(chan struct{}) go func() { - cc.t.markNewGoroutine() cc.wmu.Lock() defer cc.wmu.Unlock() if pingError = cc.fr.WritePing(false, p); pingError != nil { @@ -3128,35 +3077,102 @@ type erringRoundTripper struct{ err error } func (rt erringRoundTripper) RoundTripErr() error { return rt.err } func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err } +var errConcurrentReadOnResBody = errors.New("http2: concurrent read on response body") + // gzipReader wraps a response body so it can lazily -// call gzip.NewReader on the first call to Read +// get gzip.Reader from the pool on the first call to Read. +// After Close is called it puts gzip.Reader to the pool immediately +// if there is no Read in progress or later when Read completes. type gzipReader struct { _ incomparable body io.ReadCloser // underlying Response.Body - zr *gzip.Reader // lazily-initialized gzip reader - zerr error // sticky error + mu sync.Mutex // guards zr and zerr + zr *gzip.Reader // stores gzip reader from the pool between reads + zerr error // sticky gzip reader init error or sentinel value to detect concurrent read and read after close } -func (gz *gzipReader) Read(p []byte) (n int, err error) { +type eofReader struct{} + +func (eofReader) Read([]byte) (int, error) { return 0, io.EOF } +func (eofReader) ReadByte() (byte, error) { return 0, io.EOF } + +var gzipPool = sync.Pool{New: func() any { return new(gzip.Reader) }} + +// gzipPoolGet gets a gzip.Reader from the pool and resets it to read from r. +func gzipPoolGet(r io.Reader) (*gzip.Reader, error) { + zr := gzipPool.Get().(*gzip.Reader) + if err := zr.Reset(r); err != nil { + gzipPoolPut(zr) + return nil, err + } + return zr, nil +} + +// gzipPoolPut puts a gzip.Reader back into the pool. +func gzipPoolPut(zr *gzip.Reader) { + // Reset will allocate bufio.Reader if we pass it anything + // other than a flate.Reader, so ensure that it's getting one. + var r flate.Reader = eofReader{} + zr.Reset(r) + gzipPool.Put(zr) +} + +// acquire returns a gzip.Reader for reading response body. +// The reader must be released after use. +func (gz *gzipReader) acquire() (*gzip.Reader, error) { + gz.mu.Lock() + defer gz.mu.Unlock() if gz.zerr != nil { - return 0, gz.zerr + return nil, gz.zerr } if gz.zr == nil { - gz.zr, err = gzip.NewReader(gz.body) - if err != nil { - gz.zerr = err - return 0, err + gz.zr, gz.zerr = gzipPoolGet(gz.body) + if gz.zerr != nil { + return nil, gz.zerr } } - return gz.zr.Read(p) + ret := gz.zr + gz.zr, gz.zerr = nil, errConcurrentReadOnResBody + return ret, nil } -func (gz *gzipReader) Close() error { - if err := gz.body.Close(); err != nil { - return err +// release returns the gzip.Reader to the pool if Close was called during Read. +func (gz *gzipReader) release(zr *gzip.Reader) { + gz.mu.Lock() + defer gz.mu.Unlock() + if gz.zerr == errConcurrentReadOnResBody { + gz.zr, gz.zerr = zr, nil + } else { // fs.ErrClosed + gzipPoolPut(zr) + } +} + +// close returns the gzip.Reader to the pool immediately or +// signals release to do so after Read completes. +func (gz *gzipReader) close() { + gz.mu.Lock() + defer gz.mu.Unlock() + if gz.zerr == nil && gz.zr != nil { + gzipPoolPut(gz.zr) + gz.zr = nil } gz.zerr = fs.ErrClosed - return nil +} + +func (gz *gzipReader) Read(p []byte) (n int, err error) { + zr, err := gz.acquire() + if err != nil { + return 0, err + } + defer gz.release(zr) + + return zr.Read(p) +} + +func (gz *gzipReader) Close() error { + gz.close() + + return gz.body.Close() } type errorReader struct{ err error } @@ -3228,7 +3244,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { cc.mu.Lock() ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = cc.t.timeSince(cc.lastActive) + ci.IdleTime = time.Since(cc.lastActive) } cc.mu.Unlock() diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go index cc893adc29..7de27be525 100644 --- a/vendor/golang.org/x/net/http2/writesched.go +++ b/vendor/golang.org/x/net/http2/writesched.go @@ -42,6 +42,8 @@ type OpenStreamOptions struct { // PusherID is zero if the stream was initiated by the client. Otherwise, // PusherID names the stream that pushed the newly opened stream. PusherID uint32 + // priority is used to set the priority of the newly opened stream. + priority PriorityParam } // FrameWriteRequest is a request to write a frame. @@ -183,45 +185,75 @@ func (wr *FrameWriteRequest) replyToWriter(err error) { } // writeQueue is used by implementations of WriteScheduler. +// +// Each writeQueue contains a queue of FrameWriteRequests, meant to store all +// FrameWriteRequests associated with a given stream. This is implemented as a +// two-stage queue: currQueue[currPos:] and nextQueue. Removing an item is done +// by incrementing currPos of currQueue. Adding an item is done by appending it +// to the nextQueue. If currQueue is empty when trying to remove an item, we +// can swap currQueue and nextQueue to remedy the situation. +// This two-stage queue is analogous to the use of two lists in Okasaki's +// purely functional queue but without the overhead of reversing the list when +// swapping stages. +// +// writeQueue also contains prev and next, this can be used by implementations +// of WriteScheduler to construct data structures that represent the order of +// writing between different streams (e.g. circular linked list). type writeQueue struct { - s []FrameWriteRequest + currQueue []FrameWriteRequest + nextQueue []FrameWriteRequest + currPos int + prev, next *writeQueue } -func (q *writeQueue) empty() bool { return len(q.s) == 0 } +func (q *writeQueue) empty() bool { + return (len(q.currQueue) - q.currPos + len(q.nextQueue)) == 0 +} func (q *writeQueue) push(wr FrameWriteRequest) { - q.s = append(q.s, wr) + q.nextQueue = append(q.nextQueue, wr) } func (q *writeQueue) shift() FrameWriteRequest { - if len(q.s) == 0 { + if q.empty() { panic("invalid use of queue") } - wr := q.s[0] - // TODO: less copy-happy queue. - copy(q.s, q.s[1:]) - q.s[len(q.s)-1] = FrameWriteRequest{} - q.s = q.s[:len(q.s)-1] + if q.currPos >= len(q.currQueue) { + q.currQueue, q.currPos, q.nextQueue = q.nextQueue, 0, q.currQueue[:0] + } + wr := q.currQueue[q.currPos] + q.currQueue[q.currPos] = FrameWriteRequest{} + q.currPos++ return wr } +func (q *writeQueue) peek() *FrameWriteRequest { + if q.currPos < len(q.currQueue) { + return &q.currQueue[q.currPos] + } + if len(q.nextQueue) > 0 { + return &q.nextQueue[0] + } + return nil +} + // consume consumes up to n bytes from q.s[0]. If the frame is // entirely consumed, it is removed from the queue. If the frame // is partially consumed, the frame is kept with the consumed // bytes removed. Returns true iff any bytes were consumed. func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) { - if len(q.s) == 0 { + if q.empty() { return FrameWriteRequest{}, false } - consumed, rest, numresult := q.s[0].Consume(n) + consumed, rest, numresult := q.peek().Consume(n) switch numresult { case 0: return FrameWriteRequest{}, false case 1: q.shift() case 2: - q.s[0] = rest + *q.peek() = rest } return consumed, true } @@ -230,10 +262,15 @@ type writeQueuePool []*writeQueue // put inserts an unused writeQueue into the pool. func (p *writeQueuePool) put(q *writeQueue) { - for i := range q.s { - q.s[i] = FrameWriteRequest{} + for i := range q.currQueue { + q.currQueue[i] = FrameWriteRequest{} + } + for i := range q.nextQueue { + q.nextQueue[i] = FrameWriteRequest{} } - q.s = q.s[:0] + q.currQueue = q.currQueue[:0] + q.nextQueue = q.nextQueue[:0] + q.currPos = 0 *p = append(*p, q) } diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go similarity index 77% rename from vendor/golang.org/x/net/http2/writesched_priority.go rename to vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go index f6783339d1..4e33c29a24 100644 --- a/vendor/golang.org/x/net/http2/writesched_priority.go +++ b/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go @@ -11,7 +11,7 @@ import ( ) // RFC 7540, Section 5.3.5: the default weight is 16. -const priorityDefaultWeight = 15 // 16 = 15 + 1 +const priorityDefaultWeightRFC7540 = 15 // 16 = 15 + 1 // PriorityWriteSchedulerConfig configures a priorityWriteScheduler. type PriorityWriteSchedulerConfig struct { @@ -66,8 +66,8 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler } } - ws := &priorityWriteScheduler{ - nodes: make(map[uint32]*priorityNode), + ws := &priorityWriteSchedulerRFC7540{ + nodes: make(map[uint32]*priorityNodeRFC7540), maxClosedNodesInTree: cfg.MaxClosedNodesInTree, maxIdleNodesInTree: cfg.MaxIdleNodesInTree, enableWriteThrottle: cfg.ThrottleOutOfOrderWrites, @@ -81,32 +81,32 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler return ws } -type priorityNodeState int +type priorityNodeStateRFC7540 int const ( - priorityNodeOpen priorityNodeState = iota - priorityNodeClosed - priorityNodeIdle + priorityNodeOpenRFC7540 priorityNodeStateRFC7540 = iota + priorityNodeClosedRFC7540 + priorityNodeIdleRFC7540 ) -// priorityNode is a node in an HTTP/2 priority tree. +// priorityNodeRFC7540 is a node in an HTTP/2 priority tree. // Each node is associated with a single stream ID. // See RFC 7540, Section 5.3. -type priorityNode struct { - q writeQueue // queue of pending frames to write - id uint32 // id of the stream, or 0 for the root of the tree - weight uint8 // the actual weight is weight+1, so the value is in [1,256] - state priorityNodeState // open | closed | idle - bytes int64 // number of bytes written by this node, or 0 if closed - subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree +type priorityNodeRFC7540 struct { + q writeQueue // queue of pending frames to write + id uint32 // id of the stream, or 0 for the root of the tree + weight uint8 // the actual weight is weight+1, so the value is in [1,256] + state priorityNodeStateRFC7540 // open | closed | idle + bytes int64 // number of bytes written by this node, or 0 if closed + subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree // These links form the priority tree. - parent *priorityNode - kids *priorityNode // start of the kids list - prev, next *priorityNode // doubly-linked list of siblings + parent *priorityNodeRFC7540 + kids *priorityNodeRFC7540 // start of the kids list + prev, next *priorityNodeRFC7540 // doubly-linked list of siblings } -func (n *priorityNode) setParent(parent *priorityNode) { +func (n *priorityNodeRFC7540) setParent(parent *priorityNodeRFC7540) { if n == parent { panic("setParent to self") } @@ -141,7 +141,7 @@ func (n *priorityNode) setParent(parent *priorityNode) { } } -func (n *priorityNode) addBytes(b int64) { +func (n *priorityNodeRFC7540) addBytes(b int64) { n.bytes += b for ; n != nil; n = n.parent { n.subtreeBytes += b @@ -154,7 +154,7 @@ func (n *priorityNode) addBytes(b int64) { // // f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true // if any ancestor p of n is still open (ignoring the root node). -func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool { +func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priorityNodeRFC7540, f func(*priorityNodeRFC7540, bool) bool) bool { if !n.q.empty() && f(n, openParent) { return true } @@ -165,7 +165,7 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f // Don't consider the root "open" when updating openParent since // we can't send data frames on the root stream (only control frames). if n.id != 0 { - openParent = openParent || (n.state == priorityNodeOpen) + openParent = openParent || (n.state == priorityNodeOpenRFC7540) } // Common case: only one kid or all kids have the same weight. @@ -195,7 +195,7 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f *tmp = append(*tmp, n.kids) n.kids.setParent(nil) } - sort.Sort(sortPriorityNodeSiblings(*tmp)) + sort.Sort(sortPriorityNodeSiblingsRFC7540(*tmp)) for i := len(*tmp) - 1; i >= 0; i-- { (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids } @@ -207,15 +207,15 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f return false } -type sortPriorityNodeSiblings []*priorityNode +type sortPriorityNodeSiblingsRFC7540 []*priorityNodeRFC7540 -func (z sortPriorityNodeSiblings) Len() int { return len(z) } -func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] } -func (z sortPriorityNodeSiblings) Less(i, k int) bool { +func (z sortPriorityNodeSiblingsRFC7540) Len() int { return len(z) } +func (z sortPriorityNodeSiblingsRFC7540) Swap(i, k int) { z[i], z[k] = z[k], z[i] } +func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool { // Prefer the subtree that has sent fewer bytes relative to its weight. // See sections 5.3.2 and 5.3.4. - wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes) - wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes) + wi, bi := float64(z[i].weight)+1, float64(z[i].subtreeBytes) + wk, bk := float64(z[k].weight)+1, float64(z[k].subtreeBytes) if bi == 0 && bk == 0 { return wi >= wk } @@ -225,13 +225,13 @@ func (z sortPriorityNodeSiblings) Less(i, k int) bool { return bi/bk <= wi/wk } -type priorityWriteScheduler struct { +type priorityWriteSchedulerRFC7540 struct { // root is the root of the priority tree, where root.id = 0. // The root queues control frames that are not associated with any stream. - root priorityNode + root priorityNodeRFC7540 // nodes maps stream ids to priority tree nodes. - nodes map[uint32]*priorityNode + nodes map[uint32]*priorityNodeRFC7540 // maxID is the maximum stream id in nodes. maxID uint32 @@ -239,7 +239,7 @@ type priorityWriteScheduler struct { // lists of nodes that have been closed or are idle, but are kept in // the tree for improved prioritization. When the lengths exceed either // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded. - closedNodes, idleNodes []*priorityNode + closedNodes, idleNodes []*priorityNodeRFC7540 // From the config. maxClosedNodesInTree int @@ -248,19 +248,19 @@ type priorityWriteScheduler struct { enableWriteThrottle bool // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations. - tmp []*priorityNode + tmp []*priorityNodeRFC7540 // pool of empty queues for reuse. queuePool writeQueuePool } -func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { +func (ws *priorityWriteSchedulerRFC7540) OpenStream(streamID uint32, options OpenStreamOptions) { // The stream may be currently idle but cannot be opened or closed. if curr := ws.nodes[streamID]; curr != nil { - if curr.state != priorityNodeIdle { + if curr.state != priorityNodeIdleRFC7540 { panic(fmt.Sprintf("stream %d already opened", streamID)) } - curr.state = priorityNodeOpen + curr.state = priorityNodeOpenRFC7540 return } @@ -272,11 +272,11 @@ func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStream if parent == nil { parent = &ws.root } - n := &priorityNode{ + n := &priorityNodeRFC7540{ q: *ws.queuePool.get(), id: streamID, - weight: priorityDefaultWeight, - state: priorityNodeOpen, + weight: priorityDefaultWeightRFC7540, + state: priorityNodeOpenRFC7540, } n.setParent(parent) ws.nodes[streamID] = n @@ -285,24 +285,23 @@ func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStream } } -func (ws *priorityWriteScheduler) CloseStream(streamID uint32) { +func (ws *priorityWriteSchedulerRFC7540) CloseStream(streamID uint32) { if streamID == 0 { panic("violation of WriteScheduler interface: cannot close stream 0") } if ws.nodes[streamID] == nil { panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID)) } - if ws.nodes[streamID].state != priorityNodeOpen { + if ws.nodes[streamID].state != priorityNodeOpenRFC7540 { panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID)) } n := ws.nodes[streamID] - n.state = priorityNodeClosed + n.state = priorityNodeClosedRFC7540 n.addBytes(-n.bytes) q := n.q ws.queuePool.put(&q) - n.q.s = nil if ws.maxClosedNodesInTree > 0 { ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n) } else { @@ -310,7 +309,7 @@ func (ws *priorityWriteScheduler) CloseStream(streamID uint32) { } } -func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) { +func (ws *priorityWriteSchedulerRFC7540) AdjustStream(streamID uint32, priority PriorityParam) { if streamID == 0 { panic("adjustPriority on root") } @@ -324,11 +323,11 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit return } ws.maxID = streamID - n = &priorityNode{ + n = &priorityNodeRFC7540{ q: *ws.queuePool.get(), id: streamID, - weight: priorityDefaultWeight, - state: priorityNodeIdle, + weight: priorityDefaultWeightRFC7540, + state: priorityNodeIdleRFC7540, } n.setParent(&ws.root) ws.nodes[streamID] = n @@ -340,7 +339,7 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit parent := ws.nodes[priority.StreamDep] if parent == nil { n.setParent(&ws.root) - n.weight = priorityDefaultWeight + n.weight = priorityDefaultWeightRFC7540 return } @@ -381,8 +380,8 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit n.weight = priority.Weight } -func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { - var n *priorityNode +func (ws *priorityWriteSchedulerRFC7540) Push(wr FrameWriteRequest) { + var n *priorityNodeRFC7540 if wr.isControl() { n = &ws.root } else { @@ -401,8 +400,8 @@ func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { n.q.push(wr) } -func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) { - ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool { +func (ws *priorityWriteSchedulerRFC7540) Pop() (wr FrameWriteRequest, ok bool) { + ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNodeRFC7540, openParent bool) bool { limit := int32(math.MaxInt32) if openParent { limit = ws.writeThrottleLimit @@ -428,7 +427,7 @@ func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) { return wr, ok } -func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) { +func (ws *priorityWriteSchedulerRFC7540) addClosedOrIdleNode(list *[]*priorityNodeRFC7540, maxSize int, n *priorityNodeRFC7540) { if maxSize == 0 { return } @@ -442,7 +441,7 @@ func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, max *list = append(*list, n) } -func (ws *priorityWriteScheduler) removeNode(n *priorityNode) { +func (ws *priorityWriteSchedulerRFC7540) removeNode(n *priorityNodeRFC7540) { for n.kids != nil { n.kids.setParent(n.parent) } diff --git a/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go b/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go new file mode 100644 index 0000000000..cb4cadc32d --- /dev/null +++ b/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go @@ -0,0 +1,209 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http2 + +import ( + "fmt" + "math" +) + +type streamMetadata struct { + location *writeQueue + priority PriorityParam +} + +type priorityWriteSchedulerRFC9218 struct { + // control contains control frames (SETTINGS, PING, etc.). + control writeQueue + + // heads contain the head of a circular list of streams. + // We put these heads within a nested array that represents urgency and + // incremental, as defined in + // https://www.rfc-editor.org/rfc/rfc9218.html#name-priority-parameters. + // 8 represents u=0 up to u=7, and 2 represents i=false and i=true. + heads [8][2]*writeQueue + + // streams contains a mapping between each stream ID and their metadata, so + // we can quickly locate them when needing to, for example, adjust their + // priority. + streams map[uint32]streamMetadata + + // queuePool are empty queues for reuse. + queuePool writeQueuePool + + // prioritizeIncremental is used to determine whether we should prioritize + // incremental streams or not, when urgency is the same in a given Pop() + // call. + prioritizeIncremental bool +} + +func newPriorityWriteSchedulerRFC9218() WriteScheduler { + ws := &priorityWriteSchedulerRFC9218{ + streams: make(map[uint32]streamMetadata), + } + return ws +} + +func (ws *priorityWriteSchedulerRFC9218) OpenStream(streamID uint32, opt OpenStreamOptions) { + if ws.streams[streamID].location != nil { + panic(fmt.Errorf("stream %d already opened", streamID)) + } + q := ws.queuePool.get() + ws.streams[streamID] = streamMetadata{ + location: q, + priority: opt.priority, + } + + u, i := opt.priority.urgency, opt.priority.incremental + if ws.heads[u][i] == nil { + ws.heads[u][i] = q + q.next = q + q.prev = q + } else { + // Queues are stored in a ring. + // Insert the new stream before ws.head, putting it at the end of the list. + q.prev = ws.heads[u][i].prev + q.next = ws.heads[u][i] + q.prev.next = q + q.next.prev = q + } +} + +func (ws *priorityWriteSchedulerRFC9218) CloseStream(streamID uint32) { + metadata := ws.streams[streamID] + q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental + if q == nil { + return + } + if q.next == q { + // This was the only open stream. + ws.heads[u][i] = nil + } else { + q.prev.next = q.next + q.next.prev = q.prev + if ws.heads[u][i] == q { + ws.heads[u][i] = q.next + } + } + delete(ws.streams, streamID) + ws.queuePool.put(q) +} + +func (ws *priorityWriteSchedulerRFC9218) AdjustStream(streamID uint32, priority PriorityParam) { + metadata := ws.streams[streamID] + q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental + if q == nil { + return + } + + // Remove stream from current location. + if q.next == q { + // This was the only open stream. + ws.heads[u][i] = nil + } else { + q.prev.next = q.next + q.next.prev = q.prev + if ws.heads[u][i] == q { + ws.heads[u][i] = q.next + } + } + + // Insert stream to the new queue. + u, i = priority.urgency, priority.incremental + if ws.heads[u][i] == nil { + ws.heads[u][i] = q + q.next = q + q.prev = q + } else { + // Queues are stored in a ring. + // Insert the new stream before ws.head, putting it at the end of the list. + q.prev = ws.heads[u][i].prev + q.next = ws.heads[u][i] + q.prev.next = q + q.next.prev = q + } + + // Update the metadata. + ws.streams[streamID] = streamMetadata{ + location: q, + priority: priority, + } +} + +func (ws *priorityWriteSchedulerRFC9218) Push(wr FrameWriteRequest) { + if wr.isControl() { + ws.control.push(wr) + return + } + q := ws.streams[wr.StreamID()].location + if q == nil { + // This is a closed stream. + // wr should not be a HEADERS or DATA frame. + // We push the request onto the control queue. + if wr.DataSize() > 0 { + panic("add DATA on non-open stream") + } + ws.control.push(wr) + return + } + q.push(wr) +} + +func (ws *priorityWriteSchedulerRFC9218) Pop() (FrameWriteRequest, bool) { + // Control and RST_STREAM frames first. + if !ws.control.empty() { + return ws.control.shift(), true + } + + // On the next Pop(), we want to prioritize incremental if we prioritized + // non-incremental request of the same urgency this time. Vice-versa. + // i.e. when there are incremental and non-incremental requests at the same + // priority, we give 50% of our bandwidth to the incremental ones in + // aggregate and 50% to the first non-incremental one (since + // non-incremental streams do not use round-robin writes). + ws.prioritizeIncremental = !ws.prioritizeIncremental + + // Always prioritize lowest u (i.e. highest urgency level). + for u := range ws.heads { + for i := range ws.heads[u] { + // When we want to prioritize incremental, we try to pop i=true + // first before i=false when u is the same. + if ws.prioritizeIncremental { + i = (i + 1) % 2 + } + q := ws.heads[u][i] + if q == nil { + continue + } + for { + if wr, ok := q.consume(math.MaxInt32); ok { + if i == 1 { + // For incremental streams, we update head to q.next so + // we can round-robin between multiple streams that can + // immediately benefit from partial writes. + ws.heads[u][i] = q.next + } else { + // For non-incremental streams, we try to finish one to + // completion rather than doing round-robin. However, + // we update head here so that if q.consume() is !ok + // (e.g. the stream has no more frame to consume), head + // is updated to the next q that has frames to consume + // on future iterations. This way, we do not prioritize + // writing to unavailable stream on next Pop() calls, + // preventing head-of-line blocking. + ws.heads[u][i] = q + } + return wr, true + } + q = q.next + if q == ws.heads[u][i] { + break + } + } + + } + } + return FrameWriteRequest{}, false +} diff --git a/vendor/golang.org/x/net/http2/writesched_roundrobin.go b/vendor/golang.org/x/net/http2/writesched_roundrobin.go index 54fe86322d..737cff9ecb 100644 --- a/vendor/golang.org/x/net/http2/writesched_roundrobin.go +++ b/vendor/golang.org/x/net/http2/writesched_roundrobin.go @@ -25,7 +25,7 @@ type roundRobinWriteScheduler struct { } // newRoundRobinWriteScheduler constructs a new write scheduler. -// The round robin scheduler priorizes control frames +// The round robin scheduler prioritizes control frames // like SETTINGS and PING over DATA frames. // When there are no control frames to send, it performs a round-robin // selection from the ready streams. diff --git a/vendor/golang.org/x/net/internal/httpcommon/request.go b/vendor/golang.org/x/net/internal/httpcommon/request.go index 4b70553179..1e10f89ebf 100644 --- a/vendor/golang.org/x/net/internal/httpcommon/request.go +++ b/vendor/golang.org/x/net/internal/httpcommon/request.go @@ -51,7 +51,7 @@ type EncodeHeadersParam struct { DefaultUserAgent string } -// EncodeHeadersParam is the result of EncodeHeaders. +// EncodeHeadersResult is the result of EncodeHeaders. type EncodeHeadersResult struct { HasBody bool HasTrailers bool @@ -399,7 +399,7 @@ type ServerRequestResult struct { // If the request should be rejected, this is a short string suitable for passing // to the http2 package's CountError function. - // It might be a bit odd to return errors this way rather than returing an error, + // It might be a bit odd to return errors this way rather than returning an error, // but this ensures we don't forget to include a CountError reason. InvalidReason string } diff --git a/vendor/golang.org/x/net/internal/socks/socks.go b/vendor/golang.org/x/net/internal/socks/socks.go index 84fcc32b63..8eedb84cec 100644 --- a/vendor/golang.org/x/net/internal/socks/socks.go +++ b/vendor/golang.org/x/net/internal/socks/socks.go @@ -297,7 +297,7 @@ func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, b = append(b, up.Username...) b = append(b, byte(len(up.Password))) b = append(b, up.Password...) - // TODO(mikio): handle IO deadlines and cancelation if + // TODO(mikio): handle IO deadlines and cancellation if // necessary if _, err := rw.Write(b); err != nil { return err diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index 1d8cffae8c..2f45dbc86e 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package errgroup provides synchronization, error propagation, and Context -// cancelation for groups of goroutines working on subtasks of a common task. +// cancellation for groups of goroutines working on subtasks of a common task. // // [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks // returning errors. diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index 63541994ef..34c9ae76ef 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -92,6 +92,9 @@ var ARM64 struct { HasSHA2 bool // SHA2 hardware implementation HasCRC32 bool // CRC32 hardware implementation HasATOMICS bool // Atomic memory operation instruction set + HasHPDS bool // Hierarchical permission disables in translations tables + HasLOR bool // Limited ordering regions + HasPAN bool // Privileged access never HasFPHP bool // Half precision floating-point instruction set HasASIMDHP bool // Advanced SIMD half precision instruction set HasCPUID bool // CPUID identification scheme registers diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go index af2aa99f9f..f449c679fe 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go @@ -65,10 +65,10 @@ func setMinimalFeatures() { func readARM64Registers() { Initialized = true - parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0()) + parseARM64SystemRegisters(getisar0(), getisar1(), getmmfr1(), getpfr0()) } -func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { +func parseARM64SystemRegisters(isar0, isar1, mmfr1, pfr0 uint64) { // ID_AA64ISAR0_EL1 switch extractBits(isar0, 4, 7) { case 1: @@ -152,6 +152,22 @@ func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { ARM64.HasI8MM = true } + // ID_AA64MMFR1_EL1 + switch extractBits(mmfr1, 12, 15) { + case 1, 2: + ARM64.HasHPDS = true + } + + switch extractBits(mmfr1, 16, 19) { + case 1: + ARM64.HasLOR = true + } + + switch extractBits(mmfr1, 20, 23) { + case 1, 2, 3: + ARM64.HasPAN = true + } + // ID_AA64PFR0_EL1 switch extractBits(pfr0, 16, 19) { case 0: diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s index 22cc99844a..a4f24b3b0c 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.s +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s @@ -9,31 +9,34 @@ // func getisar0() uint64 TEXT ·getisar0(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 0 into x0 - // mrs x0, ID_AA64ISAR0_EL1 = d5380600 - WORD $0xd5380600 + MRS ID_AA64ISAR0_EL1, R0 MOVD R0, ret+0(FP) RET // func getisar1() uint64 TEXT ·getisar1(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 1 into x0 - // mrs x0, ID_AA64ISAR1_EL1 = d5380620 - WORD $0xd5380620 + MRS ID_AA64ISAR1_EL1, R0 + MOVD R0, ret+0(FP) + RET + +// func getmmfr1() uint64 +TEXT ·getmmfr1(SB),NOSPLIT,$0-8 + // get Memory Model Feature Register 1 into x0 + MRS ID_AA64MMFR1_EL1, R0 MOVD R0, ret+0(FP) RET // func getpfr0() uint64 TEXT ·getpfr0(SB),NOSPLIT,$0-8 // get Processor Feature Register 0 into x0 - // mrs x0, ID_AA64PFR0_EL1 = d5380400 - WORD $0xd5380400 + MRS ID_AA64PFR0_EL1, R0 MOVD R0, ret+0(FP) RET // func getzfr0() uint64 TEXT ·getzfr0(SB),NOSPLIT,$0-8 // get SVE Feature Register 0 into x0 - // mrs x0, ID_AA64ZFR0_EL1 = d5380480 - WORD $0xd5380480 + MRS ID_AA64ZFR0_EL1, R0 MOVD R0, ret+0(FP) RET diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go index 6ac6e1efb2..e3fc5a8d31 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go @@ -8,5 +8,6 @@ package cpu func getisar0() uint64 func getisar1() uint64 +func getmmfr1() uint64 func getpfr0() uint64 func getzfr0() uint64 diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go index 7f1946780b..8df2079e15 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go @@ -8,4 +8,5 @@ package cpu func getisar0() uint64 { return 0 } func getisar1() uint64 { return 0 } +func getmmfr1() uint64 { return 0 } func getpfr0() uint64 { return 0 } diff --git a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go index ebfb3fc8e7..19aea0633e 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go @@ -167,7 +167,7 @@ func doinit() { setMinimalFeatures() return } - parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0) + parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64mmfr1, cpuid.aa64pfr0) Initialized = true } diff --git a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go index 85b64d5ccb..87fd3a7780 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go @@ -59,7 +59,7 @@ func doinit() { if !ok { return } - parseARM64SystemRegisters(isar0, isar1, 0) + parseARM64SystemRegisters(isar0, isar1, 0, 0) Initialized = true } diff --git a/vendor/golang.org/x/sys/unix/affinity_linux.go b/vendor/golang.org/x/sys/unix/affinity_linux.go index 3c7a6d6e2f..3ea470387b 100644 --- a/vendor/golang.org/x/sys/unix/affinity_linux.go +++ b/vendor/golang.org/x/sys/unix/affinity_linux.go @@ -41,6 +41,15 @@ func (s *CPUSet) Zero() { clear(s[:]) } +// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity] +// will silently ignore any invalid CPU bits in [CPUSet] so this is an +// efficient way of resetting the CPU affinity of a process. +func (s *CPUSet) Fill() { + for i := range s { + s[i] = ^cpuMask(0) + } +} + func cpuBitsIndex(cpu int) int { return cpu / _NCPUBITS } diff --git a/vendor/golang.org/x/sys/unix/fdset.go b/vendor/golang.org/x/sys/unix/fdset.go index 9e83d18cd0..62ed12645f 100644 --- a/vendor/golang.org/x/sys/unix/fdset.go +++ b/vendor/golang.org/x/sys/unix/fdset.go @@ -23,7 +23,5 @@ func (fds *FdSet) IsSet(fd int) bool { // Zero clears the set fds. func (fds *FdSet) Zero() { - for i := range fds.Bits { - fds.Bits[i] = 0 - } + clear(fds.Bits[:]) } diff --git a/vendor/golang.org/x/sys/unix/ifreq_linux.go b/vendor/golang.org/x/sys/unix/ifreq_linux.go index 848840ae4c..309f5a2b0c 100644 --- a/vendor/golang.org/x/sys/unix/ifreq_linux.go +++ b/vendor/golang.org/x/sys/unix/ifreq_linux.go @@ -111,9 +111,7 @@ func (ifr *Ifreq) SetUint32(v uint32) { // clear zeroes the ifreq's union field to prevent trailing garbage data from // being sent to the kernel if an ifreq is reused. func (ifr *Ifreq) clear() { - for i := range ifr.raw.Ifru { - ifr.raw.Ifru[i] = 0 - } + clear(ifr.raw.Ifru[:]) } // TODO(mdlayher): export as IfreqData? For now we can provide helpers such as diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index e6f31d374d..d0ed611912 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -49,6 +49,7 @@ esac if [[ "$GOOS" = "linux" ]]; then # Use the Docker-based build system # Files generated through docker (use $cmd so you can Ctl-C the build or run) + set -e $cmd docker build --tag generate:$GOOS $GOOS $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS exit diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index d1c8b2640e..42517077c4 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -226,6 +226,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -529,6 +530,7 @@ ccflags="$@" $2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ || + $2 ~ /^(DT|EI|ELF|EV|NN|NT|PF|SHF|SHN|SHT|STB|STT|VER)_/ || $2 ~ /^O?XTABS$/ || $2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^IN_/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 4958a65708..06c0eea6fb 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -801,9 +801,7 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { // one. The kernel expects SID to be in network byte order. binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) copy(sa.raw[8:14], sa.Remote) - for i := 14; i < 14+IFNAMSIZ; i++ { - sa.raw[i] = 0 - } + clear(sa.raw[14 : 14+IFNAMSIZ]) copy(sa.raw[14:], sa.Dev) return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil } @@ -2645,3 +2643,9 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) //sys Mseal(b []byte, flags uint) (err error) + +//sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY + +func SetMemPolicy(mode int, mask *CPUSet) error { + return setMemPolicy(mode, mask, _CPU_SETSIZE) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 88162099af..34a4676973 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -248,6 +248,23 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { return Statvfs1(path, buf, ST_WAIT) } +func Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) { + var ( + _p0 unsafe.Pointer + bufsize uintptr + ) + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + bufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf)) + } + r0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index b6db27d937..d0a75da572 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -853,20 +853,86 @@ const ( DM_VERSION_MAJOR = 0x4 DM_VERSION_MINOR = 0x32 DM_VERSION_PATCHLEVEL = 0x0 + DT_ADDRRNGHI = 0x6ffffeff + DT_ADDRRNGLO = 0x6ffffe00 DT_BLK = 0x6 DT_CHR = 0x2 + DT_DEBUG = 0x15 DT_DIR = 0x4 + DT_ENCODING = 0x20 DT_FIFO = 0x1 + DT_FINI = 0xd + DT_FLAGS_1 = 0x6ffffffb + DT_GNU_HASH = 0x6ffffef5 + DT_HASH = 0x4 + DT_HIOS = 0x6ffff000 + DT_HIPROC = 0x7fffffff + DT_INIT = 0xc + DT_JMPREL = 0x17 DT_LNK = 0xa + DT_LOOS = 0x6000000d + DT_LOPROC = 0x70000000 + DT_NEEDED = 0x1 + DT_NULL = 0x0 + DT_PLTGOT = 0x3 + DT_PLTREL = 0x14 + DT_PLTRELSZ = 0x2 DT_REG = 0x8 + DT_REL = 0x11 + DT_RELA = 0x7 + DT_RELACOUNT = 0x6ffffff9 + DT_RELAENT = 0x9 + DT_RELASZ = 0x8 + DT_RELCOUNT = 0x6ffffffa + DT_RELENT = 0x13 + DT_RELSZ = 0x12 + DT_RPATH = 0xf DT_SOCK = 0xc + DT_SONAME = 0xe + DT_STRSZ = 0xa + DT_STRTAB = 0x5 + DT_SYMBOLIC = 0x10 + DT_SYMENT = 0xb + DT_SYMTAB = 0x6 + DT_TEXTREL = 0x16 DT_UNKNOWN = 0x0 + DT_VALRNGHI = 0x6ffffdff + DT_VALRNGLO = 0x6ffffd00 + DT_VERDEF = 0x6ffffffc + DT_VERDEFNUM = 0x6ffffffd + DT_VERNEED = 0x6ffffffe + DT_VERNEEDNUM = 0x6fffffff + DT_VERSYM = 0x6ffffff0 DT_WHT = 0xe ECHO = 0x8 ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_SEMAPHORE = 0x1 EFIVARFS_MAGIC = 0xde5e81e4 EFS_SUPER_MAGIC = 0x414a53 + EI_CLASS = 0x4 + EI_DATA = 0x5 + EI_MAG0 = 0x0 + EI_MAG1 = 0x1 + EI_MAG2 = 0x2 + EI_MAG3 = 0x3 + EI_NIDENT = 0x10 + EI_OSABI = 0x7 + EI_PAD = 0x8 + EI_VERSION = 0x6 + ELFCLASS32 = 0x1 + ELFCLASS64 = 0x2 + ELFCLASSNONE = 0x0 + ELFCLASSNUM = 0x3 + ELFDATA2LSB = 0x1 + ELFDATA2MSB = 0x2 + ELFDATANONE = 0x0 + ELFMAG = "\177ELF" + ELFMAG0 = 0x7f + ELFMAG1 = 'E' + ELFMAG2 = 'L' + ELFMAG3 = 'F' + ELFOSABI_LINUX = 0x3 + ELFOSABI_NONE = 0x0 EM_386 = 0x3 EM_486 = 0x6 EM_68K = 0x4 @@ -1152,14 +1218,24 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + ET_CORE = 0x4 + ET_DYN = 0x3 + ET_EXEC = 0x2 + ET_HIPROC = 0xffff + ET_LOPROC = 0xff00 + ET_NONE = 0x0 + ET_REL = 0x1 EV_ABS = 0x3 EV_CNT = 0x20 + EV_CURRENT = 0x1 EV_FF = 0x15 EV_FF_STATUS = 0x17 EV_KEY = 0x1 EV_LED = 0x11 EV_MAX = 0x1f EV_MSC = 0x4 + EV_NONE = 0x0 + EV_NUM = 0x2 EV_PWR = 0x16 EV_REL = 0x2 EV_REP = 0x14 @@ -2276,7 +2352,167 @@ const ( NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 + NN_386_IOPERM = "LINUX" + NN_386_TLS = "LINUX" + NN_ARC_V2 = "LINUX" + NN_ARM_FPMR = "LINUX" + NN_ARM_GCS = "LINUX" + NN_ARM_HW_BREAK = "LINUX" + NN_ARM_HW_WATCH = "LINUX" + NN_ARM_PACA_KEYS = "LINUX" + NN_ARM_PACG_KEYS = "LINUX" + NN_ARM_PAC_ENABLED_KEYS = "LINUX" + NN_ARM_PAC_MASK = "LINUX" + NN_ARM_POE = "LINUX" + NN_ARM_SSVE = "LINUX" + NN_ARM_SVE = "LINUX" + NN_ARM_SYSTEM_CALL = "LINUX" + NN_ARM_TAGGED_ADDR_CTRL = "LINUX" + NN_ARM_TLS = "LINUX" + NN_ARM_VFP = "LINUX" + NN_ARM_ZA = "LINUX" + NN_ARM_ZT = "LINUX" + NN_AUXV = "CORE" + NN_FILE = "CORE" + NN_GNU_PROPERTY_TYPE_0 = "GNU" + NN_LOONGARCH_CPUCFG = "LINUX" + NN_LOONGARCH_CSR = "LINUX" + NN_LOONGARCH_HW_BREAK = "LINUX" + NN_LOONGARCH_HW_WATCH = "LINUX" + NN_LOONGARCH_LASX = "LINUX" + NN_LOONGARCH_LBT = "LINUX" + NN_LOONGARCH_LSX = "LINUX" + NN_MIPS_DSP = "LINUX" + NN_MIPS_FP_MODE = "LINUX" + NN_MIPS_MSA = "LINUX" + NN_PPC_DEXCR = "LINUX" + NN_PPC_DSCR = "LINUX" + NN_PPC_EBB = "LINUX" + NN_PPC_HASHKEYR = "LINUX" + NN_PPC_PKEY = "LINUX" + NN_PPC_PMU = "LINUX" + NN_PPC_PPR = "LINUX" + NN_PPC_SPE = "LINUX" + NN_PPC_TAR = "LINUX" + NN_PPC_TM_CDSCR = "LINUX" + NN_PPC_TM_CFPR = "LINUX" + NN_PPC_TM_CGPR = "LINUX" + NN_PPC_TM_CPPR = "LINUX" + NN_PPC_TM_CTAR = "LINUX" + NN_PPC_TM_CVMX = "LINUX" + NN_PPC_TM_CVSX = "LINUX" + NN_PPC_TM_SPR = "LINUX" + NN_PPC_VMX = "LINUX" + NN_PPC_VSX = "LINUX" + NN_PRFPREG = "CORE" + NN_PRPSINFO = "CORE" + NN_PRSTATUS = "CORE" + NN_PRXFPREG = "LINUX" + NN_RISCV_CSR = "LINUX" + NN_RISCV_TAGGED_ADDR_CTRL = "LINUX" + NN_RISCV_VECTOR = "LINUX" + NN_S390_CTRS = "LINUX" + NN_S390_GS_BC = "LINUX" + NN_S390_GS_CB = "LINUX" + NN_S390_HIGH_GPRS = "LINUX" + NN_S390_LAST_BREAK = "LINUX" + NN_S390_PREFIX = "LINUX" + NN_S390_PV_CPU_DATA = "LINUX" + NN_S390_RI_CB = "LINUX" + NN_S390_SYSTEM_CALL = "LINUX" + NN_S390_TDB = "LINUX" + NN_S390_TIMER = "LINUX" + NN_S390_TODCMP = "LINUX" + NN_S390_TODPREG = "LINUX" + NN_S390_VXRS_HIGH = "LINUX" + NN_S390_VXRS_LOW = "LINUX" + NN_SIGINFO = "CORE" + NN_TASKSTRUCT = "CORE" + NN_VMCOREDD = "LINUX" + NN_X86_SHSTK = "LINUX" + NN_X86_XSAVE_LAYOUT = "LINUX" + NN_X86_XSTATE = "LINUX" NSFS_MAGIC = 0x6e736673 + NT_386_IOPERM = 0x201 + NT_386_TLS = 0x200 + NT_ARC_V2 = 0x600 + NT_ARM_FPMR = 0x40e + NT_ARM_GCS = 0x410 + NT_ARM_HW_BREAK = 0x402 + NT_ARM_HW_WATCH = 0x403 + NT_ARM_PACA_KEYS = 0x407 + NT_ARM_PACG_KEYS = 0x408 + NT_ARM_PAC_ENABLED_KEYS = 0x40a + NT_ARM_PAC_MASK = 0x406 + NT_ARM_POE = 0x40f + NT_ARM_SSVE = 0x40b + NT_ARM_SVE = 0x405 + NT_ARM_SYSTEM_CALL = 0x404 + NT_ARM_TAGGED_ADDR_CTRL = 0x409 + NT_ARM_TLS = 0x401 + NT_ARM_VFP = 0x400 + NT_ARM_ZA = 0x40c + NT_ARM_ZT = 0x40d + NT_AUXV = 0x6 + NT_FILE = 0x46494c45 + NT_GNU_PROPERTY_TYPE_0 = 0x5 + NT_LOONGARCH_CPUCFG = 0xa00 + NT_LOONGARCH_CSR = 0xa01 + NT_LOONGARCH_HW_BREAK = 0xa05 + NT_LOONGARCH_HW_WATCH = 0xa06 + NT_LOONGARCH_LASX = 0xa03 + NT_LOONGARCH_LBT = 0xa04 + NT_LOONGARCH_LSX = 0xa02 + NT_MIPS_DSP = 0x800 + NT_MIPS_FP_MODE = 0x801 + NT_MIPS_MSA = 0x802 + NT_PPC_DEXCR = 0x111 + NT_PPC_DSCR = 0x105 + NT_PPC_EBB = 0x106 + NT_PPC_HASHKEYR = 0x112 + NT_PPC_PKEY = 0x110 + NT_PPC_PMU = 0x107 + NT_PPC_PPR = 0x104 + NT_PPC_SPE = 0x101 + NT_PPC_TAR = 0x103 + NT_PPC_TM_CDSCR = 0x10f + NT_PPC_TM_CFPR = 0x109 + NT_PPC_TM_CGPR = 0x108 + NT_PPC_TM_CPPR = 0x10e + NT_PPC_TM_CTAR = 0x10d + NT_PPC_TM_CVMX = 0x10a + NT_PPC_TM_CVSX = 0x10b + NT_PPC_TM_SPR = 0x10c + NT_PPC_VMX = 0x100 + NT_PPC_VSX = 0x102 + NT_PRFPREG = 0x2 + NT_PRPSINFO = 0x3 + NT_PRSTATUS = 0x1 + NT_PRXFPREG = 0x46e62b7f + NT_RISCV_CSR = 0x900 + NT_RISCV_TAGGED_ADDR_CTRL = 0x902 + NT_RISCV_VECTOR = 0x901 + NT_S390_CTRS = 0x304 + NT_S390_GS_BC = 0x30c + NT_S390_GS_CB = 0x30b + NT_S390_HIGH_GPRS = 0x300 + NT_S390_LAST_BREAK = 0x306 + NT_S390_PREFIX = 0x305 + NT_S390_PV_CPU_DATA = 0x30e + NT_S390_RI_CB = 0x30d + NT_S390_SYSTEM_CALL = 0x307 + NT_S390_TDB = 0x308 + NT_S390_TIMER = 0x301 + NT_S390_TODCMP = 0x302 + NT_S390_TODPREG = 0x303 + NT_S390_VXRS_HIGH = 0x30a + NT_S390_VXRS_LOW = 0x309 + NT_SIGINFO = 0x53494749 + NT_TASKSTRUCT = 0x4 + NT_VMCOREDD = 0x700 + NT_X86_SHSTK = 0x204 + NT_X86_XSAVE_LAYOUT = 0x205 + NT_X86_XSTATE = 0x202 OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 @@ -2463,6 +2699,59 @@ const ( PERF_RECORD_MISC_USER = 0x2 PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 + PF_ALG = 0x26 + PF_APPLETALK = 0x5 + PF_ASH = 0x12 + PF_ATMPVC = 0x8 + PF_ATMSVC = 0x14 + PF_AX25 = 0x3 + PF_BLUETOOTH = 0x1f + PF_BRIDGE = 0x7 + PF_CAIF = 0x25 + PF_CAN = 0x1d + PF_DECnet = 0xc + PF_ECONET = 0x13 + PF_FILE = 0x1 + PF_IB = 0x1b + PF_IEEE802154 = 0x24 + PF_INET = 0x2 + PF_INET6 = 0xa + PF_IPX = 0x4 + PF_IRDA = 0x17 + PF_ISDN = 0x22 + PF_IUCV = 0x20 + PF_KCM = 0x29 + PF_KEY = 0xf + PF_LLC = 0x1a + PF_LOCAL = 0x1 + PF_MAX = 0x2e + PF_MCTP = 0x2d + PF_MPLS = 0x1c + PF_NETBEUI = 0xd + PF_NETLINK = 0x10 + PF_NETROM = 0x6 + PF_NFC = 0x27 + PF_PACKET = 0x11 + PF_PHONET = 0x23 + PF_PPPOX = 0x18 + PF_QIPCRTR = 0x2a + PF_R = 0x4 + PF_RDS = 0x15 + PF_ROSE = 0xb + PF_ROUTE = 0x10 + PF_RXRPC = 0x21 + PF_SECURITY = 0xe + PF_SMC = 0x2b + PF_SNA = 0x16 + PF_TIPC = 0x1e + PF_UNIX = 0x1 + PF_UNSPEC = 0x0 + PF_VSOCK = 0x28 + PF_W = 0x2 + PF_WANPIPE = 0x19 + PF_X = 0x1 + PF_X25 = 0x9 + PF_XDP = 0x2c PID_FS_MAGIC = 0x50494446 PIPEFS_MAGIC = 0x50495045 PPPIOCGNPMODE = 0xc008744c @@ -2758,6 +3047,23 @@ const ( PTRACE_SYSCALL_INFO_NONE = 0x0 PTRACE_SYSCALL_INFO_SECCOMP = 0x3 PTRACE_TRACEME = 0x0 + PT_AARCH64_MEMTAG_MTE = 0x70000002 + PT_DYNAMIC = 0x2 + PT_GNU_EH_FRAME = 0x6474e550 + PT_GNU_PROPERTY = 0x6474e553 + PT_GNU_RELRO = 0x6474e552 + PT_GNU_STACK = 0x6474e551 + PT_HIOS = 0x6fffffff + PT_HIPROC = 0x7fffffff + PT_INTERP = 0x3 + PT_LOAD = 0x1 + PT_LOOS = 0x60000000 + PT_LOPROC = 0x70000000 + PT_NOTE = 0x4 + PT_NULL = 0x0 + PT_PHDR = 0x6 + PT_SHLIB = 0x5 + PT_TLS = 0x7 P_ALL = 0x0 P_PGID = 0x2 P_PID = 0x1 @@ -3091,6 +3397,47 @@ const ( SEEK_MAX = 0x4 SEEK_SET = 0x0 SELINUX_MAGIC = 0xf97cff8c + SHF_ALLOC = 0x2 + SHF_EXCLUDE = 0x8000000 + SHF_EXECINSTR = 0x4 + SHF_GROUP = 0x200 + SHF_INFO_LINK = 0x40 + SHF_LINK_ORDER = 0x80 + SHF_MASKOS = 0xff00000 + SHF_MASKPROC = 0xf0000000 + SHF_MERGE = 0x10 + SHF_ORDERED = 0x4000000 + SHF_OS_NONCONFORMING = 0x100 + SHF_RELA_LIVEPATCH = 0x100000 + SHF_RO_AFTER_INIT = 0x200000 + SHF_STRINGS = 0x20 + SHF_TLS = 0x400 + SHF_WRITE = 0x1 + SHN_ABS = 0xfff1 + SHN_COMMON = 0xfff2 + SHN_HIPROC = 0xff1f + SHN_HIRESERVE = 0xffff + SHN_LIVEPATCH = 0xff20 + SHN_LOPROC = 0xff00 + SHN_LORESERVE = 0xff00 + SHN_UNDEF = 0x0 + SHT_DYNAMIC = 0x6 + SHT_DYNSYM = 0xb + SHT_HASH = 0x5 + SHT_HIPROC = 0x7fffffff + SHT_HIUSER = 0xffffffff + SHT_LOPROC = 0x70000000 + SHT_LOUSER = 0x80000000 + SHT_NOBITS = 0x8 + SHT_NOTE = 0x7 + SHT_NULL = 0x0 + SHT_NUM = 0xc + SHT_PROGBITS = 0x1 + SHT_REL = 0x9 + SHT_RELA = 0x4 + SHT_SHLIB = 0xa + SHT_STRTAB = 0x3 + SHT_SYMTAB = 0x2 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -3317,6 +3664,16 @@ const ( STATX_UID = 0x8 STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 + STB_GLOBAL = 0x1 + STB_LOCAL = 0x0 + STB_WEAK = 0x2 + STT_COMMON = 0x5 + STT_FILE = 0x4 + STT_FUNC = 0x2 + STT_NOTYPE = 0x0 + STT_OBJECT = 0x1 + STT_SECTION = 0x3 + STT_TLS = 0x6 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 SYNC_FILE_RANGE_WRITE = 0x2 @@ -3553,6 +3910,8 @@ const ( UTIME_OMIT = 0x3ffffffe V9FS_MAGIC = 0x1021997 VERASE = 0x2 + VER_FLG_BASE = 0x1 + VER_FLG_WEAK = 0x2 VINTR = 0x0 VKILL = 0x3 VLNEXT = 0xf diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 5cc1e8eb2f..8935d10a31 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -2238,3 +2238,13 @@ func Mseal(b []byte, flags uint) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setMemPolicy(mode int, mask *CPUSet, size int) (err error) { + _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(unsafe.Pointer(mask)), uintptr(size)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 944e75a11c..c1a4670171 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -3590,6 +3590,8 @@ type Nhmsg struct { Flags uint32 } +const SizeofNhmsg = 0x8 + type NexthopGrp struct { Id uint32 Weight uint8 @@ -3597,6 +3599,8 @@ type NexthopGrp struct { Resvd2 uint16 } +const SizeofNexthopGrp = 0x8 + const ( NHA_UNSPEC = 0x0 NHA_ID = 0x1 @@ -6332,3 +6336,30 @@ type SockDiagReq struct { } const RTM_NEWNVLAN = 0x70 + +const ( + MPOL_BIND = 0x2 + MPOL_DEFAULT = 0x0 + MPOL_F_ADDR = 0x2 + MPOL_F_MEMS_ALLOWED = 0x4 + MPOL_F_MOF = 0x8 + MPOL_F_MORON = 0x10 + MPOL_F_NODE = 0x1 + MPOL_F_NUMA_BALANCING = 0x2000 + MPOL_F_RELATIVE_NODES = 0x4000 + MPOL_F_SHARED = 0x1 + MPOL_F_STATIC_NODES = 0x8000 + MPOL_INTERLEAVE = 0x3 + MPOL_LOCAL = 0x4 + MPOL_MAX = 0x7 + MPOL_MF_INTERNAL = 0x10 + MPOL_MF_LAZY = 0x8 + MPOL_MF_MOVE_ALL = 0x4 + MPOL_MF_MOVE = 0x2 + MPOL_MF_STRICT = 0x1 + MPOL_MF_VALID = 0x7 + MPOL_MODE_FLAGS = 0xe000 + MPOL_PREFERRED = 0x1 + MPOL_PREFERRED_MANY = 0x5 + MPOL_WEIGHTED_INTERLEAVE = 0x6 +) diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 640f6b153f..69439df2a4 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -321,6 +321,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents +//sys FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot //sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW @@ -890,8 +892,12 @@ const socket_error = uintptr(^uint32(0)) //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx //sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex +//sys GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) = iphlpapi.GetIpForwardEntry2 +//sys GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) = iphlpapi.GetIpForwardTable2 //sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry +//sys FreeMibTable(memory unsafe.Pointer) = iphlpapi.FreeMibTable //sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange +//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2 //sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange //sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 @@ -914,6 +920,17 @@ type RawSockaddrInet6 struct { Scope_id uint32 } +// RawSockaddrInet is a union that contains an IPv4, an IPv6 address, or an address family. See +// https://learn.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet. +// +// A [*RawSockaddrInet] may be converted to a [*RawSockaddrInet4] or [*RawSockaddrInet6] using +// unsafe, depending on the address family. +type RawSockaddrInet struct { + Family uint16 + Port uint16 + Data [6]uint32 +} + type RawSockaddr struct { Family uint16 Data [14]int8 diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 993a2297db..6e4f50eb48 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -65,6 +65,22 @@ var signals = [...]string{ 15: "terminated", } +// File flags for [os.OpenFile]. The O_ prefix is used to indicate +// that these flags are specific to the OpenFile function. +const ( + O_FILE_FLAG_OPEN_NO_RECALL = FILE_FLAG_OPEN_NO_RECALL + O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT + O_FILE_FLAG_SESSION_AWARE = FILE_FLAG_SESSION_AWARE + O_FILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS + O_FILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS + O_FILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE + O_FILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN + O_FILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS + O_FILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING + O_FILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED + O_FILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH +) + const ( FILE_READ_DATA = 0x00000001 FILE_READ_ATTRIBUTES = 0x00000080 @@ -2304,6 +2320,82 @@ type MibIfRow2 struct { OutQLen uint64 } +// IP_ADDRESS_PREFIX stores an IP address prefix. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-ip_address_prefix. +type IpAddressPrefix struct { + Prefix RawSockaddrInet + PrefixLength uint8 +} + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_origin. +const ( + NlroManual = 0 + NlroWellKnown = 1 + NlroDHCP = 2 + NlroRouterAdvertisement = 3 + Nlro6to4 = 4 +) + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_protocol. +const ( + MIB_IPPROTO_OTHER = 1 + MIB_IPPROTO_LOCAL = 2 + MIB_IPPROTO_NETMGMT = 3 + MIB_IPPROTO_ICMP = 4 + MIB_IPPROTO_EGP = 5 + MIB_IPPROTO_GGP = 6 + MIB_IPPROTO_HELLO = 7 + MIB_IPPROTO_RIP = 8 + MIB_IPPROTO_IS_IS = 9 + MIB_IPPROTO_ES_IS = 10 + MIB_IPPROTO_CISCO = 11 + MIB_IPPROTO_BBN = 12 + MIB_IPPROTO_OSPF = 13 + MIB_IPPROTO_BGP = 14 + MIB_IPPROTO_IDPR = 15 + MIB_IPPROTO_EIGRP = 16 + MIB_IPPROTO_DVMRP = 17 + MIB_IPPROTO_RPL = 18 + MIB_IPPROTO_DHCP = 19 + MIB_IPPROTO_NT_AUTOSTATIC = 10002 + MIB_IPPROTO_NT_STATIC = 10006 + MIB_IPPROTO_NT_STATIC_NON_DOD = 10007 +) + +// MIB_IPFORWARD_ROW2 stores information about an IP route entry. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_row2. +type MibIpForwardRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + DestinationPrefix IpAddressPrefix + NextHop RawSockaddrInet + SitePrefixLength uint8 + ValidLifetime uint32 + PreferredLifetime uint32 + Metric uint32 + Protocol uint32 + Loopback uint8 + AutoconfigureAddress uint8 + Publish uint8 + Immortal uint8 + Age uint32 + Origin uint32 +} + +// MIB_IPFORWARD_TABLE2 contains a table of IP route entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_table2. +type MibIpForwardTable2 struct { + NumEntries uint32 + Table [1]MibIpForwardRow2 +} + +// Rows returns the IP route entries in the table. +func (t *MibIpForwardTable2) Rows() []MibIpForwardRow2 { + return unsafe.Slice(&t.Table[0], t.NumEntries) +} + // MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See // https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. type MibUnicastIpAddressRow struct { diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 641a5f4b77..f25b7308a1 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -182,13 +182,17 @@ var ( procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") + procFreeMibTable = modiphlpapi.NewProc("FreeMibTable") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") + procGetIpForwardEntry2 = modiphlpapi.NewProc("GetIpForwardEntry2") + procGetIpForwardTable2 = modiphlpapi.NewProc("GetIpForwardTable2") procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") + procNotifyRouteChange2 = modiphlpapi.NewProc("NotifyRouteChange2") procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") @@ -238,6 +242,7 @@ var ( procFindResourceW = modkernel32.NewProc("FindResourceW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer") procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") procFormatMessageW = modkernel32.NewProc("FormatMessageW") @@ -284,6 +289,7 @@ var ( procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") + procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -1622,6 +1628,11 @@ func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { return } +func FreeMibTable(memory unsafe.Pointer) { + syscall.SyscallN(procFreeMibTable.Addr(), uintptr(memory)) + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.SyscallN(procGetAdaptersAddresses.Addr(), uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer))) if r0 != 0 { @@ -1662,6 +1673,22 @@ func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { return } +func GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardEntry2.Addr(), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardTable2.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row))) if r0 != 0 { @@ -1682,6 +1709,18 @@ func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsa return } +func NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procNotifyRouteChange2.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { var _p0 uint32 if initialNotification { @@ -2111,6 +2150,14 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { return } +func FlushConsoleInputBuffer(console Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFlushConsoleInputBuffer.Addr(), uintptr(console)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func FlushFileBuffers(handle Handle) (err error) { r1, _, e1 := syscall.SyscallN(procFlushFileBuffers.Addr(), uintptr(handle)) if r1 == 0 { @@ -2481,6 +2528,14 @@ func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err erro return } +func GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNumberOfConsoleInputEvents.Addr(), uintptr(console), uintptr(unsafe.Pointer(numevents))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { var _p0 uint32 if wait { diff --git a/vendor/golang.org/x/term/terminal.go b/vendor/golang.org/x/term/terminal.go index bddb2e2aeb..9255449b9b 100644 --- a/vendor/golang.org/x/term/terminal.go +++ b/vendor/golang.org/x/term/terminal.go @@ -413,7 +413,7 @@ func (t *Terminal) eraseNPreviousChars(n int) { } } -// countToLeftWord returns then number of characters from the cursor to the +// countToLeftWord returns the number of characters from the cursor to the // start of the previous word. func (t *Terminal) countToLeftWord() int { if t.pos == 0 { @@ -438,7 +438,7 @@ func (t *Terminal) countToLeftWord() int { return t.pos - pos } -// countToRightWord returns then number of characters from the cursor to the +// countToRightWord returns the number of characters from the cursor to the // start of the next word. func (t *Terminal) countToRightWord() int { pos := t.pos @@ -478,7 +478,7 @@ func visualLength(runes []rune) int { return length } -// histroryAt unlocks the terminal and relocks it while calling History.At. +// historyAt unlocks the terminal and relocks it while calling History.At. func (t *Terminal) historyAt(idx int) (string, bool) { t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer. defer t.lock.Lock() // panic in At (or Len) protection. diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index 9d2ae547b5..fb8273236d 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -427,13 +427,6 @@ type isolatingRunSequence struct { func (i *isolatingRunSequence) Len() int { return len(i.indexes) } -func maxLevel(a, b level) level { - if a > b { - return a - } - return b -} - // Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, // either L or R, for each isolating run sequence. func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { @@ -474,8 +467,8 @@ func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { indexes: indexes, types: types, level: level, - sos: typeForLevel(maxLevel(prevLevel, level)), - eos: typeForLevel(maxLevel(succLevel, level)), + sos: typeForLevel(max(prevLevel, level)), + eos: typeForLevel(max(succLevel, level)), } } diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go index 5e5601aa46..5bacc0fa49 100644 --- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go +++ b/vendor/golang.org/x/tools/go/ast/astutil/imports.go @@ -209,48 +209,46 @@ func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) // DeleteNamedImport deletes the import with the given name and path from the file f, if present. // If there are duplicate import declarations, all matching ones are deleted. func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) { - var delspecs []*ast.ImportSpec - var delcomments []*ast.CommentGroup + var ( + delspecs = make(map[*ast.ImportSpec]bool) + delcomments = make(map[*ast.CommentGroup]bool) + ) // Find the import nodes that import path, if any. for i := 0; i < len(f.Decls); i++ { - decl := f.Decls[i] - gen, ok := decl.(*ast.GenDecl) + gen, ok := f.Decls[i].(*ast.GenDecl) if !ok || gen.Tok != token.IMPORT { continue } for j := 0; j < len(gen.Specs); j++ { - spec := gen.Specs[j] - impspec := spec.(*ast.ImportSpec) + impspec := gen.Specs[j].(*ast.ImportSpec) if importName(impspec) != name || importPath(impspec) != path { continue } // We found an import spec that imports path. // Delete it. - delspecs = append(delspecs, impspec) + delspecs[impspec] = true deleted = true - copy(gen.Specs[j:], gen.Specs[j+1:]) - gen.Specs = gen.Specs[:len(gen.Specs)-1] + gen.Specs = slices.Delete(gen.Specs, j, j+1) // If this was the last import spec in this decl, // delete the decl, too. if len(gen.Specs) == 0 { - copy(f.Decls[i:], f.Decls[i+1:]) - f.Decls = f.Decls[:len(f.Decls)-1] + f.Decls = slices.Delete(f.Decls, i, i+1) i-- break } else if len(gen.Specs) == 1 { if impspec.Doc != nil { - delcomments = append(delcomments, impspec.Doc) + delcomments[impspec.Doc] = true } if impspec.Comment != nil { - delcomments = append(delcomments, impspec.Comment) + delcomments[impspec.Comment] = true } for _, cg := range f.Comments { // Found comment on the same line as the import spec. if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line { - delcomments = append(delcomments, cg) + delcomments[cg] = true break } } @@ -294,38 +292,21 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del } // Delete imports from f.Imports. - for i := 0; i < len(f.Imports); i++ { - imp := f.Imports[i] - for j, del := range delspecs { - if imp == del { - copy(f.Imports[i:], f.Imports[i+1:]) - f.Imports = f.Imports[:len(f.Imports)-1] - copy(delspecs[j:], delspecs[j+1:]) - delspecs = delspecs[:len(delspecs)-1] - i-- - break - } - } + before := len(f.Imports) + f.Imports = slices.DeleteFunc(f.Imports, func(imp *ast.ImportSpec) bool { + _, ok := delspecs[imp] + return ok + }) + if len(f.Imports)+len(delspecs) != before { + // This can happen when the AST is invalid (i.e. imports differ between f.Decls and f.Imports). + panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs)) } // Delete comments from f.Comments. - for i := 0; i < len(f.Comments); i++ { - cg := f.Comments[i] - for j, del := range delcomments { - if cg == del { - copy(f.Comments[i:], f.Comments[i+1:]) - f.Comments = f.Comments[:len(f.Comments)-1] - copy(delcomments[j:], delcomments[j+1:]) - delcomments = delcomments[:len(delcomments)-1] - i-- - break - } - } - } - - if len(delspecs) > 0 { - panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs)) - } + f.Comments = slices.DeleteFunc(f.Comments, func(cg *ast.CommentGroup) bool { + _, ok := delcomments[cg] + return ok + }) return } diff --git a/vendor/golang.org/x/tools/go/ast/edge/edge.go b/vendor/golang.org/x/tools/go/ast/edge/edge.go new file mode 100644 index 0000000000..4f6ccfd6e5 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/edge/edge.go @@ -0,0 +1,295 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package edge defines identifiers for each field of an ast.Node +// struct type that refers to another Node. +package edge + +import ( + "fmt" + "go/ast" + "reflect" +) + +// A Kind describes a field of an ast.Node struct. +type Kind uint8 + +// String returns a description of the edge kind. +func (k Kind) String() string { + if k == Invalid { + return "" + } + info := fieldInfos[k] + return fmt.Sprintf("%v.%s", info.nodeType.Elem().Name(), info.name) +} + +// NodeType returns the pointer-to-struct type of the ast.Node implementation. +func (k Kind) NodeType() reflect.Type { return fieldInfos[k].nodeType } + +// FieldName returns the name of the field. +func (k Kind) FieldName() string { return fieldInfos[k].name } + +// FieldType returns the declared type of the field. +func (k Kind) FieldType() reflect.Type { return fieldInfos[k].fieldType } + +// Get returns the direct child of n identified by (k, idx). +// n's type must match k.NodeType(). +// idx must be a valid slice index, or -1 for a non-slice. +func (k Kind) Get(n ast.Node, idx int) ast.Node { + if k.NodeType() != reflect.TypeOf(n) { + panic(fmt.Sprintf("%v.Get(%T): invalid node type", k, n)) + } + v := reflect.ValueOf(n).Elem().Field(fieldInfos[k].index) + if idx != -1 { + v = v.Index(idx) // asserts valid index + } else { + // (The type assertion below asserts that v is not a slice.) + } + return v.Interface().(ast.Node) // may be nil +} + +const ( + Invalid Kind = iota // for nodes at the root of the traversal + + // Kinds are sorted alphabetically. + // Numbering is not stable. + // Each is named Type_Field, where Type is the + // ast.Node struct type and Field is the name of the field + + ArrayType_Elt + ArrayType_Len + AssignStmt_Lhs + AssignStmt_Rhs + BinaryExpr_X + BinaryExpr_Y + BlockStmt_List + BranchStmt_Label + CallExpr_Args + CallExpr_Fun + CaseClause_Body + CaseClause_List + ChanType_Value + CommClause_Body + CommClause_Comm + CommentGroup_List + CompositeLit_Elts + CompositeLit_Type + DeclStmt_Decl + DeferStmt_Call + Ellipsis_Elt + ExprStmt_X + FieldList_List + Field_Comment + Field_Doc + Field_Names + Field_Tag + Field_Type + File_Decls + File_Doc + File_Name + ForStmt_Body + ForStmt_Cond + ForStmt_Init + ForStmt_Post + FuncDecl_Body + FuncDecl_Doc + FuncDecl_Name + FuncDecl_Recv + FuncDecl_Type + FuncLit_Body + FuncLit_Type + FuncType_Params + FuncType_Results + FuncType_TypeParams + GenDecl_Doc + GenDecl_Specs + GoStmt_Call + IfStmt_Body + IfStmt_Cond + IfStmt_Else + IfStmt_Init + ImportSpec_Comment + ImportSpec_Doc + ImportSpec_Name + ImportSpec_Path + IncDecStmt_X + IndexExpr_Index + IndexExpr_X + IndexListExpr_Indices + IndexListExpr_X + InterfaceType_Methods + KeyValueExpr_Key + KeyValueExpr_Value + LabeledStmt_Label + LabeledStmt_Stmt + MapType_Key + MapType_Value + ParenExpr_X + RangeStmt_Body + RangeStmt_Key + RangeStmt_Value + RangeStmt_X + ReturnStmt_Results + SelectStmt_Body + SelectorExpr_Sel + SelectorExpr_X + SendStmt_Chan + SendStmt_Value + SliceExpr_High + SliceExpr_Low + SliceExpr_Max + SliceExpr_X + StarExpr_X + StructType_Fields + SwitchStmt_Body + SwitchStmt_Init + SwitchStmt_Tag + TypeAssertExpr_Type + TypeAssertExpr_X + TypeSpec_Comment + TypeSpec_Doc + TypeSpec_Name + TypeSpec_Type + TypeSpec_TypeParams + TypeSwitchStmt_Assign + TypeSwitchStmt_Body + TypeSwitchStmt_Init + UnaryExpr_X + ValueSpec_Comment + ValueSpec_Doc + ValueSpec_Names + ValueSpec_Type + ValueSpec_Values + + maxKind +) + +// Assert that the encoding fits in 7 bits, +// as the inspector relies on this. +// (We are currently at 104.) +var _ = [1 << 7]struct{}{}[maxKind] + +type fieldInfo struct { + nodeType reflect.Type // pointer-to-struct type of ast.Node implementation + name string + index int + fieldType reflect.Type +} + +func info[N ast.Node](fieldName string) fieldInfo { + nodePtrType := reflect.TypeFor[N]() + f, ok := nodePtrType.Elem().FieldByName(fieldName) + if !ok { + panic(fieldName) + } + return fieldInfo{nodePtrType, fieldName, f.Index[0], f.Type} +} + +var fieldInfos = [...]fieldInfo{ + Invalid: {}, + ArrayType_Elt: info[*ast.ArrayType]("Elt"), + ArrayType_Len: info[*ast.ArrayType]("Len"), + AssignStmt_Lhs: info[*ast.AssignStmt]("Lhs"), + AssignStmt_Rhs: info[*ast.AssignStmt]("Rhs"), + BinaryExpr_X: info[*ast.BinaryExpr]("X"), + BinaryExpr_Y: info[*ast.BinaryExpr]("Y"), + BlockStmt_List: info[*ast.BlockStmt]("List"), + BranchStmt_Label: info[*ast.BranchStmt]("Label"), + CallExpr_Args: info[*ast.CallExpr]("Args"), + CallExpr_Fun: info[*ast.CallExpr]("Fun"), + CaseClause_Body: info[*ast.CaseClause]("Body"), + CaseClause_List: info[*ast.CaseClause]("List"), + ChanType_Value: info[*ast.ChanType]("Value"), + CommClause_Body: info[*ast.CommClause]("Body"), + CommClause_Comm: info[*ast.CommClause]("Comm"), + CommentGroup_List: info[*ast.CommentGroup]("List"), + CompositeLit_Elts: info[*ast.CompositeLit]("Elts"), + CompositeLit_Type: info[*ast.CompositeLit]("Type"), + DeclStmt_Decl: info[*ast.DeclStmt]("Decl"), + DeferStmt_Call: info[*ast.DeferStmt]("Call"), + Ellipsis_Elt: info[*ast.Ellipsis]("Elt"), + ExprStmt_X: info[*ast.ExprStmt]("X"), + FieldList_List: info[*ast.FieldList]("List"), + Field_Comment: info[*ast.Field]("Comment"), + Field_Doc: info[*ast.Field]("Doc"), + Field_Names: info[*ast.Field]("Names"), + Field_Tag: info[*ast.Field]("Tag"), + Field_Type: info[*ast.Field]("Type"), + File_Decls: info[*ast.File]("Decls"), + File_Doc: info[*ast.File]("Doc"), + File_Name: info[*ast.File]("Name"), + ForStmt_Body: info[*ast.ForStmt]("Body"), + ForStmt_Cond: info[*ast.ForStmt]("Cond"), + ForStmt_Init: info[*ast.ForStmt]("Init"), + ForStmt_Post: info[*ast.ForStmt]("Post"), + FuncDecl_Body: info[*ast.FuncDecl]("Body"), + FuncDecl_Doc: info[*ast.FuncDecl]("Doc"), + FuncDecl_Name: info[*ast.FuncDecl]("Name"), + FuncDecl_Recv: info[*ast.FuncDecl]("Recv"), + FuncDecl_Type: info[*ast.FuncDecl]("Type"), + FuncLit_Body: info[*ast.FuncLit]("Body"), + FuncLit_Type: info[*ast.FuncLit]("Type"), + FuncType_Params: info[*ast.FuncType]("Params"), + FuncType_Results: info[*ast.FuncType]("Results"), + FuncType_TypeParams: info[*ast.FuncType]("TypeParams"), + GenDecl_Doc: info[*ast.GenDecl]("Doc"), + GenDecl_Specs: info[*ast.GenDecl]("Specs"), + GoStmt_Call: info[*ast.GoStmt]("Call"), + IfStmt_Body: info[*ast.IfStmt]("Body"), + IfStmt_Cond: info[*ast.IfStmt]("Cond"), + IfStmt_Else: info[*ast.IfStmt]("Else"), + IfStmt_Init: info[*ast.IfStmt]("Init"), + ImportSpec_Comment: info[*ast.ImportSpec]("Comment"), + ImportSpec_Doc: info[*ast.ImportSpec]("Doc"), + ImportSpec_Name: info[*ast.ImportSpec]("Name"), + ImportSpec_Path: info[*ast.ImportSpec]("Path"), + IncDecStmt_X: info[*ast.IncDecStmt]("X"), + IndexExpr_Index: info[*ast.IndexExpr]("Index"), + IndexExpr_X: info[*ast.IndexExpr]("X"), + IndexListExpr_Indices: info[*ast.IndexListExpr]("Indices"), + IndexListExpr_X: info[*ast.IndexListExpr]("X"), + InterfaceType_Methods: info[*ast.InterfaceType]("Methods"), + KeyValueExpr_Key: info[*ast.KeyValueExpr]("Key"), + KeyValueExpr_Value: info[*ast.KeyValueExpr]("Value"), + LabeledStmt_Label: info[*ast.LabeledStmt]("Label"), + LabeledStmt_Stmt: info[*ast.LabeledStmt]("Stmt"), + MapType_Key: info[*ast.MapType]("Key"), + MapType_Value: info[*ast.MapType]("Value"), + ParenExpr_X: info[*ast.ParenExpr]("X"), + RangeStmt_Body: info[*ast.RangeStmt]("Body"), + RangeStmt_Key: info[*ast.RangeStmt]("Key"), + RangeStmt_Value: info[*ast.RangeStmt]("Value"), + RangeStmt_X: info[*ast.RangeStmt]("X"), + ReturnStmt_Results: info[*ast.ReturnStmt]("Results"), + SelectStmt_Body: info[*ast.SelectStmt]("Body"), + SelectorExpr_Sel: info[*ast.SelectorExpr]("Sel"), + SelectorExpr_X: info[*ast.SelectorExpr]("X"), + SendStmt_Chan: info[*ast.SendStmt]("Chan"), + SendStmt_Value: info[*ast.SendStmt]("Value"), + SliceExpr_High: info[*ast.SliceExpr]("High"), + SliceExpr_Low: info[*ast.SliceExpr]("Low"), + SliceExpr_Max: info[*ast.SliceExpr]("Max"), + SliceExpr_X: info[*ast.SliceExpr]("X"), + StarExpr_X: info[*ast.StarExpr]("X"), + StructType_Fields: info[*ast.StructType]("Fields"), + SwitchStmt_Body: info[*ast.SwitchStmt]("Body"), + SwitchStmt_Init: info[*ast.SwitchStmt]("Init"), + SwitchStmt_Tag: info[*ast.SwitchStmt]("Tag"), + TypeAssertExpr_Type: info[*ast.TypeAssertExpr]("Type"), + TypeAssertExpr_X: info[*ast.TypeAssertExpr]("X"), + TypeSpec_Comment: info[*ast.TypeSpec]("Comment"), + TypeSpec_Doc: info[*ast.TypeSpec]("Doc"), + TypeSpec_Name: info[*ast.TypeSpec]("Name"), + TypeSpec_Type: info[*ast.TypeSpec]("Type"), + TypeSpec_TypeParams: info[*ast.TypeSpec]("TypeParams"), + TypeSwitchStmt_Assign: info[*ast.TypeSwitchStmt]("Assign"), + TypeSwitchStmt_Body: info[*ast.TypeSwitchStmt]("Body"), + TypeSwitchStmt_Init: info[*ast.TypeSwitchStmt]("Init"), + UnaryExpr_X: info[*ast.UnaryExpr]("X"), + ValueSpec_Comment: info[*ast.ValueSpec]("Comment"), + ValueSpec_Doc: info[*ast.ValueSpec]("Doc"), + ValueSpec_Names: info[*ast.ValueSpec]("Names"), + ValueSpec_Type: info[*ast.ValueSpec]("Type"), + ValueSpec_Values: info[*ast.ValueSpec]("Values"), +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go new file mode 100644 index 0000000000..7e72d3c284 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go @@ -0,0 +1,502 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package inspector + +import ( + "fmt" + "go/ast" + "go/token" + "iter" + "reflect" + + "golang.org/x/tools/go/ast/edge" +) + +// A Cursor represents an [ast.Node]. It is immutable. +// +// Two Cursors compare equal if they represent the same node. +// +// Call [Inspector.Root] to obtain a valid cursor for the virtual root +// node of the traversal. +// +// Use the following methods to navigate efficiently around the tree: +// - for ancestors, use [Cursor.Parent] and [Cursor.Enclosing]; +// - for children, use [Cursor.Child], [Cursor.Children], +// [Cursor.FirstChild], and [Cursor.LastChild]; +// - for siblings, use [Cursor.PrevSibling] and [Cursor.NextSibling]; +// - for descendants, use [Cursor.FindByPos], [Cursor.FindNode], +// [Cursor.Inspect], and [Cursor.Preorder]. +// +// Use the [Cursor.ChildAt] and [Cursor.ParentEdge] methods for +// information about the edges in a tree: which field (and slice +// element) of the parent node holds the child. +type Cursor struct { + in *Inspector + index int32 // index of push node; -1 for virtual root node +} + +// Root returns a cursor for the virtual root node, +// whose children are the files provided to [New]. +// +// Its [Cursor.Node] method return nil. +func (in *Inspector) Root() Cursor { + return Cursor{in, -1} +} + +// At returns the cursor at the specified index in the traversal, +// which must have been obtained from [Cursor.Index] on a Cursor +// belonging to the same Inspector (see [Cursor.Inspector]). +func (in *Inspector) At(index int32) Cursor { + if index < 0 { + panic("negative index") + } + if int(index) >= len(in.events) { + panic("index out of range for this inspector") + } + if in.events[index].index < index { + panic("invalid index") // (a push, not a pop) + } + return Cursor{in, index} +} + +// Inspector returns the cursor's Inspector. +func (c Cursor) Inspector() *Inspector { return c.in } + +// Index returns the index of this cursor position within the package. +// +// Clients should not assume anything about the numeric Index value +// except that it increases monotonically throughout the traversal. +// It is provided for use with [At]. +// +// Index must not be called on the Root node. +func (c Cursor) Index() int32 { + if c.index < 0 { + panic("Index called on Root node") + } + return c.index +} + +// Node returns the node at the current cursor position, +// or nil for the cursor returned by [Inspector.Root]. +func (c Cursor) Node() ast.Node { + if c.index < 0 { + return nil + } + return c.in.events[c.index].node +} + +// String returns information about the cursor's node, if any. +func (c Cursor) String() string { + if c.in == nil { + return "(invalid)" + } + if c.index < 0 { + return "(root)" + } + return reflect.TypeOf(c.Node()).String() +} + +// indices return the [start, end) half-open interval of event indices. +func (c Cursor) indices() (int32, int32) { + if c.index < 0 { + return 0, int32(len(c.in.events)) // root: all events + } else { + return c.index, c.in.events[c.index].index + 1 // just one subtree + } +} + +// Preorder returns an iterator over the nodes of the subtree +// represented by c in depth-first order. Each node in the sequence is +// represented by a Cursor that allows access to the Node, but may +// also be used to start a new traversal, or to obtain the stack of +// nodes enclosing the cursor. +// +// The traversal sequence is determined by [ast.Inspect]. The types +// argument, if non-empty, enables type-based filtering of events. The +// function f if is called only for nodes whose type matches an +// element of the types slice. +// +// If you need control over descent into subtrees, +// or need both pre- and post-order notifications, use [Cursor.Inspect] +func (c Cursor) Preorder(types ...ast.Node) iter.Seq[Cursor] { + mask := maskOf(types) + + return func(yield func(Cursor) bool) { + events := c.in.events + + for i, limit := c.indices(); i < limit; { + ev := events[i] + if ev.index > i { // push? + if ev.typ&mask != 0 && !yield(Cursor{c.in, i}) { + break + } + pop := ev.index + if events[pop].typ&mask == 0 { + // Subtree does not contain types: skip. + i = pop + 1 + continue + } + } + i++ + } + } +} + +// Inspect visits the nodes of the subtree represented by c in +// depth-first order. It calls f(n) for each node n before it +// visits n's children. If f returns true, Inspect invokes f +// recursively for each of the non-nil children of the node. +// +// Each node is represented by a Cursor that allows access to the +// Node, but may also be used to start a new traversal, or to obtain +// the stack of nodes enclosing the cursor. +// +// The complete traversal sequence is determined by [ast.Inspect]. +// The types argument, if non-empty, enables type-based filtering of +// events. The function f if is called only for nodes whose type +// matches an element of the types slice. +func (c Cursor) Inspect(types []ast.Node, f func(c Cursor) (descend bool)) { + mask := maskOf(types) + events := c.in.events + for i, limit := c.indices(); i < limit; { + ev := events[i] + if ev.index > i { + // push + pop := ev.index + if ev.typ&mask != 0 && !f(Cursor{c.in, i}) || + events[pop].typ&mask == 0 { + // The user opted not to descend, or the + // subtree does not contain types: + // skip past the pop. + i = pop + 1 + continue + } + } + i++ + } +} + +// Enclosing returns an iterator over the nodes enclosing the current +// current node, starting with the Cursor itself. +// +// Enclosing must not be called on the Root node (whose [Cursor.Node] returns nil). +// +// The types argument, if non-empty, enables type-based filtering of +// events: the sequence includes only enclosing nodes whose type +// matches an element of the types slice. +func (c Cursor) Enclosing(types ...ast.Node) iter.Seq[Cursor] { + if c.index < 0 { + panic("Cursor.Enclosing called on Root node") + } + + mask := maskOf(types) + + return func(yield func(Cursor) bool) { + events := c.in.events + for i := c.index; i >= 0; i = events[i].parent { + if events[i].typ&mask != 0 && !yield(Cursor{c.in, i}) { + break + } + } + } +} + +// Parent returns the parent of the current node. +// +// Parent must not be called on the Root node (whose [Cursor.Node] returns nil). +func (c Cursor) Parent() Cursor { + if c.index < 0 { + panic("Cursor.Parent called on Root node") + } + + return Cursor{c.in, c.in.events[c.index].parent} +} + +// ParentEdge returns the identity of the field in the parent node +// that holds this cursor's node, and if it is a list, the index within it. +// +// For example, f(x, y) is a CallExpr whose three children are Idents. +// f has edge kind [edge.CallExpr_Fun] and index -1. +// x and y have kind [edge.CallExpr_Args] and indices 0 and 1, respectively. +// +// If called on a child of the Root node, it returns ([edge.Invalid], -1). +// +// ParentEdge must not be called on the Root node (whose [Cursor.Node] returns nil). +func (c Cursor) ParentEdge() (edge.Kind, int) { + if c.index < 0 { + panic("Cursor.ParentEdge called on Root node") + } + events := c.in.events + pop := events[c.index].index + return unpackEdgeKindAndIndex(events[pop].parent) +} + +// ChildAt returns the cursor for the child of the +// current node identified by its edge and index. +// The index must be -1 if the edge.Kind is not a slice. +// The indicated child node must exist. +// +// ChildAt must not be called on the Root node (whose [Cursor.Node] returns nil). +// +// Invariant: c.Parent().ChildAt(c.ParentEdge()) == c. +func (c Cursor) ChildAt(k edge.Kind, idx int) Cursor { + target := packEdgeKindAndIndex(k, idx) + + // Unfortunately there's no shortcut to looping. + events := c.in.events + i := c.index + 1 + for { + pop := events[i].index + if pop < i { + break + } + if events[pop].parent == target { + return Cursor{c.in, i} + } + i = pop + 1 + } + panic(fmt.Sprintf("ChildAt(%v, %d): no such child of %v", k, idx, c)) +} + +// Child returns the cursor for n, which must be a direct child of c's Node. +// +// Child must not be called on the Root node (whose [Cursor.Node] returns nil). +func (c Cursor) Child(n ast.Node) Cursor { + if c.index < 0 { + panic("Cursor.Child called on Root node") + } + + if false { + // reference implementation + for child := range c.Children() { + if child.Node() == n { + return child + } + } + + } else { + // optimized implementation + events := c.in.events + for i := c.index + 1; events[i].index > i; i = events[i].index + 1 { + if events[i].node == n { + return Cursor{c.in, i} + } + } + } + panic(fmt.Sprintf("Child(%T): not a child of %v", n, c)) +} + +// NextSibling returns the cursor for the next sibling node in the same list +// (for example, of files, decls, specs, statements, fields, or expressions) as +// the current node. It returns (zero, false) if the node is the last node in +// the list, or is not part of a list. +// +// NextSibling must not be called on the Root node. +// +// See note at [Cursor.Children]. +func (c Cursor) NextSibling() (Cursor, bool) { + if c.index < 0 { + panic("Cursor.NextSibling called on Root node") + } + + events := c.in.events + i := events[c.index].index + 1 // after corresponding pop + if i < int32(len(events)) { + if events[i].index > i { // push? + return Cursor{c.in, i}, true + } + } + return Cursor{}, false +} + +// PrevSibling returns the cursor for the previous sibling node in the +// same list (for example, of files, decls, specs, statements, fields, +// or expressions) as the current node. It returns zero if the node is +// the first node in the list, or is not part of a list. +// +// It must not be called on the Root node. +// +// See note at [Cursor.Children]. +func (c Cursor) PrevSibling() (Cursor, bool) { + if c.index < 0 { + panic("Cursor.PrevSibling called on Root node") + } + + events := c.in.events + i := c.index - 1 + if i >= 0 { + if j := events[i].index; j < i { // pop? + return Cursor{c.in, j}, true + } + } + return Cursor{}, false +} + +// FirstChild returns the first direct child of the current node, +// or zero if it has no children. +func (c Cursor) FirstChild() (Cursor, bool) { + events := c.in.events + i := c.index + 1 // i=0 if c is root + if i < int32(len(events)) && events[i].index > i { // push? + return Cursor{c.in, i}, true + } + return Cursor{}, false +} + +// LastChild returns the last direct child of the current node, +// or zero if it has no children. +func (c Cursor) LastChild() (Cursor, bool) { + events := c.in.events + if c.index < 0 { // root? + if len(events) > 0 { + // return push of final event (a pop) + return Cursor{c.in, events[len(events)-1].index}, true + } + } else { + j := events[c.index].index - 1 // before corresponding pop + // Inv: j == c.index if c has no children + // or j is last child's pop. + if j > c.index { // c has children + return Cursor{c.in, events[j].index}, true + } + } + return Cursor{}, false +} + +// Children returns an iterator over the direct children of the +// current node, if any. +// +// When using Children, NextChild, and PrevChild, bear in mind that a +// Node's children may come from different fields, some of which may +// be lists of nodes without a distinguished intervening container +// such as [ast.BlockStmt]. +// +// For example, [ast.CaseClause] has a field List of expressions and a +// field Body of statements, so the children of a CaseClause are a mix +// of expressions and statements. Other nodes that have "uncontained" +// list fields include: +// +// - [ast.ValueSpec] (Names, Values) +// - [ast.CompositeLit] (Type, Elts) +// - [ast.IndexListExpr] (X, Indices) +// - [ast.CallExpr] (Fun, Args) +// - [ast.AssignStmt] (Lhs, Rhs) +// +// So, do not assume that the previous sibling of an ast.Stmt is also +// an ast.Stmt, or if it is, that they are executed sequentially, +// unless you have established that, say, its parent is a BlockStmt +// or its [Cursor.ParentEdge] is [edge.BlockStmt_List]. +// For example, given "for S1; ; S2 {}", the predecessor of S2 is S1, +// even though they are not executed in sequence. +func (c Cursor) Children() iter.Seq[Cursor] { + return func(yield func(Cursor) bool) { + c, ok := c.FirstChild() + for ok && yield(c) { + c, ok = c.NextSibling() + } + } +} + +// Contains reports whether c contains or is equal to c2. +// +// Both Cursors must belong to the same [Inspector]; +// neither may be its Root node. +func (c Cursor) Contains(c2 Cursor) bool { + if c.in != c2.in { + panic("different inspectors") + } + events := c.in.events + return c.index <= c2.index && events[c2.index].index <= events[c.index].index +} + +// FindNode returns the cursor for node n if it belongs to the subtree +// rooted at c. It returns zero if n is not found. +func (c Cursor) FindNode(n ast.Node) (Cursor, bool) { + + // FindNode is equivalent to this code, + // but more convenient and 15-20% faster: + if false { + for candidate := range c.Preorder(n) { + if candidate.Node() == n { + return candidate, true + } + } + return Cursor{}, false + } + + // TODO(adonovan): opt: should we assume Node.Pos is accurate + // and combine type-based filtering with position filtering + // like FindByPos? + + mask := maskOf([]ast.Node{n}) + events := c.in.events + + for i, limit := c.indices(); i < limit; i++ { + ev := events[i] + if ev.index > i { // push? + if ev.typ&mask != 0 && ev.node == n { + return Cursor{c.in, i}, true + } + pop := ev.index + if events[pop].typ&mask == 0 { + // Subtree does not contain type of n: skip. + i = pop + } + } + } + return Cursor{}, false +} + +// FindByPos returns the cursor for the innermost node n in the tree +// rooted at c such that n.Pos() <= start && end <= n.End(). +// (For an *ast.File, it uses the bounds n.FileStart-n.FileEnd.) +// +// It returns zero if none is found. +// Precondition: start <= end. +// +// See also [astutil.PathEnclosingInterval], which +// tolerates adjoining whitespace. +func (c Cursor) FindByPos(start, end token.Pos) (Cursor, bool) { + if end < start { + panic("end < start") + } + events := c.in.events + + // This algorithm could be implemented using c.Inspect, + // but it is about 2.5x slower. + + best := int32(-1) // push index of latest (=innermost) node containing range + for i, limit := c.indices(); i < limit; i++ { + ev := events[i] + if ev.index > i { // push? + n := ev.node + var nodeEnd token.Pos + if file, ok := n.(*ast.File); ok { + nodeEnd = file.FileEnd + // Note: files may be out of Pos order. + if file.FileStart > start { + i = ev.index // disjoint, after; skip to next file + continue + } + } else { + nodeEnd = n.End() + if n.Pos() > start { + break // disjoint, after; stop + } + } + // Inv: node.{Pos,FileStart} <= start + if end <= nodeEnd { + // node fully contains target range + best = i + } else if nodeEnd < start { + i = ev.index // disjoint, before; skip forward + } + } + } + if best >= 0 { + return Cursor{c.in, best}, true + } + return Cursor{}, false +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go new file mode 100644 index 0000000000..a703cdfcf9 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go @@ -0,0 +1,311 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package inspector provides helper functions for traversal over the +// syntax trees of a package, including node filtering by type, and +// materialization of the traversal stack. +// +// During construction, the inspector does a complete traversal and +// builds a list of push/pop events and their node type. Subsequent +// method calls that request a traversal scan this list, rather than walk +// the AST, and perform type filtering using efficient bit sets. +// This representation is sometimes called a "balanced parenthesis tree." +// +// Experiments suggest the inspector's traversals are about 2.5x faster +// than [ast.Inspect], but it may take around 5 traversals for this +// benefit to amortize the inspector's construction cost. +// If efficiency is the primary concern, do not use Inspector for +// one-off traversals. +// +// The [Cursor] type provides a more flexible API for efficient +// navigation of syntax trees in all four "cardinal directions". For +// example, traversals may be nested, so you can find each node of +// type A and then search within it for nodes of type B. Or you can +// traverse from a node to its immediate neighbors: its parent, its +// previous and next sibling, or its first and last child. We +// recommend using methods of Cursor in preference to Inspector where +// possible. +package inspector + +// There are four orthogonal features in a traversal: +// 1 type filtering +// 2 pruning +// 3 postorder calls to f +// 4 stack +// Rather than offer all of them in the API, +// only a few combinations are exposed: +// - Preorder is the fastest and has fewest features, +// but is the most commonly needed traversal. +// - Nodes and WithStack both provide pruning and postorder calls, +// even though few clients need it, because supporting two versions +// is not justified. +// More combinations could be supported by expressing them as +// wrappers around a more generic traversal, but this was measured +// and found to degrade performance significantly (30%). + +import ( + "go/ast" + + "golang.org/x/tools/go/ast/edge" +) + +// An Inspector provides methods for inspecting +// (traversing) the syntax trees of a package. +type Inspector struct { + events []event +} + +func packEdgeKindAndIndex(ek edge.Kind, index int) int32 { + return int32(uint32(index+1)<<7 | uint32(ek)) +} + +// unpackEdgeKindAndIndex unpacks the edge kind and edge index (within +// an []ast.Node slice) from the parent field of a pop event. +func unpackEdgeKindAndIndex(x int32) (edge.Kind, int) { + // The "parent" field of a pop node holds the + // edge Kind in the lower 7 bits and the index+1 + // in the upper 25. + return edge.Kind(x & 0x7f), int(x>>7) - 1 +} + +// New returns an Inspector for the specified syntax trees. +func New(files []*ast.File) *Inspector { + return &Inspector{traverse(files)} +} + +// An event represents a push or a pop +// of an ast.Node during a traversal. +type event struct { + node ast.Node + typ uint64 // typeOf(node) on push event, or union of typ strictly between push and pop events on pop events + index int32 // index of corresponding push or pop event + parent int32 // index of parent's push node (push nodes only), or packed edge kind/index (pop nodes only) +} + +// TODO: Experiment with storing only the second word of event.node (unsafe.Pointer). +// Type can be recovered from the sole bit in typ. +// [Tried this, wasn't faster. --adonovan] + +// Preorder visits all the nodes of the files supplied to New in +// depth-first order. It calls f(n) for each node n before it visits +// n's children. +// +// The complete traversal sequence is determined by [ast.Inspect]. +// The types argument, if non-empty, enables type-based filtering of +// events. The function f is called only for nodes whose type +// matches an element of the types slice. +// +// The [Cursor.Preorder] method provides a richer alternative interface. +// Example: +// +// for c := range in.Root().Preorder(types) { ... } +func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) { + // Because it avoids postorder calls to f, and the pruning + // check, Preorder is almost twice as fast as Nodes. The two + // features seem to contribute similar slowdowns (~1.4x each). + + // This function is equivalent to the PreorderSeq call below, + // but to avoid the additional dynamic call (which adds 13-35% + // to the benchmarks), we expand it out. + // + // in.PreorderSeq(types...)(func(n ast.Node) bool { + // f(n) + // return true + // }) + + mask := maskOf(types) + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + if ev.typ&mask != 0 { + f(ev.node) + } + pop := ev.index + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them and pop. + i = pop + 1 + continue + } + } + i++ + } +} + +// Nodes visits the nodes of the files supplied to New in depth-first +// order. It calls f(n, true) for each node n before it visits n's +// children. If f returns true, Nodes invokes f recursively for each +// of the non-nil children of the node, followed by a call of +// f(n, false). +// +// The complete traversal sequence is determined by [ast.Inspect]. +// The types argument, if non-empty, enables type-based filtering of +// events. The function f if is called only for nodes whose type +// matches an element of the types slice. +// +// The [Cursor.Inspect] method provides a richer alternative interface. +// Example: +// +// in.Root().Inspect(types, func(c Cursor) bool { +// ... +// return true +// } +func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) { + mask := maskOf(types) + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + pop := ev.index + if ev.typ&mask != 0 { + if !f(ev.node, true) { + i = pop + 1 // jump to corresponding pop + 1 + continue + } + } + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them. + i = pop + continue + } + } else { + // pop + push := ev.index + if in.events[push].typ&mask != 0 { + f(ev.node, false) + } + } + i++ + } +} + +// WithStack visits nodes in a similar manner to Nodes, but it +// supplies each call to f an additional argument, the current +// traversal stack. The stack's first element is the outermost node, +// an *ast.File; its last is the innermost, n. +// +// The [Cursor.Inspect] method provides a richer alternative interface. +// Example: +// +// in.Root().Inspect(types, func(c Cursor) bool { +// stack := slices.Collect(c.Enclosing()) +// ... +// return true +// }) +func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) { + mask := maskOf(types) + var stack []ast.Node + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + pop := ev.index + stack = append(stack, ev.node) + if ev.typ&mask != 0 { + if !f(ev.node, true, stack) { + i = pop + 1 + stack = stack[:len(stack)-1] + continue + } + } + if in.events[pop].typ&mask == 0 { + // Subtrees does not contain types: skip them. + i = pop + continue + } + } else { + // pop + push := ev.index + if in.events[push].typ&mask != 0 { + f(ev.node, false, stack) + } + stack = stack[:len(stack)-1] + } + i++ + } +} + +// traverse builds the table of events representing a traversal. +func traverse(files []*ast.File) []event { + // Preallocate approximate number of events + // based on source file extent of the declarations. + // (We use End-Pos not FileStart-FileEnd to neglect + // the effect of long doc comments.) + // This makes traverse faster by 4x (!). + var extent int + for _, f := range files { + extent += int(f.End() - f.Pos()) + } + // This estimate is based on the net/http package. + capacity := min(extent*33/100, 1e6) // impose some reasonable maximum (1M) + + v := &visitor{ + events: make([]event, 0, capacity), + stack: []item{{index: -1}}, // include an extra event so file nodes have a parent + } + for _, file := range files { + walk(v, edge.Invalid, -1, file) + } + return v.events +} + +type visitor struct { + events []event + stack []item +} + +type item struct { + index int32 // index of current node's push event + parentIndex int32 // index of parent node's push event + typAccum uint64 // accumulated type bits of current node's descendants + edgeKindAndIndex int32 // edge.Kind and index, bit packed +} + +func (v *visitor) push(ek edge.Kind, eindex int, node ast.Node) { + var ( + index = int32(len(v.events)) + parentIndex = v.stack[len(v.stack)-1].index + ) + v.events = append(v.events, event{ + node: node, + parent: parentIndex, + typ: typeOf(node), + index: 0, // (pop index is set later by visitor.pop) + }) + v.stack = append(v.stack, item{ + index: index, + parentIndex: parentIndex, + edgeKindAndIndex: packEdgeKindAndIndex(ek, eindex), + }) + + // 2B nodes ought to be enough for anyone! + if int32(len(v.events)) < 0 { + panic("event index exceeded int32") + } + + // 32M elements in an []ast.Node ought to be enough for anyone! + if ek2, eindex2 := unpackEdgeKindAndIndex(packEdgeKindAndIndex(ek, eindex)); ek2 != ek || eindex2 != eindex { + panic("Node slice index exceeded uint25") + } +} + +func (v *visitor) pop(node ast.Node) { + top := len(v.stack) - 1 + current := v.stack[top] + + push := &v.events[current.index] + parent := &v.stack[top-1] + + push.index = int32(len(v.events)) // make push event refer to pop + parent.typAccum |= current.typAccum | push.typ // accumulate type bits into parent + + v.stack = v.stack[:top] + + v.events = append(v.events, event{ + node: node, + typ: current.typAccum, + index: current.index, + parent: current.edgeKindAndIndex, // see [unpackEdgeKindAndIndex] + }) +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/iter.go b/vendor/golang.org/x/tools/go/ast/inspector/iter.go new file mode 100644 index 0000000000..c576dc70ac --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/iter.go @@ -0,0 +1,85 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.23 + +package inspector + +import ( + "go/ast" + "iter" +) + +// PreorderSeq returns an iterator that visits all the +// nodes of the files supplied to New in depth-first order. +// It visits each node n before n's children. +// The complete traversal sequence is determined by ast.Inspect. +// +// The types argument, if non-empty, enables type-based +// filtering of events: only nodes whose type matches an +// element of the types slice are included in the sequence. +func (in *Inspector) PreorderSeq(types ...ast.Node) iter.Seq[ast.Node] { + + // This implementation is identical to Preorder, + // except that it supports breaking out of the loop. + + return func(yield func(ast.Node) bool) { + mask := maskOf(types) + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + if ev.typ&mask != 0 { + if !yield(ev.node) { + break + } + } + pop := ev.index + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them and pop. + i = pop + 1 + continue + } + } + i++ + } + } +} + +// All[N] returns an iterator over all the nodes of type N. +// N must be a pointer-to-struct type that implements ast.Node. +// +// Example: +// +// for call := range All[*ast.CallExpr](in) { ... } +func All[N interface { + *S + ast.Node +}, S any](in *Inspector) iter.Seq[N] { + + // To avoid additional dynamic call overheads, + // we duplicate rather than call the logic of PreorderSeq. + + mask := typeOf((N)(nil)) + return func(yield func(N) bool) { + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + if ev.typ&mask != 0 { + if !yield(ev.node.(N)) { + break + } + } + pop := ev.index + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them and pop. + i = pop + 1 + continue + } + } + i++ + } + } +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/typeof.go b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go new file mode 100644 index 0000000000..9852331a3d --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go @@ -0,0 +1,227 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package inspector + +// This file defines func typeOf(ast.Node) uint64. +// +// The initial map-based implementation was too slow; +// see https://go-review.googlesource.com/c/tools/+/135655/1/go/ast/inspector/inspector.go#196 + +import ( + "go/ast" + "math" +) + +const ( + nArrayType = iota + nAssignStmt + nBadDecl + nBadExpr + nBadStmt + nBasicLit + nBinaryExpr + nBlockStmt + nBranchStmt + nCallExpr + nCaseClause + nChanType + nCommClause + nComment + nCommentGroup + nCompositeLit + nDeclStmt + nDeferStmt + nEllipsis + nEmptyStmt + nExprStmt + nField + nFieldList + nFile + nForStmt + nFuncDecl + nFuncLit + nFuncType + nGenDecl + nGoStmt + nIdent + nIfStmt + nImportSpec + nIncDecStmt + nIndexExpr + nIndexListExpr + nInterfaceType + nKeyValueExpr + nLabeledStmt + nMapType + nPackage + nParenExpr + nRangeStmt + nReturnStmt + nSelectStmt + nSelectorExpr + nSendStmt + nSliceExpr + nStarExpr + nStructType + nSwitchStmt + nTypeAssertExpr + nTypeSpec + nTypeSwitchStmt + nUnaryExpr + nValueSpec +) + +// typeOf returns a distinct single-bit value that represents the type of n. +// +// Various implementations were benchmarked with BenchmarkNewInspector: +// +// GOGC=off +// - type switch 4.9-5.5ms 2.1ms +// - binary search over a sorted list of types 5.5-5.9ms 2.5ms +// - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms +// - linear scan, unordered list 6.4ms 2.7ms +// - hash table 6.5ms 3.1ms +// +// A perfect hash seemed like overkill. +// +// The compiler's switch statement is the clear winner +// as it produces a binary tree in code, +// with constant conditions and good branch prediction. +// (Sadly it is the most verbose in source code.) +// Binary search suffered from poor branch prediction. +func typeOf(n ast.Node) uint64 { + // Fast path: nearly half of all nodes are identifiers. + if _, ok := n.(*ast.Ident); ok { + return 1 << nIdent + } + + // These cases include all nodes encountered by ast.Inspect. + switch n.(type) { + case *ast.ArrayType: + return 1 << nArrayType + case *ast.AssignStmt: + return 1 << nAssignStmt + case *ast.BadDecl: + return 1 << nBadDecl + case *ast.BadExpr: + return 1 << nBadExpr + case *ast.BadStmt: + return 1 << nBadStmt + case *ast.BasicLit: + return 1 << nBasicLit + case *ast.BinaryExpr: + return 1 << nBinaryExpr + case *ast.BlockStmt: + return 1 << nBlockStmt + case *ast.BranchStmt: + return 1 << nBranchStmt + case *ast.CallExpr: + return 1 << nCallExpr + case *ast.CaseClause: + return 1 << nCaseClause + case *ast.ChanType: + return 1 << nChanType + case *ast.CommClause: + return 1 << nCommClause + case *ast.Comment: + return 1 << nComment + case *ast.CommentGroup: + return 1 << nCommentGroup + case *ast.CompositeLit: + return 1 << nCompositeLit + case *ast.DeclStmt: + return 1 << nDeclStmt + case *ast.DeferStmt: + return 1 << nDeferStmt + case *ast.Ellipsis: + return 1 << nEllipsis + case *ast.EmptyStmt: + return 1 << nEmptyStmt + case *ast.ExprStmt: + return 1 << nExprStmt + case *ast.Field: + return 1 << nField + case *ast.FieldList: + return 1 << nFieldList + case *ast.File: + return 1 << nFile + case *ast.ForStmt: + return 1 << nForStmt + case *ast.FuncDecl: + return 1 << nFuncDecl + case *ast.FuncLit: + return 1 << nFuncLit + case *ast.FuncType: + return 1 << nFuncType + case *ast.GenDecl: + return 1 << nGenDecl + case *ast.GoStmt: + return 1 << nGoStmt + case *ast.Ident: + return 1 << nIdent + case *ast.IfStmt: + return 1 << nIfStmt + case *ast.ImportSpec: + return 1 << nImportSpec + case *ast.IncDecStmt: + return 1 << nIncDecStmt + case *ast.IndexExpr: + return 1 << nIndexExpr + case *ast.IndexListExpr: + return 1 << nIndexListExpr + case *ast.InterfaceType: + return 1 << nInterfaceType + case *ast.KeyValueExpr: + return 1 << nKeyValueExpr + case *ast.LabeledStmt: + return 1 << nLabeledStmt + case *ast.MapType: + return 1 << nMapType + case *ast.Package: + return 1 << nPackage + case *ast.ParenExpr: + return 1 << nParenExpr + case *ast.RangeStmt: + return 1 << nRangeStmt + case *ast.ReturnStmt: + return 1 << nReturnStmt + case *ast.SelectStmt: + return 1 << nSelectStmt + case *ast.SelectorExpr: + return 1 << nSelectorExpr + case *ast.SendStmt: + return 1 << nSendStmt + case *ast.SliceExpr: + return 1 << nSliceExpr + case *ast.StarExpr: + return 1 << nStarExpr + case *ast.StructType: + return 1 << nStructType + case *ast.SwitchStmt: + return 1 << nSwitchStmt + case *ast.TypeAssertExpr: + return 1 << nTypeAssertExpr + case *ast.TypeSpec: + return 1 << nTypeSpec + case *ast.TypeSwitchStmt: + return 1 << nTypeSwitchStmt + case *ast.UnaryExpr: + return 1 << nUnaryExpr + case *ast.ValueSpec: + return 1 << nValueSpec + } + return 0 +} + +func maskOf(nodes []ast.Node) uint64 { + if len(nodes) == 0 { + return math.MaxUint64 // match all node types + } + var mask uint64 + for _, n := range nodes { + mask |= typeOf(n) + } + return mask +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/walk.go b/vendor/golang.org/x/tools/go/ast/inspector/walk.go new file mode 100644 index 0000000000..5f1c93c8a7 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/walk.go @@ -0,0 +1,341 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package inspector + +// This file is a fork of ast.Inspect to reduce unnecessary dynamic +// calls and to gather edge information. +// +// Consistency with the original is ensured by TestInspectAllNodes. + +import ( + "fmt" + "go/ast" + + "golang.org/x/tools/go/ast/edge" +) + +func walkList[N ast.Node](v *visitor, ek edge.Kind, list []N) { + for i, node := range list { + walk(v, ek, i, node) + } +} + +func walk(v *visitor, ek edge.Kind, index int, node ast.Node) { + v.push(ek, index, node) + + // walk children + // (the order of the cases matches the order + // of the corresponding node types in ast.go) + switch n := node.(type) { + // Comments and fields + case *ast.Comment: + // nothing to do + + case *ast.CommentGroup: + walkList(v, edge.CommentGroup_List, n.List) + + case *ast.Field: + if n.Doc != nil { + walk(v, edge.Field_Doc, -1, n.Doc) + } + walkList(v, edge.Field_Names, n.Names) + if n.Type != nil { + walk(v, edge.Field_Type, -1, n.Type) + } + if n.Tag != nil { + walk(v, edge.Field_Tag, -1, n.Tag) + } + if n.Comment != nil { + walk(v, edge.Field_Comment, -1, n.Comment) + } + + case *ast.FieldList: + walkList(v, edge.FieldList_List, n.List) + + // Expressions + case *ast.BadExpr, *ast.Ident, *ast.BasicLit: + // nothing to do + + case *ast.Ellipsis: + if n.Elt != nil { + walk(v, edge.Ellipsis_Elt, -1, n.Elt) + } + + case *ast.FuncLit: + walk(v, edge.FuncLit_Type, -1, n.Type) + walk(v, edge.FuncLit_Body, -1, n.Body) + + case *ast.CompositeLit: + if n.Type != nil { + walk(v, edge.CompositeLit_Type, -1, n.Type) + } + walkList(v, edge.CompositeLit_Elts, n.Elts) + + case *ast.ParenExpr: + walk(v, edge.ParenExpr_X, -1, n.X) + + case *ast.SelectorExpr: + walk(v, edge.SelectorExpr_X, -1, n.X) + walk(v, edge.SelectorExpr_Sel, -1, n.Sel) + + case *ast.IndexExpr: + walk(v, edge.IndexExpr_X, -1, n.X) + walk(v, edge.IndexExpr_Index, -1, n.Index) + + case *ast.IndexListExpr: + walk(v, edge.IndexListExpr_X, -1, n.X) + walkList(v, edge.IndexListExpr_Indices, n.Indices) + + case *ast.SliceExpr: + walk(v, edge.SliceExpr_X, -1, n.X) + if n.Low != nil { + walk(v, edge.SliceExpr_Low, -1, n.Low) + } + if n.High != nil { + walk(v, edge.SliceExpr_High, -1, n.High) + } + if n.Max != nil { + walk(v, edge.SliceExpr_Max, -1, n.Max) + } + + case *ast.TypeAssertExpr: + walk(v, edge.TypeAssertExpr_X, -1, n.X) + if n.Type != nil { + walk(v, edge.TypeAssertExpr_Type, -1, n.Type) + } + + case *ast.CallExpr: + walk(v, edge.CallExpr_Fun, -1, n.Fun) + walkList(v, edge.CallExpr_Args, n.Args) + + case *ast.StarExpr: + walk(v, edge.StarExpr_X, -1, n.X) + + case *ast.UnaryExpr: + walk(v, edge.UnaryExpr_X, -1, n.X) + + case *ast.BinaryExpr: + walk(v, edge.BinaryExpr_X, -1, n.X) + walk(v, edge.BinaryExpr_Y, -1, n.Y) + + case *ast.KeyValueExpr: + walk(v, edge.KeyValueExpr_Key, -1, n.Key) + walk(v, edge.KeyValueExpr_Value, -1, n.Value) + + // Types + case *ast.ArrayType: + if n.Len != nil { + walk(v, edge.ArrayType_Len, -1, n.Len) + } + walk(v, edge.ArrayType_Elt, -1, n.Elt) + + case *ast.StructType: + walk(v, edge.StructType_Fields, -1, n.Fields) + + case *ast.FuncType: + if n.TypeParams != nil { + walk(v, edge.FuncType_TypeParams, -1, n.TypeParams) + } + if n.Params != nil { + walk(v, edge.FuncType_Params, -1, n.Params) + } + if n.Results != nil { + walk(v, edge.FuncType_Results, -1, n.Results) + } + + case *ast.InterfaceType: + walk(v, edge.InterfaceType_Methods, -1, n.Methods) + + case *ast.MapType: + walk(v, edge.MapType_Key, -1, n.Key) + walk(v, edge.MapType_Value, -1, n.Value) + + case *ast.ChanType: + walk(v, edge.ChanType_Value, -1, n.Value) + + // Statements + case *ast.BadStmt: + // nothing to do + + case *ast.DeclStmt: + walk(v, edge.DeclStmt_Decl, -1, n.Decl) + + case *ast.EmptyStmt: + // nothing to do + + case *ast.LabeledStmt: + walk(v, edge.LabeledStmt_Label, -1, n.Label) + walk(v, edge.LabeledStmt_Stmt, -1, n.Stmt) + + case *ast.ExprStmt: + walk(v, edge.ExprStmt_X, -1, n.X) + + case *ast.SendStmt: + walk(v, edge.SendStmt_Chan, -1, n.Chan) + walk(v, edge.SendStmt_Value, -1, n.Value) + + case *ast.IncDecStmt: + walk(v, edge.IncDecStmt_X, -1, n.X) + + case *ast.AssignStmt: + walkList(v, edge.AssignStmt_Lhs, n.Lhs) + walkList(v, edge.AssignStmt_Rhs, n.Rhs) + + case *ast.GoStmt: + walk(v, edge.GoStmt_Call, -1, n.Call) + + case *ast.DeferStmt: + walk(v, edge.DeferStmt_Call, -1, n.Call) + + case *ast.ReturnStmt: + walkList(v, edge.ReturnStmt_Results, n.Results) + + case *ast.BranchStmt: + if n.Label != nil { + walk(v, edge.BranchStmt_Label, -1, n.Label) + } + + case *ast.BlockStmt: + walkList(v, edge.BlockStmt_List, n.List) + + case *ast.IfStmt: + if n.Init != nil { + walk(v, edge.IfStmt_Init, -1, n.Init) + } + walk(v, edge.IfStmt_Cond, -1, n.Cond) + walk(v, edge.IfStmt_Body, -1, n.Body) + if n.Else != nil { + walk(v, edge.IfStmt_Else, -1, n.Else) + } + + case *ast.CaseClause: + walkList(v, edge.CaseClause_List, n.List) + walkList(v, edge.CaseClause_Body, n.Body) + + case *ast.SwitchStmt: + if n.Init != nil { + walk(v, edge.SwitchStmt_Init, -1, n.Init) + } + if n.Tag != nil { + walk(v, edge.SwitchStmt_Tag, -1, n.Tag) + } + walk(v, edge.SwitchStmt_Body, -1, n.Body) + + case *ast.TypeSwitchStmt: + if n.Init != nil { + walk(v, edge.TypeSwitchStmt_Init, -1, n.Init) + } + walk(v, edge.TypeSwitchStmt_Assign, -1, n.Assign) + walk(v, edge.TypeSwitchStmt_Body, -1, n.Body) + + case *ast.CommClause: + if n.Comm != nil { + walk(v, edge.CommClause_Comm, -1, n.Comm) + } + walkList(v, edge.CommClause_Body, n.Body) + + case *ast.SelectStmt: + walk(v, edge.SelectStmt_Body, -1, n.Body) + + case *ast.ForStmt: + if n.Init != nil { + walk(v, edge.ForStmt_Init, -1, n.Init) + } + if n.Cond != nil { + walk(v, edge.ForStmt_Cond, -1, n.Cond) + } + if n.Post != nil { + walk(v, edge.ForStmt_Post, -1, n.Post) + } + walk(v, edge.ForStmt_Body, -1, n.Body) + + case *ast.RangeStmt: + if n.Key != nil { + walk(v, edge.RangeStmt_Key, -1, n.Key) + } + if n.Value != nil { + walk(v, edge.RangeStmt_Value, -1, n.Value) + } + walk(v, edge.RangeStmt_X, -1, n.X) + walk(v, edge.RangeStmt_Body, -1, n.Body) + + // Declarations + case *ast.ImportSpec: + if n.Doc != nil { + walk(v, edge.ImportSpec_Doc, -1, n.Doc) + } + if n.Name != nil { + walk(v, edge.ImportSpec_Name, -1, n.Name) + } + walk(v, edge.ImportSpec_Path, -1, n.Path) + if n.Comment != nil { + walk(v, edge.ImportSpec_Comment, -1, n.Comment) + } + + case *ast.ValueSpec: + if n.Doc != nil { + walk(v, edge.ValueSpec_Doc, -1, n.Doc) + } + walkList(v, edge.ValueSpec_Names, n.Names) + if n.Type != nil { + walk(v, edge.ValueSpec_Type, -1, n.Type) + } + walkList(v, edge.ValueSpec_Values, n.Values) + if n.Comment != nil { + walk(v, edge.ValueSpec_Comment, -1, n.Comment) + } + + case *ast.TypeSpec: + if n.Doc != nil { + walk(v, edge.TypeSpec_Doc, -1, n.Doc) + } + walk(v, edge.TypeSpec_Name, -1, n.Name) + if n.TypeParams != nil { + walk(v, edge.TypeSpec_TypeParams, -1, n.TypeParams) + } + walk(v, edge.TypeSpec_Type, -1, n.Type) + if n.Comment != nil { + walk(v, edge.TypeSpec_Comment, -1, n.Comment) + } + + case *ast.BadDecl: + // nothing to do + + case *ast.GenDecl: + if n.Doc != nil { + walk(v, edge.GenDecl_Doc, -1, n.Doc) + } + walkList(v, edge.GenDecl_Specs, n.Specs) + + case *ast.FuncDecl: + if n.Doc != nil { + walk(v, edge.FuncDecl_Doc, -1, n.Doc) + } + if n.Recv != nil { + walk(v, edge.FuncDecl_Recv, -1, n.Recv) + } + walk(v, edge.FuncDecl_Name, -1, n.Name) + walk(v, edge.FuncDecl_Type, -1, n.Type) + if n.Body != nil { + walk(v, edge.FuncDecl_Body, -1, n.Body) + } + + case *ast.File: + if n.Doc != nil { + walk(v, edge.File_Doc, -1, n.Doc) + } + walk(v, edge.File_Name, -1, n.Name) + walkList(v, edge.File_Decls, n.Decls) + // don't walk n.Comments - they have been + // visited already through the individual + // nodes + + default: + // (includes *ast.Package) + panic(fmt.Sprintf("Walk: unexpected node type %T", n)) + } + + v.pop(node) +} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go index 89f89dd2dc..680a70ca8f 100644 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -364,12 +364,6 @@ type jsonPackage struct { DepsErrors []*packagesinternal.PackageError } -type jsonPackageError struct { - ImportStack []string - Pos string - Err string -} - func otherFiles(p *jsonPackage) [][]string { return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} } diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go index df14ffd94d..af6a60d75f 100644 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ b/vendor/golang.org/x/tools/go/packages/visit.go @@ -5,9 +5,11 @@ package packages import ( + "cmp" "fmt" + "iter" "os" - "sort" + "slices" ) // Visit visits all the packages in the import graph whose roots are @@ -16,6 +18,20 @@ import ( // package's dependencies have been visited (postorder). // The boolean result of pre(pkg) determines whether // the imports of package pkg are visited. +// +// Example: +// +// pkgs, err := Load(...) +// if err != nil { ... } +// Visit(pkgs, nil, func(pkg *Package) { +// log.Println(pkg) +// }) +// +// In most cases, it is more convenient to use [Postorder]: +// +// for pkg := range Postorder(pkgs) { +// log.Println(pkg) +// } func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { seen := make(map[*Package]bool) var visit func(*Package) @@ -24,13 +40,8 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { seen[pkg] = true if pre == nil || pre(pkg) { - paths := make([]string, 0, len(pkg.Imports)) - for path := range pkg.Imports { - paths = append(paths, path) - } - sort.Strings(paths) // Imports is a map, this makes visit stable - for _, path := range paths { - visit(pkg.Imports[path]) + for _, imp := range sorted(pkg.Imports) { // for determinism + visit(imp) } } @@ -50,7 +61,7 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { func PrintErrors(pkgs []*Package) int { var n int errModules := make(map[*Module]bool) - Visit(pkgs, nil, func(pkg *Package) { + for pkg := range Postorder(pkgs) { for _, err := range pkg.Errors { fmt.Fprintln(os.Stderr, err) n++ @@ -63,6 +74,60 @@ func PrintErrors(pkgs []*Package) int { fmt.Fprintln(os.Stderr, mod.Error.Err) n++ } - }) + } return n } + +// Postorder returns an iterator over the the packages in +// the import graph whose roots are pkg. +// Packages are enumerated in dependencies-first order. +func Postorder(pkgs []*Package) iter.Seq[*Package] { + return func(yield func(*Package) bool) { + seen := make(map[*Package]bool) + var visit func(*Package) bool + visit = func(pkg *Package) bool { + if !seen[pkg] { + seen[pkg] = true + for _, imp := range sorted(pkg.Imports) { // for determinism + if !visit(imp) { + return false + } + } + if !yield(pkg) { + return false + } + } + return true + } + for _, pkg := range pkgs { + if !visit(pkg) { + break + } + } + } +} + +// -- copied from golang.org.x/tools/gopls/internal/util/moremaps -- + +// sorted returns an iterator over the entries of m in key order. +func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] { + // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted. + return func(yield func(K, V) bool) { + keys := keySlice(m) + slices.Sort(keys) + for _, k := range keys { + if !yield(k, m[k]) { + break + } + } + } +} + +// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)). +func keySlice[M ~map[K]V, K comparable, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + return r +} diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go index d3c2913bef..6c0c74968f 100644 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -698,7 +698,10 @@ func Object(pkg *types.Package, p Path) (types.Object, error) { } else if false && aliases.Enabled() { // The Enabled check is too expensive, so for now we // simply assume that aliases are not enabled. - // TODO(adonovan): replace with "if true {" when go1.24 is assured. + // + // Now that go1.24 is assured, we should be able to + // replace this with "if true {", but it causes tests + // to fail. TODO(adonovan): investigate. return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t) } diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go index b6d542c64e..f035a0b6be 100644 --- a/vendor/golang.org/x/tools/go/types/typeutil/map.go +++ b/vendor/golang.org/x/tools/go/types/typeutil/map.go @@ -11,7 +11,6 @@ import ( "fmt" "go/types" "hash/maphash" - "unsafe" "golang.org/x/tools/internal/typeparams" ) @@ -380,22 +379,8 @@ var theSeed = maphash.MakeSeed() func (hasher) hashTypeName(tname *types.TypeName) uint32 { // Since types.Identical uses == to compare TypeNames, // the Hash function uses maphash.Comparable. - // TODO(adonovan): or will, when it becomes available in go1.24. - // In the meantime we use the pointer's numeric value. - // - // hash := maphash.Comparable(theSeed, tname) - // - // (Another approach would be to hash the name and package - // path, and whether or not it is a package-level typename. It - // is rare for a package to define multiple local types with - // the same name.) - ptr := uintptr(unsafe.Pointer(tname)) - if unsafe.Sizeof(ptr) == 8 { - hash := uint64(ptr) - return uint32(hash ^ (hash >> 32)) - } else { - return uint32(ptr) - } + hash := maphash.Comparable(theSeed, tname) + return uint32(hash ^ (hash >> 32)) } // shallowHash computes a hash of t without looking at any of its diff --git a/vendor/golang.org/x/tools/imports/forward.go b/vendor/golang.org/x/tools/imports/forward.go index cb6db8893f..22ae777726 100644 --- a/vendor/golang.org/x/tools/imports/forward.go +++ b/vendor/golang.org/x/tools/imports/forward.go @@ -69,9 +69,3 @@ func Process(filename string, src []byte, opt *Options) ([]byte, error) { } return intimp.Process(filename, src, intopt) } - -// VendorlessPath returns the devendorized version of the import path ipath. -// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b". -func VendorlessPath(ipath string) string { - return intimp.VendorlessPath(ipath) -} diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go index a6cf0e64a4..ade5d1e799 100644 --- a/vendor/golang.org/x/tools/internal/event/core/event.go +++ b/vendor/golang.org/x/tools/internal/event/core/event.go @@ -28,11 +28,6 @@ type Event struct { dynamic []label.Label // dynamically sized storage for remaining labels } -// eventLabelMap implements label.Map for a the labels of an Event. -type eventLabelMap struct { - event Event -} - func (ev Event) At() time.Time { return ev.at } func (ev Event) Format(f fmt.State, r rune) { diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go index 780873e3ae..4a4357d2bd 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go @@ -569,7 +569,6 @@ func (p *iexporter) exportName(obj types.Object) (res string) { type iexporter struct { fset *token.FileSet - out *bytes.Buffer version int shallow bool // don't put types from other packages in the index diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go deleted file mode 100644 index 7586bfaca6..0000000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.22 && !go1.24 - -package gcimporter - -import ( - "go/token" - "go/types" - "unsafe" -) - -// TODO(rfindley): delete this workaround once go1.24 is assured. - -func init() { - // Update markBlack so that it correctly sets the color - // of imported TypeNames. - // - // See the doc comment for markBlack for details. - - type color uint32 - const ( - white color = iota - black - grey - ) - type object struct { - _ *types.Scope - _ token.Pos - _ *types.Package - _ string - _ types.Type - _ uint32 - color_ color - _ token.Pos - } - type typeName struct { - object - } - - // If the size of types.TypeName changes, this will fail to compile. - const delta = int64(unsafe.Sizeof(typeName{})) - int64(unsafe.Sizeof(types.TypeName{})) - var _ [-delta * delta]int - - markBlack = func(obj *types.TypeName) { - type uP = unsafe.Pointer - var ptr *typeName - *(*uP)(uP(&ptr)) = uP(obj) - ptr.color_ = black - } -} diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go index 50b6ca51a6..1b4dc0cb5d 100644 --- a/vendor/golang.org/x/tools/internal/imports/fix.go +++ b/vendor/golang.org/x/tools/internal/imports/fix.go @@ -16,6 +16,7 @@ import ( "go/types" "io/fs" "io/ioutil" + "maps" "os" "path" "path/filepath" @@ -27,8 +28,6 @@ import ( "unicode" "unicode/utf8" - "maps" - "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/gocommand" @@ -43,7 +42,7 @@ var importToGroup = []func(localPrefix, importPath string) (num int, ok bool){ if localPrefix == "" { return } - for _, p := range strings.Split(localPrefix, ",") { + for p := range strings.SplitSeq(localPrefix, ",") { if strings.HasPrefix(importPath, p) || strings.TrimSuffix(p, "/") == importPath { return 3, true } @@ -1251,7 +1250,6 @@ func ImportPathToAssumedName(importPath string) string { // gopathResolver implements resolver for GOPATH workspaces. type gopathResolver struct { env *ProcessEnv - walked bool cache *DirInfoCache scanSema chan struct{} // scanSema prevents concurrent scans. } diff --git a/vendor/golang.org/x/tools/internal/modindex/symbols.go b/vendor/golang.org/x/tools/internal/modindex/symbols.go index fe24db9b13..8e9702d84b 100644 --- a/vendor/golang.org/x/tools/internal/modindex/symbols.go +++ b/vendor/golang.org/x/tools/internal/modindex/symbols.go @@ -206,8 +206,7 @@ func isDeprecated(doc *ast.CommentGroup) bool { // go.dev/wiki/Deprecated Paragraph starting 'Deprecated:' // This code fails for /* Deprecated: */, but it's the code from // gopls/internal/analysis/deprecated - lines := strings.Split(doc.Text(), "\n\n") - for _, line := range lines { + for line := range strings.SplitSeq(doc.Text(), "\n\n") { if strings.HasPrefix(line, "Deprecated:") { return true } diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go index 77cf8d2181..96ad6c5821 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/deps.go +++ b/vendor/golang.org/x/tools/internal/stdlib/deps.go @@ -12,348 +12,354 @@ type pkginfo struct { } var deps = [...]pkginfo{ - {"archive/tar", "\x03j\x03E5\x01\v\x01#\x01\x01\x02\x05\n\x02\x01\x02\x02\v"}, - {"archive/zip", "\x02\x04`\a\x16\x0205\x01+\x05\x01\x11\x03\x02\r\x04"}, - {"bufio", "\x03j}F\x13"}, - {"bytes", "m+R\x03\fH\x02\x02"}, + {"archive/tar", "\x03k\x03E;\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\f"}, + {"archive/zip", "\x02\x04a\a\x03\x12\x021;\x01+\x05\x01\x0f\x03\x02\x0e\x04"}, + {"bufio", "\x03k\x83\x01D\x14"}, + {"bytes", "n*Y\x03\fG\x02\x02"}, {"cmp", ""}, - {"compress/bzip2", "\x02\x02\xe6\x01C"}, - {"compress/flate", "\x02k\x03z\r\x025\x01\x03"}, - {"compress/gzip", "\x02\x04`\a\x03\x15eU"}, - {"compress/lzw", "\x02k\x03z"}, - {"compress/zlib", "\x02\x04`\a\x03\x13\x01f"}, - {"container/heap", "\xae\x02"}, + {"compress/bzip2", "\x02\x02\xed\x01A"}, + {"compress/flate", "\x02l\x03\x80\x01\f\x033\x01\x03"}, + {"compress/gzip", "\x02\x04a\a\x03\x14lT"}, + {"compress/lzw", "\x02l\x03\x80\x01"}, + {"compress/zlib", "\x02\x04a\a\x03\x12\x01m"}, + {"container/heap", "\xb3\x02"}, {"container/list", ""}, {"container/ring", ""}, - {"context", "m\\i\x01\f"}, - {"crypto", "\x83\x01gE"}, - {"crypto/aes", "\x10\n\a\x8e\x02"}, - {"crypto/cipher", "\x03\x1e\x01\x01\x1d\x11\x1c,Q"}, - {"crypto/des", "\x10\x13\x1d-,\x96\x01\x03"}, - {"crypto/dsa", "@\x04)}\x0e"}, - {"crypto/ecdh", "\x03\v\f\x0e\x04\x14\x04\r\x1c}"}, - {"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\x16\x01\x04\f\x01\x1c}\x0e\x04L\x01"}, - {"crypto/ed25519", "\x0e\x1c\x16\n\a\x1c}E"}, - {"crypto/elliptic", "0=}\x0e:"}, - {"crypto/fips140", " \x05\x90\x01"}, - {"crypto/hkdf", "-\x12\x01-\x16"}, - {"crypto/hmac", "\x1a\x14\x11\x01\x112"}, + {"context", "n\\m\x01\r"}, + {"crypto", "\x83\x01nC"}, + {"crypto/aes", "\x10\n\a\x93\x02"}, + {"crypto/cipher", "\x03\x1e\x01\x01\x1e\x11\x1c+X"}, + {"crypto/des", "\x10\x13\x1e-+\x9b\x01\x03"}, + {"crypto/dsa", "A\x04)\x83\x01\r"}, + {"crypto/ecdh", "\x03\v\f\x0e\x04\x15\x04\r\x1c\x83\x01"}, + {"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\a\v\x05\x01\x04\f\x01\x1c\x83\x01\r\x05K\x01"}, + {"crypto/ed25519", "\x0e\x1c\x11\x06\n\a\x1c\x83\x01C"}, + {"crypto/elliptic", "0>\x83\x01\r9"}, + {"crypto/fips140", " \x05"}, + {"crypto/hkdf", "-\x13\x01-\x15"}, + {"crypto/hmac", "\x1a\x14\x12\x01\x111"}, {"crypto/internal/boring", "\x0e\x02\rf"}, - {"crypto/internal/boring/bbig", "\x1a\xde\x01M"}, - {"crypto/internal/boring/bcache", "\xb3\x02\x12"}, + {"crypto/internal/boring/bbig", "\x1a\xe4\x01M"}, + {"crypto/internal/boring/bcache", "\xb8\x02\x13"}, {"crypto/internal/boring/sig", ""}, - {"crypto/internal/cryptotest", "\x03\r\n)\x0e\x19\x06\x13\x12#\a\t\x11\x11\x11\x1b\x01\f\r\x05\n"}, - {"crypto/internal/entropy", "E"}, - {"crypto/internal/fips140", ">/}9\r\x15"}, - {"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x04\x01\x01\x05*\x8c\x016"}, - {"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x04\x01\x06*\x8a\x01"}, - {"crypto/internal/fips140/alias", "\xc5\x02"}, - {"crypto/internal/fips140/bigmod", "%\x17\x01\x06*\x8c\x01"}, - {"crypto/internal/fips140/check", " \x0e\x06\b\x02\xac\x01["}, - {"crypto/internal/fips140/check/checktest", "%\xfe\x01\""}, - {"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x04\b\x01(}\x0f9"}, - {"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\f1}\x0f9"}, - {"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x067}H"}, - {"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v7\xc2\x01\x03"}, - {"crypto/internal/fips140/edwards25519", "%\a\f\x041\x8c\x019"}, - {"crypto/internal/fips140/edwards25519/field", "%\x13\x041\x8c\x01"}, - {"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x069"}, - {"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x017"}, - {"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x041"}, - {"crypto/internal/fips140/nistec", "%\f\a\x041\x8c\x01*\x0f\x13"}, - {"crypto/internal/fips140/nistec/fiat", "%\x135\x8c\x01"}, - {"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x069"}, - {"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x025}H"}, - {"crypto/internal/fips140/sha256", "\x03\x1d\x1c\x01\x06*\x8c\x01"}, - {"crypto/internal/fips140/sha3", "\x03\x1d\x18\x04\x010\x8c\x01L"}, - {"crypto/internal/fips140/sha512", "\x03\x1d\x1c\x01\x06*\x8c\x01"}, - {"crypto/internal/fips140/ssh", " \x05"}, - {"crypto/internal/fips140/subtle", "#"}, - {"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x027"}, - {"crypto/internal/fips140/tls13", "\x03\x1d\x05\b\a\b1"}, + {"crypto/internal/cryptotest", "\x03\r\n\x06$\x0e\x19\x06\x12\x12 \x04\a\t\x16\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\v"}, + {"crypto/internal/entropy", "F"}, + {"crypto/internal/fips140", "?/\x15\xa7\x01\v\x16"}, + {"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x05\x01\x01\x05*\x92\x014"}, + {"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x05\x01\x06*\x8f\x01"}, + {"crypto/internal/fips140/alias", "\xcb\x02"}, + {"crypto/internal/fips140/bigmod", "%\x18\x01\x06*\x92\x01"}, + {"crypto/internal/fips140/check", " \x0e\x06\t\x02\xb2\x01Z"}, + {"crypto/internal/fips140/check/checktest", "%\x85\x02!"}, + {"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x05\b\x01(\x83\x01\x0f7"}, + {"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\r1\x83\x01\x0f7"}, + {"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x068\x15nF"}, + {"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v8\xc6\x01\x03"}, + {"crypto/internal/fips140/edwards25519", "%\a\f\x051\x92\x017"}, + {"crypto/internal/fips140/edwards25519/field", "%\x13\x051\x92\x01"}, + {"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x06:\x15"}, + {"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x018\x15"}, + {"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x051"}, + {"crypto/internal/fips140/nistec", "%\f\a\x051\x92\x01*\r\x14"}, + {"crypto/internal/fips140/nistec/fiat", "%\x136\x92\x01"}, + {"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x06:\x15"}, + {"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x026\x15nF"}, + {"crypto/internal/fips140/sha256", "\x03\x1d\x1d\x01\x06*\x15}"}, + {"crypto/internal/fips140/sha3", "\x03\x1d\x18\x05\x010\x92\x01K"}, + {"crypto/internal/fips140/sha512", "\x03\x1d\x1d\x01\x06*\x15}"}, + {"crypto/internal/fips140/ssh", "%^"}, + {"crypto/internal/fips140/subtle", "#\x1a\xc3\x01"}, + {"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x028\x15"}, + {"crypto/internal/fips140/tls13", "\x03\x1d\x05\b\a\t1\x15"}, + {"crypto/internal/fips140cache", "\xaa\x02\r&"}, {"crypto/internal/fips140deps", ""}, {"crypto/internal/fips140deps/byteorder", "\x99\x01"}, - {"crypto/internal/fips140deps/cpu", "\xad\x01\a"}, - {"crypto/internal/fips140deps/godebug", "\xb5\x01"}, - {"crypto/internal/fips140hash", "5\x1a4\xc2\x01"}, - {"crypto/internal/fips140only", "'\r\x01\x01M25"}, + {"crypto/internal/fips140deps/cpu", "\xae\x01\a"}, + {"crypto/internal/fips140deps/godebug", "\xb6\x01"}, + {"crypto/internal/fips140hash", "5\x1b3\xc8\x01"}, + {"crypto/internal/fips140only", "'\r\x01\x01M3;"}, {"crypto/internal/fips140test", ""}, - {"crypto/internal/hpke", "\x0e\x01\x01\x03\x1a\x1d#,`N"}, - {"crypto/internal/impl", "\xb0\x02"}, - {"crypto/internal/randutil", "\xea\x01\x12"}, - {"crypto/internal/sysrand", "mi!\x1f\r\x0f\x01\x01\v\x06"}, - {"crypto/internal/sysrand/internal/seccomp", "m"}, - {"crypto/md5", "\x0e2-\x16\x16`"}, + {"crypto/internal/hpke", "\x0e\x01\x01\x03\x053#+gM"}, + {"crypto/internal/impl", "\xb5\x02"}, + {"crypto/internal/randutil", "\xf1\x01\x12"}, + {"crypto/internal/sysrand", "nn! \r\r\x01\x01\f\x06"}, + {"crypto/internal/sysrand/internal/seccomp", "n"}, + {"crypto/md5", "\x0e3-\x15\x16g"}, {"crypto/mlkem", "/"}, - {"crypto/pbkdf2", "2\r\x01-\x16"}, - {"crypto/rand", "\x1a\x06\a\x19\x04\x01(}\x0eM"}, - {"crypto/rc4", "#\x1d-\xc2\x01"}, - {"crypto/rsa", "\x0e\f\x01\t\x0f\f\x01\x04\x06\a\x1c\x03\x1325\r\x01"}, - {"crypto/sha1", "\x0e\f&-\x16\x16\x14L"}, + {"crypto/pbkdf2", "2\x0e\x01-\x15"}, + {"crypto/rand", "\x1a\x06\a\x1a\x04\x01(\x83\x01\rM"}, + {"crypto/rc4", "#\x1e-\xc6\x01"}, + {"crypto/rsa", "\x0e\f\x01\t\x0f\r\x01\x04\x06\a\x1c\x03\x123;\f\x01"}, + {"crypto/sha1", "\x0e\f'\x03*\x15\x16\x15R"}, {"crypto/sha256", "\x0e\f\x1aO"}, - {"crypto/sha3", "\x0e'N\xc2\x01"}, + {"crypto/sha3", "\x0e'N\xc8\x01"}, {"crypto/sha512", "\x0e\f\x1cM"}, - {"crypto/subtle", "8\x96\x01U"}, - {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x03\x01\a\x01\v\x02\n\x01\b\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x14\b5\x16\x16\r\n\x01\x01\x01\x02\x01\f\x06\x02\x01"}, - {"crypto/tls/internal/fips140tls", " \x93\x02"}, - {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x011\x03\x02\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x032\x01\x02\t\x01\x01\x01\a\x10\x05\x01\x06\x02\x05\f\x01\x02\r\x02\x01\x01\x02\x03\x01"}, - {"crypto/x509/pkix", "c\x06\a\x88\x01G"}, - {"database/sql", "\x03\nJ\x16\x03z\f\x06\"\x05\n\x02\x03\x01\f\x02\x02\x02"}, - {"database/sql/driver", "\r`\x03\xae\x01\x11\x10"}, - {"debug/buildinfo", "\x03W\x02\x01\x01\b\a\x03`\x18\x02\x01+\x0f "}, - {"debug/dwarf", "\x03c\a\x03z1\x13\x01\x01"}, - {"debug/elf", "\x03\x06P\r\a\x03`\x19\x01,\x19\x01\x15"}, - {"debug/gosym", "\x03c\n\xbe\x01\x01\x01\x02"}, - {"debug/macho", "\x03\x06P\r\n`\x1a,\x19\x01"}, - {"debug/pe", "\x03\x06P\r\a\x03`\x1a,\x19\x01\x15"}, - {"debug/plan9obj", "f\a\x03`\x1a,"}, - {"embed", "m+:\x18\x01T"}, + {"crypto/subtle", "8\x9b\x01W"}, + {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\a\x01\r\n\x01\t\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x12\x16\x15\b;\x16\x16\r\b\x01\x01\x01\x02\x01\r\x06\x02\x01\x0f"}, + {"crypto/tls/internal/fips140tls", "\x17\xa1\x02"}, + {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x012\x05\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x038\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\x02\x05\n\x01\x02\x0e\x02\x01\x01\x02\x03\x01"}, + {"crypto/x509/pkix", "d\x06\a\x8d\x01G"}, + {"database/sql", "\x03\nK\x16\x03\x80\x01\v\a\"\x05\b\x02\x03\x01\r\x02\x02\x02"}, + {"database/sql/driver", "\ra\x03\xb4\x01\x0f\x11"}, + {"debug/buildinfo", "\x03X\x02\x01\x01\b\a\x03e\x19\x02\x01+\x0f\x1f"}, + {"debug/dwarf", "\x03d\a\x03\x80\x011\x11\x01\x01"}, + {"debug/elf", "\x03\x06Q\r\a\x03e\x1a\x01,\x17\x01\x16"}, + {"debug/gosym", "\x03d\n\xc2\x01\x01\x01\x02"}, + {"debug/macho", "\x03\x06Q\r\ne\x1b,\x17\x01"}, + {"debug/pe", "\x03\x06Q\r\a\x03e\x1b,\x17\x01\x16"}, + {"debug/plan9obj", "g\a\x03e\x1b,"}, + {"embed", "n*@\x19\x01S"}, {"embed/internal/embedtest", ""}, {"encoding", ""}, - {"encoding/ascii85", "\xea\x01E"}, - {"encoding/asn1", "\x03j\x03\x87\x01\x01&\x0f\x02\x01\x0f\x03\x01"}, - {"encoding/base32", "\xea\x01C\x02"}, - {"encoding/base64", "\x99\x01QC\x02"}, - {"encoding/binary", "m}\r'\x0f\x05"}, - {"encoding/csv", "\x02\x01j\x03zF\x11\x02"}, - {"encoding/gob", "\x02_\x05\a\x03`\x1a\f\x01\x02\x1d\b\x14\x01\x0e\x02"}, - {"encoding/hex", "m\x03zC\x03"}, - {"encoding/json", "\x03\x01]\x04\b\x03z\r'\x0f\x02\x01\x02\x0f\x01\x01\x02"}, - {"encoding/pem", "\x03b\b}C\x03"}, - {"encoding/xml", "\x02\x01^\f\x03z4\x05\f\x01\x02\x0f\x02"}, - {"errors", "\xc9\x01|"}, - {"expvar", "jK9\t\n\x15\r\n\x02\x03\x01\x10"}, - {"flag", "a\f\x03z,\b\x05\n\x02\x01\x0f"}, - {"fmt", "mE8\r\x1f\b\x0f\x02\x03\x11"}, - {"go/ast", "\x03\x01l\x0f\x01j\x03)\b\x0f\x02\x01"}, - {"go/ast/internal/tests", ""}, - {"go/build", "\x02\x01j\x03\x01\x03\x02\a\x02\x01\x17\x1e\x04\x02\t\x14\x12\x01+\x01\x04\x01\a\n\x02\x01\x11\x02\x02"}, - {"go/build/constraint", "m\xc2\x01\x01\x11\x02"}, - {"go/constant", "p\x10w\x01\x016\x01\x02\x11"}, - {"go/doc", "\x04l\x01\x06\t=-1\x12\x02\x01\x11\x02"}, - {"go/doc/comment", "\x03m\xbd\x01\x01\x01\x01\x11\x02"}, - {"go/format", "\x03m\x01\f\x01\x02jF"}, - {"go/importer", "s\a\x01\x01\x04\x01i9"}, - {"go/internal/gccgoimporter", "\x02\x01W\x13\x03\x05\v\x01g\x02,\x01\x05\x13\x01\v\b"}, - {"go/internal/gcimporter", "\x02n\x10\x01/\x05\x0e',\x17\x03\x02"}, - {"go/internal/srcimporter", "p\x01\x02\n\x03\x01i,\x01\x05\x14\x02\x13"}, - {"go/parser", "\x03j\x03\x01\x03\v\x01j\x01+\x06\x14"}, - {"go/printer", "p\x01\x03\x03\tj\r\x1f\x17\x02\x01\x02\n\x05\x02"}, - {"go/scanner", "\x03m\x10j2\x12\x01\x12\x02"}, - {"go/token", "\x04l\xbd\x01\x02\x03\x01\x0e\x02"}, - {"go/types", "\x03\x01\x06c\x03\x01\x04\b\x03\x02\x15\x1e\x06+\x04\x03\n%\a\n\x01\x01\x01\x02\x01\x0e\x02\x02"}, - {"go/version", "\xba\x01v"}, - {"hash", "\xea\x01"}, - {"hash/adler32", "m\x16\x16"}, - {"hash/crc32", "m\x16\x16\x14\x85\x01\x01\x12"}, - {"hash/crc64", "m\x16\x16\x99\x01"}, - {"hash/fnv", "m\x16\x16`"}, - {"hash/maphash", "\x94\x01\x05\x1b\x03@N"}, - {"html", "\xb0\x02\x02\x11"}, - {"html/template", "\x03g\x06\x19,5\x01\v \x05\x01\x02\x03\x0e\x01\x02\v\x01\x03\x02"}, - {"image", "\x02k\x1f^\x0f6\x03\x01"}, + {"encoding/ascii85", "\xf1\x01C"}, + {"encoding/asn1", "\x03k\x03\x8c\x01\x01'\r\x02\x01\x10\x03\x01"}, + {"encoding/base32", "\xf1\x01A\x02"}, + {"encoding/base64", "\x99\x01XA\x02"}, + {"encoding/binary", "n\x83\x01\f(\r\x05"}, + {"encoding/csv", "\x02\x01k\x03\x80\x01D\x12\x02"}, + {"encoding/gob", "\x02`\x05\a\x03e\x1b\v\x01\x03\x1d\b\x12\x01\x0f\x02"}, + {"encoding/hex", "n\x03\x80\x01A\x03"}, + {"encoding/json", "\x03\x01^\x04\b\x03\x80\x01\f(\r\x02\x01\x02\x10\x01\x01\x02"}, + {"encoding/pem", "\x03c\b\x83\x01A\x03"}, + {"encoding/xml", "\x02\x01_\f\x03\x80\x014\x05\n\x01\x02\x10\x02"}, + {"errors", "\xca\x01\x81\x01"}, + {"expvar", "kK?\b\v\x15\r\b\x02\x03\x01\x11"}, + {"flag", "b\f\x03\x80\x01,\b\x05\b\x02\x01\x10"}, + {"fmt", "nE>\f \b\r\x02\x03\x12"}, + {"go/ast", "\x03\x01m\x0e\x01q\x03)\b\r\x02\x01"}, + {"go/build", "\x02\x01k\x03\x01\x02\x02\a\x02\x01\x17\x1f\x04\x02\t\x19\x13\x01+\x01\x04\x01\a\b\x02\x01\x12\x02\x02"}, + {"go/build/constraint", "n\xc6\x01\x01\x12\x02"}, + {"go/constant", "q\x0f}\x01\x024\x01\x02\x12"}, + {"go/doc", "\x04m\x01\x05\t>31\x10\x02\x01\x12\x02"}, + {"go/doc/comment", "\x03n\xc1\x01\x01\x01\x01\x12\x02"}, + {"go/format", "\x03n\x01\v\x01\x02qD"}, + {"go/importer", "s\a\x01\x01\x04\x01p9"}, + {"go/internal/gccgoimporter", "\x02\x01X\x13\x03\x04\v\x01n\x02,\x01\x05\x11\x01\f\b"}, + {"go/internal/gcimporter", "\x02o\x0f\x010\x05\x0e-,\x15\x03\x02"}, + {"go/internal/srcimporter", "q\x01\x01\n\x03\x01p,\x01\x05\x12\x02\x14"}, + {"go/parser", "\x03k\x03\x01\x02\v\x01q\x01+\x06\x12"}, + {"go/printer", "q\x01\x02\x03\tq\f \x15\x02\x01\x02\v\x05\x02"}, + {"go/scanner", "\x03n\x0fq2\x10\x01\x13\x02"}, + {"go/token", "\x04m\x83\x01>\x02\x03\x01\x0f\x02"}, + {"go/types", "\x03\x01\x06d\x03\x01\x03\b\x03\x02\x15\x1f\x061\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x0f\x02\x02"}, + {"go/version", "\xbb\x01z"}, + {"hash", "\xf1\x01"}, + {"hash/adler32", "n\x15\x16"}, + {"hash/crc32", "n\x15\x16\x15\x89\x01\x01\x13"}, + {"hash/crc64", "n\x15\x16\x9e\x01"}, + {"hash/fnv", "n\x15\x16g"}, + {"hash/maphash", "\x83\x01\x11!\x03\x93\x01"}, + {"html", "\xb5\x02\x02\x12"}, + {"html/template", "\x03h\x06\x18-;\x01\n!\x05\x01\x02\x03\f\x01\x02\f\x01\x03\x02"}, + {"image", "\x02l\x1ee\x0f4\x03\x01"}, {"image/color", ""}, {"image/color/palette", "\x8c\x01"}, {"image/draw", "\x8b\x01\x01\x04"}, - {"image/gif", "\x02\x01\x05e\x03\x1b\x01\x01\x01\vQ"}, + {"image/gif", "\x02\x01\x05f\x03\x1a\x01\x01\x01\vX"}, {"image/internal/imageutil", "\x8b\x01"}, - {"image/jpeg", "\x02k\x1e\x01\x04Z"}, - {"image/png", "\x02\a]\n\x13\x02\x06\x01^E"}, - {"index/suffixarray", "\x03c\a}\r*\f\x01"}, - {"internal/abi", "\xb4\x01\x91\x01"}, - {"internal/asan", "\xc5\x02"}, - {"internal/bisect", "\xa3\x02\x0f\x01"}, - {"internal/buildcfg", "pG_\x06\x02\x05\f\x01"}, - {"internal/bytealg", "\xad\x01\x98\x01"}, + {"image/jpeg", "\x02l\x1d\x01\x04a"}, + {"image/png", "\x02\a^\n\x12\x02\x06\x01eC"}, + {"index/suffixarray", "\x03d\a\x83\x01\f+\n\x01"}, + {"internal/abi", "\xb5\x01\x96\x01"}, + {"internal/asan", "\xcb\x02"}, + {"internal/bisect", "\xaa\x02\r\x01"}, + {"internal/buildcfg", "qGe\x06\x02\x05\n\x01"}, + {"internal/bytealg", "\xae\x01\x9d\x01"}, {"internal/byteorder", ""}, {"internal/cfg", ""}, - {"internal/chacha8rand", "\x99\x01\x1b\x91\x01"}, + {"internal/cgrouptest", "q[Q\x06\x0f\x02\x01\x04\x01"}, + {"internal/chacha8rand", "\x99\x01\x15\a\x96\x01"}, {"internal/copyright", ""}, {"internal/coverage", ""}, {"internal/coverage/calloc", ""}, - {"internal/coverage/cfile", "j\x06\x17\x16\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x01\x1f,\x06\a\f\x01\x03\f\x06"}, - {"internal/coverage/cformat", "\x04l-\x04I\f7\x01\x02\f"}, - {"internal/coverage/cmerge", "p-Z"}, - {"internal/coverage/decodecounter", "f\n-\v\x02@,\x19\x16"}, - {"internal/coverage/decodemeta", "\x02d\n\x17\x16\v\x02@,"}, - {"internal/coverage/encodecounter", "\x02d\n-\f\x01\x02>\f \x17"}, - {"internal/coverage/encodemeta", "\x02\x01c\n\x13\x04\x16\r\x02>,/"}, - {"internal/coverage/pods", "\x04l-y\x06\x05\f\x02\x01"}, - {"internal/coverage/rtcov", "\xc5\x02"}, - {"internal/coverage/slicereader", "f\nz["}, - {"internal/coverage/slicewriter", "pz"}, - {"internal/coverage/stringtab", "p8\x04>"}, + {"internal/coverage/cfile", "k\x06\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x02$,\x06\a\n\x01\x03\r\x06"}, + {"internal/coverage/cformat", "\x04m-\x04O\v6\x01\x02\r"}, + {"internal/coverage/cmerge", "q-_"}, + {"internal/coverage/decodecounter", "g\n-\v\x02F,\x17\x17"}, + {"internal/coverage/decodemeta", "\x02e\n\x16\x17\v\x02F,"}, + {"internal/coverage/encodecounter", "\x02e\n-\f\x01\x02D\v!\x15"}, + {"internal/coverage/encodemeta", "\x02\x01d\n\x12\x04\x17\r\x02D,."}, + {"internal/coverage/pods", "\x04m-\x7f\x06\x05\n\x02\x01"}, + {"internal/coverage/rtcov", "\xcb\x02"}, + {"internal/coverage/slicereader", "g\n\x80\x01Z"}, + {"internal/coverage/slicewriter", "q\x80\x01"}, + {"internal/coverage/stringtab", "q8\x04D"}, {"internal/coverage/test", ""}, {"internal/coverage/uleb128", ""}, - {"internal/cpu", "\xc5\x02"}, - {"internal/dag", "\x04l\xbd\x01\x03"}, - {"internal/diff", "\x03m\xbe\x01\x02"}, - {"internal/exportdata", "\x02\x01j\x03\x03]\x1a,\x01\x05\x13\x01\x02"}, - {"internal/filepathlite", "m+:\x19B"}, - {"internal/fmtsort", "\x04\x9a\x02\x0f"}, - {"internal/fuzz", "\x03\nA\x18\x04\x03\x03\x01\f\x0355\r\x02\x1d\x01\x05\x02\x05\f\x01\x02\x01\x01\v\x04\x02"}, + {"internal/cpu", "\xcb\x02"}, + {"internal/dag", "\x04m\xc1\x01\x03"}, + {"internal/diff", "\x03n\xc2\x01\x02"}, + {"internal/exportdata", "\x02\x01k\x03\x02c\x1b,\x01\x05\x11\x01\x02"}, + {"internal/filepathlite", "n*@\x1a@"}, + {"internal/fmtsort", "\x04\xa1\x02\r"}, + {"internal/fuzz", "\x03\nB\x18\x04\x03\x03\x01\v\x036;\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\f\x04\x02"}, {"internal/goarch", ""}, - {"internal/godebug", "\x96\x01 |\x01\x12"}, + {"internal/godebug", "\x96\x01!\x80\x01\x01\x13"}, {"internal/godebugs", ""}, {"internal/goexperiment", ""}, {"internal/goos", ""}, - {"internal/goroot", "\x96\x02\x01\x05\x14\x02"}, + {"internal/goroot", "\x9d\x02\x01\x05\x12\x02"}, {"internal/gover", "\x04"}, {"internal/goversion", ""}, {"internal/itoa", ""}, - {"internal/lazyregexp", "\x96\x02\v\x0f\x02"}, - {"internal/lazytemplate", "\xea\x01,\x1a\x02\v"}, - {"internal/msan", "\xc5\x02"}, + {"internal/lazyregexp", "\x9d\x02\v\r\x02"}, + {"internal/lazytemplate", "\xf1\x01,\x18\x02\f"}, + {"internal/msan", "\xcb\x02"}, {"internal/nettrace", ""}, - {"internal/obscuretestdata", "e\x85\x01,"}, - {"internal/oserror", "m"}, - {"internal/pkgbits", "\x03K\x18\a\x03\x05\vj\x0e\x1e\r\f\x01"}, + {"internal/obscuretestdata", "f\x8b\x01,"}, + {"internal/oserror", "n"}, + {"internal/pkgbits", "\x03L\x18\a\x03\x04\vq\r\x1f\r\n\x01"}, {"internal/platform", ""}, - {"internal/poll", "mO\x1a\x149\x0f\x01\x01\v\x06"}, - {"internal/profile", "\x03\x04f\x03z7\r\x01\x01\x0f"}, + {"internal/poll", "nO\x1f\x159\r\x01\x01\f\x06"}, + {"internal/profile", "\x03\x04g\x03\x80\x017\v\x01\x01\x10"}, {"internal/profilerecord", ""}, - {"internal/race", "\x94\x01\xb1\x01"}, - {"internal/reflectlite", "\x94\x01 3<\""}, - {"internal/runtime/atomic", "\xc5\x02"}, - {"internal/runtime/exithook", "\xca\x01{"}, - {"internal/runtime/maps", "\x94\x01\x01\x1f\v\t\x05\x01w"}, - {"internal/runtime/math", "\xb4\x01"}, - {"internal/runtime/sys", "\xb4\x01\x04"}, - {"internal/runtime/syscall", "\xc5\x02"}, - {"internal/saferio", "\xea\x01["}, - {"internal/singleflight", "\xb2\x02"}, - {"internal/stringslite", "\x98\x01\xad\x01"}, - {"internal/sync", "\x94\x01 \x14k\x12"}, - {"internal/synctest", "\xc5\x02"}, - {"internal/syscall/execenv", "\xb4\x02"}, - {"internal/syscall/unix", "\xa3\x02\x10\x01\x11"}, - {"internal/sysinfo", "\x02\x01\xaa\x01=,\x1a\x02"}, + {"internal/race", "\x94\x01\xb7\x01"}, + {"internal/reflectlite", "\x94\x01!9\b\x13\x01\a\x03E;\x01\x03\a\x01\x03\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\r\x02\x02\x02\b\x01\x01\x01"}, + {"net/http/cgi", "\x02Q\x1b\x03\x80\x01\x04\a\v\x01\x13\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x10\x0e"}, + {"net/http/cookiejar", "\x04j\x03\x96\x01\x01\b\f\x16\x03\x02\x0e\x04"}, + {"net/http/fcgi", "\x02\x01\nZ\a\x03\x80\x01\x16\x01\x01\x14\x18\x02\x0e"}, + {"net/http/httptest", "\x02\x01\nF\x02\x1b\x01\x80\x01\x04\x12\x01\n\t\x02\x17\x01\x02\x0e\x0e"}, + {"net/http/httptrace", "\rFnF\x14\n "}, + {"net/http/httputil", "\x02\x01\na\x03\x80\x01\x04\x0f\x03\x01\x05\x02\x01\v\x01\x19\x02\x0e\x0e"}, + {"net/http/internal", "\x02\x01k\x03\x80\x01"}, + {"net/http/internal/ascii", "\xb5\x02\x12"}, + {"net/http/internal/httpcommon", "\ra\x03\x9c\x01\x0e\x01\x17\x01\x01\x02\x1c\x02"}, + {"net/http/internal/testcert", "\xb5\x02"}, + {"net/http/pprof", "\x02\x01\nd\x18-\x11*\x04\x13\x14\x01\r\x04\x03\x01\x02\x01\x10"}, {"net/internal/cgotest", ""}, - {"net/internal/socktest", "p\xc2\x01\x02"}, - {"net/mail", "\x02k\x03z\x04\x0f\x03\x14\x1c\x02\r\x04"}, - {"net/netip", "\x04i+\x01#;\x026\x15"}, - {"net/rpc", "\x02f\x05\x03\x10\n`\x04\x12\x01\x1d\x0f\x03\x02"}, - {"net/rpc/jsonrpc", "j\x03\x03z\x16\x11!"}, - {"net/smtp", "\x19.\v\x13\b\x03z\x16\x14\x1c"}, - {"net/textproto", "\x02\x01j\x03z\r\t/\x01\x02\x13"}, - {"net/url", "m\x03\x86\x01%\x12\x02\x01\x15"}, - {"os", "m+\x01\x18\x03\b\t\r\x03\x01\x04\x10\x018\n\x05\x01\x01\v\x06"}, - {"os/exec", "\x03\n`H \x01\x14\x01+\x06\a\f\x01\x04\v"}, - {"os/exec/internal/fdtest", "\xb4\x02"}, - {"os/signal", "\r\x89\x02\x17\x05\x02"}, - {"os/user", "\x02\x01j\x03z,\r\f\x01\x02"}, - {"path", "m+\xab\x01"}, - {"path/filepath", "m+\x19:+\r\n\x03\x04\x0f"}, - {"plugin", "m"}, - {"reflect", "m'\x04\x1c\b\f\x04\x02\x19\x10,\f\x03\x0f\x02\x02"}, + {"net/internal/socktest", "q\xc6\x01\x02"}, + {"net/mail", "\x02l\x03\x80\x01\x04\x0f\x03\x14\x1a\x02\x0e\x04"}, + {"net/netip", "\x04j*\x01$@\x034\x16"}, + {"net/rpc", "\x02g\x05\x03\x0f\ng\x04\x12\x01\x1d\r\x03\x02"}, + {"net/rpc/jsonrpc", "k\x03\x03\x80\x01\x16\x11\x1f"}, + {"net/smtp", "\x19/\v\x13\b\x03\x80\x01\x16\x14\x1a"}, + {"net/textproto", "\x02\x01k\x03\x80\x01\f\n-\x01\x02\x14"}, + {"net/url", "n\x03\x8b\x01&\x10\x02\x01\x16"}, + {"os", "n*\x01\x19\x03\b\t\x12\x03\x01\x05\x10\x018\b\x05\x01\x01\f\x06"}, + {"os/exec", "\x03\naH%\x01\x15\x01+\x06\a\n\x01\x04\f"}, + {"os/exec/internal/fdtest", "\xb9\x02"}, + {"os/signal", "\r\x90\x02\x15\x05\x02"}, + {"os/user", "\x02\x01k\x03\x80\x01,\r\n\x01\x02"}, + {"path", "n*\xb1\x01"}, + {"path/filepath", "n*\x1a@+\r\b\x03\x04\x10"}, + {"plugin", "n"}, + {"reflect", "n&\x04\x1d\b\f\x06\x04\x1b\x06\t-\n\x03\x10\x02\x02"}, {"reflect/internal/example1", ""}, {"reflect/internal/example2", ""}, - {"regexp", "\x03\xe7\x018\v\x02\x01\x02\x0f\x02"}, - {"regexp/syntax", "\xad\x02\x01\x01\x01\x11\x02"}, - {"runtime", "\x94\x01\x04\x01\x02\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x03\x0fd"}, - {"runtime/coverage", "\x9f\x01K"}, - {"runtime/debug", "pUQ\r\n\x02\x01\x0f\x06"}, - {"runtime/internal/startlinetest", ""}, - {"runtime/internal/wasitest", ""}, - {"runtime/metrics", "\xb6\x01A,\""}, - {"runtime/pprof", "\x02\x01\x01\x03\x06Y\a\x03$3#\r\x1f\r\n\x01\x01\x01\x02\x02\b\x03\x06"}, - {"runtime/race", "\xab\x02"}, + {"regexp", "\x03\xee\x018\t\x02\x01\x02\x10\x02"}, + {"regexp/syntax", "\xb2\x02\x01\x01\x01\x02\x10\x02"}, + {"runtime", "\x94\x01\x04\x01\x03\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x02\x01\x01\x04\x10c"}, + {"runtime/coverage", "\xa0\x01Q"}, + {"runtime/debug", "qUW\r\b\x02\x01\x10\x06"}, + {"runtime/metrics", "\xb7\x01F-!"}, + {"runtime/pprof", "\x02\x01\x01\x03\x06Z\a\x03#4)\f \r\b\x01\x01\x01\x02\x02\t\x03\x06"}, + {"runtime/race", "\xb0\x02"}, {"runtime/race/internal/amd64v1", ""}, - {"runtime/trace", "\rcz9\x0f\x01\x12"}, - {"slices", "\x04\xe9\x01\fL"}, - {"sort", "\xc9\x0104"}, - {"strconv", "m+:%\x02J"}, - {"strings", "m'\x04:\x18\x03\f9\x0f\x02\x02"}, + {"runtime/trace", "\ra\x03w\t9\b\x05\x01\r\x06"}, + {"slices", "\x04\xf0\x01\fK"}, + {"sort", "\xca\x0162"}, + {"strconv", "n*@%\x03I"}, + {"strings", "n&\x04@\x19\x03\f7\x10\x02\x02"}, {"structs", ""}, - {"sync", "\xc8\x01\vP\x10\x12"}, - {"sync/atomic", "\xc5\x02"}, - {"syscall", "m(\x03\x01\x1b\b\x03\x03\x06\aT\n\x05\x01\x12"}, - {"testing", "\x03\n`\x02\x01X\x0f\x13\r\x04\x1b\x06\x02\x05\x02\a\x01\x02\x01\x02\x01\f\x02\x02\x02"}, - {"testing/fstest", "m\x03z\x01\v%\x12\x03\b\a"}, - {"testing/internal/testdeps", "\x02\v\xa6\x01'\x10,\x03\x05\x03\b\a\x02\r"}, - {"testing/iotest", "\x03j\x03z\x04"}, - {"testing/quick", "o\x01\x87\x01\x04#\x12\x0f"}, - {"testing/slogtest", "\r`\x03\x80\x01.\x05\x12\n"}, - {"text/scanner", "\x03mz,+\x02"}, - {"text/tabwriter", "pzY"}, - {"text/template", "m\x03B8\x01\v\x1f\x01\x05\x01\x02\x05\r\x02\f\x03\x02"}, - {"text/template/parse", "\x03m\xb3\x01\f\x01\x11\x02"}, - {"time", "m+\x1d\x1d'*\x0f\x02\x11"}, - {"time/tzdata", "m\xc7\x01\x11"}, + {"sync", "\xc9\x01\x10\x01P\x0e\x13"}, + {"sync/atomic", "\xcb\x02"}, + {"syscall", "n'\x03\x01\x1c\b\x03\x03\x06\vV\b\x05\x01\x13"}, + {"testing", "\x03\na\x02\x01X\x14\x14\f\x05\x1b\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\r\x02\x02\x02"}, + {"testing/fstest", "n\x03\x80\x01\x01\n&\x10\x03\b\b"}, + {"testing/internal/testdeps", "\x02\v\xa7\x01-\x10,\x03\x05\x03\x06\a\x02\x0e"}, + {"testing/iotest", "\x03k\x03\x80\x01\x04"}, + {"testing/quick", "p\x01\x8c\x01\x05#\x10\x10"}, + {"testing/slogtest", "\ra\x03\x86\x01.\x05\x10\v"}, + {"testing/synctest", "\xda\x01`\x11"}, + {"text/scanner", "\x03n\x80\x01,*\x02"}, + {"text/tabwriter", "q\x80\x01X"}, + {"text/template", "n\x03B>\x01\n \x01\x05\x01\x02\x05\v\x02\r\x03\x02"}, + {"text/template/parse", "\x03n\xb9\x01\n\x01\x12\x02"}, + {"time", "n*\x1e\"(*\r\x02\x12"}, + {"time/tzdata", "n\xcb\x01\x12"}, {"unicode", ""}, {"unicode/utf16", ""}, {"unicode/utf8", ""}, - {"unique", "\x94\x01>\x01P\x0f\x13\x12"}, + {"unique", "\x94\x01!#\x01Q\r\x01\x13\x12"}, {"unsafe", ""}, - {"vendor/golang.org/x/crypto/chacha20", "\x10V\a\x8c\x01*'"}, - {"vendor/golang.org/x/crypto/chacha20poly1305", "\x10V\a\xd9\x01\x04\x01\a"}, - {"vendor/golang.org/x/crypto/cryptobyte", "c\n\x03\x88\x01&!\n"}, + {"vendor/golang.org/x/crypto/chacha20", "\x10W\a\x92\x01*&"}, + {"vendor/golang.org/x/crypto/chacha20poly1305", "\x10W\a\xde\x01\x04\x01\a"}, + {"vendor/golang.org/x/crypto/cryptobyte", "d\n\x03\x8d\x01' \n"}, {"vendor/golang.org/x/crypto/cryptobyte/asn1", ""}, - {"vendor/golang.org/x/crypto/internal/alias", "\xc5\x02"}, - {"vendor/golang.org/x/crypto/internal/poly1305", "Q\x15\x93\x01"}, - {"vendor/golang.org/x/net/dns/dnsmessage", "m"}, - {"vendor/golang.org/x/net/http/httpguts", "\x80\x02\x14\x1c\x13\r"}, - {"vendor/golang.org/x/net/http/httpproxy", "m\x03\x90\x01\x15\x01\x1a\x13\r"}, - {"vendor/golang.org/x/net/http2/hpack", "\x03j\x03zH"}, - {"vendor/golang.org/x/net/idna", "p\x87\x019\x13\x10\x02\x01"}, - {"vendor/golang.org/x/net/nettest", "\x03c\a\x03z\x11\x05\x16\x01\f\f\x01\x02\x02\x01\n"}, - {"vendor/golang.org/x/sys/cpu", "\x96\x02\r\f\x01\x15"}, - {"vendor/golang.org/x/text/secure/bidirule", "m\xd6\x01\x11\x01"}, - {"vendor/golang.org/x/text/transform", "\x03j}Y"}, - {"vendor/golang.org/x/text/unicode/bidi", "\x03\be~@\x15"}, - {"vendor/golang.org/x/text/unicode/norm", "f\nzH\x11\x11"}, - {"weak", "\x94\x01\x8f\x01\""}, + {"vendor/golang.org/x/crypto/internal/alias", "\xcb\x02"}, + {"vendor/golang.org/x/crypto/internal/poly1305", "R\x15\x99\x01"}, + {"vendor/golang.org/x/net/dns/dnsmessage", "n"}, + {"vendor/golang.org/x/net/http/httpguts", "\x87\x02\x14\x1a\x14\r"}, + {"vendor/golang.org/x/net/http/httpproxy", "n\x03\x96\x01\x10\x05\x01\x18\x14\r"}, + {"vendor/golang.org/x/net/http2/hpack", "\x03k\x03\x80\x01F"}, + {"vendor/golang.org/x/net/idna", "q\x8c\x018\x14\x10\x02\x01"}, + {"vendor/golang.org/x/net/nettest", "\x03d\a\x03\x80\x01\x11\x05\x16\x01\f\n\x01\x02\x02\x01\v"}, + {"vendor/golang.org/x/sys/cpu", "\x9d\x02\r\n\x01\x16"}, + {"vendor/golang.org/x/text/secure/bidirule", "n\xdb\x01\x11\x01"}, + {"vendor/golang.org/x/text/transform", "\x03k\x83\x01X"}, + {"vendor/golang.org/x/text/unicode/bidi", "\x03\bf\x84\x01>\x16"}, + {"vendor/golang.org/x/text/unicode/norm", "g\n\x80\x01F\x12\x11"}, + {"weak", "\x94\x01\x96\x01!"}, } diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go index 64f0326b64..c1faa50d36 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/manifest.go +++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go @@ -502,6 +502,7 @@ var PackageSymbols = map[string][]Symbol{ {"MD4", Const, 0, ""}, {"MD5", Const, 0, ""}, {"MD5SHA1", Const, 0, ""}, + {"MessageSigner", Type, 25, ""}, {"PrivateKey", Type, 0, ""}, {"PublicKey", Type, 2, ""}, {"RIPEMD160", Const, 0, ""}, @@ -517,6 +518,7 @@ var PackageSymbols = map[string][]Symbol{ {"SHA512", Const, 0, ""}, {"SHA512_224", Const, 5, ""}, {"SHA512_256", Const, 5, ""}, + {"SignMessage", Func, 25, "func(signer Signer, rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)"}, {"Signer", Type, 4, ""}, {"SignerOpts", Type, 4, ""}, }, @@ -600,10 +602,12 @@ var PackageSymbols = map[string][]Symbol{ {"X25519", Func, 20, "func() Curve"}, }, "crypto/ecdsa": { + {"(*PrivateKey).Bytes", Method, 25, ""}, {"(*PrivateKey).ECDH", Method, 20, ""}, {"(*PrivateKey).Equal", Method, 15, ""}, {"(*PrivateKey).Public", Method, 4, ""}, {"(*PrivateKey).Sign", Method, 4, ""}, + {"(*PublicKey).Bytes", Method, 25, ""}, {"(*PublicKey).ECDH", Method, 20, ""}, {"(*PublicKey).Equal", Method, 15, ""}, {"(PrivateKey).Add", Method, 0, ""}, @@ -619,6 +623,8 @@ var PackageSymbols = map[string][]Symbol{ {"(PublicKey).ScalarBaseMult", Method, 0, ""}, {"(PublicKey).ScalarMult", Method, 0, ""}, {"GenerateKey", Func, 0, "func(c elliptic.Curve, rand io.Reader) (*PrivateKey, error)"}, + {"ParseRawPrivateKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PrivateKey, error)"}, + {"ParseUncompressedPublicKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PublicKey, error)"}, {"PrivateKey", Type, 0, ""}, {"PrivateKey.D", Field, 0, ""}, {"PrivateKey.PublicKey", Field, 0, ""}, @@ -815,6 +821,7 @@ var PackageSymbols = map[string][]Symbol{ "crypto/sha3": { {"(*SHA3).AppendBinary", Method, 24, ""}, {"(*SHA3).BlockSize", Method, 24, ""}, + {"(*SHA3).Clone", Method, 25, ""}, {"(*SHA3).MarshalBinary", Method, 24, ""}, {"(*SHA3).Reset", Method, 24, ""}, {"(*SHA3).Size", Method, 24, ""}, @@ -967,6 +974,7 @@ var PackageSymbols = map[string][]Symbol{ {"Config.GetCertificate", Field, 4, ""}, {"Config.GetClientCertificate", Field, 8, ""}, {"Config.GetConfigForClient", Field, 8, ""}, + {"Config.GetEncryptedClientHelloKeys", Field, 25, ""}, {"Config.InsecureSkipVerify", Field, 0, ""}, {"Config.KeyLogWriter", Field, 8, ""}, {"Config.MaxVersion", Field, 2, ""}, @@ -5463,6 +5471,7 @@ var PackageSymbols = map[string][]Symbol{ {"ParenExpr.X", Field, 0, ""}, {"Pkg", Const, 0, ""}, {"Preorder", Func, 23, "func(root Node) iter.Seq[Node]"}, + {"PreorderStack", Func, 25, "func(root Node, stack []Node, f func(n Node, stack []Node) bool)"}, {"Print", Func, 0, "func(fset *token.FileSet, x any) error"}, {"RECV", Const, 0, ""}, {"RangeStmt", Type, 0, ""}, @@ -5933,6 +5942,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*File).SetLines", Method, 0, ""}, {"(*File).SetLinesForContent", Method, 0, ""}, {"(*File).Size", Method, 0, ""}, + {"(*FileSet).AddExistingFiles", Method, 25, ""}, {"(*FileSet).AddFile", Method, 0, ""}, {"(*FileSet).Base", Method, 0, ""}, {"(*FileSet).File", Method, 0, ""}, @@ -6382,7 +6392,7 @@ var PackageSymbols = map[string][]Symbol{ {"Label", Type, 5, ""}, {"LocalVar", Const, 25, ""}, {"LookupFieldOrMethod", Func, 5, "func(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool)"}, - {"LookupSelection", Func, 25, ""}, + {"LookupSelection", Func, 25, "func(T Type, addressable bool, pkg *Package, name string) (Selection, bool)"}, {"Map", Type, 5, ""}, {"MethodExpr", Const, 5, ""}, {"MethodSet", Type, 5, ""}, @@ -6490,9 +6500,11 @@ var PackageSymbols = map[string][]Symbol{ {"Lang", Func, 22, "func(x string) string"}, }, "hash": { + {"Cloner", Type, 25, ""}, {"Hash", Type, 0, ""}, {"Hash32", Type, 0, ""}, {"Hash64", Type, 0, ""}, + {"XOF", Type, 25, ""}, }, "hash/adler32": { {"Checksum", Func, 0, "func(data []byte) uint32"}, @@ -6533,6 +6545,7 @@ var PackageSymbols = map[string][]Symbol{ }, "hash/maphash": { {"(*Hash).BlockSize", Method, 14, ""}, + {"(*Hash).Clone", Method, 25, ""}, {"(*Hash).Reset", Method, 14, ""}, {"(*Hash).Seed", Method, 14, ""}, {"(*Hash).SetSeed", Method, 14, ""}, @@ -7133,7 +7146,7 @@ var PackageSymbols = map[string][]Symbol{ {"FormatFileInfo", Func, 21, "func(info FileInfo) string"}, {"Glob", Func, 16, "func(fsys FS, pattern string) (matches []string, err error)"}, {"GlobFS", Type, 16, ""}, - {"Lstat", Func, 25, ""}, + {"Lstat", Func, 25, "func(fsys FS, name string) (FileInfo, error)"}, {"ModeAppend", Const, 16, ""}, {"ModeCharDevice", Const, 16, ""}, {"ModeDevice", Const, 16, ""}, @@ -7158,7 +7171,7 @@ var PackageSymbols = map[string][]Symbol{ {"ReadDirFile", Type, 16, ""}, {"ReadFile", Func, 16, "func(fsys FS, name string) ([]byte, error)"}, {"ReadFileFS", Type, 16, ""}, - {"ReadLink", Func, 25, ""}, + {"ReadLink", Func, 25, "func(fsys FS, name string) (string, error)"}, {"ReadLinkFS", Type, 25, ""}, {"SkipAll", Var, 20, ""}, {"SkipDir", Var, 16, ""}, @@ -7275,6 +7288,7 @@ var PackageSymbols = map[string][]Symbol{ {"(Record).Attrs", Method, 21, ""}, {"(Record).Clone", Method, 21, ""}, {"(Record).NumAttrs", Method, 21, ""}, + {"(Record).Source", Method, 25, ""}, {"(Value).Any", Method, 21, ""}, {"(Value).Bool", Method, 21, ""}, {"(Value).Duration", Method, 21, ""}, @@ -7306,6 +7320,7 @@ var PackageSymbols = map[string][]Symbol{ {"Float64", Func, 21, "func(key string, v float64) Attr"}, {"Float64Value", Func, 21, "func(v float64) Value"}, {"Group", Func, 21, "func(key string, args ...any) Attr"}, + {"GroupAttrs", Func, 25, "func(key string, attrs ...Attr) Attr"}, {"GroupValue", Func, 21, "func(as ...Attr) Value"}, {"Handler", Type, 21, ""}, {"HandlerOptions", Type, 21, ""}, @@ -7916,7 +7931,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*Writer).WriteField", Method, 0, ""}, {"ErrMessageTooLarge", Var, 9, ""}, {"File", Type, 0, ""}, - {"FileContentDisposition", Func, 25, ""}, + {"FileContentDisposition", Func, 25, "func(fieldname string, filename string) string"}, {"FileHeader", Type, 0, ""}, {"FileHeader.Filename", Field, 0, ""}, {"FileHeader.Header", Field, 0, ""}, @@ -8294,6 +8309,11 @@ var PackageSymbols = map[string][]Symbol{ {"(*Client).PostForm", Method, 0, ""}, {"(*Cookie).String", Method, 0, ""}, {"(*Cookie).Valid", Method, 18, ""}, + {"(*CrossOriginProtection).AddInsecureBypassPattern", Method, 25, ""}, + {"(*CrossOriginProtection).AddTrustedOrigin", Method, 25, ""}, + {"(*CrossOriginProtection).Check", Method, 25, ""}, + {"(*CrossOriginProtection).Handler", Method, 25, ""}, + {"(*CrossOriginProtection).SetDenyHandler", Method, 25, ""}, {"(*MaxBytesError).Error", Method, 19, ""}, {"(*ProtocolError).Error", Method, 0, ""}, {"(*ProtocolError).Is", Method, 21, ""}, @@ -8388,6 +8408,7 @@ var PackageSymbols = map[string][]Symbol{ {"Cookie.Unparsed", Field, 0, ""}, {"Cookie.Value", Field, 0, ""}, {"CookieJar", Type, 0, ""}, + {"CrossOriginProtection", Type, 25, ""}, {"DefaultClient", Var, 0, ""}, {"DefaultMaxHeaderBytes", Const, 0, ""}, {"DefaultMaxIdleConnsPerHost", Const, 0, ""}, @@ -8460,6 +8481,7 @@ var PackageSymbols = map[string][]Symbol{ {"MethodPost", Const, 6, ""}, {"MethodPut", Const, 6, ""}, {"MethodTrace", Const, 6, ""}, + {"NewCrossOriginProtection", Func, 25, "func() *CrossOriginProtection"}, {"NewFileTransport", Func, 0, "func(fs FileSystem) RoundTripper"}, {"NewFileTransportFS", Func, 22, "func(fsys fs.FS) RoundTripper"}, {"NewRequest", Func, 0, "func(method string, url string, body io.Reader) (*Request, error)"}, @@ -9174,15 +9196,19 @@ var PackageSymbols = map[string][]Symbol{ {"(*Root).Link", Method, 25, ""}, {"(*Root).Lstat", Method, 24, ""}, {"(*Root).Mkdir", Method, 24, ""}, + {"(*Root).MkdirAll", Method, 25, ""}, {"(*Root).Name", Method, 24, ""}, {"(*Root).Open", Method, 24, ""}, {"(*Root).OpenFile", Method, 24, ""}, {"(*Root).OpenRoot", Method, 24, ""}, + {"(*Root).ReadFile", Method, 25, ""}, {"(*Root).Readlink", Method, 25, ""}, {"(*Root).Remove", Method, 24, ""}, + {"(*Root).RemoveAll", Method, 25, ""}, {"(*Root).Rename", Method, 25, ""}, {"(*Root).Stat", Method, 24, ""}, {"(*Root).Symlink", Method, 25, ""}, + {"(*Root).WriteFile", Method, 25, ""}, {"(*SyscallError).Error", Method, 0, ""}, {"(*SyscallError).Timeout", Method, 10, ""}, {"(*SyscallError).Unwrap", Method, 13, ""}, @@ -9623,6 +9649,7 @@ var PackageSymbols = map[string][]Symbol{ {"StructTag", Type, 0, ""}, {"Swapper", Func, 8, "func(slice any) func(i int, j int)"}, {"Type", Type, 0, ""}, + {"TypeAssert", Func, 25, "func[T any](v Value) (T, bool)"}, {"TypeFor", Func, 22, "func[T any]() Type"}, {"TypeOf", Func, 0, "func(i any) Type"}, {"Uint", Const, 0, ""}, @@ -9909,6 +9936,7 @@ var PackageSymbols = map[string][]Symbol{ {"SetBlockProfileRate", Func, 1, "func(rate int)"}, {"SetCPUProfileRate", Func, 0, "func(hz int)"}, {"SetCgoTraceback", Func, 7, "func(version int, traceback unsafe.Pointer, context unsafe.Pointer, symbolizer unsafe.Pointer)"}, + {"SetDefaultGOMAXPROCS", Func, 25, "func()"}, {"SetFinalizer", Func, 0, "func(obj any, finalizer any)"}, {"SetMutexProfileFraction", Func, 8, "func(rate int) int"}, {"Stack", Func, 0, "func(buf []byte, all bool) int"}, @@ -10021,11 +10049,20 @@ var PackageSymbols = map[string][]Symbol{ {"WriteHeapProfile", Func, 0, "func(w io.Writer) error"}, }, "runtime/trace": { + {"(*FlightRecorder).Enabled", Method, 25, ""}, + {"(*FlightRecorder).Start", Method, 25, ""}, + {"(*FlightRecorder).Stop", Method, 25, ""}, + {"(*FlightRecorder).WriteTo", Method, 25, ""}, {"(*Region).End", Method, 11, ""}, {"(*Task).End", Method, 11, ""}, + {"FlightRecorder", Type, 25, ""}, + {"FlightRecorderConfig", Type, 25, ""}, + {"FlightRecorderConfig.MaxBytes", Field, 25, ""}, + {"FlightRecorderConfig.MinAge", Field, 25, ""}, {"IsEnabled", Func, 11, "func() bool"}, {"Log", Func, 11, "func(ctx context.Context, category string, message string)"}, {"Logf", Func, 11, "func(ctx context.Context, category string, format string, args ...any)"}, + {"NewFlightRecorder", Func, 25, "func(cfg FlightRecorderConfig) *FlightRecorder"}, {"NewTask", Func, 11, "func(pctx context.Context, taskType string) (ctx context.Context, task *Task)"}, {"Region", Type, 11, ""}, {"Start", Func, 5, "func(w io.Writer) error"}, @@ -16642,6 +16679,7 @@ var PackageSymbols = map[string][]Symbol{ {"ValueOf", Func, 0, ""}, }, "testing": { + {"(*B).Attr", Method, 25, ""}, {"(*B).Chdir", Method, 24, ""}, {"(*B).Cleanup", Method, 14, ""}, {"(*B).Context", Method, 24, ""}, @@ -16658,6 +16696,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*B).Logf", Method, 0, ""}, {"(*B).Loop", Method, 24, ""}, {"(*B).Name", Method, 8, ""}, + {"(*B).Output", Method, 25, ""}, {"(*B).ReportAllocs", Method, 1, ""}, {"(*B).ReportMetric", Method, 13, ""}, {"(*B).ResetTimer", Method, 0, ""}, @@ -16674,6 +16713,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*B).StopTimer", Method, 0, ""}, {"(*B).TempDir", Method, 15, ""}, {"(*F).Add", Method, 18, ""}, + {"(*F).Attr", Method, 25, ""}, {"(*F).Chdir", Method, 24, ""}, {"(*F).Cleanup", Method, 18, ""}, {"(*F).Context", Method, 24, ""}, @@ -16689,6 +16729,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*F).Log", Method, 18, ""}, {"(*F).Logf", Method, 18, ""}, {"(*F).Name", Method, 18, ""}, + {"(*F).Output", Method, 25, ""}, {"(*F).Setenv", Method, 18, ""}, {"(*F).Skip", Method, 18, ""}, {"(*F).SkipNow", Method, 18, ""}, @@ -16697,6 +16738,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*F).TempDir", Method, 18, ""}, {"(*M).Run", Method, 4, ""}, {"(*PB).Next", Method, 3, ""}, + {"(*T).Attr", Method, 25, ""}, {"(*T).Chdir", Method, 24, ""}, {"(*T).Cleanup", Method, 14, ""}, {"(*T).Context", Method, 24, ""}, @@ -16712,6 +16754,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*T).Log", Method, 0, ""}, {"(*T).Logf", Method, 0, ""}, {"(*T).Name", Method, 8, ""}, + {"(*T).Output", Method, 25, ""}, {"(*T).Parallel", Method, 0, ""}, {"(*T).Run", Method, 7, ""}, {"(*T).Setenv", Method, 17, ""}, @@ -16834,6 +16877,10 @@ var PackageSymbols = map[string][]Symbol{ {"Run", Func, 22, "func(t *testing.T, newHandler func(*testing.T) slog.Handler, result func(*testing.T) map[string]any)"}, {"TestHandler", Func, 21, "func(h slog.Handler, results func() []map[string]any) error"}, }, + "testing/synctest": { + {"Test", Func, 25, "func(t *testing.T, f func(*testing.T))"}, + {"Wait", Func, 25, "func()"}, + }, "text/scanner": { {"(*Position).IsValid", Method, 0, ""}, {"(*Scanner).Init", Method, 0, ""}, @@ -17347,6 +17394,7 @@ var PackageSymbols = map[string][]Symbol{ {"CaseRange.Lo", Field, 0, ""}, {"CaseRanges", Var, 0, ""}, {"Categories", Var, 0, ""}, + {"CategoryAliases", Var, 25, ""}, {"Caucasian_Albanian", Var, 4, ""}, {"Cc", Var, 0, ""}, {"Cf", Var, 0, ""}, @@ -17354,6 +17402,7 @@ var PackageSymbols = map[string][]Symbol{ {"Cham", Var, 0, ""}, {"Cherokee", Var, 0, ""}, {"Chorasmian", Var, 16, ""}, + {"Cn", Var, 25, ""}, {"Co", Var, 0, ""}, {"Common", Var, 0, ""}, {"Coptic", Var, 0, ""}, @@ -17432,6 +17481,7 @@ var PackageSymbols = map[string][]Symbol{ {"Khojki", Var, 4, ""}, {"Khudawadi", Var, 4, ""}, {"L", Var, 0, ""}, + {"LC", Var, 25, ""}, {"Lao", Var, 0, ""}, {"Latin", Var, 0, ""}, {"Lepcha", Var, 0, ""}, diff --git a/vendor/golang.org/x/tools/internal/typesinternal/fx.go b/vendor/golang.org/x/tools/internal/typesinternal/fx.go new file mode 100644 index 0000000000..93acff2170 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/fx.go @@ -0,0 +1,49 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typesinternal + +import ( + "go/ast" + "go/token" + "go/types" +) + +// NoEffects reports whether the expression has no side effects, i.e., it +// does not modify the memory state. This function is conservative: it may +// return false even when the expression has no effect. +func NoEffects(info *types.Info, expr ast.Expr) bool { + noEffects := true + ast.Inspect(expr, func(n ast.Node) bool { + switch v := n.(type) { + case nil, *ast.Ident, *ast.BasicLit, *ast.BinaryExpr, *ast.ParenExpr, + *ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr, *ast.TypeAssertExpr, + *ast.StarExpr, *ast.CompositeLit, *ast.ArrayType, *ast.StructType, + *ast.MapType, *ast.InterfaceType, *ast.KeyValueExpr: + // No effect + case *ast.UnaryExpr: + // Channel send <-ch has effects + if v.Op == token.ARROW { + noEffects = false + } + case *ast.CallExpr: + // Type conversion has no effects + if !info.Types[v.Fun].IsType() { + // TODO(adonovan): Add a case for built-in functions without side + // effects (by using callsPureBuiltin from tools/internal/refactor/inline) + + noEffects = false + } + case *ast.FuncLit: + // A FuncLit has no effects, but do not descend into it. + return false + default: + // All other expressions have effects + noEffects = false + } + + return noEffects + }) + return noEffects +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go b/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go new file mode 100644 index 0000000000..f2affec4fb --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go @@ -0,0 +1,71 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typesinternal + +import ( + "go/types" + "slices" +) + +// IsTypeNamed reports whether t is (or is an alias for) a +// package-level defined type with the given package path and one of +// the given names. It returns false if t is nil. +// +// This function avoids allocating the concatenation of "pkg.Name", +// which is important for the performance of syntax matching. +func IsTypeNamed(t types.Type, pkgPath string, names ...string) bool { + if named, ok := types.Unalias(t).(*types.Named); ok { + tname := named.Obj() + return tname != nil && + IsPackageLevel(tname) && + tname.Pkg().Path() == pkgPath && + slices.Contains(names, tname.Name()) + } + return false +} + +// IsPointerToNamed reports whether t is (or is an alias for) a pointer to a +// package-level defined type with the given package path and one of the given +// names. It returns false if t is not a pointer type. +func IsPointerToNamed(t types.Type, pkgPath string, names ...string) bool { + r := Unpointer(t) + if r == t { + return false + } + return IsTypeNamed(r, pkgPath, names...) +} + +// IsFunctionNamed reports whether obj is a package-level function +// defined in the given package and has one of the given names. +// It returns false if obj is nil. +// +// This function avoids allocating the concatenation of "pkg.Name", +// which is important for the performance of syntax matching. +func IsFunctionNamed(obj types.Object, pkgPath string, names ...string) bool { + f, ok := obj.(*types.Func) + return ok && + IsPackageLevel(obj) && + f.Pkg().Path() == pkgPath && + f.Type().(*types.Signature).Recv() == nil && + slices.Contains(names, f.Name()) +} + +// IsMethodNamed reports whether obj is a method defined on a +// package-level type with the given package and type name, and has +// one of the given names. It returns false if obj is nil. +// +// This function avoids allocating the concatenation of "pkg.TypeName.Name", +// which is important for the performance of syntax matching. +func IsMethodNamed(obj types.Object, pkgPath string, typeName string, names ...string) bool { + if fn, ok := obj.(*types.Func); ok { + if recv := fn.Type().(*types.Signature).Recv(); recv != nil { + _, T := ReceiverNamed(recv) + return T != nil && + IsTypeNamed(T, pkgPath, typeName) && + slices.Contains(names, fn.Name()) + } + } + return false +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go index b64f714eb3..64f47919f0 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go @@ -15,6 +15,14 @@ import ( // file. // If the same package is imported multiple times, the last appearance is // recorded. +// +// TODO(adonovan): this function ignores the effect of shadowing. It +// should accept a [token.Pos] and a [types.Info] and compute only the +// set of imports that are not shadowed at that point, analogous to +// [analysisinternal.AddImport]. It could also compute (as a side +// effect) the set of additional imports required to ensure that there +// is an accessible import for each necessary package, making it +// converge even more closely with AddImport. func FileQualifier(f *ast.File, pkg *types.Package) types.Qualifier { // Construct mapping of import paths to their defined names. // It is only necessary to look at renaming imports. diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go index a5cd7e8dbf..fef74a7856 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -2,8 +2,20 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package typesinternal provides access to internal go/types APIs that are not -// yet exported. +// Package typesinternal provides helpful operators for dealing with +// go/types: +// +// - operators for querying typed syntax trees (e.g. [Imports], [IsFunctionNamed]); +// - functions for converting types to strings or syntax (e.g. [TypeExpr], FileQualifier]); +// - helpers for working with the [go/types] API (e.g. [NewTypesInfo]); +// - access to internal go/types APIs that are not yet +// exported (e.g. [SetUsesCgo], [ErrorCodeStartEnd], [VarKind]); and +// - common algorithms related to types (e.g. [TooNewStdSymbols]). +// +// See also: +// - [golang.org/x/tools/internal/astutil], for operations on untyped syntax; +// - [golang.org/x/tools/internal/analysisinernal], for helpers for analyzers; +// - [golang.org/x/tools/internal/refactor], for operators to compute text edits. package typesinternal import ( @@ -13,6 +25,7 @@ import ( "reflect" "unsafe" + "golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/internal/aliases" ) @@ -60,6 +73,9 @@ func ErrorCodeStartEnd(err types.Error) (code ErrorCode, start, end token.Pos, o // which is often excessive.) // // If pkg is nil, it is equivalent to [*types.Package.Name]. +// +// TODO(adonovan): all uses of this with TypeString should be +// eliminated when https://go.dev/issues/75604 is resolved. func NameRelativeTo(pkg *types.Package) types.Qualifier { return func(other *types.Package) string { if pkg != nil && pkg == other { @@ -153,3 +169,31 @@ func NewTypesInfo() *types.Info { FileVersions: map[*ast.File]string{}, } } + +// EnclosingScope returns the innermost block logically enclosing the cursor. +func EnclosingScope(info *types.Info, cur inspector.Cursor) *types.Scope { + for cur := range cur.Enclosing() { + n := cur.Node() + // A function's Scope is associated with its FuncType. + switch f := n.(type) { + case *ast.FuncDecl: + n = f.Type + case *ast.FuncLit: + n = f.Type + } + if b := info.Scopes[n]; b != nil { + return b + } + } + panic("no Scope for *ast.File") +} + +// Imports reports whether path is imported by pkg. +func Imports(pkg *types.Package, path string) bool { + for _, imp := range pkg.Imports() { + if imp.Path() == path { + return true + } + } + return false +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go index d272949c17..453bba2ad5 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go @@ -204,23 +204,12 @@ func ZeroExpr(t types.Type, qual types.Qualifier) (_ ast.Expr, isValid bool) { } } -// IsZeroExpr uses simple syntactic heuristics to report whether expr -// is a obvious zero value, such as 0, "", nil, or false. -// It cannot do better without type information. -func IsZeroExpr(expr ast.Expr) bool { - switch e := expr.(type) { - case *ast.BasicLit: - return e.Value == "0" || e.Value == `""` - case *ast.Ident: - return e.Name == "nil" || e.Name == "false" - default: - return false - } -} - // TypeExpr returns syntax for the specified type. References to named types // are qualified by an appropriate (optional) qualifier function. // It may panic for types such as Tuple or Union. +// +// See also https://go.dev/issues/75604, which will provide a robust +// Type-to-valid-Go-syntax formatter. func TypeExpr(t types.Type, qual types.Qualifier) ast.Expr { switch t := t.(type) { case *types.Basic: diff --git a/vendor/gopkg.in/evanphx/json-patch.v4/README.md b/vendor/gopkg.in/evanphx/json-patch.v4/README.md index 28e3516937..86fefd5bf7 100644 --- a/vendor/gopkg.in/evanphx/json-patch.v4/README.md +++ b/vendor/gopkg.in/evanphx/json-patch.v4/README.md @@ -4,7 +4,7 @@ well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ietf.org/html/rfc7396). [![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch) -[![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=master)](https://travis-ci.org/evanphx/json-patch) +[![Build Status](https://github.com/evanphx/json-patch/actions/workflows/go.yml/badge.svg)](https://github.com/evanphx/json-patch/actions/workflows/go.yml) [![Report Card](https://goreportcard.com/badge/github.com/evanphx/json-patch)](https://goreportcard.com/report/github.com/evanphx/json-patch) # Get It! @@ -14,9 +14,7 @@ well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ie go get -u github.com/evanphx/json-patch/v5 ``` -**Stable Versions**: -* Version 5: `go get -u gopkg.in/evanphx/json-patch.v5` -* Version 4: `go get -u gopkg.in/evanphx/json-patch.v4` +If you need version 4, use `go get -u gopkg.in/evanphx/json-patch.v4` (previous versions below `v3` are unavailable) @@ -314,4 +312,4 @@ go test -cover ./... ``` Builds for pull requests are tested automatically -using [TravisCI](https://travis-ci.org/evanphx/json-patch). +using [GitHub Actions](https://github.com/evanphx/json-patch/actions/workflows/go.yml). diff --git a/vendor/gopkg.in/evanphx/json-patch.v4/patch.go b/vendor/gopkg.in/evanphx/json-patch.v4/patch.go index dc2b7e51e6..95136681ba 100644 --- a/vendor/gopkg.in/evanphx/json-patch.v4/patch.go +++ b/vendor/gopkg.in/evanphx/json-patch.v4/patch.go @@ -3,11 +3,10 @@ package jsonpatch import ( "bytes" "encoding/json" + "errors" "fmt" "strconv" "strings" - - "github.com/pkg/errors" ) const ( @@ -277,7 +276,7 @@ func (o Operation) Path() (string, error) { return op, nil } - return "unknown", errors.Wrapf(ErrMissing, "operation missing path field") + return "unknown", fmt.Errorf("operation missing path field: %w", ErrMissing) } // From reads the "from" field of the Operation. @@ -294,7 +293,7 @@ func (o Operation) From() (string, error) { return op, nil } - return "unknown", errors.Wrapf(ErrMissing, "operation, missing from field") + return "unknown", fmt.Errorf("operation, missing from field: %w", ErrMissing) } func (o Operation) value() *lazyNode { @@ -319,7 +318,7 @@ func (o Operation) ValueInterface() (interface{}, error) { return v, nil } - return nil, errors.Wrapf(ErrMissing, "operation, missing value field") + return nil, fmt.Errorf("operation, missing value field: %w", ErrMissing) } func isArray(buf []byte) bool { @@ -359,7 +358,7 @@ func findObject(pd *container, path string) (container, string) { next, ok := doc.get(decodePatchKey(part)) - if next == nil || ok != nil { + if next == nil || ok != nil || next.raw == nil { return nil, "" } @@ -398,7 +397,7 @@ func (d *partialDoc) get(key string) (*lazyNode, error) { func (d *partialDoc) remove(key string) error { _, ok := (*d)[key] if !ok { - return errors.Wrapf(ErrMissing, "Unable to remove nonexistent key: %s", key) + return fmt.Errorf("Unable to remove nonexistent key: %s: %w", key, ErrMissing) } delete(*d, key) @@ -415,10 +414,10 @@ func (d *partialArray) set(key string, val *lazyNode) error { if idx < 0 { if !SupportNegativeIndices { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(*d) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(*d) } @@ -435,7 +434,7 @@ func (d *partialArray) add(key string, val *lazyNode) error { idx, err := strconv.Atoi(key) if err != nil { - return errors.Wrapf(err, "value was not a proper array index: '%s'", key) + return fmt.Errorf("value was not a proper array index: '%s': %w", key, err) } sz := len(*d) + 1 @@ -445,15 +444,15 @@ func (d *partialArray) add(key string, val *lazyNode) error { cur := *d if idx >= len(ary) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < 0 { if !SupportNegativeIndices { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(ary) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(ary) } @@ -475,16 +474,16 @@ func (d *partialArray) get(key string) (*lazyNode, error) { if idx < 0 { if !SupportNegativeIndices { - return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(*d) { - return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(*d) } if idx >= len(*d) { - return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } return (*d)[idx], nil @@ -499,15 +498,15 @@ func (d *partialArray) remove(key string) error { cur := *d if idx >= len(cur) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < 0 { if !SupportNegativeIndices { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(cur) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(cur) } @@ -525,18 +524,18 @@ func (d *partialArray) remove(key string) error { func (p Patch) add(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(ErrMissing, "add operation failed to decode path") + return fmt.Errorf("add operation failed to decode path: %w", ErrMissing) } con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "add operation does not apply: doc is missing path: \"%s\"", path) + return fmt.Errorf("add operation does not apply: doc is missing path: \"%s\": %w", path, ErrMissing) } err = con.add(key, op.value()) if err != nil { - return errors.Wrapf(err, "error in add for path: '%s'", path) + return fmt.Errorf("error in add for path: '%s': %w", path, err) } return nil @@ -545,18 +544,18 @@ func (p Patch) add(doc *container, op Operation) error { func (p Patch) remove(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(ErrMissing, "remove operation failed to decode path") + return fmt.Errorf("remove operation failed to decode path: %w", ErrMissing) } con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "remove operation does not apply: doc is missing path: \"%s\"", path) + return fmt.Errorf("remove operation does not apply: doc is missing path: \"%s\": %w", path, ErrMissing) } err = con.remove(key) if err != nil { - return errors.Wrapf(err, "error in remove for path: '%s'", path) + return fmt.Errorf("error in remove for path: '%s': %w", path, err) } return nil @@ -565,7 +564,7 @@ func (p Patch) remove(doc *container, op Operation) error { func (p Patch) replace(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(err, "replace operation failed to decode path") + return fmt.Errorf("replace operation failed to decode path: %w", err) } if path == "" { @@ -574,7 +573,7 @@ func (p Patch) replace(doc *container, op Operation) error { if val.which == eRaw { if !val.tryDoc() { if !val.tryAry() { - return errors.Wrapf(err, "replace operation value must be object or array") + return fmt.Errorf("replace operation value must be object or array: %w", err) } } } @@ -585,7 +584,7 @@ func (p Patch) replace(doc *container, op Operation) error { case eDoc: *doc = &val.doc case eRaw: - return errors.Wrapf(err, "replace operation hit impossible case") + return fmt.Errorf("replace operation hit impossible case: %w", err) } return nil @@ -594,17 +593,17 @@ func (p Patch) replace(doc *container, op Operation) error { con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing path: %s", path) + return fmt.Errorf("replace operation does not apply: doc is missing path: %s: %w", path, ErrMissing) } _, ok := con.get(key) if ok != nil { - return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing key: %s", path) + return fmt.Errorf("replace operation does not apply: doc is missing key: %s: %w", path, ErrMissing) } err = con.set(key, op.value()) if err != nil { - return errors.Wrapf(err, "error in remove for path: '%s'", path) + return fmt.Errorf("error in remove for path: '%s': %w", path, err) } return nil @@ -613,39 +612,39 @@ func (p Patch) replace(doc *container, op Operation) error { func (p Patch) move(doc *container, op Operation) error { from, err := op.From() if err != nil { - return errors.Wrapf(err, "move operation failed to decode from") + return fmt.Errorf("move operation failed to decode from: %w", err) } con, key := findObject(doc, from) if con == nil { - return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing from path: %s", from) + return fmt.Errorf("move operation does not apply: doc is missing from path: %s: %w", from, ErrMissing) } val, err := con.get(key) if err != nil { - return errors.Wrapf(err, "error in move for path: '%s'", key) + return fmt.Errorf("error in move for path: '%s': %w", key, err) } err = con.remove(key) if err != nil { - return errors.Wrapf(err, "error in move for path: '%s'", key) + return fmt.Errorf("error in move for path: '%s': %w", key, err) } path, err := op.Path() if err != nil { - return errors.Wrapf(err, "move operation failed to decode path") + return fmt.Errorf("move operation failed to decode path: %w", err) } con, key = findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing destination path: %s", path) + return fmt.Errorf("move operation does not apply: doc is missing destination path: %s: %w", path, ErrMissing) } err = con.add(key, val) if err != nil { - return errors.Wrapf(err, "error in move for path: '%s'", path) + return fmt.Errorf("error in move for path: '%s': %w", path, err) } return nil @@ -654,7 +653,7 @@ func (p Patch) move(doc *container, op Operation) error { func (p Patch) test(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(err, "test operation failed to decode path") + return fmt.Errorf("test operation failed to decode path: %w", err) } if path == "" { @@ -673,67 +672,67 @@ func (p Patch) test(doc *container, op Operation) error { return nil } - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "test operation does not apply: is missing path: %s", path) + return fmt.Errorf("test operation does not apply: is missing path: %s: %w", path, ErrMissing) } val, err := con.get(key) if err != nil { - return errors.Wrapf(err, "error in test for path: '%s'", path) + return fmt.Errorf("error in test for path: '%s': %w", path, err) } if val == nil { - if op.value().raw == nil { + if op.value() == nil || op.value().raw == nil { return nil } - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } else if op.value() == nil { - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } if val.equal(op.value()) { return nil } - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64) error { from, err := op.From() if err != nil { - return errors.Wrapf(err, "copy operation failed to decode from") + return fmt.Errorf("copy operation failed to decode from: %w", err) } con, key := findObject(doc, from) if con == nil { - return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing from path: %s", from) + return fmt.Errorf("copy operation does not apply: doc is missing from path: %s: %w", from, ErrMissing) } val, err := con.get(key) if err != nil { - return errors.Wrapf(err, "error in copy for from: '%s'", from) + return fmt.Errorf("error in copy for from: '%s': %w", from, err) } path, err := op.Path() if err != nil { - return errors.Wrapf(ErrMissing, "copy operation failed to decode path") + return fmt.Errorf("copy operation failed to decode path: %w", ErrMissing) } con, key = findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing destination path: %s", path) + return fmt.Errorf("copy operation does not apply: doc is missing destination path: %s: %w", path, ErrMissing) } valCopy, sz, err := deepCopy(val) if err != nil { - return errors.Wrapf(err, "error while performing deep copy") + return fmt.Errorf("error while performing deep copy: %w", err) } (*accumulatedCopySize) += int64(sz) @@ -743,7 +742,7 @@ func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64) er err = con.add(key, valCopy) if err != nil { - return errors.Wrapf(err, "error while adding value during copy") + return fmt.Errorf("error while adding value during copy: %w", err) } return nil diff --git a/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go b/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go index 153784ed9b..7634c727b3 100644 --- a/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go +++ b/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go @@ -33,6 +33,12 @@ type Args struct { // by API linter. If specified, API rule violations will be printed to report file. // Otherwise default value "-" will be used which indicates stdout. ReportFilename string + + // OutputModelNameFile is the name of the file to be generated for OpenAPI schema name + // accessor functions. If empty, no model name accessor functions are generated. + // When this is specified, the OpenAPI spec generator will use the function names + // instead of Go type names for schema names. + OutputModelNameFile string } // New returns default arguments for the generator. Returning the arguments instead @@ -54,6 +60,13 @@ func (args *Args) AddFlags(fs *pflag.FlagSet) { "the base Go import-path under which to generate results") fs.StringVar(&args.OutputFile, "output-file", "generated.openapi.go", "the name of the file to be generated") + fs.StringVar(&args.OutputModelNameFile, "output-model-name-file", "", + `The filename for generated model name accessor functions. +If specified, a file with this name will be created in each package containing +a "+k8s:openapi-model-package" tag. The generated functions return fully qualified +model names, which are used in the OpenAPI spec as schema references instead of +Go type names. If empty, no model name accessor functions are generated and names +are inferred from Go type names.`) fs.StringVar(&args.GoHeaderFile, "go-header-file", "", "the path to a file containing boilerplate header text; the string \"YEAR\" will be replaced with the current 4-digit year") fs.StringVarP(&args.ReportFilename, "report-filename", "r", args.ReportFilename, diff --git a/vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go b/vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go index b466019ad6..b19da6f63b 100644 --- a/vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go +++ b/vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go @@ -25,6 +25,7 @@ import ( "log" "github.com/spf13/pflag" + "k8s.io/gengo/v2" "k8s.io/gengo/v2/generator" "k8s.io/klog/v2" @@ -45,15 +46,35 @@ func main() { log.Fatalf("Arguments validation error: %v", err) } - myTargets := func(context *generator.Context) []generator.Target { - return generators.GetTargets(context, args) + boilerplate, err := gengo.GoBoilerplate(args.GoHeaderFile, gengo.StdBuildTag, gengo.StdGeneratedBy) + if err != nil { + log.Fatalf("Failed loading boilerplate: %v", err) + } + + // Generates the code for model name accessors. + if len(args.OutputModelNameFile) > 0 { + modelNameTargets := func(context *generator.Context) []generator.Target { + return generators.GetModelNameTargets(context, args, boilerplate) + } + if err := gengo.Execute( + generators.NameSystems(), + generators.DefaultNameSystem(), + modelNameTargets, + gengo.StdBuildTag, + pflag.Args(), + ); err != nil { + log.Fatalf("Model name code generation error: %v", err) + } } // Generates the code for the OpenAPIDefinitions. + openAPITargets := func(context *generator.Context) []generator.Target { + return generators.GetOpenAPITargets(context, args, boilerplate) + } if err := gengo.Execute( generators.NameSystems(), generators.DefaultNameSystem(), - myTargets, + openAPITargets, gengo.StdBuildTag, pflag.Args(), ); err != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/config.go b/vendor/k8s.io/kube-openapi/pkg/generators/config.go index 1fbd775985..1bcf2a5231 100644 --- a/vendor/k8s.io/kube-openapi/pkg/generators/config.go +++ b/vendor/k8s.io/kube-openapi/pkg/generators/config.go @@ -19,7 +19,6 @@ package generators import ( "path" - "k8s.io/gengo/v2" "k8s.io/gengo/v2/generator" "k8s.io/gengo/v2/namer" "k8s.io/gengo/v2/types" @@ -49,12 +48,8 @@ func DefaultNameSystem() string { return "sorting_namer" } -func GetTargets(context *generator.Context, args *args.Args) []generator.Target { - boilerplate, err := gengo.GoBoilerplate(args.GoHeaderFile, gengo.StdBuildTag, gengo.StdGeneratedBy) - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - +// GetOpenAPITargets returns the targets for OpenAPI definition generation. +func GetOpenAPITargets(context *generator.Context, args *args.Args, boilerplate []byte) []generator.Target { reportPath := "-" if args.ReportFilename != "" { reportPath = args.ReportFilename @@ -82,3 +77,56 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target }, } } + +// GetModelNameTargets returns the targets for model name generation. +func GetModelNameTargets(context *generator.Context, args *args.Args, boilerplate []byte) []generator.Target { + var targets []generator.Target + for _, i := range context.Inputs { + klog.V(5).Infof("Considering pkg %q", i) + + pkg := context.Universe[i] + + openAPISchemaNamePackage, err := extractOpenAPISchemaNamePackage(pkg.Comments) + if err != nil { + klog.Fatalf("Package %v: invalid %s:%v", i, tagModelPackage, err) + } + hasPackageTag := len(openAPISchemaNamePackage) > 0 + + hasCandidates := false + for _, t := range pkg.Types { + v, err := singularTag(tagModelPackage, t.CommentLines) + if err != nil { + klog.Fatalf("Type %v: invalid %s:%v", t.Name, tagModelPackage, err) + } + hasTag := hasPackageTag || v != nil + hasModel := isSchemaNameType(t) + if hasModel && hasTag { + hasCandidates = true + break + } + } + if !hasCandidates { + klog.V(5).Infof(" skipping package") + continue + } + + klog.V(3).Infof("Generating package %q", pkg.Path) + + targets = append(targets, + &generator.SimpleTarget{ + PkgName: path.Base(pkg.Path), + PkgPath: pkg.Path, + PkgDir: pkg.Dir, // output pkg is the same as the input + HeaderComment: boilerplate, + FilterFunc: func(c *generator.Context, t *types.Type) bool { + return t.Name.Package == pkg.Path + }, + GeneratorsFunc: func(c *generator.Context) (generators []generator.Generator) { + return []generator.Generator{ + NewSchemaNameGen(args.OutputModelNameFile, pkg.Path, openAPISchemaNamePackage), + } + }, + }) + } + return targets +} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/model_names.go b/vendor/k8s.io/kube-openapi/pkg/generators/model_names.go new file mode 100644 index 0000000000..783e975d44 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/generators/model_names.go @@ -0,0 +1,177 @@ +/* +Copyright 2025 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 generators + +import ( + "fmt" + "io" + "strings" + + "k8s.io/gengo/v2" + "k8s.io/gengo/v2/generator" + "k8s.io/gengo/v2/namer" + "k8s.io/gengo/v2/types" + "k8s.io/klog/v2" +) + +const ( + tagModelPackage = "k8s:openapi-model-package" +) + +func extractOpenAPISchemaNamePackage(comments []string) (string, error) { + v, err := singularTag(tagModelPackage, comments) + if v == nil || err != nil { + return "", err + } + return v.Value, nil +} + +func singularTag(tagName string, comments []string) (*gengo.Tag, error) { + tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{tagName}, comments) + if err != nil { + return nil, err + } + if len(tags) == 0 { + return nil, nil + } + if len(tags) > 1 { + return nil, fmt.Errorf("multiple %s tags found", tagName) + } + tag := tags[tagName] + if len(tag) == 0 { + return nil, nil + } + if len(tag) > 1 { + klog.V(5).Infof("multiple %s tags found, using the first one", tagName) + } + value := tag[0] + return &value, nil +} + +// genSchemaName produces a file with autogenerated openapi schema name functions. +type genSchemaName struct { + generator.GoGenerator + targetPackage string + imports namer.ImportTracker + typesForInit []*types.Type + openAPISchemaNamePackage string +} + +// NewSchemaNameGen creates a generator +func NewSchemaNameGen(outputFilename, targetPackage string, openAPISchemaNamePackage string) generator.Generator { + return &genSchemaName{ + GoGenerator: generator.GoGenerator{ + OutputFilename: outputFilename, + }, + targetPackage: targetPackage, + imports: generator.NewImportTracker(), + typesForInit: make([]*types.Type, 0), + openAPISchemaNamePackage: openAPISchemaNamePackage, + } +} + +func (g *genSchemaName) Namers(c *generator.Context) namer.NameSystems { + return namer.NameSystems{ + "public": namer.NewPublicNamer(1), + "local": namer.NewPublicNamer(0), + "raw": namer.NewRawNamer("", nil), + } +} + +func (g *genSchemaName) Filter(c *generator.Context, t *types.Type) bool { + // Filter out types not being processed or not copyable within the package. + if !isSchemaNameType(t) { + klog.V(2).Infof("Type %v is not a valid target for OpenAPI schema name", t) + return false + } + g.typesForInit = append(g.typesForInit, t) + return true +} + +// isSchemaNameType indicates whether or not a type could be used to serve an API. +func isSchemaNameType(t *types.Type) bool { + // Filter out private types. + if namer.IsPrivateGoName(t.Name.Name) { + return false + } + + for t.Kind == types.Alias { + t = t.Underlying + } + + if t.Kind != types.Struct { + return false + } + return true +} + +func (g *genSchemaName) isOtherPackage(pkg string) bool { + if pkg == g.targetPackage { + return false + } + if strings.HasSuffix(pkg, ""+g.targetPackage+"") { + return false + } + return true +} + +func (g *genSchemaName) Imports(c *generator.Context) (imports []string) { + importLines := []string{} + for _, singleImport := range g.imports.ImportLines() { + if g.isOtherPackage(singleImport) { + importLines = append(importLines, singleImport) + } + } + return importLines +} + +func (g *genSchemaName) Init(c *generator.Context, w io.Writer) error { + return nil +} + +func (g *genSchemaName) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { + klog.V(3).Infof("Generating openapi schema name for type %v", t) + + openAPISchemaNamePackage := g.openAPISchemaNamePackage + v, err := singularTag(tagModelPackage, t.CommentLines) + if err != nil { + return fmt.Errorf("type %v: invalid %s:%v", t.Name, tagModelPackage, err) + } + if v != nil && v.Value != "" { + openAPISchemaNamePackage = v.Value + } + + if openAPISchemaNamePackage == "" { + return nil + } + + schemaName := openAPISchemaNamePackage + "." + t.Name.Name + + a := map[string]interface{}{ + "type": t, + "schemaName": schemaName, + } + + sw := generator.NewSnippetWriter(w, c, "$", "$") + + sw.Do("// OpenAPIModelName returns the OpenAPI model name for this type.\n", a) + sw.Do("func (in $.type|local$) OpenAPIModelName() string {\n", a) + sw.Do("\treturn \"$.schemaName$\"\n", a) + sw.Do("}\n\n", nil) + + return sw.Error() +} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go b/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go index c5c0093818..5d58754a77 100644 --- a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go +++ b/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go @@ -295,6 +295,40 @@ func hasOpenAPIV3OneOfMethod(t *types.Type) bool { return false } +func hasOpenAPIModelName(t *types.Type) bool { + for mn, mt := range t.Methods { + if mn != "OpenAPIModelName" { + continue + } + return methodReturnsValue(mt, "", "string") + } + return false +} + +func (g openAPITypeWriter) shouldUseOpenAPIModelName(t *types.Type) bool { + // Finds non-generated OpenAPIModelName() functions. + // Generated OpenAPIModelName() are ignored due to the 'ignore_autogenerated' build tag + // but are handled below by checking for use of the +k8s:openapi-model-package. + // This approach allows code generators to be called in any order. + if hasOpenAPIModelName(t) { + return true + } + + value, err := extractOpenAPISchemaNamePackage(t.CommentLines) + if err != nil { + klog.Fatalf("Type %v: invalid %s:%v", t, tagModelPackage, err) + } + if value != "" { + return true + } + pkg := g.context.Universe.Package(t.Name.Package) + value, err = extractOpenAPISchemaNamePackage(pkg.Comments) + if err != nil { + klog.Fatalf("Package %v: invalid %s:%v", pkg, tagModelPackage, err) + } + return value != "" +} + // typeShortName returns short package name (e.g. the name x appears in package x definition) dot type name. func typeShortName(t *types.Type) string { // `path` vs. `filepath` because packages use '/' @@ -339,8 +373,18 @@ func (g openAPITypeWriter) generateCall(t *types.Type) error { // Only generate for struct type and ignore the rest switch t.Kind { case types.Struct: + if namer.IsPrivateGoName(t.Name.Name) { // skip private types + return nil + } + args := argsFromType(t) - g.Do("\"$.$\": ", t.Name) + + if g.shouldUseOpenAPIModelName(t) { + g.Do("$.|raw${}.OpenAPIModelName(): ", t) + } else { + // Legacy case: use the "canonical type name" + g.Do("\"$.$\": ", t.Name) + } hasV2Definition := hasOpenAPIDefinitionMethod(t) hasV2DefinitionTypeAndFormat := hasOpenAPIDefinitionMethods(t) @@ -657,6 +701,9 @@ func (g openAPITypeWriter) generate(t *types.Type) error { deps := []string{} for _, k := range keys { v := g.refTypes[k] + if t.Kind != types.Struct { + continue + } if t, _ := openapi.OpenAPITypeFormat(v.String()); t != "" { // This is a known type, we do not need a reference to it // Will eliminate special case of time.Time @@ -667,7 +714,12 @@ func (g openAPITypeWriter) generate(t *types.Type) error { if len(deps) > 0 { g.Do("Dependencies: []string{\n", args) for _, k := range deps { - g.Do("\"$.$\",", k) + t := g.refTypes[k] + if g.shouldUseOpenAPIModelName(t) { + g.Do("$.|raw${}.OpenAPIModelName(),", t) + } else { + g.Do("\"$.$\",", k) + } } g.Do("},\n", nil) } @@ -1011,8 +1063,10 @@ func (g openAPITypeWriter) generateProperty(m *types.Member, parent *types.Type) if err := g.generateSliceProperty(t); err != nil { return fmt.Errorf("failed to generate slice property in %v: %v: %v", parent, m.Name, err) } - case types.Struct, types.Interface: + case types.Struct: g.generateReferenceProperty(t) + case types.Interface: + // Don't generate references to interfaces since we don't declare them default: return fmt.Errorf("cannot generate spec for type %v", t) } @@ -1027,7 +1081,11 @@ func (g openAPITypeWriter) generateSimpleProperty(typeString, format string) { func (g openAPITypeWriter) generateReferenceProperty(t *types.Type) { g.refTypes[t.Name.String()] = t - g.Do("Ref: ref(\"$.$\"),\n", t.Name.String()) + if g.shouldUseOpenAPIModelName(t) { + g.Do("Ref: ref($.|raw${}.OpenAPIModelName()),\n", t) + } else { + g.Do("Ref: ref(\"$.$\"),\n", t.Name.String()) + } } func resolvePtrType(t *types.Type) *types.Type { diff --git a/vendor/k8s.io/kube-openapi/pkg/util/util.go b/vendor/k8s.io/kube-openapi/pkg/util/util.go index 6eee935b22..830ec3ca09 100644 --- a/vendor/k8s.io/kube-openapi/pkg/util/util.go +++ b/vendor/k8s.io/kube-openapi/pkg/util/util.go @@ -92,10 +92,21 @@ type OpenAPICanonicalTypeNamer interface { OpenAPICanonicalTypeName() string } +// OpenAPIModelNamer is an interface Go types may implement to provide an OpenAPI model name. +// +// This takes precedence over OpenAPICanonicalTypeNamer, and should be used when a Go type has a model +// name that differs from its canonical type name as determined by Go package name reflection. +type OpenAPIModelNamer interface { + OpenAPIModelName() string +} + // GetCanonicalTypeName will find the canonical type name of a sample object, removing // the "vendor" part of the path func GetCanonicalTypeName(model interface{}) string { - if namer, ok := model.(OpenAPICanonicalTypeNamer); ok { + switch namer := model.(type) { + case OpenAPIModelNamer: + return namer.OpenAPIModelName() + case OpenAPICanonicalTypeNamer: return namer.OpenAPICanonicalTypeName() } t := reflect.TypeOf(model) diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go index 97b2f989e9..23109816eb 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go @@ -17,7 +17,6 @@ package strfmt import ( "encoding/base64" "encoding/json" - "fmt" "net/mail" "regexp" "strings" @@ -247,29 +246,6 @@ func (b *Base64) UnmarshalText(data []byte) error { // validation is performed l return nil } -// Scan read a value from a database driver -func (b *Base64) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(v))) - n, err := base64.StdEncoding.Decode(dbuf, v) - if err != nil { - return err - } - *b = dbuf[:n] - case string: - vv, err := base64.StdEncoding.DecodeString(v) - if err != nil { - return err - } - *b = Base64(vv) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.Base64 from: %#v", v) - } - - return nil -} - func (b Base64) String() string { return base64.StdEncoding.EncodeToString([]byte(b)) } @@ -324,20 +300,6 @@ func (u *URI) UnmarshalText(data []byte) error { // validation is performed late return nil } -// Scan read a value from a database driver -func (u *URI) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = URI(string(v)) - case string: - *u = URI(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v", v) - } - - return nil -} - func (u URI) String() string { return string(u) } @@ -388,20 +350,6 @@ func (e *Email) UnmarshalText(data []byte) error { // validation is performed la return nil } -// Scan read a value from a database driver -func (e *Email) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *e = Email(string(v)) - case string: - *e = Email(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.Email from: %#v", v) - } - - return nil -} - func (e Email) String() string { return string(e) } @@ -452,20 +400,6 @@ func (h *Hostname) UnmarshalText(data []byte) error { // validation is performed return nil } -// Scan read a value from a database driver -func (h *Hostname) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *h = Hostname(string(v)) - case string: - *h = Hostname(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.Hostname from: %#v", v) - } - - return nil -} - func (h Hostname) String() string { return string(h) } @@ -516,20 +450,6 @@ func (u *IPv4) UnmarshalText(data []byte) error { // validation is performed lat return nil } -// Scan read a value from a database driver -func (u *IPv4) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = IPv4(string(v)) - case string: - *u = IPv4(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v", v) - } - - return nil -} - func (u IPv4) String() string { return string(u) } @@ -580,20 +500,6 @@ func (u *IPv6) UnmarshalText(data []byte) error { // validation is performed lat return nil } -// Scan read a value from a database driver -func (u *IPv6) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = IPv6(string(v)) - case string: - *u = IPv6(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.IPv6 from: %#v", v) - } - - return nil -} - func (u IPv6) String() string { return string(u) } @@ -644,20 +550,6 @@ func (u *CIDR) UnmarshalText(data []byte) error { // validation is performed lat return nil } -// Scan read a value from a database driver -func (u *CIDR) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = CIDR(string(v)) - case string: - *u = CIDR(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.CIDR from: %#v", v) - } - - return nil -} - func (u CIDR) String() string { return string(u) } @@ -708,20 +600,6 @@ func (u *MAC) UnmarshalText(data []byte) error { // validation is performed late return nil } -// Scan read a value from a database driver -func (u *MAC) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = MAC(string(v)) - case string: - *u = MAC(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v", v) - } - - return nil -} - func (u MAC) String() string { return string(u) } @@ -772,20 +650,6 @@ func (u *UUID) UnmarshalText(data []byte) error { // validation is performed lat return nil } -// Scan read a value from a database driver -func (u *UUID) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = UUID(string(v)) - case string: - *u = UUID(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.UUID from: %#v", v) - } - - return nil -} - func (u UUID) String() string { return string(u) } @@ -839,20 +703,6 @@ func (u *UUID3) UnmarshalText(data []byte) error { // validation is performed la return nil } -// Scan read a value from a database driver -func (u *UUID3) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = UUID3(string(v)) - case string: - *u = UUID3(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.UUID3 from: %#v", v) - } - - return nil -} - func (u UUID3) String() string { return string(u) } @@ -906,20 +756,6 @@ func (u *UUID4) UnmarshalText(data []byte) error { // validation is performed la return nil } -// Scan read a value from a database driver -func (u *UUID4) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = UUID4(string(v)) - case string: - *u = UUID4(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.UUID4 from: %#v", v) - } - - return nil -} - func (u UUID4) String() string { return string(u) } @@ -973,20 +809,6 @@ func (u *UUID5) UnmarshalText(data []byte) error { // validation is performed la return nil } -// Scan read a value from a database driver -func (u *UUID5) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = UUID5(string(v)) - case string: - *u = UUID5(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.UUID5 from: %#v", v) - } - - return nil -} - func (u UUID5) String() string { return string(u) } @@ -1040,20 +862,6 @@ func (u *ISBN) UnmarshalText(data []byte) error { // validation is performed lat return nil } -// Scan read a value from a database driver -func (u *ISBN) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = ISBN(string(v)) - case string: - *u = ISBN(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.ISBN from: %#v", v) - } - - return nil -} - func (u ISBN) String() string { return string(u) } @@ -1107,20 +915,6 @@ func (u *ISBN10) UnmarshalText(data []byte) error { // validation is performed l return nil } -// Scan read a value from a database driver -func (u *ISBN10) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = ISBN10(string(v)) - case string: - *u = ISBN10(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.ISBN10 from: %#v", v) - } - - return nil -} - func (u ISBN10) String() string { return string(u) } @@ -1174,20 +968,6 @@ func (u *ISBN13) UnmarshalText(data []byte) error { // validation is performed l return nil } -// Scan read a value from a database driver -func (u *ISBN13) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = ISBN13(string(v)) - case string: - *u = ISBN13(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.ISBN13 from: %#v", v) - } - - return nil -} - func (u ISBN13) String() string { return string(u) } @@ -1241,20 +1021,6 @@ func (u *CreditCard) UnmarshalText(data []byte) error { // validation is perform return nil } -// Scan read a value from a database driver -func (u *CreditCard) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = CreditCard(string(v)) - case string: - *u = CreditCard(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.CreditCard from: %#v", v) - } - - return nil -} - func (u CreditCard) String() string { return string(u) } @@ -1308,20 +1074,6 @@ func (u *SSN) UnmarshalText(data []byte) error { // validation is performed late return nil } -// Scan read a value from a database driver -func (u *SSN) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *u = SSN(string(v)) - case string: - *u = SSN(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.SSN from: %#v", v) - } - - return nil -} - func (u SSN) String() string { return string(u) } @@ -1375,20 +1127,6 @@ func (h *HexColor) UnmarshalText(data []byte) error { // validation is performed return nil } -// Scan read a value from a database driver -func (h *HexColor) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *h = HexColor(string(v)) - case string: - *h = HexColor(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.HexColor from: %#v", v) - } - - return nil -} - func (h HexColor) String() string { return string(h) } @@ -1442,20 +1180,6 @@ func (r *RGBColor) UnmarshalText(data []byte) error { // validation is performed return nil } -// Scan read a value from a database driver -func (r *RGBColor) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *r = RGBColor(string(v)) - case string: - *r = RGBColor(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.RGBColor from: %#v", v) - } - - return nil -} - func (r RGBColor) String() string { return string(r) } @@ -1510,20 +1234,6 @@ func (r *Password) UnmarshalText(data []byte) error { // validation is performed return nil } -// Scan read a value from a database driver -func (r *Password) Scan(raw interface{}) error { - switch v := raw.(type) { - case []byte: - *r = Password(string(v)) - case string: - *r = Password(v) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.Password from: %#v", v) - } - - return nil -} - func (r Password) String() string { return string(r) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/duration.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/duration.go index 8fbeb635fb..04545296bd 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/duration.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/duration.go @@ -119,23 +119,6 @@ func ParseDuration(cand string) (time.Duration, error) { return 0, fmt.Errorf("unable to parse %s as duration", cand) } -// Scan reads a Duration value from database driver type. -func (d *Duration) Scan(raw interface{}) error { - switch v := raw.(type) { - // TODO: case []byte: // ? - case int64: - *d = Duration(v) - case float64: - *d = Duration(int64(v)) - case nil: - *d = Duration(0) - default: - return fmt.Errorf("cannot sql.Scan() strfmt.Duration from: %#v", v) - } - - return nil -} - // String converts this duration to a string func (d Duration) String() string { return time.Duration(d).String() diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/time.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/time.go index b2324db052..d0fd31a9db 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/time.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/time.go @@ -16,7 +16,6 @@ package strfmt import ( "encoding/json" - "fmt" "regexp" "strings" "time" @@ -114,25 +113,6 @@ func (t *DateTime) UnmarshalText(text []byte) error { return nil } -// Scan scans a DateTime value from database driver type. -func (t *DateTime) Scan(raw interface{}) error { - // TODO: case int64: and case float64: ? - switch v := raw.(type) { - case []byte: - return t.UnmarshalText(v) - case string: - return t.UnmarshalText([]byte(v)) - case time.Time: - *t = DateTime(v) - case nil: - *t = DateTime{} - default: - return fmt.Errorf("cannot sql.Scan() strfmt.DateTime from: %#v", v) - } - - return nil -} - // MarshalJSON returns the DateTime as JSON func (t DateTime) MarshalJSON() ([]byte, error) { return json.Marshal(time.Time(t).Format(MarshalFormat)) diff --git a/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go b/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go index dfa129dae9..4b19c985c8 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/cache/volumecache.go @@ -114,11 +114,19 @@ func (c *volumeCache) AddVolume(logger klog.Logger, volumeName v1.UniqueVolumeNa } // The volume is already known - // Add the pod to the cache or update its properties - volume.pods[podKey] = podInfo{ + podInfo := podInfo{ seLinuxLabel: label, changePolicy: changePolicy, } + oldPodInfo, found := volume.pods[podKey] + if found && oldPodInfo == podInfo { + // The Pod is already known too and nothing changed since the last update. + // All conflicts were already reported when the Pod was added / updated in the cache last time. + return conflicts + } + + // Add the updated pod info to the cache + volume.pods[podKey] = podInfo // Emit conflicts for the pod for otherPodKey, otherPodInfo := range volume.pods { diff --git a/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go b/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go index e5049e05ab..d373eeabf5 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/selinux_warning_controller.go @@ -140,9 +140,9 @@ func NewController( logger := klog.FromContext(ctx) _, err = podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { c.addPod(logger, obj) }, - DeleteFunc: func(obj interface{}) { c.deletePod(logger, obj) }, - // Not watching updates: Pod volumes and SecurityContext are immutable after creation + AddFunc: func(obj interface{}) { c.enqueuePod(logger, obj) }, + UpdateFunc: func(oldObj, newObj interface{}) { c.updatePod(logger, oldObj, newObj) }, + DeleteFunc: func(obj interface{}) { c.enqueuePod(logger, obj) }, }) if err != nil { return nil, err @@ -178,7 +178,7 @@ func NewController( return c, nil } -func (c *Controller) addPod(_ klog.Logger, obj interface{}) { +func (c *Controller) enqueuePod(_ klog.Logger, obj interface{}) { podRef, err := cache.DeletionHandlingObjectToName(obj) if err != nil { utilruntime.HandleError(fmt.Errorf("couldn't get key for pod %#v: %w", obj, err)) @@ -186,12 +186,29 @@ func (c *Controller) addPod(_ klog.Logger, obj interface{}) { c.queue.Add(podRef) } -func (c *Controller) deletePod(_ klog.Logger, obj interface{}) { - podRef, err := cache.DeletionHandlingObjectToName(obj) - if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for pod %#v: %w", obj, err)) +func (c *Controller) updatePod(logger klog.Logger, oldObj, newObj interface{}) { + // Pod.Spec fields that are relevant to this controller are immutable after creation (i.e. + // pod volumes, SELinux labels, privileged flag). React to update only when the Pod + // reaches its final state - kubelet will unmount the Pod volumes and the controller should + // therefore remove them from the cache. + oldPod, ok := oldObj.(*v1.Pod) + if !ok { + return } - c.queue.Add(podRef) + newPod, ok := newObj.(*v1.Pod) + if !ok { + return + } + + // This is an optimization. In theory, passing most pod updates to the controller queue should lead to noop. + // To save some CPU, pass only pod updates that can cause any action in the controller + if oldPod.Status.Phase == newPod.Status.Phase { + return + } + if newPod.Status.Phase != v1.PodFailed && newPod.Status.Phase != v1.PodSucceeded { + return + } + c.enqueuePod(logger, newObj) } func (c *Controller) addPVC(logger klog.Logger, obj interface{}) { @@ -277,11 +294,7 @@ func (c *Controller) enqueueAllPodsForPVC(logger klog.Logger, namespace, name st return } for _, obj := range objs { - podRef, err := cache.DeletionHandlingObjectToName(obj) - if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for pod %#v: %w", obj, err)) - } - c.queue.Add(podRef) + c.enqueuePod(logger, obj) } } @@ -401,6 +414,11 @@ func (c *Controller) sync(ctx context.Context, podRef cache.ObjectName) error { logger.V(5).Info("Error getting pod from informer", "pod", klog.KObj(pod), "podUID", pod.UID, "err", err) return err } + if pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded { + // The pod has reached its final state and kubelet is unmounting is volumes. + // Remove them from the cache. + return c.syncPodDelete(ctx, podRef) + } return c.syncPod(ctx, pod) } @@ -481,8 +499,15 @@ func (c *Controller) syncVolume(logger klog.Logger, pod *v1.Pod, spec *volume.Sp changePolicy := v1.SELinuxChangePolicyMountOption if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxChangePolicy != nil { changePolicy = *pod.Spec.SecurityContext.SELinuxChangePolicy + logger.V(5).Info("Using Pod SELinux change policy", "pod", klog.KObj(pod), "changePolicy", changePolicy) } - if !pluginSupportsSELinuxContextMount { + if !pluginSupportsSELinuxContextMount && changePolicy != v1.SELinuxChangePolicyRecursive { + logger.V(5).Info("Volume does not support SELinux context mount, setting changePolicy to Recursive", "pod", klog.KObj(pod), "volume", spec.Name()) + changePolicy = v1.SELinuxChangePolicyRecursive + } + + if seLinuxLabel == "" && changePolicy != v1.SELinuxChangePolicyRecursive { + logger.V(5).Info("Pod has empty SELinux label, setting changePolicy to Recursive", "pod", klog.KObj(pod)) changePolicy = v1.SELinuxChangePolicyRecursive } diff --git a/vendor/modules.txt b/vendor/modules.txt index 9856f5411a..d0109545ba 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,6 +1,12 @@ # cel.dev/expr v0.24.0 ## explicit; go 1.22.0 cel.dev/expr +# cyphar.com/go-pathrs v0.2.1 +## explicit; go 1.18 +cyphar.com/go-pathrs +cyphar.com/go-pathrs/internal/fdutils +cyphar.com/go-pathrs/internal/libpathrs +cyphar.com/go-pathrs/procfs # github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 ## explicit; go 1.16 github.com/Azure/go-ansiterm @@ -97,7 +103,7 @@ github.com/coreos/go-systemd/daemon github.com/coreos/go-systemd/v22/daemon github.com/coreos/go-systemd/v22/dbus github.com/coreos/go-systemd/v22/journal -# github.com/cyphar/filepath-securejoin v0.5.1 +# github.com/cyphar/filepath-securejoin v0.6.0 ## explicit; go 1.18 github.com/cyphar/filepath-securejoin github.com/cyphar/filepath-securejoin/internal/consts @@ -106,6 +112,7 @@ github.com/cyphar/filepath-securejoin/pathrs-lite/internal github.com/cyphar/filepath-securejoin/pathrs-lite/internal/assert github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat +github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs github.com/cyphar/filepath-securejoin/pathrs-lite/internal/kernelversion github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs @@ -288,8 +295,8 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad -## explicit; go 1.22 +# github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 +## explicit; go 1.23 github.com/google/pprof/profile # github.com/google/uuid v1.6.0 ## explicit @@ -419,7 +426,7 @@ github.com/opencontainers/runc/libcontainer/utils # github.com/opencontainers/runtime-spec v1.2.0 ## explicit github.com/opencontainers/runtime-spec/specs-go -# github.com/opencontainers/selinux v1.12.0 +# github.com/opencontainers/selinux v1.13.0 ## explicit; go 1.19 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label @@ -681,7 +688,7 @@ github.com/openshift/cluster-policy-controller/pkg/security/controller github.com/openshift/cluster-policy-controller/pkg/security/mcs github.com/openshift/cluster-policy-controller/pkg/security/uidallocator github.com/openshift/cluster-policy-controller/pkg/version -# github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f +# github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 ## explicit; go 1.24.0 github.com/openshift/library-go/pkg/apiserver/admission/admissionrestconfig github.com/openshift/library-go/pkg/apiserver/admission/admissiontimeout @@ -731,8 +738,8 @@ github.com/openshift/library-go/pkg/route/validation github.com/openshift/library-go/pkg/security/ldaputil github.com/openshift/library-go/pkg/security/uid github.com/openshift/library-go/pkg/serviceability -# github.com/openshift/route-controller-manager v0.0.0-20260127173744-2b9e93a5f0fc -## explicit; go 1.24.0 +# github.com/openshift/route-controller-manager v0.0.0-20260211095309-624742d93f3a +## explicit; go 1.25.0 github.com/openshift/route-controller-manager/pkg/cmd/controller github.com/openshift/route-controller-manager/pkg/cmd/route-controller-manager github.com/openshift/route-controller-manager/pkg/route/ingress @@ -797,7 +804,7 @@ github.com/russross/blackfriday/v2 # github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13 github.com/sirupsen/logrus -# github.com/spf13/cobra v1.9.1 +# github.com/spf13/cobra v1.10.0 ## explicit; go 1.15 github.com/spf13/cobra # github.com/spf13/pflag v1.0.10 @@ -828,8 +835,8 @@ github.com/x448/float16 # github.com/xlab/treeprint v1.2.0 ## explicit; go 1.13 github.com/xlab/treeprint -# go.etcd.io/etcd/api/v3 v3.6.4 -## explicit; go 1.23.0 +# go.etcd.io/etcd/api/v3 v3.6.5 +## explicit; go 1.24 go.etcd.io/etcd/api/v3/authpb go.etcd.io/etcd/api/v3/etcdserverpb go.etcd.io/etcd/api/v3/membershippb @@ -837,8 +844,8 @@ go.etcd.io/etcd/api/v3/mvccpb go.etcd.io/etcd/api/v3/v3rpc/rpctypes go.etcd.io/etcd/api/v3/version go.etcd.io/etcd/api/v3/versionpb -# go.etcd.io/etcd/client/pkg/v3 v3.6.4 -## explicit; go 1.23.0 +# go.etcd.io/etcd/client/pkg/v3 v3.6.5 +## explicit; go 1.24 go.etcd.io/etcd/client/pkg/v3/fileutil go.etcd.io/etcd/client/pkg/v3/logutil go.etcd.io/etcd/client/pkg/v3/systemd @@ -846,8 +853,8 @@ go.etcd.io/etcd/client/pkg/v3/tlsutil go.etcd.io/etcd/client/pkg/v3/transport go.etcd.io/etcd/client/pkg/v3/types go.etcd.io/etcd/client/pkg/v3/verify -# go.etcd.io/etcd/client/v3 v3.6.4 -## explicit; go 1.23.0 +# go.etcd.io/etcd/client/v3 v3.6.5 +## explicit; go 1.24 go.etcd.io/etcd/client/v3 go.etcd.io/etcd/client/v3/credentials go.etcd.io/etcd/client/v3/internal/endpoint @@ -865,8 +872,8 @@ go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelr ## explicit; go 1.22.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal -# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 -## explicit; go 1.22.0 +# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 +## explicit; go 1.23.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv @@ -941,13 +948,13 @@ go.uber.org/zap/internal/pool go.uber.org/zap/internal/stacktrace go.uber.org/zap/zapcore go.uber.org/zap/zapgrpc -# go.yaml.in/yaml/v2 v2.4.2 +# go.yaml.in/yaml/v2 v2.4.3 ## explicit; go 1.15 go.yaml.in/yaml/v2 # go.yaml.in/yaml/v3 v3.0.4 ## explicit; go 1.16 go.yaml.in/yaml/v3 -# golang.org/x/crypto v0.42.0 +# golang.org/x/crypto v0.45.0 ## explicit; go 1.24.0 golang.org/x/crypto/cryptobyte golang.org/x/crypto/cryptobyte/asn1 @@ -963,13 +970,13 @@ golang.org/x/crypto/salsa20/salsa ## explicit; go 1.20 golang.org/x/exp/constraints golang.org/x/exp/slices -# golang.org/x/mod v0.27.0 -## explicit; go 1.23.0 +# golang.org/x/mod v0.29.0 +## explicit; go 1.24.0 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.43.0 -## explicit; go 1.23.0 +# golang.org/x/net v0.47.0 +## explicit; go 1.24.0 golang.org/x/net/bpf golang.org/x/net/context golang.org/x/net/html @@ -992,11 +999,11 @@ golang.org/x/net/websocket ## explicit; go 1.23.0 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.17.0 +# golang.org/x/sync v0.18.0 ## explicit; go 1.24.0 golang.org/x/sync/errgroup golang.org/x/sync/singleflight -# golang.org/x/sys v0.36.0 +# golang.org/x/sys v0.38.0 ## explicit; go 1.24.0 golang.org/x/sys/cpu golang.org/x/sys/plan9 @@ -1005,10 +1012,10 @@ golang.org/x/sys/windows golang.org/x/sys/windows/registry golang.org/x/sys/windows/svc golang.org/x/sys/windows/svc/mgr -# golang.org/x/term v0.35.0 +# golang.org/x/term v0.37.0 ## explicit; go 1.24.0 golang.org/x/term -# golang.org/x/text v0.29.0 +# golang.org/x/text v0.31.0 ## explicit; go 1.24.0 golang.org/x/text/encoding golang.org/x/text/encoding/internal @@ -1035,10 +1042,12 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.9.0 ## explicit; go 1.18 golang.org/x/time/rate -# golang.org/x/tools v0.36.0 -## explicit; go 1.23.0 +# golang.org/x/tools v0.38.0 +## explicit; go 1.24.0 golang.org/x/tools/container/intsets golang.org/x/tools/go/ast/astutil +golang.org/x/tools/go/ast/edge +golang.org/x/tools/go/ast/inspector golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/packages golang.org/x/tools/go/types/objectpath @@ -1180,7 +1189,7 @@ google.golang.org/protobuf/types/known/fieldmaskpb google.golang.org/protobuf/types/known/structpb google.golang.org/protobuf/types/known/timestamppb google.golang.org/protobuf/types/known/wrapperspb -# gopkg.in/evanphx/json-patch.v4 v4.12.0 +# gopkg.in/evanphx/json-patch.v4 v4.13.0 ## explicit gopkg.in/evanphx/json-patch.v4 # gopkg.in/go-jose/go-jose.v2 v2.6.3 @@ -2142,8 +2151,8 @@ k8s.io/kube-aggregator/pkg/registry/apiservice/rest # k8s.io/kube-controller-manager v1.34.2 => ./deps/github.com/openshift/kubernetes/staging/src/k8s.io/kube-controller-manager ## explicit; go 1.24.0 k8s.io/kube-controller-manager/config/v1alpha1 -# k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b -## explicit; go 1.23 +# k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 +## explicit; go 1.23.0 k8s.io/kube-openapi/cmd/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen/args k8s.io/kube-openapi/pkg/aggregator @@ -2236,7 +2245,7 @@ k8s.io/kubelet/pkg/cri/streaming k8s.io/kubelet/pkg/cri/streaming/portforward k8s.io/kubelet/pkg/cri/streaming/remotecommand k8s.io/kubelet/pkg/types -# k8s.io/kubernetes v1.34.2 => ./deps/github.com/openshift/kubernetes +# k8s.io/kubernetes v1.35.0 => ./deps/github.com/openshift/kubernetes ## explicit; go 1.24.0 k8s.io/kubernetes/cmd/kube-apiserver/app k8s.io/kubernetes/cmd/kube-apiserver/app/options @@ -3126,7 +3135,7 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client -# sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 +# sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 ## explicit; go 1.23 sigs.k8s.io/json sigs.k8s.io/json/internal/golang/encoding/json diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go index d538ac119b..3fe528bbf3 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go @@ -52,8 +52,8 @@ import ( // - bool, for JSON booleans // - float64, for JSON numbers // - string, for JSON strings -// - []interface{}, for JSON arrays -// - map[string]interface{}, for JSON objects +// - []any, for JSON arrays +// - map[string]any, for JSON objects // - nil for JSON null // // To unmarshal a JSON array into a slice, Unmarshal resets the slice length @@ -117,9 +117,6 @@ func Unmarshal(data []byte, v any, opts ...UnmarshalOpt) error { // The input can be assumed to be a valid encoding of // a JSON value. UnmarshalJSON must copy the JSON data // if it wishes to retain the data after returning. -// -// By convention, to approximate the behavior of [Unmarshal] itself, -// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. type Unmarshaler interface { UnmarshalJSON([]byte) error } @@ -132,7 +129,7 @@ type UnmarshalTypeError struct { Type reflect.Type // type of Go value it could not be assigned to Offset int64 // error occurred after reading Offset bytes Struct string // name of the struct type containing the field - Field string // the full path from root node to the field + Field string // the full path from root node to the field, include embedded struct } func (e *UnmarshalTypeError) Error() string { @@ -281,7 +278,11 @@ func (d *decodeState) addErrorContext(err error) error { switch err := err.(type) { case *UnmarshalTypeError: err.Struct = d.errorContext.Struct.Name() - err.Field = strings.Join(d.errorContext.FieldStack, ".") + fieldStack := d.errorContext.FieldStack + if err.Field != "" { + fieldStack = append(fieldStack, err.Field) + } + err.Field = strings.Join(fieldStack, ".") } } return err @@ -492,9 +493,9 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm } // Prevent infinite loop if v is an interface pointing to its own address: - // var v interface{} + // var v any // v = &v - if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v { + if v.Elem().Kind() == reflect.Interface && v.Elem().Elem().Equal(v) { v = v.Elem() break } @@ -784,7 +785,10 @@ func (d *decodeState) object(v reflect.Value) error { } subv = v destring = f.quoted - for _, i := range f.index { + if d.errorContext == nil { + d.errorContext = new(errorContext) + } + for i, ind := range f.index { if subv.Kind() == reflect.Pointer { if subv.IsNil() { // If a struct embeds a pointer to an unexported type, @@ -804,13 +808,16 @@ func (d *decodeState) object(v reflect.Value) error { } subv = subv.Elem() } - subv = subv.Field(i) - } - if d.errorContext == nil { - d.errorContext = new(errorContext) + if i < len(f.index)-1 { + d.errorContext.FieldStack = append( + d.errorContext.FieldStack, + subv.Type().Field(ind).Name, + ) + } + subv = subv.Field(ind) } - d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name) d.errorContext.Struct = t + d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name) d.appendStrictFieldStackKey(f.name) } else if d.disallowUnknownFields { d.saveStrictError(d.newFieldError(unknownStrictErrType, string(key))) @@ -1118,7 +1125,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool // in an empty interface. They are not strictly necessary, // but they avoid the weight of reflection in this common case. -// valueInterface is like value but returns interface{} +// valueInterface is like value but returns any. func (d *decodeState) valueInterface() (val any) { switch d.opcode { default: @@ -1135,7 +1142,7 @@ func (d *decodeState) valueInterface() (val any) { return } -// arrayInterface is like array but returns []interface{}. +// arrayInterface is like array but returns []any. func (d *decodeState) arrayInterface() []any { origStrictFieldStackLen := len(d.strictFieldStack) defer func() { @@ -1170,7 +1177,7 @@ func (d *decodeState) arrayInterface() []any { return v } -// objectInterface is like object but returns map[string]interface{}. +// objectInterface is like object but returns map[string]any. func (d *decodeState) objectInterface() map[string]any { origStrictFieldStackLen := len(d.strictFieldStack) defer func() { diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go index eb73bff58b..4e3a1a2f10 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go @@ -71,8 +71,8 @@ import ( // // The "omitempty" option specifies that the field should be omitted // from the encoding if the field has an empty value, defined as -// false, 0, a nil pointer, a nil interface value, and any empty array, -// slice, map, or string. +// false, 0, a nil pointer, a nil interface value, and any array, +// slice, map, or string of length zero. // // As a special case, if the field tag is "-", the field is always omitted. // Note that a field with name "-" can still be generated using the tag "-,". @@ -98,6 +98,17 @@ import ( // // Field appears in JSON as key "-". // Field int `json:"-,"` // +// The "omitzero" option specifies that the field should be omitted +// from the encoding if the field has a zero value, according to rules: +// +// 1) If the field type has an "IsZero() bool" method, that will be used to +// determine whether the value is zero. +// +// 2) Otherwise, the value is zero if it is the zero value for its type. +// +// If both "omitempty" and "omitzero" are specified, the field will be omitted +// if the value is either empty or zero (or both). +// // The "string" option signals that a field is stored as JSON inside a // JSON-encoded string. It applies only to fields of string, floating point, // integer, or boolean types. This extra level of encoding is sometimes used @@ -690,7 +701,8 @@ FieldLoop: fv = fv.Field(i) } - if f.omitEmpty && isEmptyValue(fv) { + if (f.omitEmpty && isEmptyValue(fv)) || + (f.omitZero && (f.isZero == nil && fv.IsZero() || (f.isZero != nil && f.isZero(fv)))) { continue } e.WriteByte(next) @@ -808,7 +820,7 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { // Here we use a struct to memorize the pointer to the first element of the slice // and its length. ptr := struct { - ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe + ptr any // always an unsafe.Pointer, but avoids a dependency on package unsafe len int }{v.UnsafePointer(), v.Len()} if _, ok := e.ptrSeen[ptr]; ok { @@ -1039,11 +1051,19 @@ type field struct { index []int typ reflect.Type omitEmpty bool + omitZero bool + isZero func(reflect.Value) bool quoted bool encoder encoderFunc } +type isZeroer interface { + IsZero() bool +} + +var isZeroerType = reflect.TypeFor[isZeroer]() + // typeFields returns a list of fields that JSON should recognize for the given type. // The algorithm is breadth-first search over the set of structs to include - the top struct // and then any reachable anonymous structs. @@ -1135,6 +1155,7 @@ func typeFields(t reflect.Type) structFields { index: index, typ: ft, omitEmpty: opts.Contains("omitempty"), + omitZero: opts.Contains("omitzero"), quoted: quoted, } field.nameBytes = []byte(field.name) @@ -1144,6 +1165,40 @@ func typeFields(t reflect.Type) structFields { field.nameEscHTML = `"` + string(nameEscBuf) + `":` field.nameNonEsc = `"` + field.name + `":` + if field.omitZero { + t := sf.Type + // Provide a function that uses a type's IsZero method. + switch { + case t.Kind() == reflect.Interface && t.Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + // Avoid panics calling IsZero on a nil interface or + // non-nil interface with nil pointer. + return v.IsNil() || + (v.Elem().Kind() == reflect.Pointer && v.Elem().IsNil()) || + v.Interface().(isZeroer).IsZero() + } + case t.Kind() == reflect.Pointer && t.Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + // Avoid panics calling IsZero on nil pointer. + return v.IsNil() || v.Interface().(isZeroer).IsZero() + } + case t.Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + return v.Interface().(isZeroer).IsZero() + } + case reflect.PointerTo(t).Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + if !v.CanAddr() { + // Temporarily box v so we can take the address. + v2 := reflect.New(v.Type()).Elem() + v2.Set(v) + v = v2 + } + return v.Addr().Interface().(isZeroer).IsZero() + } + } + } + fields = append(fields, field) if count[f.typ] > 1 { // If there were multiple instances, add a second, diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go index 48fc4d9453..cc2108b927 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go @@ -31,8 +31,8 @@ func NewDecoder(r io.Reader) *Decoder { return &Decoder{r: r} } -// UseNumber causes the Decoder to unmarshal a number into an interface{} as a -// [Number] instead of as a float64. +// UseNumber causes the Decoder to unmarshal a number into an +// interface value as a [Number] instead of as a float64. func (dec *Decoder) UseNumber() { dec.d.useNumber = true } // DisallowUnknownFields causes the Decoder to return an error when the destination From 02b1bb8e0d651328949e98654b80ef2783ac9fdb Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:03:31 +0100 Subject: [PATCH 06/15] update etcd/go.mod --- etcd/go.mod | 37 ++++++++++++++++------------------ etcd/go.sum | 58 ++++++++++++++++++++++++++--------------------------- 2 files changed, 46 insertions(+), 49 deletions(-) diff --git a/etcd/go.mod b/etcd/go.mod index 308f95e434..9a1f94c56f 100644 --- a/etcd/go.mod +++ b/etcd/go.mod @@ -1,17 +1,14 @@ module github.com/openshift/microshift/etcd -go 1.24.0 +go 1.25.0 -require github.com/openshift/microshift v0.0.0 - -replace ( - github.com/openshift/microshift => ../ -) +replace github.com/openshift/microshift => ../ require ( github.com/openshift/api v0.0.0-20251214014457-bfa868a22401 github.com/openshift/build-machinery-go v0.0.0-20251023084048-5d77c1a5e5af - github.com/spf13/cobra v1.9.1 + github.com/openshift/microshift v0.0.0-00010101000000-000000000000 + github.com/spf13/cobra v1.10.0 go.etcd.io/etcd/server/v3 v3.6.4 k8s.io/apimachinery v1.34.2 k8s.io/cli-runtime v1.34.2 @@ -22,7 +19,9 @@ require ( ) require ( + github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -35,7 +34,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/run v1.2.0 // indirect - github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f // indirect + github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/squat/generic-device-plugin v0.0.0-20251019101956-043a51e18f31 // indirect @@ -45,12 +44,12 @@ require ( go.etcd.io/raft/v3 v3.6.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sync v0.17.0 // indirect + golang.org/x/sync v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect k8s.io/apiserver v1.34.2 // indirect k8s.io/kubelet v1.34.2 // indirect sigs.k8s.io/randfill v1.0.0 // indirect @@ -60,7 +59,6 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect - github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -70,7 +68,6 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.4.3 // indirect @@ -122,12 +119,12 @@ require ( go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.42.0 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/crypto v0.45.0 // indirect + golang.org/x/net v0.47.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/term v0.35.0 // indirect - golang.org/x/text v0.29.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.9.0 // indirect google.golang.org/grpc v1.76.0 // indirect google.golang.org/protobuf v1.36.8 // indirect @@ -136,9 +133,9 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v1.34.2 // indirect k8s.io/client-go v1.34.2 // indirect - k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect ) diff --git a/etcd/go.sum b/etcd/go.sum index d8723d369f..9e4f0844e6 100644 --- a/etcd/go.sum +++ b/etcd/go.sum @@ -74,8 +74,8 @@ github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7O github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -147,8 +147,8 @@ github.com/openshift/etcd/pkg/v3 v3.5.0-alpha.0.0.20260202131331-6a0992267004 h1 github.com/openshift/etcd/pkg/v3 v3.5.0-alpha.0.0.20260202131331-6a0992267004/go.mod h1:uqrXrzmMIJDEy5j00bCqhVLzR5jEJIwDp5wTlLwPGOU= github.com/openshift/etcd/server/v3 v3.5.0-alpha.0.0.20260202131331-6a0992267004 h1:cyY8/K2U6XIxYUUxQypattfKCUi/0x59N5Lr2seP/mQ= github.com/openshift/etcd/server/v3 v3.5.0-alpha.0.0.20260202131331-6a0992267004/go.mod h1:PLuhyVXz8WWRhzXDsl3A3zv/+aK9e4A9lpQkqawIaH0= -github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f h1:r1pLosA7z3+t+lzW29FU54sg4/pAWu+lsKD0L5Gx3wg= -github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f/go.mod h1:ErDfiIrPHH+menTP/B4LKd0nxFDdvCbTamAc6SWMIh8= +github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 h1:Fm9C8pT4l6VjpdqdhI1cBX9Y3D3S+rFxptVhCPBbMAI= +github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04/go.mod h1:nIzWQQE49XbiKizVnVOip9CEB7HJ0hoJwNi3g3YKnKc= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= @@ -177,9 +177,9 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.0 h1:a5/WeUlSDCvV5a45ljW2ZFtV0bTDpkfSAj3uqB6Sc+0= +github.com/spf13/cobra v1.10.0/go.mod h1:9dhySC7dnTtEiqzmqfkLj47BslqLCUPMXjG2lj/NgoE= +github.com/spf13/pflag v1.0.8/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/squat/generic-device-plugin v0.0.0-20251019101956-043a51e18f31 h1:wPJNupO/W9VJkwf/5vVnEReuS3pf5u+V+RGv6TOPrLM= @@ -237,15 +237,15 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -254,15 +254,15 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -274,24 +274,24 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -309,8 +309,8 @@ google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXn gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= @@ -320,12 +320,12 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78= From 09db24ae84a047c8a7a7e088221591dd7d1fbda0 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:10:44 +0100 Subject: [PATCH 07/15] update changelog --- scripts/auto-rebase/changelog.txt | 432 ------------------------------ 1 file changed, 432 deletions(-) diff --git a/scripts/auto-rebase/changelog.txt b/scripts/auto-rebase/changelog.txt index db46c98cb0..e69de29bb2 100644 --- a/scripts/auto-rebase/changelog.txt +++ b/scripts/auto-rebase/changelog.txt @@ -1,432 +0,0 @@ -- api embedded-component 81371d13d1fcad175a48627cf11524a94a80c377 to d34f11c515b3d00fdb3809cd59737e3bd77167c4 - - a51a8c21 2026-02-13T14:33:53-05:00 CORS-4096: Add DNS Record Type for IPv6 Domain mapping - - 164ef8ee 2026-02-11T21:51:41+01:00 make update - - 9ee7e57f 2026-02-11T21:51:40+01:00 TLSSecurityProfile: Remove go's unsupported ciphers - - 2a4d5aca 2026-02-11T16:55:12Z Synchronous review updates - - f1afd44b 2026-02-11T15:55:12Z Add ClusterAPI config - - 03090cfb 2026-02-11T15:58:03+01:00 Remove CPMSMachineNamePrefix featuregate - - 43458f18 2026-02-09T16:17:23Z Add a timeout for aysnc calls in integration tests - - 8d70004f 2026-02-09T14:04:43Z Update integration test timeout and make parallel where possible - - 49591510 2026-02-09T13:05:22Z Deploy CompatibilityRequirement from o/api repo - - 33223cf6 2026-02-09T13:01:36Z Feature gate CVO application of CompatibilityRequirement CRD - - f8283c1d 2026-02-05T11:44:39-05:00 Add link to the dynamic-config-manager EP PR - - 1fece6c0 2026-02-05T10:44:12-05:00 Add DRAPartitionableDevices to TechPreviewNoUpgrade - - 2fc32cc5 2026-02-05T08:14:06-05:00 Added support for dynamic AWS dedicated hosts - - 40188ba8 2026-02-05T01:24:01-05:00 Move DynamicConfigurationManager back to TPNU - - 3643afa3 2026-02-05T10:36:51+08:00 Graduate MutableCSINodeAllocatableCount to GA - - a47ac128 2026-02-04T04:56:57-05:00 NE-2480: Add featuregate for Gateway API without OLM - - f39c09df 2026-01-28T14:06:41+01:00 Remove VolumeAttributesClass FeatureGate - -- cluster-dns-operator embedded-component 41a53fed36e6e99c7c9ceb3a699c3547ee5d9bb9 to 5d7c973968909d4155796363222f6edc001e19a3 - - e2b909a 2026-01-15T10:37:12-05:00 Use `trafficDistribution: PreferSameNode` for openshift-dns Service - -- cluster-ingress-operator embedded-component 77901360f18951f2a51d38acd1a07714f9183493 to abfb6fa7b9c95dc54fb3988e84297912ad88e0e4 - - 15e4cae 2026-02-06T10:35:49-05:00 Fix formatting in secret_hash.go - - 900e9f0 2026-02-06T09:44:08-03:00 bump go on base image - - ff08e12 2026-02-05T17:30:47-05:00 Move CanaryServingCertHashAnnotation to daemonset.go - - 9df597d 2026-02-05T17:29:11-05:00 Address PR review comments: use CanaryCertificateName and propagate context - - 1e5f504 2026-02-05T17:22:04-05:00 OCPBUGS-58145: reload serving cert on rotation - - 9fbaa11 2026-02-05T11:34:38-03:00 bump controller-runtime - - a2e1cd1 2026-02-05T11:15:27-03:00 bump k8s libraries to v0.35.0 Update Kubernetes libraries to v0.35.0. Due to the library version update: * Indirect dependencies were also updated * Minimal go version updated to 1.25, so updating build image accordingly - - 0de9609 2026-01-22T14:59:26-03:00 NO-JIRA: Add coderabbit to CIO - -- cluster-kube-apiserver-operator embedded-component fecf00cbeaf1fc18178bffddab767ee8f3d7e36f to cee7acb6c820b707fbb1e1dc01cef6c1971f146d - - 4cf4d0b 2026-02-09T12:48:47+03:00 Test encryption provider migration - - 2a40ac5 2026-02-09T12:48:41+03:00 Bump library-go - - 436f939 2026-02-05T15:15:23+05:30 vendor: update library-go to latest - - fe307df 2026-02-04T19:05:31+05:30 CNTRLPLANE-2247: Add KMS TestKMSEncryptionOnOff e2e test - - b9d2f86 2026-01-22T11:52:23Z remove kube-apiserver user from crb - -- cluster-kube-scheduler-operator embedded-component b37b73a87e7a6612f3354c2ffc134a23a0a8c13c to 14c5fdcfc2602292e19cab8713e42accf94b593d - - 4746564 2026-02-12T15:26:40+05:30 Register preferred-host test suite in OTE and update documentation - - 6d5d557 2026-02-12T15:24:43+05:30 Refactor test utilities to eliminate code duplication - - c58aa5c 2026-02-03T20:12:57+05:30 Add Ginkgo-based e2e tests and parallel test suite - -- cluster-network-operator embedded-component f0bdee37451757734c3e84cb6c0a8646290c4ffa to 9d540eb7929f83879d3dafbcd1ae6cb1feca36b3 - - d69bd30 2025-08-04T16:54:19+02:00 silenced output of start-audit-log-rotation and made it ENV dependning instead - -- cluster-openshift-controller-manager-operator embedded-component a6ce1136e71ded4af3cb5e771435e098b5e30349 to 7634c413830a510ff942bd6886ffe5f79db707b4 - - 2e329e3 2026-02-03T12:30:47+01:00 CNTRLPLANE-2620: propagate global tls config to operand - - 5282921 2026-02-02T19:27:01+01:00 CNTRLPLANE-2620: vendor github.com/openshift/library-go/pkg/operator/configobserver - - 44f341c 2026-02-02T14:40:44+01:00 CNTRLPLANE-2620: bump github.com/openshift/library-go - -- kubernetes embedded-component 9d521311f5fb67dc43f49eeb728ee2c80976835a to 047d96223dd843e9d54bed59bc212d2e9122c56a - - bbdf0eb44 2026-02-06T13:54:27+01:00 UPSTREAM: 135629: selinux: Fix the controller to ignore finished pods - -- machine-config-operator embedded-component 067395ed863e0254c4e7ce85bf8bce7e464778bb to 7eb4793ae255b19327e781f66aaf1dbd3e5210c5 - - 64d3b69c 2026-02-13T13:16:27-05:00 bump openshift/client-go - - d98db2ff 2026-02-13T10:00:11-05:00 e2e: update boot image tests - - 604c1dae 2026-02-13T09:58:43-05:00 bootimage: enable opt-out for azure and vsphere - - 85764598 2026-02-12T10:44:04-05:00 OCPBUGS-76444: pkg/daemon/update: Remove conditional logic for kernel-rt-kvm - - a9c528d1 2026-02-12T09:00:42Z Make tls tests more stable - - 55ddcf86 2026-02-11T15:33:35-05:00 Bump openshift/api - - 5b2e93d4 2026-02-11T10:32:33-05:00 Fix cleanup verification timeouts in e2e-ocl tests - - 84eedc34 2026-02-11T09:09:01-05:00 copy binaries directly into final stage - - b8507587 2026-02-11T09:06:47-05:00 clear dnf cache to reduce image size - - 1cf8e054 2026-02-10T12:17:38-06:00 fix pull secret log spam make verify error - - b84815f0 2026-02-09T13:41:23Z Adapt boot images test cases to the new skew functionality - - 6ab5da81 2026-02-09T10:22:37Z MCO-2110: Migrate security tests - - 945c0af3 2026-02-06T14:51:16-05:00 Revert "Merge pull request #5586 from pablintino/dbus" - - 23650384 2026-02-05T15:31:31-05:00 crio: disable short_name_mode until we introduce ctrcfg api for it - - 6bde8f65 2026-02-05T13:39:36-05:00 node: add skew enforcement prometheus alert - - ed0b5ca8 2026-02-05T13:39:02-05:00 text/extended: add skew enforcement e2es - - 4d993aa6 2026-02-05T13:39:02-05:00 test/extended: refactor bootimage helpers - - b138090f 2026-02-05T12:07:53-05:00 hack: fix ami update script - - 6ef06dff 2026-02-05T00:54:41-05:00 feat: increase reserved memory for tnf masters - - 936c8e17 2026-02-04T13:15:09-05:00 hack: update ami script and list - - 24a0730d 2026-02-04T08:50:26-05:00 daemon: rewrite all systemd units when forcefile exists - - d89321d9 2026-02-02T10:51:18-05:00 Make TestImagePrunerErrors flexible to registry behavior changes - - 2277bea0 2026-01-30T14:21:59-05:00 operator: verify boot image controller state - - a16d81c4 2026-01-30T14:21:59-05:00 operator: add upgrade block unit tests - - e2b09f2a 2026-01-30T14:21:59-05:00 operator: block upgrades on skew violation - - c82370ae 2026-01-30T14:21:59-05:00 bootimage: update skew enforcement status - - 985f299c 2026-01-30T14:21:59-05:00 operator: add skew enforcement status unit tests - - 62becfc1 2026-01-30T14:21:59-05:00 operator: populate skew enforcement status - - aedd96ea 2026-01-29T23:46:05+01:00 OCPBUGS-63699: Remove MCD liveness probe - - 688d5dd1 2026-01-27T12:12:02+01:00 MCO-2065: Move systemctl execs to dbus calls - -- operator-framework-olm embedded-component fae41b2724eeab7a0e9b1ad89408bbbb36516fe2 to 811919f88bc3b8da4f97c6e6ca031258cc4fa13b - - 459f2fe9 2026-02-11T00:07:13Z :seedling: Bump go.podman.io/image/v5 from 5.38.0 to 5.39.1 (#3763) - - 81299149 2026-02-06T16:55:00-05:00 chore(deps): upgrade Go module dependencies (edge) (#473) - - 554de2ad 2026-02-06T16:55:00-05:00 Bump github.com/google/cel-go from 0.26.1 to 0.27.0 (#472) - - caa6e197 2026-02-06T16:55:00-05:00 move binary dependency management to bingo (#471) - - 9deb9d8a 2026-02-06T16:55:00-05:00 Bump sigs.k8s.io/controller-runtime (#470) - - 351eed19 2026-02-06T16:54:53-05:00 Fix k8s dependencies ci (#469) - - 5b805800 2026-02-06T16:54:38-05:00 fix(release) Issues faced with invalid latest tag after changes in goreleaser (#1901) - - 02a7f066 2026-02-06T16:54:38-05:00 fix CreateTemplateByType regression (#1899) - - 3b7ae219 2026-02-06T16:54:37-05:00 Bump github.com/operator-framework/api from 0.38.0 to 0.39.0 (#1900) - - ff328222 2026-02-06T16:54:37-05:00 chore(deps): upgrade Go module dependencies (edge) (#1897) - - 60763c02 2026-02-06T16:54:37-05:00 Bump github.com/onsi/gomega from 1.39.0 to 1.39.1 (#1895) - - 92ca3e1c 2026-02-06T16:54:37-05:00 Bump github.com/docker/cli (#1896) - - 550443d3 2026-02-06T16:54:37-05:00 Bump github.com/onsi/ginkgo/v2 from 2.27.5 to 2.28.1 (#1894) - - 5b9ccbc9 2026-02-06T16:54:36-05:00 Bump sigs.k8s.io/controller-runtime (#1893) - - bddef8d5 2026-02-06T16:54:36-05:00 Bump the k8s-dependencies with additional fixes (#1892) - - 01f01c89 2026-02-06T16:54:36-05:00 Bump github.com/docker/cli (#1890) - - 486368bc 2026-02-06T16:54:36-05:00 fix dropped :latest tag publication from migration to goreleaser v2.12 and go1.25 (#1891) - - e549c695 2026-02-06T16:54:36-05:00 upgraded github.com/operator-framework/operator-registry v1.62.0 => v1.63.0 (#3761) - - 8a49e5fd 2026-02-06T16:54:36-05:00 Add pedjak to OWNERS (#3760) - - 6c8852fe 2026-02-06T16:54:35-05:00 chore(deps): upgrade Go module dependencies (edge) (#3759) - - 275fbcf2 2026-02-06T16:54:35-05:00 fix: add OpenAPIModelName for PackageManifest to fix oc explain (#3755) - - e19d4286 2026-02-06T16:54:35-05:00 :seedling: Bump github.com/onsi/gomega from 1.39.0 to 1.39.1 (#3758) - - 561217b4 2026-02-06T16:54:35-05:00 :seedling: Bump github.com/onsi/ginkgo/v2 from 2.27.5 to 2.28.1 (#3757) - - 5d4b1b37 2026-02-06T16:54:35-05:00 fix: disable WatchListClient for envtest-based tests (#3756) - - ea7e0300 2026-02-06T16:54:34-05:00 :seedling: Bump sigs.k8s.io/controller-runtime (#3754) - - 2925d07f 2026-02-06T16:54:34-05:00 :seedling: Bump the k8s-dependencies group to 1.35 (#3743) - - 8bb814da 2026-02-06T16:54:22-05:00 fishing to see if testing explicitly for success will work for matrixed tests with fail-fast:false (#3752) - - 16ebb98d 2026-02-06T10:05:08+08:00 remove qe case of testing collect-profiles - - 82a07751 2026-02-05T18:29:54-03:00 UPSTREAM: : automate OCP-40945 - - 7b17a6ac 2026-02-05T02:30:31-03:00 tests: update OLMv0 QE cases - -- route-controller-manager embedded-component 2b9e93a5f0fc1e93090bbe34ce95f3b4ad5cff15 to 624742d93f3a7885cf7f70985f1e23ff60da580d - - 4ca0f15 2026-02-10T15:21:30-03:00 bump library-go version - - cd4fccc 2026-02-06T18:19:54-03:00 fix compilation error after bump k8s lib - - d65cfe0 2026-02-06T18:16:17-03:00 bump k8s libraries to v0.35.0 - -- oc image-amd64 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 to 8b0a043216f7ae608606afb5bdb0ce451561021e - - deaedbf2 2026-02-06T20:16:54-05:00 Revert "CNTRLPLANE-2656: Fixing oc client cases for microshift and metal ipv6 profiles" - - 82d41d0b 2026-02-05T11:33:56+05:30 CNTRLPLANE-2656: Add oc CLI e2e tests with OTE framework support - -- router image-amd64 d2db065ae452ecfdb482f0ac4c6778b0c0e48b7f to d8ed3559fd4808a4f10c927ba4a199d3fd5b84a2 - - c46d819 2026-02-11T09:03:56-03:00 update base image to OCP 4.22 - - cb8dba6 2026-02-10T09:19:25-03:00 disable WatchListClient featuregate - - b92c259 2026-02-05T11:24:23-03:00 bump k8s libraries to v0.35.0 - -- ovn-kubernetes image-amd64 1938041fd8f8c1fb5d376fa59faec1fef7614a92 to 2a9cd189db9c74dc678fcfca68473d6fdc278028 - - 7dd0e556 2026-01-27T15:00:53-08:00 skip new NetSeg Localnet test - - 245941b1 2026-01-27T20:09:36Z sync openshift/go.mod with upstream dependencies - - aaf3f757 2026-01-26T21:36:19+02:00 docs: add OVS Dynamic CPU Affinity feature documentation - - 1e68f901 2026-01-26T21:36:18+02:00 createFileWatcherFor: rename argument - - 9dccb75e 2026-01-26T21:36:18+02:00 vendor: go mod tidy && go mod vendor - - 31ea00c0 2026-01-26T21:36:18+02:00 unit-test: adjust to new logic - - da87ab85 2026-01-26T21:36:18+02:00 ovspinning: detect reservedSystemCPUs - - e6606173 2026-01-26T21:36:18+02:00 ovspinning: detect nonpinned cpus using podresourceAPI - - 23fdd5fd 2026-01-26T21:36:18+02:00 ovspinning: pass context - - 5ba2cc11 2026-01-26T21:36:18+02:00 package: podresourceAPI client - - c9a29b50 2026-01-24T17:46:28-08:00 Use promhttp handler for emitting metrics - - cbba98ef 2026-01-24T17:46:28-08:00 change from periodic interval to request-based metrics collection - - c01ff2ff 2026-01-23T11:42:00-05:00 Integrate Network Manager resolver everywhere - - 7f0a4df1 2026-01-22T18:20:05-05:00 Fixes shouldFilter with Dynamic UDN - - 64d6bc2e 2026-01-22T18:20:05-05:00 Adds support for CNC with Dynamic UDN - - 56202d01 2026-01-22T18:20:05-05:00 Fix syncNAD - - 6e8dee9a 2026-01-22T18:20:05-05:00 NodeHasNAD -> NodeHasNetwork Refactor - - 8d7a89b3 2026-01-22T18:20:05-05:00 simplify NAD controller dynamic logic - - 7daff06c 2026-01-22T18:20:05-05:00 Fixes releasing network IDs for filtered NADs - - ea687aab 2026-01-22T18:20:05-05:00 Simplify ref counting with NCC and D-UDN - - 87a20d77 2026-01-22T18:20:05-05:00 Refactor remote D-UDN handling (again) - - 1dcd01fe 2026-01-22T18:20:05-05:00 Move D-UDN status/metrics to NCC - - 998e916f 2026-01-22T18:20:05-05:00 Fix DoWithLock crash - - 3e160739 2026-01-22T18:20:05-05:00 Add better debug logging for NAD controller - - a6b34b3b 2026-01-22T18:20:05-05:00 Critical Dynamic UDN NAD controller fixes - - 4dae25a6 2026-01-22T18:20:05-05:00 Convert pod/egress ip trackers to register with nad controller - - 20411a9a 2026-01-22T18:20:05-05:00 Add .gocache to gitignore - - f9531483 2026-01-22T18:20:05-05:00 Add unit test for Dynamic UDN status update - - 09f8efbd 2026-01-22T18:20:05-05:00 Move Dynamic UDN status/metrics to nad controller - - c0add608 2026-01-22T18:20:05-05:00 Move the trackers and dynamic filtering to the nad_controller. - - c09fcf05 2026-01-22T18:20:05-05:00 Only reconcile remote nodes on start up once - - fda7f71d 2026-01-22T18:20:05-05:00 Refactor OnNetworkRefChange - - a797c8c6 2026-01-22T18:20:05-05:00 Optimize performance for tracker primary nad lookups - - 4e11aa41 2026-01-22T18:20:05-05:00 Updates unit test nodes with new transit topo anno - - 57d9cad8 2026-01-22T18:20:05-05:00 Add Dynamic UDN metrics - - a96d67b5 2026-01-22T18:20:05-05:00 Add status update for UDNs with dynamic allocation - - 70f4f131 2026-01-22T18:20:05-05:00 Change pod handling to not rely on active network - - f1ff2e7b 2026-01-22T18:20:05-05:00 Add unit test for UDN deletion grace period - - 08248fcb 2026-01-22T18:20:05-05:00 Skip service tests to "other node" - - 8725a93d 2026-01-22T18:20:05-05:00 Fixes remote node removal with UDN - - 3440f2ad 2026-01-22T18:20:05-05:00 Enable Dynamic UDN in CI for one lane - - 7abc582e 2026-01-22T17:14:12-05:00 Enable dynamic UDN allocation with kind/helm - - 950aba76 2026-01-22T17:12:59-05:00 Enable NAD on Node tracking in UDN controllers - - f841691e 2026-01-22T17:12:59-05:00 Fix UDN controller test framework - - 58a969c2 2026-01-22T17:12:59-05:00 Integrate the trackers into controller managers and nad controller - - 6e6201f0 2026-01-22T17:12:59-05:00 Adds EgressIPTracker - - 48de82d1 2026-01-22T17:12:59-05:00 Adds pod tracker controller - - db4ca916 2026-01-22T17:12:59-05:00 Move WatchFactory interface to API - - ea1d89fc 2026-01-22T17:12:58-05:00 Exposes new dynamic allocation config knobs - - 47400690 2026-01-22T11:56:47Z Add EVPN feature flag - - 4b85ee3f 2026-01-22T10:03:29+08:00 test: fix race condition in waitForRollout - - 9dd6dc8d 2026-01-20T21:14:15+09:00 add Internet Initiative Japan Inc. to ADOPTERS - - 765fbd9a 2026-01-16T13:03:26-05:00 codegen: fix script when GOPATH is not in PATH - - 19f191fc 2026-01-16T14:59:51+01:00 Move common helpers into util/network-connect - - 9ca888f5 2026-01-16T14:59:51+01:00 ci: increase network-segmentation lane timeout to 190 minutes - - 2dc80388 2026-01-16T14:59:51+01:00 e2e: support multiple CNCs with different connect subnets - - c17da56e 2026-01-16T14:59:51+01:00 e2e: add ClusterNetworkConnect OVN controller connectivity tests - - 5a69fb5e 2026-01-16T14:59:51+01:00 making the e2e utils global for reusability - - b101a3d0 2026-01-16T14:59:51+01:00 Add controller integration tests - - db5e941f 2026-01-16T14:59:51+01:00 STEP4: Add LRSRs to connect router - - 17f77b3a 2026-01-16T14:59:50+01:00 STEP3: Add routing policies to connected network routers - - 64279f6e 2026-01-16T14:59:50+01:00 Add GetNetworkScopedSwitchToRouterPortName util - - 7dc67800 2026-01-16T14:59:23+01:00 STEP2: Create patch ports to connect routers together - - e371fc55 2026-01-16T14:54:10+01:00 Add GetNetworkByID util to network manager - - 8f60a8b5 2026-01-16T14:54:10+01:00 Add static subnet and tunnel key generator helpers for CNC - - 4291607f 2026-01-16T14:54:10+01:00 Add COPP protection for connect router - - 56db7ae7 2026-01-16T14:53:01+01:00 STEP1: Create Connect Router for CNC - - c3666788 2026-01-16T12:33:21+01:00 Add network connect controller plumbing - - 622a3f23 2026-01-15T19:18:31-08:00 Skip Node Shutdown and OVN node pod restart sync tests - - 80db3f2c 2026-01-15T19:18:31-08:00 OpenShift E2E: Add deployment config timeout support - - 118948b6 2026-01-15T19:18:31-08:00 Skip net-seg overlapping CIDRs tests - - cb301f71 2026-01-15T19:18:31-08:00 skip ClusterNetworkConnect: API validations tests - - d1963911 2026-01-15T19:18:31-08:00 Bump k8s.io to v1.34.1 - - 9770e116 2026-01-15T19:18:14-08:00 infraprovider: Add openshift provider - - 40cf2ff1 2026-01-15T19:18:09-08:00 Add o/test-exts - - 34337f0a 2026-01-15T22:15:34+01:00 Add RBAC for CNCs access from ovnkube-node pod - - 1b665e97 2026-01-15T22:15:33+01:00 Add factory and clientset settings for ovnkube-controller - - cdb9e9a3 2026-01-15T21:59:47+09:00 fix golang builder image registry path in docker workflow - - 75e38626 2026-01-15T02:46:17-05:00 test: unskip Services fallback to local terminating endpoints test - - 2c3671c4 2026-01-15T02:46:17-05:00 for LGW with ETP=Local have different error code for l3 and l2 - - 0dc90599 2026-01-14T10:34:17+01:00 Use labels to skip tests - - d6501811 2026-01-13T16:13:28+01:00 Expose EVPN fields via NetInfo utils - - 6b33ee67 2026-01-13T16:13:28+01:00 Add NetConf fields for EVPN - - 13415218 2026-01-13T16:13:28+01:00 Add E2E test for VTEP API Validations - - a1fe31d9 2026-01-13T16:13:28+01:00 Add E2E test for CUDN-EVPN validation - - 69647db7 2026-01-13T16:13:28+01:00 Add VTEP API reference docs - - 9c30fc27 2026-01-13T16:13:28+01:00 Generate VTEP Yaml - - 6641c7c3 2026-01-13T16:13:28+01:00 Add VTEP CRD - - 155779fa 2026-01-13T16:13:28+01:00 Update CUDN API reference docs - - fc37829e 2026-01-13T16:13:28+01:00 Generate CUDN Yaml - - 00ed2851 2026-01-13T16:13:28+01:00 Add EVPN fields to CUDN - - ecb3b72c 2026-01-13T16:13:28+01:00 Update tests for noOverlay field - - 00f1291f 2026-01-13T16:13:28+01:00 Update API reference docs - - 2c3ab32b 2026-01-13T16:13:28+01:00 Re-generate CUDN YAML - - 953bb6ac 2026-01-13T16:13:28+01:00 Rename noOverlayOptions to noOverlay - - 06486fa7 2026-01-13T16:13:28+01:00 Cleanup codegen files before regenerating - - 5ffc1bef 2026-01-12T16:25:38-05:00 Bug fix: Skip BridgeEIPAddrManager in DPU-host mode - - 106ea801 2026-01-12T11:20:41-05:00 iprulemanager: add mark check when comparing netlink rule equality - - e60b1cdb 2026-01-12T11:20:41-05:00 iprulemanager: remove string operations from areNetlinkRulesEqual - - 10c9c2a8 2026-01-09T06:44:18-05:00 Addressing trozet feedback - - 560aee20 2026-01-08T19:26:03-05:00 Attempt to capture and store pprof data - - ac29faf5 2026-01-08T19:26:03-05:00 Adding kubelet-density-cni performance workload - - 3c1c3967 2026-01-08T18:33:55+08:00 add eip e2e case on namespace/pod labels update - - 67f9fbf8 2026-01-08T10:54:40+01:00 bump up frr-k8s and frr image versions - - 0c3604e3 2026-01-08T10:05:13+01:00 Use interface index for IPv6 zone when sending unsolicited neighbor advertisements - - 4e343bc4 2026-01-07T15:27:04-08:00 always set arp sysctl configuration for multiple same network interfaces - - e200f2d1 2026-01-07T15:10:41-08:00 docs/multi-homing: support of multiple interfaces in the same network - - 36ddd004 2026-01-06T12:44:28-08:00 e2e: add e2e test case for Pod with multiple same secondary UDN - - 76d27a29 2026-01-06T12:44:28-08:00 add ECMP pod route for multiple same secondary UDN interfaces - - d0120301 2026-01-06T08:06:51-08:00 support ipamClaim for multiple same UDN on the pod - - 1597b780 2026-01-06T08:06:51-08:00 add additional pod-if-name external-id for Pod OVS interface - - 66cf0639 2026-01-06T08:06:51-08:00 support pod with multiple same secondary UDN - - 3c0e3d2d 2026-01-06T13:38:45Z Updating ose-ovn-kubernetes-base-container image to be consistent with ART for 4.22 Reconciling with https://github.com/openshift/ocp-build-data/tree/532305ad2d84f57355ac03b308650bcc5a8d7740/images/ovn-kubernetes-base.yml - - 2ea53bd1 2026-01-06T12:10:29+08:00 node: fix DeleteEndpointSlice namespace deletion race condition - - 61cc216e 2025-12-30T07:36:52-05:00 add nodePort etp=local e2e test for UDN and default network when advertised BGP routes - - 2d4a479c 2025-12-29T15:20:13+01:00 egressip: Skip bridge configuration for secondary network IPs - - d1c55f1c 2025-12-29T11:57:24+01:00 fix(localnet, ipamless): Prevent LSP deletion on sync - - 47cecd9c 2025-12-29T10:13:56+02:00 dist, fedora: Use the right package manager - - 54bc8959 2025-12-28T12:18:46+02:00 dist: Use the project golang container image - - 7b413f85 2025-12-22T18:28:19+01:00 Re-order upgrade image step - - 542bbb37 2025-12-22T17:40:27+01:00 Allow CI workflow dispatcher on release-1.2 branch - - 0b7607fe 2025-12-22T17:40:27+01:00 Update release docs to mention new cadance - - 32287237 2025-12-22T17:40:27+01:00 Update helm-chart version to 1.2.0 - - 8571ba40 2025-12-22T17:40:26+01:00 Change OVN_DAEMONSET_VERSION to 1.2.0 - - 69e28d98 2025-12-22T16:11:30+01:00 OVN-Kubernetes 1.2 release - - 727a0e82 2025-12-22T16:11:29+01:00 Add deprecation warning signs on docs/scripts for central mode - - aa6c1c86 2025-12-22T13:42:08+01:00 Update L2 topology to reflect new TR - - c75a25a0 2025-12-22T09:19:04+08:00 Update libovsdb bindings to ovn 25.09 - - f50653ee 2025-12-21T14:45:36-08:00 minor updates on unit test cases - - 988ace17 2025-12-21T14:45:36-08:00 metrics: move OVN/OVS metrics update from periodic interval to request-based - - 9e7c7180 2025-12-19T15:27:54-05:00 Adds level-driven, UDN aware dev docs - - 5b01e17b 2025-12-19T15:27:54-05:00 Refactor NADController notifying into level driven reconciler - - e8fb693f 2025-12-19T19:29:18+01:00 Skip FRR bfdd process Coredumps - - f10deeba 2025-12-19T14:08:58+01:00 [retry] Make an exception for pods and retry them infinitely. - - 07b68bb6 2025-12-19T09:23:34+01:00 fix template referencing gatewayOps instead of gatewayOpts variable - - d22f59da 2025-12-18T17:15:49-05:00 OKEP 5674: DPU Healthcheck - - bbc03ca8 2025-12-17T17:08:11Z egressip: handle LinkNotFoundError gracefully in isEgressIPOnLink - - 8c83e326 2025-12-10T07:43:41+01:00 fix(e2e, kubevirt): Wait for IP after VM restart in ipamless localnet tests - - 5856fb09 2025-09-02T12:42:39+01:00 fix: drop prometheus operator CRDs and make CRs configurable - -- kubernetes image-amd64 9d521311f5fb67dc43f49eeb728ee2c80976835a to 047d96223dd843e9d54bed59bc212d2e9122c56a - - bbdf0eb44 2026-02-06T13:54:27+01:00 UPSTREAM: 135629: selinux: Fix the controller to ignore finished pods - -- oc image-arm64 7e80dbab5a9ce563cd4f78f2874f18e4664767f5 to 7f88fe2132f6969e1686808e5301aa3c808d4a45 - - 1de915e0 2026-02-12T14:47:52-05:00 images/tools: Install subscription-manager - - 12d5804c 2026-02-11T13:45:48-05:00 OCPBUGS-76394: Install subscription-manager in cli image - - deaedbf2 2026-02-06T20:16:54-05:00 Revert "CNTRLPLANE-2656: Fixing oc client cases for microshift and metal ipv6 profiles" - - 82d41d0b 2026-02-05T11:33:56+05:30 CNTRLPLANE-2656: Add oc CLI e2e tests with OTE framework support - -- router image-arm64 d2db065ae452ecfdb482f0ac4c6778b0c0e48b7f to d8ed3559fd4808a4f10c927ba4a199d3fd5b84a2 - - c46d819 2026-02-11T09:03:56-03:00 update base image to OCP 4.22 - - cb8dba6 2026-02-10T09:19:25-03:00 disable WatchListClient featuregate - - b92c259 2026-02-05T11:24:23-03:00 bump k8s libraries to v0.35.0 - -- ovn-kubernetes image-arm64 1938041fd8f8c1fb5d376fa59faec1fef7614a92 to 2a9cd189db9c74dc678fcfca68473d6fdc278028 - - 7dd0e556 2026-01-27T15:00:53-08:00 skip new NetSeg Localnet test - - 245941b1 2026-01-27T20:09:36Z sync openshift/go.mod with upstream dependencies - - aaf3f757 2026-01-26T21:36:19+02:00 docs: add OVS Dynamic CPU Affinity feature documentation - - 1e68f901 2026-01-26T21:36:18+02:00 createFileWatcherFor: rename argument - - 9dccb75e 2026-01-26T21:36:18+02:00 vendor: go mod tidy && go mod vendor - - 31ea00c0 2026-01-26T21:36:18+02:00 unit-test: adjust to new logic - - da87ab85 2026-01-26T21:36:18+02:00 ovspinning: detect reservedSystemCPUs - - e6606173 2026-01-26T21:36:18+02:00 ovspinning: detect nonpinned cpus using podresourceAPI - - 23fdd5fd 2026-01-26T21:36:18+02:00 ovspinning: pass context - - 5ba2cc11 2026-01-26T21:36:18+02:00 package: podresourceAPI client - - c9a29b50 2026-01-24T17:46:28-08:00 Use promhttp handler for emitting metrics - - cbba98ef 2026-01-24T17:46:28-08:00 change from periodic interval to request-based metrics collection - - c01ff2ff 2026-01-23T11:42:00-05:00 Integrate Network Manager resolver everywhere - - 7f0a4df1 2026-01-22T18:20:05-05:00 Fixes shouldFilter with Dynamic UDN - - 64d6bc2e 2026-01-22T18:20:05-05:00 Adds support for CNC with Dynamic UDN - - 56202d01 2026-01-22T18:20:05-05:00 Fix syncNAD - - 6e8dee9a 2026-01-22T18:20:05-05:00 NodeHasNAD -> NodeHasNetwork Refactor - - 8d7a89b3 2026-01-22T18:20:05-05:00 simplify NAD controller dynamic logic - - 7daff06c 2026-01-22T18:20:05-05:00 Fixes releasing network IDs for filtered NADs - - ea687aab 2026-01-22T18:20:05-05:00 Simplify ref counting with NCC and D-UDN - - 87a20d77 2026-01-22T18:20:05-05:00 Refactor remote D-UDN handling (again) - - 1dcd01fe 2026-01-22T18:20:05-05:00 Move D-UDN status/metrics to NCC - - 998e916f 2026-01-22T18:20:05-05:00 Fix DoWithLock crash - - 3e160739 2026-01-22T18:20:05-05:00 Add better debug logging for NAD controller - - a6b34b3b 2026-01-22T18:20:05-05:00 Critical Dynamic UDN NAD controller fixes - - 4dae25a6 2026-01-22T18:20:05-05:00 Convert pod/egress ip trackers to register with nad controller - - 20411a9a 2026-01-22T18:20:05-05:00 Add .gocache to gitignore - - f9531483 2026-01-22T18:20:05-05:00 Add unit test for Dynamic UDN status update - - 09f8efbd 2026-01-22T18:20:05-05:00 Move Dynamic UDN status/metrics to nad controller - - c0add608 2026-01-22T18:20:05-05:00 Move the trackers and dynamic filtering to the nad_controller. - - c09fcf05 2026-01-22T18:20:05-05:00 Only reconcile remote nodes on start up once - - fda7f71d 2026-01-22T18:20:05-05:00 Refactor OnNetworkRefChange - - a797c8c6 2026-01-22T18:20:05-05:00 Optimize performance for tracker primary nad lookups - - 4e11aa41 2026-01-22T18:20:05-05:00 Updates unit test nodes with new transit topo anno - - 57d9cad8 2026-01-22T18:20:05-05:00 Add Dynamic UDN metrics - - a96d67b5 2026-01-22T18:20:05-05:00 Add status update for UDNs with dynamic allocation - - 70f4f131 2026-01-22T18:20:05-05:00 Change pod handling to not rely on active network - - f1ff2e7b 2026-01-22T18:20:05-05:00 Add unit test for UDN deletion grace period - - 08248fcb 2026-01-22T18:20:05-05:00 Skip service tests to "other node" - - 8725a93d 2026-01-22T18:20:05-05:00 Fixes remote node removal with UDN - - 3440f2ad 2026-01-22T18:20:05-05:00 Enable Dynamic UDN in CI for one lane - - 7abc582e 2026-01-22T17:14:12-05:00 Enable dynamic UDN allocation with kind/helm - - 950aba76 2026-01-22T17:12:59-05:00 Enable NAD on Node tracking in UDN controllers - - f841691e 2026-01-22T17:12:59-05:00 Fix UDN controller test framework - - 58a969c2 2026-01-22T17:12:59-05:00 Integrate the trackers into controller managers and nad controller - - 6e6201f0 2026-01-22T17:12:59-05:00 Adds EgressIPTracker - - 48de82d1 2026-01-22T17:12:59-05:00 Adds pod tracker controller - - db4ca916 2026-01-22T17:12:59-05:00 Move WatchFactory interface to API - - ea1d89fc 2026-01-22T17:12:58-05:00 Exposes new dynamic allocation config knobs - - 47400690 2026-01-22T11:56:47Z Add EVPN feature flag - - 4b85ee3f 2026-01-22T10:03:29+08:00 test: fix race condition in waitForRollout - - 9dd6dc8d 2026-01-20T21:14:15+09:00 add Internet Initiative Japan Inc. to ADOPTERS - - 765fbd9a 2026-01-16T13:03:26-05:00 codegen: fix script when GOPATH is not in PATH - - 19f191fc 2026-01-16T14:59:51+01:00 Move common helpers into util/network-connect - - 9ca888f5 2026-01-16T14:59:51+01:00 ci: increase network-segmentation lane timeout to 190 minutes - - 2dc80388 2026-01-16T14:59:51+01:00 e2e: support multiple CNCs with different connect subnets - - c17da56e 2026-01-16T14:59:51+01:00 e2e: add ClusterNetworkConnect OVN controller connectivity tests - - 5a69fb5e 2026-01-16T14:59:51+01:00 making the e2e utils global for reusability - - b101a3d0 2026-01-16T14:59:51+01:00 Add controller integration tests - - db5e941f 2026-01-16T14:59:51+01:00 STEP4: Add LRSRs to connect router - - 17f77b3a 2026-01-16T14:59:50+01:00 STEP3: Add routing policies to connected network routers - - 64279f6e 2026-01-16T14:59:50+01:00 Add GetNetworkScopedSwitchToRouterPortName util - - 7dc67800 2026-01-16T14:59:23+01:00 STEP2: Create patch ports to connect routers together - - e371fc55 2026-01-16T14:54:10+01:00 Add GetNetworkByID util to network manager - - 8f60a8b5 2026-01-16T14:54:10+01:00 Add static subnet and tunnel key generator helpers for CNC - - 4291607f 2026-01-16T14:54:10+01:00 Add COPP protection for connect router - - 56db7ae7 2026-01-16T14:53:01+01:00 STEP1: Create Connect Router for CNC - - c3666788 2026-01-16T12:33:21+01:00 Add network connect controller plumbing - - 622a3f23 2026-01-15T19:18:31-08:00 Skip Node Shutdown and OVN node pod restart sync tests - - 80db3f2c 2026-01-15T19:18:31-08:00 OpenShift E2E: Add deployment config timeout support - - 118948b6 2026-01-15T19:18:31-08:00 Skip net-seg overlapping CIDRs tests - - cb301f71 2026-01-15T19:18:31-08:00 skip ClusterNetworkConnect: API validations tests - - d1963911 2026-01-15T19:18:31-08:00 Bump k8s.io to v1.34.1 - - 9770e116 2026-01-15T19:18:14-08:00 infraprovider: Add openshift provider - - 40cf2ff1 2026-01-15T19:18:09-08:00 Add o/test-exts - - 34337f0a 2026-01-15T22:15:34+01:00 Add RBAC for CNCs access from ovnkube-node pod - - 1b665e97 2026-01-15T22:15:33+01:00 Add factory and clientset settings for ovnkube-controller - - cdb9e9a3 2026-01-15T21:59:47+09:00 fix golang builder image registry path in docker workflow - - 75e38626 2026-01-15T02:46:17-05:00 test: unskip Services fallback to local terminating endpoints test - - 2c3671c4 2026-01-15T02:46:17-05:00 for LGW with ETP=Local have different error code for l3 and l2 - - 0dc90599 2026-01-14T10:34:17+01:00 Use labels to skip tests - - d6501811 2026-01-13T16:13:28+01:00 Expose EVPN fields via NetInfo utils - - 6b33ee67 2026-01-13T16:13:28+01:00 Add NetConf fields for EVPN - - 13415218 2026-01-13T16:13:28+01:00 Add E2E test for VTEP API Validations - - a1fe31d9 2026-01-13T16:13:28+01:00 Add E2E test for CUDN-EVPN validation - - 69647db7 2026-01-13T16:13:28+01:00 Add VTEP API reference docs - - 9c30fc27 2026-01-13T16:13:28+01:00 Generate VTEP Yaml - - 6641c7c3 2026-01-13T16:13:28+01:00 Add VTEP CRD - - 155779fa 2026-01-13T16:13:28+01:00 Update CUDN API reference docs - - fc37829e 2026-01-13T16:13:28+01:00 Generate CUDN Yaml - - 00ed2851 2026-01-13T16:13:28+01:00 Add EVPN fields to CUDN - - ecb3b72c 2026-01-13T16:13:28+01:00 Update tests for noOverlay field - - 00f1291f 2026-01-13T16:13:28+01:00 Update API reference docs - - 2c3ab32b 2026-01-13T16:13:28+01:00 Re-generate CUDN YAML - - 953bb6ac 2026-01-13T16:13:28+01:00 Rename noOverlayOptions to noOverlay - - 06486fa7 2026-01-13T16:13:28+01:00 Cleanup codegen files before regenerating - - 5ffc1bef 2026-01-12T16:25:38-05:00 Bug fix: Skip BridgeEIPAddrManager in DPU-host mode - - 106ea801 2026-01-12T11:20:41-05:00 iprulemanager: add mark check when comparing netlink rule equality - - e60b1cdb 2026-01-12T11:20:41-05:00 iprulemanager: remove string operations from areNetlinkRulesEqual - - 10c9c2a8 2026-01-09T06:44:18-05:00 Addressing trozet feedback - - 560aee20 2026-01-08T19:26:03-05:00 Attempt to capture and store pprof data - - ac29faf5 2026-01-08T19:26:03-05:00 Adding kubelet-density-cni performance workload - - 3c1c3967 2026-01-08T18:33:55+08:00 add eip e2e case on namespace/pod labels update - - 67f9fbf8 2026-01-08T10:54:40+01:00 bump up frr-k8s and frr image versions - - 0c3604e3 2026-01-08T10:05:13+01:00 Use interface index for IPv6 zone when sending unsolicited neighbor advertisements - - 4e343bc4 2026-01-07T15:27:04-08:00 always set arp sysctl configuration for multiple same network interfaces - - e200f2d1 2026-01-07T15:10:41-08:00 docs/multi-homing: support of multiple interfaces in the same network - - 36ddd004 2026-01-06T12:44:28-08:00 e2e: add e2e test case for Pod with multiple same secondary UDN - - 76d27a29 2026-01-06T12:44:28-08:00 add ECMP pod route for multiple same secondary UDN interfaces - - d0120301 2026-01-06T08:06:51-08:00 support ipamClaim for multiple same UDN on the pod - - 1597b780 2026-01-06T08:06:51-08:00 add additional pod-if-name external-id for Pod OVS interface - - 66cf0639 2026-01-06T08:06:51-08:00 support pod with multiple same secondary UDN - - 3c0e3d2d 2026-01-06T13:38:45Z Updating ose-ovn-kubernetes-base-container image to be consistent with ART for 4.22 Reconciling with https://github.com/openshift/ocp-build-data/tree/532305ad2d84f57355ac03b308650bcc5a8d7740/images/ovn-kubernetes-base.yml - - 2ea53bd1 2026-01-06T12:10:29+08:00 node: fix DeleteEndpointSlice namespace deletion race condition - - 61cc216e 2025-12-30T07:36:52-05:00 add nodePort etp=local e2e test for UDN and default network when advertised BGP routes - - 2d4a479c 2025-12-29T15:20:13+01:00 egressip: Skip bridge configuration for secondary network IPs - - d1c55f1c 2025-12-29T11:57:24+01:00 fix(localnet, ipamless): Prevent LSP deletion on sync - - 47cecd9c 2025-12-29T10:13:56+02:00 dist, fedora: Use the right package manager - - 54bc8959 2025-12-28T12:18:46+02:00 dist: Use the project golang container image - - 7b413f85 2025-12-22T18:28:19+01:00 Re-order upgrade image step - - 542bbb37 2025-12-22T17:40:27+01:00 Allow CI workflow dispatcher on release-1.2 branch - - 0b7607fe 2025-12-22T17:40:27+01:00 Update release docs to mention new cadance - - 32287237 2025-12-22T17:40:27+01:00 Update helm-chart version to 1.2.0 - - 8571ba40 2025-12-22T17:40:26+01:00 Change OVN_DAEMONSET_VERSION to 1.2.0 - - 69e28d98 2025-12-22T16:11:30+01:00 OVN-Kubernetes 1.2 release - - 727a0e82 2025-12-22T16:11:29+01:00 Add deprecation warning signs on docs/scripts for central mode - - aa6c1c86 2025-12-22T13:42:08+01:00 Update L2 topology to reflect new TR - - c75a25a0 2025-12-22T09:19:04+08:00 Update libovsdb bindings to ovn 25.09 - - f50653ee 2025-12-21T14:45:36-08:00 minor updates on unit test cases - - 988ace17 2025-12-21T14:45:36-08:00 metrics: move OVN/OVS metrics update from periodic interval to request-based - - 9e7c7180 2025-12-19T15:27:54-05:00 Adds level-driven, UDN aware dev docs - - 5b01e17b 2025-12-19T15:27:54-05:00 Refactor NADController notifying into level driven reconciler - - e8fb693f 2025-12-19T19:29:18+01:00 Skip FRR bfdd process Coredumps - - f10deeba 2025-12-19T14:08:58+01:00 [retry] Make an exception for pods and retry them infinitely. - - 07b68bb6 2025-12-19T09:23:34+01:00 fix template referencing gatewayOps instead of gatewayOpts variable - - d22f59da 2025-12-18T17:15:49-05:00 OKEP 5674: DPU Healthcheck - - bbc03ca8 2025-12-17T17:08:11Z egressip: handle LinkNotFoundError gracefully in isEgressIPOnLink - - 8c83e326 2025-12-10T07:43:41+01:00 fix(e2e, kubevirt): Wait for IP after VM restart in ipamless localnet tests - - 5856fb09 2025-09-02T12:42:39+01:00 fix: drop prometheus operator CRDs and make CRs configurable - -- kubernetes image-arm64 9d521311f5fb67dc43f49eeb728ee2c80976835a to 047d96223dd843e9d54bed59bc212d2e9122c56a - - bbdf0eb44 2026-02-06T13:54:27+01:00 UPSTREAM: 135629: selinux: Fix the controller to ignore finished pods - From 7cc5cf400c6e029117b31b81cc0f2d8feb81cfe3 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:12:29 +0100 Subject: [PATCH 08/15] update etcd/go.mod --- etcd/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etcd/go.mod b/etcd/go.mod index 9a1f94c56f..5397d665c3 100644 --- a/etcd/go.mod +++ b/etcd/go.mod @@ -35,6 +35,7 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/run v1.2.0 // indirect github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/squat/generic-device-plugin v0.0.0-20251019101956-043a51e18f31 // indirect @@ -94,7 +95,6 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.66.1 // indirect From 55f143c29545194603318f14bdabcec36fca0266 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:12:36 +0100 Subject: [PATCH 09/15] update etcd/vendor --- .../openshift/library-go/pkg/crypto/crypto.go | 50 +-- .../github.com/spf13/cobra/.golangci.yml | 28 +- etcd/vendor/github.com/spf13/cobra/README.md | 24 +- .../vendor/github.com/spf13/cobra/SECURITY.md | 105 +++++ etcd/vendor/github.com/spf13/cobra/command.go | 11 +- .../github.com/spf13/cobra/completions.go | 19 +- .../golang.org/x/net/context/context.go | 70 ++-- etcd/vendor/golang.org/x/net/html/escape.go | 2 +- etcd/vendor/golang.org/x/net/html/parse.go | 57 ++- etcd/vendor/golang.org/x/net/html/render.go | 2 +- etcd/vendor/golang.org/x/net/http2/config.go | 63 ++- .../golang.org/x/net/http2/config_go124.go | 61 --- .../golang.org/x/net/http2/config_go125.go | 15 + .../golang.org/x/net/http2/config_go126.go | 15 + .../x/net/http2/config_pre_go124.go | 16 - etcd/vendor/golang.org/x/net/http2/frame.go | 101 +++-- etcd/vendor/golang.org/x/net/http2/gotrack.go | 17 +- etcd/vendor/golang.org/x/net/http2/http2.go | 35 +- etcd/vendor/golang.org/x/net/http2/server.go | 143 ++++--- etcd/vendor/golang.org/x/net/http2/timer.go | 20 - .../golang.org/x/net/http2/transport.go | 196 +++++----- .../golang.org/x/net/http2/writesched.go | 67 +++- ...rity.go => writesched_priority_rfc7540.go} | 109 +++--- .../net/http2/writesched_priority_rfc9218.go | 209 ++++++++++ .../x/net/http2/writesched_roundrobin.go | 2 +- .../x/net/internal/httpcommon/request.go | 4 +- .../golang.org/x/net/internal/socks/socks.go | 2 +- .../golang.org/x/sync/errgroup/errgroup.go | 2 +- .../golang.org/x/sys/unix/affinity_linux.go | 9 + etcd/vendor/golang.org/x/sys/unix/fdset.go | 4 +- .../golang.org/x/sys/unix/ifreq_linux.go | 4 +- etcd/vendor/golang.org/x/sys/unix/mkall.sh | 1 + etcd/vendor/golang.org/x/sys/unix/mkerrors.sh | 2 + .../golang.org/x/sys/unix/syscall_linux.go | 10 +- .../golang.org/x/sys/unix/syscall_netbsd.go | 17 + .../golang.org/x/sys/unix/zerrors_linux.go | 359 ++++++++++++++++++ .../golang.org/x/sys/unix/zsyscall_linux.go | 10 + .../golang.org/x/sys/unix/ztypes_linux.go | 31 ++ .../x/sys/windows/syscall_windows.go | 17 + .../golang.org/x/sys/windows/types_windows.go | 92 +++++ .../x/sys/windows/zsyscall_windows.go | 55 +++ etcd/vendor/golang.org/x/term/terminal.go | 6 +- .../golang.org/x/text/unicode/bidi/core.go | 11 +- .../gopkg.in/evanphx/json-patch.v4/README.md | 8 +- .../gopkg.in/evanphx/json-patch.v4/patch.go | 105 +++-- etcd/vendor/modules.txt | 32 +- .../internal/golang/encoding/json/decode.go | 43 ++- .../internal/golang/encoding/json/encode.go | 63 ++- .../internal/golang/encoding/json/stream.go | 4 +- 49 files changed, 1699 insertions(+), 629 deletions(-) create mode 100644 etcd/vendor/github.com/spf13/cobra/SECURITY.md delete mode 100644 etcd/vendor/golang.org/x/net/http2/config_go124.go create mode 100644 etcd/vendor/golang.org/x/net/http2/config_go125.go create mode 100644 etcd/vendor/golang.org/x/net/http2/config_go126.go delete mode 100644 etcd/vendor/golang.org/x/net/http2/config_pre_go124.go delete mode 100644 etcd/vendor/golang.org/x/net/http2/timer.go rename etcd/vendor/golang.org/x/net/http2/{writesched_priority.go => writesched_priority_rfc7540.go} (77%) create mode 100644 etcd/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go diff --git a/etcd/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go b/etcd/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go index 33a09ae16e..bff6155c2f 100644 --- a/etcd/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go +++ b/etcd/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go @@ -242,35 +242,41 @@ func ValidCipherSuites() []string { sort.Strings(validCipherSuites) return validCipherSuites } + +// DefaultCiphers returns the default cipher suites for TLS connections. +// +// RECOMMENDATION: Instead of relying on this function directly, consumers should respect +// TLSSecurityProfile settings from one of the OpenShift API configuration resources: +// - For API servers: Use apiserver.config.openshift.io/cluster Spec.TLSSecurityProfile +// - For ingress controllers: Use operator.openshift.io/v1 IngressController Spec.TLSSecurityProfile +// - For kubelet: Use machineconfiguration.openshift.io/v1 KubeletConfig Spec.TLSSecurityProfile +// +// These API resources allow cluster administrators to choose between Old, Intermediate, +// Modern, or Custom TLS profiles. Components should observe these settings. func DefaultCiphers() []uint16 { - // HTTP/2 mandates TLS 1.2 or higher with an AEAD cipher - // suite (GCM, Poly1305) and ephemeral key exchange (ECDHE, DHE) for - // perfect forward secrecy. Servers may provide additional cipher - // suites for backwards compatibility with HTTP/1.1 clients. - // See RFC7540, section 9.2 (Use of TLS Features) and Appendix A - // (TLS 1.2 Cipher Suite Black List). + // Aligned with intermediate profile of the 5.7 version of the Mozilla Server + // Side TLS guidelines found at: https://ssl-config.mozilla.org/guidelines/5.7.json + // + // Latest guidelines: https://ssl-config.mozilla.org/guidelines/latest.json + // + // This profile provides strong security with wide compatibility. + // It requires TLS 1.2+ and uses only AEAD cipher suites (GCM, ChaCha20-Poly1305) + // with ECDHE key exchange for perfect forward secrecy. + // + // All CBC-mode ciphers have been removed due to padding oracle vulnerabilities. + // All RSA key exchange ciphers have been removed due to lack of perfect forward secrecy. + // + // HTTP/2 compliance: All ciphers are compliant with RFC7540, section 9.2. return []uint16{ + // TLS 1.2 cipher suites with ECDHE + AEAD tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // required by http/2 + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // required by HTTP/2 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // forbidden by http/2, not flagged by http2isBadCipher() in go1.8 - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // forbidden by http/2, not flagged by http2isBadCipher() in go1.8 - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 - tls.TLS_RSA_WITH_AES_128_GCM_SHA256, // forbidden by http/2 - tls.TLS_RSA_WITH_AES_256_GCM_SHA384, // forbidden by http/2 - // the next one is in the intermediate suite, but go1.8 http2isBadCipher() complains when it is included at the recommended index - // because it comes after ciphers forbidden by the http/2 spec - // tls.TLS_RSA_WITH_AES_128_CBC_SHA256, - // tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, // forbidden by http/2, disabled to mitigate SWEET32 attack - // tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, // forbidden by http/2, disabled to mitigate SWEET32 attack - tls.TLS_RSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 - tls.TLS_RSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 + + // TLS 1.3 cipher suites (negotiated automatically, not configurable) tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384, tls.TLS_CHACHA20_POLY1305_SHA256, diff --git a/etcd/vendor/github.com/spf13/cobra/.golangci.yml b/etcd/vendor/github.com/spf13/cobra/.golangci.yml index 2c8f4808c1..6acf8ab1ea 100644 --- a/etcd/vendor/github.com/spf13/cobra/.golangci.yml +++ b/etcd/vendor/github.com/spf13/cobra/.golangci.yml @@ -12,14 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. +version: "2" + run: - deadline: 5m + timeout: 5m + +formatters: + enable: + - gofmt + - goimports linters: - disable-all: true + default: none enable: #- bodyclose - # - deadcode ! deprecated since v1.49.0; replaced by 'unused' #- depguard #- dogsled #- dupl @@ -30,28 +36,24 @@ linters: - goconst - gocritic #- gocyclo - - gofmt - - goimports - #- gomnd #- goprintffuncname - gosec - - gosimple - govet - ineffassign #- lll - misspell + #- mnd #- nakedret #- noctx - nolintlint #- rowserrcheck - #- scopelint - staticcheck - #- structcheck ! deprecated since v1.49.0; replaced by 'unused' - - stylecheck - #- typecheck - unconvert #- unparam - unused - # - varcheck ! deprecated since v1.49.0; replaced by 'unused' #- whitespace - fast: false + exclusions: + presets: + - common-false-positives + - legacy + - std-error-handling diff --git a/etcd/vendor/github.com/spf13/cobra/README.md b/etcd/vendor/github.com/spf13/cobra/README.md index 71757151c3..8416275f48 100644 --- a/etcd/vendor/github.com/spf13/cobra/README.md +++ b/etcd/vendor/github.com/spf13/cobra/README.md @@ -1,8 +1,14 @@ - -![cobra logo](https://github.com/user-attachments/assets/cbc3adf8-0dff-46e9-a88d-5e2d971c169e) +
+ +cobra-logo + +
Cobra is a library for creating powerful modern CLI applications. +Visit Cobra.dev for extensive documentation + + Cobra is used in many Go projects such as [Kubernetes](https://kubernetes.io/), [Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to name a few. [This list](site/content/projects_using_cobra.md) contains a more extensive list of projects using Cobra. @@ -11,6 +17,20 @@ name a few. [This list](site/content/projects_using_cobra.md) contains a more ex [![Go Reference](https://pkg.go.dev/badge/github.com/spf13/cobra.svg)](https://pkg.go.dev/github.com/spf13/cobra) [![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra) [![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199) +
+
+ Supported by: +
+
+ + Warp sponsorship + + +### [Warp, the AI terminal for devs](https://www.warp.dev/cobra) +[Try Cobra in Warp today](https://www.warp.dev/cobra)
+ +
+
# Overview diff --git a/etcd/vendor/github.com/spf13/cobra/SECURITY.md b/etcd/vendor/github.com/spf13/cobra/SECURITY.md new file mode 100644 index 0000000000..54e60c28c1 --- /dev/null +++ b/etcd/vendor/github.com/spf13/cobra/SECURITY.md @@ -0,0 +1,105 @@ +# Security Policy + +## Reporting a Vulnerability + +The `cobra` maintainers take security issues seriously and +we appreciate your efforts to _**responsibly**_ disclose your findings. +We will make every effort to swiftly respond and address concerns. + +To report a security vulnerability: + +1. **DO NOT** create a public GitHub issue for the vulnerability! +2. **DO NOT** create a public GitHub Pull Request with a fix for the vulnerability! +3. Send an email to `cobra-security@googlegroups.com`. +4. Include the following details in your report: + - Description of the vulnerability + - Steps to reproduce + - Potential impact of the vulnerability (to your downstream project, to the Go ecosystem, etc.) + - Any potential mitigations you've already identified +5. Allow up to 7 days for an initial response. + You should receive an acknowledgment of your report and an estimated timeline for a fix. +6. (Optional) If you have a fix and would like to contribute your patch, please work + directly with the maintainers via `cobra-security@googlegroups.com` to + coordinate pushing the patch to GitHub, cutting a new release, and disclosing the change. + +## Response Process + +When a security vulnerability report is received, the `cobra` maintainers will: + +1. Confirm receipt of the vulnerability report within 7 days. +2. Assess the report to determine if it constitutes a security vulnerability. +3. If confirmed, assign the vulnerability a severity level and create a timeline for addressing it. +4. Develop and test a fix. +5. Patch the vulnerability and make a new GitHub release: the maintainers will coordinate disclosure with the reporter. +6. Create a new GitHub Security Advisory to inform the broader Go ecosystem + +## Disclosure Policy + +The `cobra` maintainers follow a coordinated disclosure process: + +1. Security vulnerabilities will be addressed as quickly as possible. +2. A CVE (Common Vulnerabilities and Exposures) identifier will be requested for significant vulnerabilities + that are within `cobra` itself. +3. Once a fix is ready, the maintainers will: + - Release a new version containing the fix. + - Update the security advisory with details about the vulnerability. + - Credit the reporter (unless they wish to remain anonymous). + - Credit the fixer (unless they wish to remain anonymous, this may be the same as the reporter). + - Announce the vulnerability through appropriate channels + (GitHub Security Advisory, mailing lists, GitHub Releases, etc.) + +## Supported Versions + +Security fixes will typically only be released for the most recent major release. + +## Upstream Security Issues + +`cobra` generally will not accept vulnerability reports that originate in upstream +dependencies. I.e., if there is a problem in Go code that `cobra` depends on, +it is best to engage that project's maintainers and owners. + +This security policy primarily pertains only to `cobra` itself but if you believe you've +identified a problem that originates in an upstream dependency and is being widely +distributed by `cobra`, please follow the disclosure procedure above: the `cobra` +maintainers will work with you to determine the severity and ecosystem impact. + +## Security Updates and CVEs + +Information about known security vulnerabilities and CVEs affecting `cobra` will +be published as GitHub Security Advisories at +https://github.com/spf13/cobra/security/advisories. + +All users are encouraged to watch the repository and upgrade promptly when +security releases are published. + +## `cobra` Security Best Practices for Users + +When using `cobra` in your CLIs, the `cobra` maintainers recommend the following: + +1. Always use the latest version of `cobra`. +2. [Use Go modules](https://go.dev/blog/using-go-modules) for dependency management. +3. Always use the latest possible version of Go. + +## Security Best Practices for Contributors + +When contributing to `cobra`: + +1. Be mindful of security implications when adding new features or modifying existing ones. +2. Be aware of `cobra`'s extremely large reach: it is used in nearly every Go CLI + (like Kubernetes, Docker, Prometheus, etc. etc.) +3. Write tests that explicitly cover edge cases and potential issues. +4. If you discover a security issue while working on `cobra`, please report it + following the process above rather than opening a public pull request or issue that + addresses the vulnerability. +5. Take personal sec-ops seriously and secure your GitHub account: use [two-factor authentication](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa), + [sign your commits with a GPG or SSH key](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification), + etc. + +## Acknowledgments + +The `cobra` maintainers would like to thank all security researchers and +community members who help keep cobra, its users, and the entire Go ecosystem secure through responsible disclosures!! + +--- + +*This security policy is inspired by the [Open Web Application Security Project (OWASP)](https://owasp.org/) guidelines and security best practices.* diff --git a/etcd/vendor/github.com/spf13/cobra/command.go b/etcd/vendor/github.com/spf13/cobra/command.go index dbb2c298ba..78088db69c 100644 --- a/etcd/vendor/github.com/spf13/cobra/command.go +++ b/etcd/vendor/github.com/spf13/cobra/command.go @@ -39,7 +39,7 @@ const ( ) // FParseErrWhitelist configures Flag parse errors to be ignored -type FParseErrWhitelist flag.ParseErrorsWhitelist +type FParseErrWhitelist flag.ParseErrorsAllowlist // Group Structure to manage groups for commands type Group struct { @@ -1296,6 +1296,11 @@ Simply type ` + c.DisplayName() + ` help [path to command] for full details.`, c.Printf("Unknown help topic %#q\n", args) CheckErr(c.Root().Usage()) } else { + // FLow the context down to be used in help text + if cmd.ctx == nil { + cmd.ctx = c.ctx + } + cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown cmd.InitDefaultVersionFlag() // make possible 'version' flag to be shown CheckErr(cmd.Help()) @@ -1872,7 +1877,7 @@ func (c *Command) ParseFlags(args []string) error { c.mergePersistentFlags() // do it here after merging all flags and just before parse - c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist) + c.Flags().ParseErrorsAllowlist = flag.ParseErrorsAllowlist(c.FParseErrWhitelist) err := c.Flags().Parse(args) // Print warnings if they occurred (e.g. deprecated flag messages). @@ -2020,7 +2025,7 @@ func defaultUsageFunc(w io.Writer, in interface{}) error { fmt.Fprint(w, trimRightSpace(c.InheritedFlags().FlagUsages())) } if c.HasHelpSubCommands() { - fmt.Fprintf(w, "\n\nAdditional help topcis:") + fmt.Fprintf(w, "\n\nAdditional help topics:") for _, subcmd := range c.Commands() { if subcmd.IsAdditionalHelpTopicCommand() { fmt.Fprintf(w, "\n %s %s", rpad(subcmd.CommandPath(), subcmd.CommandPathPadding()), subcmd.Short) diff --git a/etcd/vendor/github.com/spf13/cobra/completions.go b/etcd/vendor/github.com/spf13/cobra/completions.go index a1752f7631..d3607c2d2f 100644 --- a/etcd/vendor/github.com/spf13/cobra/completions.go +++ b/etcd/vendor/github.com/spf13/cobra/completions.go @@ -115,6 +115,13 @@ type CompletionOptions struct { DisableDescriptions bool // HiddenDefaultCmd makes the default 'completion' command hidden HiddenDefaultCmd bool + // DefaultShellCompDirective sets the ShellCompDirective that is returned + // if no special directive can be determined + DefaultShellCompDirective *ShellCompDirective +} + +func (receiver *CompletionOptions) SetDefaultShellCompDirective(directive ShellCompDirective) { + receiver.DefaultShellCompDirective = &directive } // Completion is a string that can be used for completions @@ -375,7 +382,7 @@ func (c *Command) getCompletions(args []string) (*Command, []Completion, ShellCo // Error while attempting to parse flags if flagErr != nil { // If error type is flagCompError and we don't want flagCompletion we should ignore the error - if _, ok := flagErr.(*flagCompError); !(ok && !flagCompletion) { + if _, ok := flagErr.(*flagCompError); !ok || flagCompletion { return finalCmd, []Completion{}, ShellCompDirectiveDefault, flagErr } } @@ -480,6 +487,14 @@ func (c *Command) getCompletions(args []string) (*Command, []Completion, ShellCo } } else { directive = ShellCompDirectiveDefault + // check current and parent commands for a custom DefaultShellCompDirective + for cmd := finalCmd; cmd != nil; cmd = cmd.parent { + if cmd.CompletionOptions.DefaultShellCompDirective != nil { + directive = *cmd.CompletionOptions.DefaultShellCompDirective + break + } + } + if flag == nil { foundLocalNonPersistentFlag := false // If TraverseChildren is true on the root command we don't check for @@ -773,7 +788,7 @@ See each sub-command's help for details on how to use the generated script. // shell completion for it (prog __complete completion '') subCmd, cmdArgs, err := c.Find(args) if err != nil || subCmd.Name() != compCmdName && - !(subCmd.Name() == ShellCompRequestCmd && len(cmdArgs) > 1 && cmdArgs[0] == compCmdName) { + (subCmd.Name() != ShellCompRequestCmd || len(cmdArgs) <= 1 || cmdArgs[0] != compCmdName) { // The completion command is not being called or being completed so we remove it. c.RemoveCommand(completionCmd) return diff --git a/etcd/vendor/golang.org/x/net/context/context.go b/etcd/vendor/golang.org/x/net/context/context.go index db1c95fab1..24cea68820 100644 --- a/etcd/vendor/golang.org/x/net/context/context.go +++ b/etcd/vendor/golang.org/x/net/context/context.go @@ -2,44 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package context defines the Context type, which carries deadlines, -// cancellation signals, and other request-scoped values across API boundaries -// and between processes. -// As of Go 1.7 this package is available in the standard library under the -// name [context], and migrating to it can be done automatically with [go fix]. -// -// Incoming requests to a server should create a [Context], and outgoing -// calls to servers should accept a Context. The chain of function -// calls between them must propagate the Context, optionally replacing -// it with a derived Context created using [WithCancel], [WithDeadline], -// [WithTimeout], or [WithValue]. -// -// Programs that use Contexts should follow these rules to keep interfaces -// consistent across packages and enable static analysis tools to check context -// propagation: -// -// Do not store Contexts inside a struct type; instead, pass a Context -// explicitly to each function that needs it. This is discussed further in -// https://go.dev/blog/context-and-structs. The Context should be the first -// parameter, typically named ctx: -// -// func DoSomething(ctx context.Context, arg Arg) error { -// // ... use ctx ... -// } -// -// Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] -// if you are unsure about which Context to use. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. +// Package context has been superseded by the standard library [context] package. // -// The same Context may be passed to functions running in different goroutines; -// Contexts are safe for simultaneous use by multiple goroutines. -// -// See https://go.dev/blog/context for example code for a server that uses -// Contexts. -// -// [go fix]: https://go.dev/cmd/go#hdr-Update_packages_to_use_new_APIs +// Deprecated: Use the standard library context package instead. package context import ( @@ -51,36 +16,37 @@ import ( // API boundaries. // // Context's methods may be called by multiple goroutines simultaneously. +// +//go:fix inline type Context = context.Context // Canceled is the error returned by [Context.Err] when the context is canceled // for some reason other than its deadline passing. +// +//go:fix inline var Canceled = context.Canceled // DeadlineExceeded is the error returned by [Context.Err] when the context is canceled // due to its deadline passing. +// +//go:fix inline var DeadlineExceeded = context.DeadlineExceeded // Background returns a non-nil, empty Context. It is never canceled, has no // values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming // requests. -func Background() Context { - return background -} +// +//go:fix inline +func Background() Context { return context.Background() } // TODO returns a non-nil, empty Context. Code should use context.TODO when // it's unclear which Context to use or it is not yet available (because the // surrounding function has not yet been extended to accept a Context // parameter). -func TODO() Context { - return todo -} - -var ( - background = context.Background() - todo = context.TODO() -) +// +//go:fix inline +func TODO() Context { return context.TODO() } // A CancelFunc tells an operation to abandon its work. // A CancelFunc does not wait for the work to stop. @@ -95,6 +61,8 @@ type CancelFunc = context.CancelFunc // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this [Context] complete. +// +//go:fix inline func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { return context.WithCancel(parent) } @@ -108,6 +76,8 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this [Context] complete. +// +//go:fix inline func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { return context.WithDeadline(parent, d) } @@ -122,6 +92,8 @@ func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { // defer cancel() // releases resources if slowOperation completes before timeout elapses // return slowOperation(ctx) // } +// +//go:fix inline func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { return context.WithTimeout(parent, timeout) } @@ -139,6 +111,8 @@ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { // interface{}, context keys often have concrete type // struct{}. Alternatively, exported context key variables' static // type should be a pointer or interface. +// +//go:fix inline func WithValue(parent Context, key, val interface{}) Context { return context.WithValue(parent, key, val) } diff --git a/etcd/vendor/golang.org/x/net/html/escape.go b/etcd/vendor/golang.org/x/net/html/escape.go index 04c6bec210..12f2273706 100644 --- a/etcd/vendor/golang.org/x/net/html/escape.go +++ b/etcd/vendor/golang.org/x/net/html/escape.go @@ -299,7 +299,7 @@ func escape(w writer, s string) error { case '\r': esc = " " default: - panic("unrecognized escape character") + panic("html: unrecognized escape character") } s = s[i+1:] if _, err := w.WriteString(esc); err != nil { diff --git a/etcd/vendor/golang.org/x/net/html/parse.go b/etcd/vendor/golang.org/x/net/html/parse.go index 518ee4c94e..88fc0056a3 100644 --- a/etcd/vendor/golang.org/x/net/html/parse.go +++ b/etcd/vendor/golang.org/x/net/html/parse.go @@ -136,7 +136,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { return -1 } default: - panic("unreachable") + panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s)) } } switch s { @@ -179,7 +179,7 @@ func (p *parser) clearStackToContext(s scope) { return } default: - panic("unreachable") + panic(fmt.Sprintf("html: internal error: clearStackToContext unknown scope: %d", s)) } } } @@ -231,7 +231,14 @@ func (p *parser) addChild(n *Node) { } if n.Type == ElementNode { - p.oe = append(p.oe, n) + p.insertOpenElement(n) + } +} + +func (p *parser) insertOpenElement(n *Node) { + p.oe = append(p.oe, n) + if len(p.oe) > 512 { + panic("html: open stack of elements exceeds 512 nodes") } } @@ -810,7 +817,7 @@ func afterHeadIM(p *parser) bool { p.im = inFramesetIM return true case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title: - p.oe = append(p.oe, p.head) + p.insertOpenElement(p.head) defer p.oe.remove(p.head) return inHeadIM(p) case a.Head: @@ -1678,7 +1685,7 @@ func inTableBodyIM(p *parser) bool { return inTableIM(p) } -// Section 12.2.6.4.14. +// Section 13.2.6.4.14. func inRowIM(p *parser) bool { switch p.tok.Type { case StartTagToken: @@ -1690,7 +1697,9 @@ func inRowIM(p *parser) bool { p.im = inCellIM return true case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr: - if p.popUntil(tableScope, a.Tr) { + if p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() p.im = inTableBodyIM return false } @@ -1700,22 +1709,28 @@ func inRowIM(p *parser) bool { case EndTagToken: switch p.tok.DataAtom { case a.Tr: - if p.popUntil(tableScope, a.Tr) { + if p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() p.im = inTableBodyIM return true } // Ignore the token. return true case a.Table: - if p.popUntil(tableScope, a.Tr) { + if p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() p.im = inTableBodyIM return false } // Ignore the token. return true case a.Tbody, a.Tfoot, a.Thead: - if p.elementInScope(tableScope, p.tok.DataAtom) { - p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String()) + if p.elementInScope(tableScope, p.tok.DataAtom) && p.elementInScope(tableScope, a.Tr) { + p.clearStackToContext(tableRowScope) + p.oe.pop() + p.im = inTableBodyIM return false } // Ignore the token. @@ -2222,16 +2237,20 @@ func parseForeignContent(p *parser) bool { p.acknowledgeSelfClosingTag() } case EndTagToken: + if strings.EqualFold(p.oe[len(p.oe)-1].Data, p.tok.Data) { + p.oe = p.oe[:len(p.oe)-1] + return true + } for i := len(p.oe) - 1; i >= 0; i-- { - if p.oe[i].Namespace == "" { - return p.im(p) - } if strings.EqualFold(p.oe[i].Data, p.tok.Data) { p.oe = p.oe[:i] + return true + } + if i > 0 && p.oe[i-1].Namespace == "" { break } } - return true + return p.im(p) default: // Ignore the token. } @@ -2312,9 +2331,13 @@ func (p *parser) parseCurrentToken() { } } -func (p *parser) parse() error { +func (p *parser) parse() (err error) { + defer func() { + if panicErr := recover(); panicErr != nil { + err = fmt.Errorf("%s", panicErr) + } + }() // Iterate until EOF. Any other error will cause an early return. - var err error for err != io.EOF { // CDATA sections are allowed only in foreign content. n := p.oe.top() @@ -2343,6 +2366,8 @@ func (p *parser) parse() error { // s. Conversely, explicit s in r's data can be silently dropped, // with no corresponding node in the resulting tree. // +// Parse will reject HTML that is nested deeper than 512 elements. +// // The input is assumed to be UTF-8 encoded. func Parse(r io.Reader) (*Node, error) { return ParseWithOptions(r) diff --git a/etcd/vendor/golang.org/x/net/html/render.go b/etcd/vendor/golang.org/x/net/html/render.go index e8c1233455..0157d89e1f 100644 --- a/etcd/vendor/golang.org/x/net/html/render.go +++ b/etcd/vendor/golang.org/x/net/html/render.go @@ -184,7 +184,7 @@ func render1(w writer, n *Node) error { return err } - // Add initial newline where there is danger of a newline beging ignored. + // Add initial newline where there is danger of a newline being ignored. if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") { switch n.Data { case "pre", "listing", "textarea": diff --git a/etcd/vendor/golang.org/x/net/http2/config.go b/etcd/vendor/golang.org/x/net/http2/config.go index ca645d9a1a..8a7a89d016 100644 --- a/etcd/vendor/golang.org/x/net/http2/config.go +++ b/etcd/vendor/golang.org/x/net/http2/config.go @@ -27,6 +27,7 @@ import ( // - If the resulting value is zero or out of range, use a default. type http2Config struct { MaxConcurrentStreams uint32 + StrictMaxConcurrentRequests bool MaxDecoderHeaderTableSize uint32 MaxEncoderHeaderTableSize uint32 MaxReadFrameSize uint32 @@ -55,7 +56,7 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config { PermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites, CountError: h2.CountError, } - fillNetHTTPServerConfig(&conf, h1) + fillNetHTTPConfig(&conf, h1.HTTP2) setConfigDefaults(&conf, true) return conf } @@ -64,12 +65,13 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config { // (the net/http Transport). func configFromTransport(h2 *Transport) http2Config { conf := http2Config{ - MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, - MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, - MaxReadFrameSize: h2.MaxReadFrameSize, - SendPingTimeout: h2.ReadIdleTimeout, - PingTimeout: h2.PingTimeout, - WriteByteTimeout: h2.WriteByteTimeout, + StrictMaxConcurrentRequests: h2.StrictMaxConcurrentStreams, + MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, + MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, + MaxReadFrameSize: h2.MaxReadFrameSize, + SendPingTimeout: h2.ReadIdleTimeout, + PingTimeout: h2.PingTimeout, + WriteByteTimeout: h2.WriteByteTimeout, } // Unlike most config fields, where out-of-range values revert to the default, @@ -81,7 +83,7 @@ func configFromTransport(h2 *Transport) http2Config { } if h2.t1 != nil { - fillNetHTTPTransportConfig(&conf, h2.t1) + fillNetHTTPConfig(&conf, h2.t1.HTTP2) } setConfigDefaults(&conf, false) return conf @@ -120,3 +122,48 @@ func adjustHTTP1MaxHeaderSize(n int64) int64 { const typicalHeaders = 10 // conservative return n + typicalHeaders*perFieldOverhead } + +func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { + if h2 == nil { + return + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if http2ConfigStrictMaxConcurrentRequests(h2) { + conf.StrictMaxConcurrentRequests = true + } + if h2.MaxEncoderHeaderTableSize != 0 { + conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) + } + if h2.MaxDecoderHeaderTableSize != 0 { + conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if h2.MaxReadFrameSize != 0 { + conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) + } + if h2.MaxReceiveBufferPerConnection != 0 { + conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) + } + if h2.MaxReceiveBufferPerStream != 0 { + conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) + } + if h2.SendPingTimeout != 0 { + conf.SendPingTimeout = h2.SendPingTimeout + } + if h2.PingTimeout != 0 { + conf.PingTimeout = h2.PingTimeout + } + if h2.WriteByteTimeout != 0 { + conf.WriteByteTimeout = h2.WriteByteTimeout + } + if h2.PermitProhibitedCipherSuites { + conf.PermitProhibitedCipherSuites = true + } + if h2.CountError != nil { + conf.CountError = h2.CountError + } +} diff --git a/etcd/vendor/golang.org/x/net/http2/config_go124.go b/etcd/vendor/golang.org/x/net/http2/config_go124.go deleted file mode 100644 index 5b516c55ff..0000000000 --- a/etcd/vendor/golang.org/x/net/http2/config_go124.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.24 - -package http2 - -import "net/http" - -// fillNetHTTPServerConfig sets fields in conf from srv.HTTP2. -func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) { - fillNetHTTPConfig(conf, srv.HTTP2) -} - -// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. -func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { - fillNetHTTPConfig(conf, tr.HTTP2) -} - -func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { - if h2 == nil { - return - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if h2.MaxEncoderHeaderTableSize != 0 { - conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) - } - if h2.MaxDecoderHeaderTableSize != 0 { - conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if h2.MaxReadFrameSize != 0 { - conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) - } - if h2.MaxReceiveBufferPerConnection != 0 { - conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) - } - if h2.MaxReceiveBufferPerStream != 0 { - conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) - } - if h2.SendPingTimeout != 0 { - conf.SendPingTimeout = h2.SendPingTimeout - } - if h2.PingTimeout != 0 { - conf.PingTimeout = h2.PingTimeout - } - if h2.WriteByteTimeout != 0 { - conf.WriteByteTimeout = h2.WriteByteTimeout - } - if h2.PermitProhibitedCipherSuites { - conf.PermitProhibitedCipherSuites = true - } - if h2.CountError != nil { - conf.CountError = h2.CountError - } -} diff --git a/etcd/vendor/golang.org/x/net/http2/config_go125.go b/etcd/vendor/golang.org/x/net/http2/config_go125.go new file mode 100644 index 0000000000..b4373fe33c --- /dev/null +++ b/etcd/vendor/golang.org/x/net/http2/config_go125.go @@ -0,0 +1,15 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.26 + +package http2 + +import ( + "net/http" +) + +func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool { + return false +} diff --git a/etcd/vendor/golang.org/x/net/http2/config_go126.go b/etcd/vendor/golang.org/x/net/http2/config_go126.go new file mode 100644 index 0000000000..6b071c149d --- /dev/null +++ b/etcd/vendor/golang.org/x/net/http2/config_go126.go @@ -0,0 +1,15 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.26 + +package http2 + +import ( + "net/http" +) + +func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool { + return h2.StrictMaxConcurrentRequests +} diff --git a/etcd/vendor/golang.org/x/net/http2/config_pre_go124.go b/etcd/vendor/golang.org/x/net/http2/config_pre_go124.go deleted file mode 100644 index 060fd6c64c..0000000000 --- a/etcd/vendor/golang.org/x/net/http2/config_pre_go124.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.24 - -package http2 - -import "net/http" - -// Pre-Go 1.24 fallback. -// The Server.HTTP2 and Transport.HTTP2 config fields were added in Go 1.24. - -func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {} - -func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {} diff --git a/etcd/vendor/golang.org/x/net/http2/frame.go b/etcd/vendor/golang.org/x/net/http2/frame.go index db3264da8c..9a4bd123c9 100644 --- a/etcd/vendor/golang.org/x/net/http2/frame.go +++ b/etcd/vendor/golang.org/x/net/http2/frame.go @@ -280,6 +280,8 @@ type Framer struct { // lastHeaderStream is non-zero if the last frame was an // unfinished HEADERS/CONTINUATION. lastHeaderStream uint32 + // lastFrameType holds the type of the last frame for verifying frame order. + lastFrameType FrameType maxReadSize uint32 headerBuf [frameHeaderLen]byte @@ -347,7 +349,7 @@ func (fr *Framer) maxHeaderListSize() uint32 { func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) { // Write the FrameHeader. f.wbuf = append(f.wbuf[:0], - 0, // 3 bytes of length, filled in in endWrite + 0, // 3 bytes of length, filled in endWrite 0, 0, byte(ftype), @@ -488,30 +490,41 @@ func terminalReadFrameError(err error) bool { return err != nil } -// ReadFrame reads a single frame. The returned Frame is only valid -// until the next call to ReadFrame. +// ReadFrameHeader reads the header of the next frame. +// It reads the 9-byte fixed frame header, and does not read any portion of the +// frame payload. The caller is responsible for consuming the payload, either +// with ReadFrameForHeader or directly from the Framer's io.Reader. // -// If the frame is larger than previously set with SetMaxReadFrameSize, the -// returned error is ErrFrameTooLarge. Other errors may be of type -// ConnectionError, StreamError, or anything else from the underlying -// reader. +// If the frame is larger than previously set with SetMaxReadFrameSize, it +// returns the frame header and ErrFrameTooLarge. // -// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID -// indicates the stream responsible for the error. -func (fr *Framer) ReadFrame() (Frame, error) { +// If the returned FrameHeader.StreamID is non-zero, it indicates the stream +// responsible for the error. +func (fr *Framer) ReadFrameHeader() (FrameHeader, error) { fr.errDetail = nil - if fr.lastFrame != nil { - fr.lastFrame.invalidate() - } fh, err := readFrameHeader(fr.headerBuf[:], fr.r) if err != nil { - return nil, err + return fh, err } if fh.Length > fr.maxReadSize { if fh == invalidHTTP1LookingFrameHeader() { - return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge) + return fh, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge) } - return nil, ErrFrameTooLarge + return fh, ErrFrameTooLarge + } + if err := fr.checkFrameOrder(fh); err != nil { + return fh, err + } + return fh, nil +} + +// ReadFrameForHeader reads the payload for the frame with the given FrameHeader. +// +// It behaves identically to ReadFrame, other than not checking the maximum +// frame size. +func (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error) { + if fr.lastFrame != nil { + fr.lastFrame.invalidate() } payload := fr.getReadBuf(fh.Length) if _, err := io.ReadFull(fr.r, payload); err != nil { @@ -527,9 +540,7 @@ func (fr *Framer) ReadFrame() (Frame, error) { } return nil, err } - if err := fr.checkFrameOrder(f); err != nil { - return nil, err - } + fr.lastFrame = f if fr.logReads { fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) } @@ -539,6 +550,24 @@ func (fr *Framer) ReadFrame() (Frame, error) { return f, nil } +// ReadFrame reads a single frame. The returned Frame is only valid +// until the next call to ReadFrame or ReadFrameBodyForHeader. +// +// If the frame is larger than previously set with SetMaxReadFrameSize, the +// returned error is ErrFrameTooLarge. Other errors may be of type +// ConnectionError, StreamError, or anything else from the underlying +// reader. +// +// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID +// indicates the stream responsible for the error. +func (fr *Framer) ReadFrame() (Frame, error) { + fh, err := fr.ReadFrameHeader() + if err != nil { + return nil, err + } + return fr.ReadFrameForHeader(fh) +} + // connError returns ConnectionError(code) but first // stashes away a public reason to the caller can optionally relay it // to the peer before hanging up on them. This might help others debug @@ -551,20 +580,19 @@ func (fr *Framer) connError(code ErrCode, reason string) error { // checkFrameOrder reports an error if f is an invalid frame to return // next from ReadFrame. Mostly it checks whether HEADERS and // CONTINUATION frames are contiguous. -func (fr *Framer) checkFrameOrder(f Frame) error { - last := fr.lastFrame - fr.lastFrame = f +func (fr *Framer) checkFrameOrder(fh FrameHeader) error { + lastType := fr.lastFrameType + fr.lastFrameType = fh.Type if fr.AllowIllegalReads { return nil } - fh := f.Header() if fr.lastHeaderStream != 0 { if fh.Type != FrameContinuation { return fr.connError(ErrCodeProtocol, fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", fh.Type, fh.StreamID, - last.Header().Type, fr.lastHeaderStream)) + lastType, fr.lastHeaderStream)) } if fh.StreamID != fr.lastHeaderStream { return fr.connError(ErrCodeProtocol, @@ -1152,7 +1180,16 @@ type PriorityFrame struct { PriorityParam } -// PriorityParam are the stream prioritzation parameters. +var defaultRFC9218Priority = PriorityParam{ + incremental: 0, + urgency: 3, +} + +// Note that HTTP/2 has had two different prioritization schemes, and +// PriorityParam struct below is a superset of both schemes. The exported +// symbols are from RFC 7540 and the non-exported ones are from RFC 9218. + +// PriorityParam are the stream prioritization parameters. type PriorityParam struct { // StreamDep is a 31-bit stream identifier for the // stream that this stream depends on. Zero means no @@ -1167,6 +1204,20 @@ type PriorityParam struct { // the spec, "Add one to the value to obtain a weight between // 1 and 256." Weight uint8 + + // "The urgency (u) parameter value is Integer (see Section 3.3.1 of + // [STRUCTURED-FIELDS]), between 0 and 7 inclusive, in descending order of + // priority. The default is 3." + urgency uint8 + + // "The incremental (i) parameter value is Boolean (see Section 3.3.6 of + // [STRUCTURED-FIELDS]). It indicates if an HTTP response can be processed + // incrementally, i.e., provide some meaningful output as chunks of the + // response arrive." + // + // We use uint8 (i.e. 0 is false, 1 is true) instead of bool so we can + // avoid unnecessary type conversions and because either type takes 1 byte. + incremental uint8 } func (p PriorityParam) IsZero() bool { diff --git a/etcd/vendor/golang.org/x/net/http2/gotrack.go b/etcd/vendor/golang.org/x/net/http2/gotrack.go index 9933c9f8c7..9921ca096d 100644 --- a/etcd/vendor/golang.org/x/net/http2/gotrack.go +++ b/etcd/vendor/golang.org/x/net/http2/gotrack.go @@ -15,21 +15,32 @@ import ( "runtime" "strconv" "sync" + "sync/atomic" ) var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" +// Setting DebugGoroutines to false during a test to disable goroutine debugging +// results in race detector complaints when a test leaves goroutines running before +// returning. Tests shouldn't do this, of course, but when they do it generally shows +// up as infrequent, hard-to-debug flakes. (See #66519.) +// +// Disable goroutine debugging during individual tests with an atomic bool. +// (Note that it's safe to enable/disable debugging mid-test, so the actual race condition +// here is harmless.) +var disableDebugGoroutines atomic.Bool + type goroutineLock uint64 func newGoroutineLock() goroutineLock { - if !DebugGoroutines { + if !DebugGoroutines || disableDebugGoroutines.Load() { return 0 } return goroutineLock(curGoroutineID()) } func (g goroutineLock) check() { - if !DebugGoroutines { + if !DebugGoroutines || disableDebugGoroutines.Load() { return } if curGoroutineID() != uint64(g) { @@ -38,7 +49,7 @@ func (g goroutineLock) check() { } func (g goroutineLock) checkNotOn() { - if !DebugGoroutines { + if !DebugGoroutines || disableDebugGoroutines.Load() { return } if curGoroutineID() == uint64(g) { diff --git a/etcd/vendor/golang.org/x/net/http2/http2.go b/etcd/vendor/golang.org/x/net/http2/http2.go index ea5ae629fd..105fe12fef 100644 --- a/etcd/vendor/golang.org/x/net/http2/http2.go +++ b/etcd/vendor/golang.org/x/net/http2/http2.go @@ -15,7 +15,6 @@ package http2 // import "golang.org/x/net/http2" import ( "bufio" - "context" "crypto/tls" "errors" "fmt" @@ -35,7 +34,6 @@ var ( VerboseLogs bool logFrameWrites bool logFrameReads bool - inTests bool // Enabling extended CONNECT by causes browsers to attempt to use // WebSockets-over-HTTP/2. This results in problems when the server's websocket @@ -255,15 +253,13 @@ func (cw closeWaiter) Wait() { // idle memory usage with many connections. type bufferedWriter struct { _ incomparable - group synctestGroupInterface // immutable - conn net.Conn // immutable - bw *bufio.Writer // non-nil when data is buffered - byteTimeout time.Duration // immutable, WriteByteTimeout + conn net.Conn // immutable + bw *bufio.Writer // non-nil when data is buffered + byteTimeout time.Duration // immutable, WriteByteTimeout } -func newBufferedWriter(group synctestGroupInterface, conn net.Conn, timeout time.Duration) *bufferedWriter { +func newBufferedWriter(conn net.Conn, timeout time.Duration) *bufferedWriter { return &bufferedWriter{ - group: group, conn: conn, byteTimeout: timeout, } @@ -314,24 +310,18 @@ func (w *bufferedWriter) Flush() error { type bufferedWriterTimeoutWriter bufferedWriter func (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) { - return writeWithByteTimeout(w.group, w.conn, w.byteTimeout, p) + return writeWithByteTimeout(w.conn, w.byteTimeout, p) } // writeWithByteTimeout writes to conn. // If more than timeout passes without any bytes being written to the connection, // the write fails. -func writeWithByteTimeout(group synctestGroupInterface, conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { +func writeWithByteTimeout(conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { if timeout <= 0 { return conn.Write(p) } for { - var now time.Time - if group == nil { - now = time.Now() - } else { - now = group.Now() - } - conn.SetWriteDeadline(now.Add(timeout)) + conn.SetWriteDeadline(time.Now().Add(timeout)) nn, err := conn.Write(p[n:]) n += nn if n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) { @@ -417,14 +407,3 @@ func (s *sorter) SortStrings(ss []string) { // makes that struct also non-comparable, and generally doesn't add // any size (as long as it's first). type incomparable [0]func() - -// synctestGroupInterface is the methods of synctestGroup used by Server and Transport. -// It's defined as an interface here to let us keep synctestGroup entirely test-only -// and not a part of non-test builds. -type synctestGroupInterface interface { - Join() - Now() time.Time - NewTimer(d time.Duration) timer - AfterFunc(d time.Duration, f func()) timer - ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) -} diff --git a/etcd/vendor/golang.org/x/net/http2/server.go b/etcd/vendor/golang.org/x/net/http2/server.go index 51fca38f61..bdc5520ebd 100644 --- a/etcd/vendor/golang.org/x/net/http2/server.go +++ b/etcd/vendor/golang.org/x/net/http2/server.go @@ -176,44 +176,15 @@ type Server struct { // so that we don't embed a Mutex in this struct, which will make the // struct non-copyable, which might break some callers. state *serverInternalState - - // Synchronization group used for testing. - // Outside of tests, this is nil. - group synctestGroupInterface -} - -func (s *Server) markNewGoroutine() { - if s.group != nil { - s.group.Join() - } -} - -func (s *Server) now() time.Time { - if s.group != nil { - return s.group.Now() - } - return time.Now() -} - -// newTimer creates a new time.Timer, or a synthetic timer in tests. -func (s *Server) newTimer(d time.Duration) timer { - if s.group != nil { - return s.group.NewTimer(d) - } - return timeTimer{time.NewTimer(d)} -} - -// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. -func (s *Server) afterFunc(d time.Duration, f func()) timer { - if s.group != nil { - return s.group.AfterFunc(d, f) - } - return timeTimer{time.AfterFunc(d, f)} } type serverInternalState struct { mu sync.Mutex activeConns map[*serverConn]struct{} + + // Pool of error channels. This is per-Server rather than global + // because channels can't be reused across synctest bubbles. + errChanPool sync.Pool } func (s *serverInternalState) registerConn(sc *serverConn) { @@ -245,6 +216,27 @@ func (s *serverInternalState) startGracefulShutdown() { s.mu.Unlock() } +// Global error channel pool used for uninitialized Servers. +// We use a per-Server pool when possible to avoid using channels across synctest bubbles. +var errChanPool = sync.Pool{ + New: func() any { return make(chan error, 1) }, +} + +func (s *serverInternalState) getErrChan() chan error { + if s == nil { + return errChanPool.Get().(chan error) // Server used without calling ConfigureServer + } + return s.errChanPool.Get().(chan error) +} + +func (s *serverInternalState) putErrChan(ch chan error) { + if s == nil { + errChanPool.Put(ch) // Server used without calling ConfigureServer + return + } + s.errChanPool.Put(ch) +} + // ConfigureServer adds HTTP/2 support to a net/http Server. // // The configuration conf may be nil. @@ -257,7 +249,10 @@ func ConfigureServer(s *http.Server, conf *Server) error { if conf == nil { conf = new(Server) } - conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} + conf.state = &serverInternalState{ + activeConns: make(map[*serverConn]struct{}), + errChanPool: sync.Pool{New: func() any { return make(chan error, 1) }}, + } if h1, h2 := s, conf; h2.IdleTimeout == 0 { if h1.IdleTimeout != 0 { h2.IdleTimeout = h1.IdleTimeout @@ -423,6 +418,9 @@ func (o *ServeConnOpts) handler() http.Handler { // // The opts parameter is optional. If nil, default values are used. func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { + if opts == nil { + opts = &ServeConnOpts{} + } s.serveConn(c, opts, nil) } @@ -438,7 +436,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon conn: c, baseCtx: baseCtx, remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(s.group, c, conf.WriteByteTimeout), + bw: newBufferedWriter(c, conf.WriteByteTimeout), handler: opts.handler(), streams: make(map[uint32]*stream), readFrameCh: make(chan readFrameResult), @@ -638,11 +636,11 @@ type serverConn struct { pingSent bool sentPingData [8]byte goAwayCode ErrCode - shutdownTimer timer // nil until used - idleTimer timer // nil if unused + shutdownTimer *time.Timer // nil until used + idleTimer *time.Timer // nil if unused readIdleTimeout time.Duration pingTimeout time.Duration - readIdleTimer timer // nil if unused + readIdleTimer *time.Timer // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer @@ -687,12 +685,12 @@ type stream struct { flow outflow // limits writing from Handler to client inflow inflow // what the client is allowed to POST/etc to us state streamState - resetQueued bool // RST_STREAM queued for write; set by sc.resetStream - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - readDeadline timer // nil if unused - writeDeadline timer // nil if unused - closeErr error // set before cw is closed + resetQueued bool // RST_STREAM queued for write; set by sc.resetStream + gotTrailerHeader bool // HEADER frame for trailers was seen + wroteHeaders bool // whether we wrote headers (not status 100) + readDeadline *time.Timer // nil if unused + writeDeadline *time.Timer // nil if unused + closeErr error // set before cw is closed trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -848,7 +846,6 @@ type readFrameResult struct { // consumer is done with the frame. // It's run on its own goroutine. func (sc *serverConn) readFrames() { - sc.srv.markNewGoroutine() gate := make(chan struct{}) gateDone := func() { gate <- struct{}{} } for { @@ -881,7 +878,6 @@ type frameWriteResult struct { // At most one goroutine can be running writeFrameAsync at a time per // serverConn. func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) { - sc.srv.markNewGoroutine() var err error if wd == nil { err = wr.write.writeFrame(sc) @@ -965,22 +961,22 @@ func (sc *serverConn) serve(conf http2Config) { sc.setConnState(http.StateIdle) if sc.srv.IdleTimeout > 0 { - sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) + sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } if conf.SendPingTimeout > 0 { sc.readIdleTimeout = conf.SendPingTimeout - sc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) + sc.readIdleTimer = time.AfterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) defer sc.readIdleTimer.Stop() } go sc.readFrames() // closed by defer sc.conn.Close above - settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer) + settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer) defer settingsTimer.Stop() - lastFrameTime := sc.srv.now() + lastFrameTime := time.Now() loopNum := 0 for { loopNum++ @@ -994,7 +990,7 @@ func (sc *serverConn) serve(conf http2Config) { case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: - lastFrameTime = sc.srv.now() + lastFrameTime = time.Now() // Process any written frames before reading new frames from the client since a // written frame could have triggered a new stream to be started. if sc.writingFrameAsync { @@ -1077,7 +1073,7 @@ func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) { } pingAt := lastFrameReadTime.Add(sc.readIdleTimeout) - now := sc.srv.now() + now := time.Now() if pingAt.After(now) { // We received frames since arming the ping timer. // Reset it for the next possible timeout. @@ -1141,10 +1137,10 @@ func (sc *serverConn) readPreface() error { errc <- nil } }() - timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server? + timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server? defer timer.Stop() select { - case <-timer.C(): + case <-timer.C: return errPrefaceTimeout case err := <-errc: if err == nil { @@ -1156,10 +1152,6 @@ func (sc *serverConn) readPreface() error { } } -var errChanPool = sync.Pool{ - New: func() interface{} { return make(chan error, 1) }, -} - var writeDataPool = sync.Pool{ New: func() interface{} { return new(writeData) }, } @@ -1167,7 +1159,7 @@ var writeDataPool = sync.Pool{ // writeDataFromHandler writes DATA response frames from a handler on // the given stream. func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error { - ch := errChanPool.Get().(chan error) + ch := sc.srv.state.getErrChan() writeArg := writeDataPool.Get().(*writeData) *writeArg = writeData{stream.id, data, endStream} err := sc.writeFrameFromHandler(FrameWriteRequest{ @@ -1199,7 +1191,7 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea return errStreamClosed } } - errChanPool.Put(ch) + sc.srv.state.putErrChan(ch) if frameWriteDone { writeDataPool.Put(writeArg) } @@ -1513,7 +1505,7 @@ func (sc *serverConn) goAway(code ErrCode) { func (sc *serverConn) shutDownIn(d time.Duration) { sc.serveG.check() - sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer) + sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer) } func (sc *serverConn) resetStream(se StreamError) { @@ -2118,7 +2110,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // (in Go 1.8), though. That's a more sane option anyway. if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) - st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout) + st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } return sc.scheduleHandler(id, rw, req, handler) @@ -2216,7 +2208,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.initialStreamRecvWindowSize) if sc.hs.WriteTimeout > 0 { - st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) + st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } sc.streams[id] = st @@ -2405,7 +2397,6 @@ func (sc *serverConn) handlerDone() { // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { - sc.srv.markNewGoroutine() defer sc.sendServeMsg(handlerDoneMsg) didPanic := true defer func() { @@ -2454,7 +2445,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro // waiting for this frame to be written, so an http.Flush mid-handler // writes out the correct value of keys, before a handler later potentially // mutates it. - errc = errChanPool.Get().(chan error) + errc = sc.srv.state.getErrChan() } if err := sc.writeFrameFromHandler(FrameWriteRequest{ write: headerData, @@ -2466,7 +2457,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro if errc != nil { select { case err := <-errc: - errChanPool.Put(errc) + sc.srv.state.putErrChan(errc) return err case <-sc.doneServing: return errClientDisconnected @@ -2573,7 +2564,7 @@ func (b *requestBody) Read(p []byte) (n int, err error) { if err == io.EOF { b.sawEOF = true } - if b.conn == nil && inTests { + if b.conn == nil { return } b.conn.noteBodyReadFromHandler(b.stream, n, err) @@ -2702,7 +2693,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { var date string if _, ok := rws.snapHeader["Date"]; !ok { // TODO(bradfitz): be faster here, like net/http? measure. - date = rws.conn.srv.now().UTC().Format(http.TimeFormat) + date = time.Now().UTC().Format(http.TimeFormat) } for _, v := range rws.snapHeader["Trailer"] { @@ -2824,7 +2815,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() { func (w *responseWriter) SetReadDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { + if !deadline.IsZero() && deadline.Before(time.Now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onReadTimeout() @@ -2840,9 +2831,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { if deadline.IsZero() { st.readDeadline = nil } else if st.readDeadline == nil { - st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout) + st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout) } else { - st.readDeadline.Reset(deadline.Sub(sc.srv.now())) + st.readDeadline.Reset(deadline.Sub(time.Now())) } }) return nil @@ -2850,7 +2841,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { + if !deadline.IsZero() && deadline.Before(time.Now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onWriteTimeout() @@ -2866,9 +2857,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { if deadline.IsZero() { st.writeDeadline = nil } else if st.writeDeadline == nil { - st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout) + st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout) } else { - st.writeDeadline.Reset(deadline.Sub(sc.srv.now())) + st.writeDeadline.Reset(deadline.Sub(time.Now())) } }) return nil @@ -3147,7 +3138,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error { method: opts.Method, url: u, header: cloneHeader(opts.Header), - done: errChanPool.Get().(chan error), + done: sc.srv.state.getErrChan(), } select { @@ -3164,7 +3155,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error { case <-st.cw: return errStreamClosed case err := <-msg.done: - errChanPool.Put(msg.done) + sc.srv.state.putErrChan(msg.done) return err } } diff --git a/etcd/vendor/golang.org/x/net/http2/timer.go b/etcd/vendor/golang.org/x/net/http2/timer.go deleted file mode 100644 index 0b1c17b812..0000000000 --- a/etcd/vendor/golang.org/x/net/http2/timer.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package http2 - -import "time" - -// A timer is a time.Timer, as an interface which can be replaced in tests. -type timer = interface { - C() <-chan time.Time - Reset(d time.Duration) bool - Stop() bool -} - -// timeTimer adapts a time.Timer to the timer interface. -type timeTimer struct { - *time.Timer -} - -func (t timeTimer) C() <-chan time.Time { return t.Timer.C } diff --git a/etcd/vendor/golang.org/x/net/http2/transport.go b/etcd/vendor/golang.org/x/net/http2/transport.go index f26356b9cd..1965913e54 100644 --- a/etcd/vendor/golang.org/x/net/http2/transport.go +++ b/etcd/vendor/golang.org/x/net/http2/transport.go @@ -9,6 +9,7 @@ package http2 import ( "bufio" "bytes" + "compress/flate" "compress/gzip" "context" "crypto/rand" @@ -193,50 +194,6 @@ type Transport struct { type transportTestHooks struct { newclientconn func(*ClientConn) - group synctestGroupInterface -} - -func (t *Transport) markNewGoroutine() { - if t != nil && t.transportTestHooks != nil { - t.transportTestHooks.group.Join() - } -} - -func (t *Transport) now() time.Time { - if t != nil && t.transportTestHooks != nil { - return t.transportTestHooks.group.Now() - } - return time.Now() -} - -func (t *Transport) timeSince(when time.Time) time.Duration { - if t != nil && t.transportTestHooks != nil { - return t.now().Sub(when) - } - return time.Since(when) -} - -// newTimer creates a new time.Timer, or a synthetic timer in tests. -func (t *Transport) newTimer(d time.Duration) timer { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.NewTimer(d) - } - return timeTimer{time.NewTimer(d)} -} - -// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. -func (t *Transport) afterFunc(d time.Duration, f func()) timer { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.AfterFunc(d, f) - } - return timeTimer{time.AfterFunc(d, f)} -} - -func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.ContextWithTimeout(ctx, d) - } - return context.WithTimeout(ctx, d) } func (t *Transport) maxHeaderListSize() uint32 { @@ -366,7 +323,7 @@ type ClientConn struct { readerErr error // set before readerDone is closed idleTimeout time.Duration // or 0 for never - idleTimer timer + idleTimer *time.Timer mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes @@ -399,6 +356,7 @@ type ClientConn struct { readIdleTimeout time.Duration pingTimeout time.Duration extendedConnectAllowed bool + strictMaxConcurrentStreams bool // rstStreamPingsBlocked works around an unfortunate gRPC behavior. // gRPC strictly limits the number of PING frames that it will receive. @@ -534,14 +492,12 @@ func (cs *clientStream) closeReqBodyLocked() { cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed go func() { - cs.cc.t.markNewGoroutine() cs.reqBody.Close() close(reqBodyClosed) }() } type stickyErrWriter struct { - group synctestGroupInterface conn net.Conn timeout time.Duration err *error @@ -551,7 +507,7 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { if *sew.err != nil { return 0, *sew.err } - n, err = writeWithByteTimeout(sew.group, sew.conn, sew.timeout, p) + n, err = writeWithByteTimeout(sew.conn, sew.timeout, p) *sew.err = err return n, err } @@ -650,9 +606,9 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - tm := t.newTimer(d) + tm := time.NewTimer(d) select { - case <-tm.C(): + case <-tm.C: t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) continue case <-req.Context().Done(): @@ -699,6 +655,7 @@ var ( errClientConnUnusable = errors.New("http2: client conn not usable") errClientConnNotEstablished = errors.New("http2: client conn could not be established") errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") + errClientConnForceClosed = errors.New("http2: client connection force closed via ClientConn.Close") ) // shouldRetryRequest is called by RoundTrip when a request fails to get @@ -829,7 +786,8 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro initialWindowSize: 65535, // spec default initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream, maxConcurrentStreams: initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings. - peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. + strictMaxConcurrentStreams: conf.StrictMaxConcurrentRequests, + peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. streams: make(map[uint32]*clientStream), singleUse: singleUse, seenSettingsChan: make(chan struct{}), @@ -838,14 +796,11 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro pingTimeout: conf.PingTimeout, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), - lastActive: t.now(), + lastActive: time.Now(), } - var group synctestGroupInterface if t.transportTestHooks != nil { - t.markNewGoroutine() t.transportTestHooks.newclientconn(cc) c = cc.tconn - group = t.group } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -857,7 +812,6 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // TODO: adjust this writer size to account for frame size + // MTU + crypto/tls record padding. cc.bw = bufio.NewWriter(stickyErrWriter{ - group: group, conn: c, timeout: conf.WriteByteTimeout, err: &cc.werr, @@ -906,7 +860,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // Start the idle timer after the connection is fully initialized. if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d - cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout) + cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) } go cc.readLoop() @@ -917,7 +871,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.pingTimeout // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout) + ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1067,7 +1021,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { return } var maxConcurrentOkay bool - if cc.t.StrictMaxConcurrentStreams { + if cc.strictMaxConcurrentStreams { // We'll tell the caller we can take a new request to // prevent the caller from dialing a new TCP // connection, but then we'll block later before @@ -1120,7 +1074,7 @@ func (cc *ClientConn) tooIdleLocked() bool { // times are compared based on their wall time. We don't want // to reuse a connection that's been sitting idle during // VM/laptop suspend if monotonic time was also frozen. - return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout + return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout } // onIdleTimeout is called from a time.AfterFunc goroutine. It will @@ -1186,7 +1140,6 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { done := make(chan struct{}) cancelled := false // guarded by cc.mu go func() { - cc.t.markNewGoroutine() cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1257,8 +1210,7 @@ func (cc *ClientConn) closeForError(err error) { // // In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. func (cc *ClientConn) Close() error { - err := errors.New("http2: client connection force closed via ClientConn.Close") - cc.closeForError(err) + cc.closeForError(errClientConnForceClosed) return nil } @@ -1427,7 +1379,6 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) // // It sends the request and performs post-request cleanup (closing Request.Body, etc.). func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) { - cs.cc.t.markNewGoroutine() err := cs.writeRequest(req, streamf) cs.cleanupWriteRequest(err) } @@ -1558,9 +1509,9 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := cc.t.newTimer(d) + timer := time.NewTimer(d) defer timer.Stop() - respHeaderTimer = timer.C() + respHeaderTimer = timer.C respHeaderRecv = cs.respHeaderRecv } // Wait until the peer half-closes its end of the stream, @@ -1753,7 +1704,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { // Return a fatal error which aborts the retry loop. return errClientConnNotEstablished } - cc.lastActive = cc.t.now() + cc.lastActive = time.Now() if cc.closed || !cc.canTakeNewRequestLocked() { return errClientConnUnusable } @@ -2092,10 +2043,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) { if len(cc.streams) != slen-1 { panic("forgetting unknown stream id") } - cc.lastActive = cc.t.now() + cc.lastActive = time.Now() if len(cc.streams) == 0 && cc.idleTimer != nil { cc.idleTimer.Reset(cc.idleTimeout) - cc.lastIdle = cc.t.now() + cc.lastIdle = time.Now() } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. @@ -2121,7 +2072,6 @@ type clientConnReadLoop struct { // readLoop runs in its own goroutine and reads and dispatches frames. func (cc *ClientConn) readLoop() { - cc.t.markNewGoroutine() rl := &clientConnReadLoop{cc: cc} defer rl.cleanup() cc.readerErr = rl.run() @@ -2188,9 +2138,9 @@ func (rl *clientConnReadLoop) cleanup() { if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { unusedWaitTime = cc.idleTimeout } - idleTime := cc.t.now().Sub(cc.lastActive) + idleTime := time.Now().Sub(cc.lastActive) if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { - cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { + cc.idleTimer = time.AfterFunc(unusedWaitTime-idleTime, func() { cc.t.connPool().MarkDead(cc) }) } else { @@ -2250,9 +2200,9 @@ func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false readIdleTimeout := cc.readIdleTimeout - var t timer + var t *time.Timer if readIdleTimeout != 0 { - t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck) + t = time.AfterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -2998,7 +2948,6 @@ func (cc *ClientConn) Ping(ctx context.Context) error { var pingError error errc := make(chan struct{}) go func() { - cc.t.markNewGoroutine() cc.wmu.Lock() defer cc.wmu.Unlock() if pingError = cc.fr.WritePing(false, p); pingError != nil { @@ -3128,35 +3077,102 @@ type erringRoundTripper struct{ err error } func (rt erringRoundTripper) RoundTripErr() error { return rt.err } func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err } +var errConcurrentReadOnResBody = errors.New("http2: concurrent read on response body") + // gzipReader wraps a response body so it can lazily -// call gzip.NewReader on the first call to Read +// get gzip.Reader from the pool on the first call to Read. +// After Close is called it puts gzip.Reader to the pool immediately +// if there is no Read in progress or later when Read completes. type gzipReader struct { _ incomparable body io.ReadCloser // underlying Response.Body - zr *gzip.Reader // lazily-initialized gzip reader - zerr error // sticky error + mu sync.Mutex // guards zr and zerr + zr *gzip.Reader // stores gzip reader from the pool between reads + zerr error // sticky gzip reader init error or sentinel value to detect concurrent read and read after close } -func (gz *gzipReader) Read(p []byte) (n int, err error) { +type eofReader struct{} + +func (eofReader) Read([]byte) (int, error) { return 0, io.EOF } +func (eofReader) ReadByte() (byte, error) { return 0, io.EOF } + +var gzipPool = sync.Pool{New: func() any { return new(gzip.Reader) }} + +// gzipPoolGet gets a gzip.Reader from the pool and resets it to read from r. +func gzipPoolGet(r io.Reader) (*gzip.Reader, error) { + zr := gzipPool.Get().(*gzip.Reader) + if err := zr.Reset(r); err != nil { + gzipPoolPut(zr) + return nil, err + } + return zr, nil +} + +// gzipPoolPut puts a gzip.Reader back into the pool. +func gzipPoolPut(zr *gzip.Reader) { + // Reset will allocate bufio.Reader if we pass it anything + // other than a flate.Reader, so ensure that it's getting one. + var r flate.Reader = eofReader{} + zr.Reset(r) + gzipPool.Put(zr) +} + +// acquire returns a gzip.Reader for reading response body. +// The reader must be released after use. +func (gz *gzipReader) acquire() (*gzip.Reader, error) { + gz.mu.Lock() + defer gz.mu.Unlock() if gz.zerr != nil { - return 0, gz.zerr + return nil, gz.zerr } if gz.zr == nil { - gz.zr, err = gzip.NewReader(gz.body) - if err != nil { - gz.zerr = err - return 0, err + gz.zr, gz.zerr = gzipPoolGet(gz.body) + if gz.zerr != nil { + return nil, gz.zerr } } - return gz.zr.Read(p) + ret := gz.zr + gz.zr, gz.zerr = nil, errConcurrentReadOnResBody + return ret, nil } -func (gz *gzipReader) Close() error { - if err := gz.body.Close(); err != nil { - return err +// release returns the gzip.Reader to the pool if Close was called during Read. +func (gz *gzipReader) release(zr *gzip.Reader) { + gz.mu.Lock() + defer gz.mu.Unlock() + if gz.zerr == errConcurrentReadOnResBody { + gz.zr, gz.zerr = zr, nil + } else { // fs.ErrClosed + gzipPoolPut(zr) + } +} + +// close returns the gzip.Reader to the pool immediately or +// signals release to do so after Read completes. +func (gz *gzipReader) close() { + gz.mu.Lock() + defer gz.mu.Unlock() + if gz.zerr == nil && gz.zr != nil { + gzipPoolPut(gz.zr) + gz.zr = nil } gz.zerr = fs.ErrClosed - return nil +} + +func (gz *gzipReader) Read(p []byte) (n int, err error) { + zr, err := gz.acquire() + if err != nil { + return 0, err + } + defer gz.release(zr) + + return zr.Read(p) +} + +func (gz *gzipReader) Close() error { + gz.close() + + return gz.body.Close() } type errorReader struct{ err error } @@ -3228,7 +3244,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { cc.mu.Lock() ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = cc.t.timeSince(cc.lastActive) + ci.IdleTime = time.Since(cc.lastActive) } cc.mu.Unlock() diff --git a/etcd/vendor/golang.org/x/net/http2/writesched.go b/etcd/vendor/golang.org/x/net/http2/writesched.go index cc893adc29..7de27be525 100644 --- a/etcd/vendor/golang.org/x/net/http2/writesched.go +++ b/etcd/vendor/golang.org/x/net/http2/writesched.go @@ -42,6 +42,8 @@ type OpenStreamOptions struct { // PusherID is zero if the stream was initiated by the client. Otherwise, // PusherID names the stream that pushed the newly opened stream. PusherID uint32 + // priority is used to set the priority of the newly opened stream. + priority PriorityParam } // FrameWriteRequest is a request to write a frame. @@ -183,45 +185,75 @@ func (wr *FrameWriteRequest) replyToWriter(err error) { } // writeQueue is used by implementations of WriteScheduler. +// +// Each writeQueue contains a queue of FrameWriteRequests, meant to store all +// FrameWriteRequests associated with a given stream. This is implemented as a +// two-stage queue: currQueue[currPos:] and nextQueue. Removing an item is done +// by incrementing currPos of currQueue. Adding an item is done by appending it +// to the nextQueue. If currQueue is empty when trying to remove an item, we +// can swap currQueue and nextQueue to remedy the situation. +// This two-stage queue is analogous to the use of two lists in Okasaki's +// purely functional queue but without the overhead of reversing the list when +// swapping stages. +// +// writeQueue also contains prev and next, this can be used by implementations +// of WriteScheduler to construct data structures that represent the order of +// writing between different streams (e.g. circular linked list). type writeQueue struct { - s []FrameWriteRequest + currQueue []FrameWriteRequest + nextQueue []FrameWriteRequest + currPos int + prev, next *writeQueue } -func (q *writeQueue) empty() bool { return len(q.s) == 0 } +func (q *writeQueue) empty() bool { + return (len(q.currQueue) - q.currPos + len(q.nextQueue)) == 0 +} func (q *writeQueue) push(wr FrameWriteRequest) { - q.s = append(q.s, wr) + q.nextQueue = append(q.nextQueue, wr) } func (q *writeQueue) shift() FrameWriteRequest { - if len(q.s) == 0 { + if q.empty() { panic("invalid use of queue") } - wr := q.s[0] - // TODO: less copy-happy queue. - copy(q.s, q.s[1:]) - q.s[len(q.s)-1] = FrameWriteRequest{} - q.s = q.s[:len(q.s)-1] + if q.currPos >= len(q.currQueue) { + q.currQueue, q.currPos, q.nextQueue = q.nextQueue, 0, q.currQueue[:0] + } + wr := q.currQueue[q.currPos] + q.currQueue[q.currPos] = FrameWriteRequest{} + q.currPos++ return wr } +func (q *writeQueue) peek() *FrameWriteRequest { + if q.currPos < len(q.currQueue) { + return &q.currQueue[q.currPos] + } + if len(q.nextQueue) > 0 { + return &q.nextQueue[0] + } + return nil +} + // consume consumes up to n bytes from q.s[0]. If the frame is // entirely consumed, it is removed from the queue. If the frame // is partially consumed, the frame is kept with the consumed // bytes removed. Returns true iff any bytes were consumed. func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) { - if len(q.s) == 0 { + if q.empty() { return FrameWriteRequest{}, false } - consumed, rest, numresult := q.s[0].Consume(n) + consumed, rest, numresult := q.peek().Consume(n) switch numresult { case 0: return FrameWriteRequest{}, false case 1: q.shift() case 2: - q.s[0] = rest + *q.peek() = rest } return consumed, true } @@ -230,10 +262,15 @@ type writeQueuePool []*writeQueue // put inserts an unused writeQueue into the pool. func (p *writeQueuePool) put(q *writeQueue) { - for i := range q.s { - q.s[i] = FrameWriteRequest{} + for i := range q.currQueue { + q.currQueue[i] = FrameWriteRequest{} + } + for i := range q.nextQueue { + q.nextQueue[i] = FrameWriteRequest{} } - q.s = q.s[:0] + q.currQueue = q.currQueue[:0] + q.nextQueue = q.nextQueue[:0] + q.currPos = 0 *p = append(*p, q) } diff --git a/etcd/vendor/golang.org/x/net/http2/writesched_priority.go b/etcd/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go similarity index 77% rename from etcd/vendor/golang.org/x/net/http2/writesched_priority.go rename to etcd/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go index f6783339d1..4e33c29a24 100644 --- a/etcd/vendor/golang.org/x/net/http2/writesched_priority.go +++ b/etcd/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go @@ -11,7 +11,7 @@ import ( ) // RFC 7540, Section 5.3.5: the default weight is 16. -const priorityDefaultWeight = 15 // 16 = 15 + 1 +const priorityDefaultWeightRFC7540 = 15 // 16 = 15 + 1 // PriorityWriteSchedulerConfig configures a priorityWriteScheduler. type PriorityWriteSchedulerConfig struct { @@ -66,8 +66,8 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler } } - ws := &priorityWriteScheduler{ - nodes: make(map[uint32]*priorityNode), + ws := &priorityWriteSchedulerRFC7540{ + nodes: make(map[uint32]*priorityNodeRFC7540), maxClosedNodesInTree: cfg.MaxClosedNodesInTree, maxIdleNodesInTree: cfg.MaxIdleNodesInTree, enableWriteThrottle: cfg.ThrottleOutOfOrderWrites, @@ -81,32 +81,32 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler return ws } -type priorityNodeState int +type priorityNodeStateRFC7540 int const ( - priorityNodeOpen priorityNodeState = iota - priorityNodeClosed - priorityNodeIdle + priorityNodeOpenRFC7540 priorityNodeStateRFC7540 = iota + priorityNodeClosedRFC7540 + priorityNodeIdleRFC7540 ) -// priorityNode is a node in an HTTP/2 priority tree. +// priorityNodeRFC7540 is a node in an HTTP/2 priority tree. // Each node is associated with a single stream ID. // See RFC 7540, Section 5.3. -type priorityNode struct { - q writeQueue // queue of pending frames to write - id uint32 // id of the stream, or 0 for the root of the tree - weight uint8 // the actual weight is weight+1, so the value is in [1,256] - state priorityNodeState // open | closed | idle - bytes int64 // number of bytes written by this node, or 0 if closed - subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree +type priorityNodeRFC7540 struct { + q writeQueue // queue of pending frames to write + id uint32 // id of the stream, or 0 for the root of the tree + weight uint8 // the actual weight is weight+1, so the value is in [1,256] + state priorityNodeStateRFC7540 // open | closed | idle + bytes int64 // number of bytes written by this node, or 0 if closed + subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree // These links form the priority tree. - parent *priorityNode - kids *priorityNode // start of the kids list - prev, next *priorityNode // doubly-linked list of siblings + parent *priorityNodeRFC7540 + kids *priorityNodeRFC7540 // start of the kids list + prev, next *priorityNodeRFC7540 // doubly-linked list of siblings } -func (n *priorityNode) setParent(parent *priorityNode) { +func (n *priorityNodeRFC7540) setParent(parent *priorityNodeRFC7540) { if n == parent { panic("setParent to self") } @@ -141,7 +141,7 @@ func (n *priorityNode) setParent(parent *priorityNode) { } } -func (n *priorityNode) addBytes(b int64) { +func (n *priorityNodeRFC7540) addBytes(b int64) { n.bytes += b for ; n != nil; n = n.parent { n.subtreeBytes += b @@ -154,7 +154,7 @@ func (n *priorityNode) addBytes(b int64) { // // f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true // if any ancestor p of n is still open (ignoring the root node). -func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool { +func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priorityNodeRFC7540, f func(*priorityNodeRFC7540, bool) bool) bool { if !n.q.empty() && f(n, openParent) { return true } @@ -165,7 +165,7 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f // Don't consider the root "open" when updating openParent since // we can't send data frames on the root stream (only control frames). if n.id != 0 { - openParent = openParent || (n.state == priorityNodeOpen) + openParent = openParent || (n.state == priorityNodeOpenRFC7540) } // Common case: only one kid or all kids have the same weight. @@ -195,7 +195,7 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f *tmp = append(*tmp, n.kids) n.kids.setParent(nil) } - sort.Sort(sortPriorityNodeSiblings(*tmp)) + sort.Sort(sortPriorityNodeSiblingsRFC7540(*tmp)) for i := len(*tmp) - 1; i >= 0; i-- { (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids } @@ -207,15 +207,15 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f return false } -type sortPriorityNodeSiblings []*priorityNode +type sortPriorityNodeSiblingsRFC7540 []*priorityNodeRFC7540 -func (z sortPriorityNodeSiblings) Len() int { return len(z) } -func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] } -func (z sortPriorityNodeSiblings) Less(i, k int) bool { +func (z sortPriorityNodeSiblingsRFC7540) Len() int { return len(z) } +func (z sortPriorityNodeSiblingsRFC7540) Swap(i, k int) { z[i], z[k] = z[k], z[i] } +func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool { // Prefer the subtree that has sent fewer bytes relative to its weight. // See sections 5.3.2 and 5.3.4. - wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes) - wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes) + wi, bi := float64(z[i].weight)+1, float64(z[i].subtreeBytes) + wk, bk := float64(z[k].weight)+1, float64(z[k].subtreeBytes) if bi == 0 && bk == 0 { return wi >= wk } @@ -225,13 +225,13 @@ func (z sortPriorityNodeSiblings) Less(i, k int) bool { return bi/bk <= wi/wk } -type priorityWriteScheduler struct { +type priorityWriteSchedulerRFC7540 struct { // root is the root of the priority tree, where root.id = 0. // The root queues control frames that are not associated with any stream. - root priorityNode + root priorityNodeRFC7540 // nodes maps stream ids to priority tree nodes. - nodes map[uint32]*priorityNode + nodes map[uint32]*priorityNodeRFC7540 // maxID is the maximum stream id in nodes. maxID uint32 @@ -239,7 +239,7 @@ type priorityWriteScheduler struct { // lists of nodes that have been closed or are idle, but are kept in // the tree for improved prioritization. When the lengths exceed either // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded. - closedNodes, idleNodes []*priorityNode + closedNodes, idleNodes []*priorityNodeRFC7540 // From the config. maxClosedNodesInTree int @@ -248,19 +248,19 @@ type priorityWriteScheduler struct { enableWriteThrottle bool // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations. - tmp []*priorityNode + tmp []*priorityNodeRFC7540 // pool of empty queues for reuse. queuePool writeQueuePool } -func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { +func (ws *priorityWriteSchedulerRFC7540) OpenStream(streamID uint32, options OpenStreamOptions) { // The stream may be currently idle but cannot be opened or closed. if curr := ws.nodes[streamID]; curr != nil { - if curr.state != priorityNodeIdle { + if curr.state != priorityNodeIdleRFC7540 { panic(fmt.Sprintf("stream %d already opened", streamID)) } - curr.state = priorityNodeOpen + curr.state = priorityNodeOpenRFC7540 return } @@ -272,11 +272,11 @@ func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStream if parent == nil { parent = &ws.root } - n := &priorityNode{ + n := &priorityNodeRFC7540{ q: *ws.queuePool.get(), id: streamID, - weight: priorityDefaultWeight, - state: priorityNodeOpen, + weight: priorityDefaultWeightRFC7540, + state: priorityNodeOpenRFC7540, } n.setParent(parent) ws.nodes[streamID] = n @@ -285,24 +285,23 @@ func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStream } } -func (ws *priorityWriteScheduler) CloseStream(streamID uint32) { +func (ws *priorityWriteSchedulerRFC7540) CloseStream(streamID uint32) { if streamID == 0 { panic("violation of WriteScheduler interface: cannot close stream 0") } if ws.nodes[streamID] == nil { panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID)) } - if ws.nodes[streamID].state != priorityNodeOpen { + if ws.nodes[streamID].state != priorityNodeOpenRFC7540 { panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID)) } n := ws.nodes[streamID] - n.state = priorityNodeClosed + n.state = priorityNodeClosedRFC7540 n.addBytes(-n.bytes) q := n.q ws.queuePool.put(&q) - n.q.s = nil if ws.maxClosedNodesInTree > 0 { ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n) } else { @@ -310,7 +309,7 @@ func (ws *priorityWriteScheduler) CloseStream(streamID uint32) { } } -func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) { +func (ws *priorityWriteSchedulerRFC7540) AdjustStream(streamID uint32, priority PriorityParam) { if streamID == 0 { panic("adjustPriority on root") } @@ -324,11 +323,11 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit return } ws.maxID = streamID - n = &priorityNode{ + n = &priorityNodeRFC7540{ q: *ws.queuePool.get(), id: streamID, - weight: priorityDefaultWeight, - state: priorityNodeIdle, + weight: priorityDefaultWeightRFC7540, + state: priorityNodeIdleRFC7540, } n.setParent(&ws.root) ws.nodes[streamID] = n @@ -340,7 +339,7 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit parent := ws.nodes[priority.StreamDep] if parent == nil { n.setParent(&ws.root) - n.weight = priorityDefaultWeight + n.weight = priorityDefaultWeightRFC7540 return } @@ -381,8 +380,8 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit n.weight = priority.Weight } -func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { - var n *priorityNode +func (ws *priorityWriteSchedulerRFC7540) Push(wr FrameWriteRequest) { + var n *priorityNodeRFC7540 if wr.isControl() { n = &ws.root } else { @@ -401,8 +400,8 @@ func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { n.q.push(wr) } -func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) { - ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool { +func (ws *priorityWriteSchedulerRFC7540) Pop() (wr FrameWriteRequest, ok bool) { + ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNodeRFC7540, openParent bool) bool { limit := int32(math.MaxInt32) if openParent { limit = ws.writeThrottleLimit @@ -428,7 +427,7 @@ func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) { return wr, ok } -func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) { +func (ws *priorityWriteSchedulerRFC7540) addClosedOrIdleNode(list *[]*priorityNodeRFC7540, maxSize int, n *priorityNodeRFC7540) { if maxSize == 0 { return } @@ -442,7 +441,7 @@ func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, max *list = append(*list, n) } -func (ws *priorityWriteScheduler) removeNode(n *priorityNode) { +func (ws *priorityWriteSchedulerRFC7540) removeNode(n *priorityNodeRFC7540) { for n.kids != nil { n.kids.setParent(n.parent) } diff --git a/etcd/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go b/etcd/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go new file mode 100644 index 0000000000..cb4cadc32d --- /dev/null +++ b/etcd/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go @@ -0,0 +1,209 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http2 + +import ( + "fmt" + "math" +) + +type streamMetadata struct { + location *writeQueue + priority PriorityParam +} + +type priorityWriteSchedulerRFC9218 struct { + // control contains control frames (SETTINGS, PING, etc.). + control writeQueue + + // heads contain the head of a circular list of streams. + // We put these heads within a nested array that represents urgency and + // incremental, as defined in + // https://www.rfc-editor.org/rfc/rfc9218.html#name-priority-parameters. + // 8 represents u=0 up to u=7, and 2 represents i=false and i=true. + heads [8][2]*writeQueue + + // streams contains a mapping between each stream ID and their metadata, so + // we can quickly locate them when needing to, for example, adjust their + // priority. + streams map[uint32]streamMetadata + + // queuePool are empty queues for reuse. + queuePool writeQueuePool + + // prioritizeIncremental is used to determine whether we should prioritize + // incremental streams or not, when urgency is the same in a given Pop() + // call. + prioritizeIncremental bool +} + +func newPriorityWriteSchedulerRFC9218() WriteScheduler { + ws := &priorityWriteSchedulerRFC9218{ + streams: make(map[uint32]streamMetadata), + } + return ws +} + +func (ws *priorityWriteSchedulerRFC9218) OpenStream(streamID uint32, opt OpenStreamOptions) { + if ws.streams[streamID].location != nil { + panic(fmt.Errorf("stream %d already opened", streamID)) + } + q := ws.queuePool.get() + ws.streams[streamID] = streamMetadata{ + location: q, + priority: opt.priority, + } + + u, i := opt.priority.urgency, opt.priority.incremental + if ws.heads[u][i] == nil { + ws.heads[u][i] = q + q.next = q + q.prev = q + } else { + // Queues are stored in a ring. + // Insert the new stream before ws.head, putting it at the end of the list. + q.prev = ws.heads[u][i].prev + q.next = ws.heads[u][i] + q.prev.next = q + q.next.prev = q + } +} + +func (ws *priorityWriteSchedulerRFC9218) CloseStream(streamID uint32) { + metadata := ws.streams[streamID] + q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental + if q == nil { + return + } + if q.next == q { + // This was the only open stream. + ws.heads[u][i] = nil + } else { + q.prev.next = q.next + q.next.prev = q.prev + if ws.heads[u][i] == q { + ws.heads[u][i] = q.next + } + } + delete(ws.streams, streamID) + ws.queuePool.put(q) +} + +func (ws *priorityWriteSchedulerRFC9218) AdjustStream(streamID uint32, priority PriorityParam) { + metadata := ws.streams[streamID] + q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental + if q == nil { + return + } + + // Remove stream from current location. + if q.next == q { + // This was the only open stream. + ws.heads[u][i] = nil + } else { + q.prev.next = q.next + q.next.prev = q.prev + if ws.heads[u][i] == q { + ws.heads[u][i] = q.next + } + } + + // Insert stream to the new queue. + u, i = priority.urgency, priority.incremental + if ws.heads[u][i] == nil { + ws.heads[u][i] = q + q.next = q + q.prev = q + } else { + // Queues are stored in a ring. + // Insert the new stream before ws.head, putting it at the end of the list. + q.prev = ws.heads[u][i].prev + q.next = ws.heads[u][i] + q.prev.next = q + q.next.prev = q + } + + // Update the metadata. + ws.streams[streamID] = streamMetadata{ + location: q, + priority: priority, + } +} + +func (ws *priorityWriteSchedulerRFC9218) Push(wr FrameWriteRequest) { + if wr.isControl() { + ws.control.push(wr) + return + } + q := ws.streams[wr.StreamID()].location + if q == nil { + // This is a closed stream. + // wr should not be a HEADERS or DATA frame. + // We push the request onto the control queue. + if wr.DataSize() > 0 { + panic("add DATA on non-open stream") + } + ws.control.push(wr) + return + } + q.push(wr) +} + +func (ws *priorityWriteSchedulerRFC9218) Pop() (FrameWriteRequest, bool) { + // Control and RST_STREAM frames first. + if !ws.control.empty() { + return ws.control.shift(), true + } + + // On the next Pop(), we want to prioritize incremental if we prioritized + // non-incremental request of the same urgency this time. Vice-versa. + // i.e. when there are incremental and non-incremental requests at the same + // priority, we give 50% of our bandwidth to the incremental ones in + // aggregate and 50% to the first non-incremental one (since + // non-incremental streams do not use round-robin writes). + ws.prioritizeIncremental = !ws.prioritizeIncremental + + // Always prioritize lowest u (i.e. highest urgency level). + for u := range ws.heads { + for i := range ws.heads[u] { + // When we want to prioritize incremental, we try to pop i=true + // first before i=false when u is the same. + if ws.prioritizeIncremental { + i = (i + 1) % 2 + } + q := ws.heads[u][i] + if q == nil { + continue + } + for { + if wr, ok := q.consume(math.MaxInt32); ok { + if i == 1 { + // For incremental streams, we update head to q.next so + // we can round-robin between multiple streams that can + // immediately benefit from partial writes. + ws.heads[u][i] = q.next + } else { + // For non-incremental streams, we try to finish one to + // completion rather than doing round-robin. However, + // we update head here so that if q.consume() is !ok + // (e.g. the stream has no more frame to consume), head + // is updated to the next q that has frames to consume + // on future iterations. This way, we do not prioritize + // writing to unavailable stream on next Pop() calls, + // preventing head-of-line blocking. + ws.heads[u][i] = q + } + return wr, true + } + q = q.next + if q == ws.heads[u][i] { + break + } + } + + } + } + return FrameWriteRequest{}, false +} diff --git a/etcd/vendor/golang.org/x/net/http2/writesched_roundrobin.go b/etcd/vendor/golang.org/x/net/http2/writesched_roundrobin.go index 54fe86322d..737cff9ecb 100644 --- a/etcd/vendor/golang.org/x/net/http2/writesched_roundrobin.go +++ b/etcd/vendor/golang.org/x/net/http2/writesched_roundrobin.go @@ -25,7 +25,7 @@ type roundRobinWriteScheduler struct { } // newRoundRobinWriteScheduler constructs a new write scheduler. -// The round robin scheduler priorizes control frames +// The round robin scheduler prioritizes control frames // like SETTINGS and PING over DATA frames. // When there are no control frames to send, it performs a round-robin // selection from the ready streams. diff --git a/etcd/vendor/golang.org/x/net/internal/httpcommon/request.go b/etcd/vendor/golang.org/x/net/internal/httpcommon/request.go index 4b70553179..1e10f89ebf 100644 --- a/etcd/vendor/golang.org/x/net/internal/httpcommon/request.go +++ b/etcd/vendor/golang.org/x/net/internal/httpcommon/request.go @@ -51,7 +51,7 @@ type EncodeHeadersParam struct { DefaultUserAgent string } -// EncodeHeadersParam is the result of EncodeHeaders. +// EncodeHeadersResult is the result of EncodeHeaders. type EncodeHeadersResult struct { HasBody bool HasTrailers bool @@ -399,7 +399,7 @@ type ServerRequestResult struct { // If the request should be rejected, this is a short string suitable for passing // to the http2 package's CountError function. - // It might be a bit odd to return errors this way rather than returing an error, + // It might be a bit odd to return errors this way rather than returning an error, // but this ensures we don't forget to include a CountError reason. InvalidReason string } diff --git a/etcd/vendor/golang.org/x/net/internal/socks/socks.go b/etcd/vendor/golang.org/x/net/internal/socks/socks.go index 84fcc32b63..8eedb84cec 100644 --- a/etcd/vendor/golang.org/x/net/internal/socks/socks.go +++ b/etcd/vendor/golang.org/x/net/internal/socks/socks.go @@ -297,7 +297,7 @@ func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, b = append(b, up.Username...) b = append(b, byte(len(up.Password))) b = append(b, up.Password...) - // TODO(mikio): handle IO deadlines and cancelation if + // TODO(mikio): handle IO deadlines and cancellation if // necessary if _, err := rw.Write(b); err != nil { return err diff --git a/etcd/vendor/golang.org/x/sync/errgroup/errgroup.go b/etcd/vendor/golang.org/x/sync/errgroup/errgroup.go index 1d8cffae8c..2f45dbc86e 100644 --- a/etcd/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/etcd/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package errgroup provides synchronization, error propagation, and Context -// cancelation for groups of goroutines working on subtasks of a common task. +// cancellation for groups of goroutines working on subtasks of a common task. // // [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks // returning errors. diff --git a/etcd/vendor/golang.org/x/sys/unix/affinity_linux.go b/etcd/vendor/golang.org/x/sys/unix/affinity_linux.go index 3c7a6d6e2f..3ea470387b 100644 --- a/etcd/vendor/golang.org/x/sys/unix/affinity_linux.go +++ b/etcd/vendor/golang.org/x/sys/unix/affinity_linux.go @@ -41,6 +41,15 @@ func (s *CPUSet) Zero() { clear(s[:]) } +// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity] +// will silently ignore any invalid CPU bits in [CPUSet] so this is an +// efficient way of resetting the CPU affinity of a process. +func (s *CPUSet) Fill() { + for i := range s { + s[i] = ^cpuMask(0) + } +} + func cpuBitsIndex(cpu int) int { return cpu / _NCPUBITS } diff --git a/etcd/vendor/golang.org/x/sys/unix/fdset.go b/etcd/vendor/golang.org/x/sys/unix/fdset.go index 9e83d18cd0..62ed12645f 100644 --- a/etcd/vendor/golang.org/x/sys/unix/fdset.go +++ b/etcd/vendor/golang.org/x/sys/unix/fdset.go @@ -23,7 +23,5 @@ func (fds *FdSet) IsSet(fd int) bool { // Zero clears the set fds. func (fds *FdSet) Zero() { - for i := range fds.Bits { - fds.Bits[i] = 0 - } + clear(fds.Bits[:]) } diff --git a/etcd/vendor/golang.org/x/sys/unix/ifreq_linux.go b/etcd/vendor/golang.org/x/sys/unix/ifreq_linux.go index 848840ae4c..309f5a2b0c 100644 --- a/etcd/vendor/golang.org/x/sys/unix/ifreq_linux.go +++ b/etcd/vendor/golang.org/x/sys/unix/ifreq_linux.go @@ -111,9 +111,7 @@ func (ifr *Ifreq) SetUint32(v uint32) { // clear zeroes the ifreq's union field to prevent trailing garbage data from // being sent to the kernel if an ifreq is reused. func (ifr *Ifreq) clear() { - for i := range ifr.raw.Ifru { - ifr.raw.Ifru[i] = 0 - } + clear(ifr.raw.Ifru[:]) } // TODO(mdlayher): export as IfreqData? For now we can provide helpers such as diff --git a/etcd/vendor/golang.org/x/sys/unix/mkall.sh b/etcd/vendor/golang.org/x/sys/unix/mkall.sh index e6f31d374d..d0ed611912 100644 --- a/etcd/vendor/golang.org/x/sys/unix/mkall.sh +++ b/etcd/vendor/golang.org/x/sys/unix/mkall.sh @@ -49,6 +49,7 @@ esac if [[ "$GOOS" = "linux" ]]; then # Use the Docker-based build system # Files generated through docker (use $cmd so you can Ctl-C the build or run) + set -e $cmd docker build --tag generate:$GOOS $GOOS $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS exit diff --git a/etcd/vendor/golang.org/x/sys/unix/mkerrors.sh b/etcd/vendor/golang.org/x/sys/unix/mkerrors.sh index d1c8b2640e..42517077c4 100644 --- a/etcd/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/etcd/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -226,6 +226,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -529,6 +530,7 @@ ccflags="$@" $2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ || + $2 ~ /^(DT|EI|ELF|EV|NN|NT|PF|SHF|SHN|SHT|STB|STT|VER)_/ || $2 ~ /^O?XTABS$/ || $2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^IN_/ || diff --git a/etcd/vendor/golang.org/x/sys/unix/syscall_linux.go b/etcd/vendor/golang.org/x/sys/unix/syscall_linux.go index 4958a65708..06c0eea6fb 100644 --- a/etcd/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/etcd/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -801,9 +801,7 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { // one. The kernel expects SID to be in network byte order. binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) copy(sa.raw[8:14], sa.Remote) - for i := 14; i < 14+IFNAMSIZ; i++ { - sa.raw[i] = 0 - } + clear(sa.raw[14 : 14+IFNAMSIZ]) copy(sa.raw[14:], sa.Dev) return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil } @@ -2645,3 +2643,9 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) //sys Mseal(b []byte, flags uint) (err error) + +//sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY + +func SetMemPolicy(mode int, mask *CPUSet) error { + return setMemPolicy(mode, mask, _CPU_SETSIZE) +} diff --git a/etcd/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/etcd/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 88162099af..34a4676973 100644 --- a/etcd/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/etcd/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -248,6 +248,23 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { return Statvfs1(path, buf, ST_WAIT) } +func Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) { + var ( + _p0 unsafe.Pointer + bufsize uintptr + ) + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + bufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf)) + } + r0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + /* * Exposed directly */ diff --git a/etcd/vendor/golang.org/x/sys/unix/zerrors_linux.go b/etcd/vendor/golang.org/x/sys/unix/zerrors_linux.go index b6db27d937..d0a75da572 100644 --- a/etcd/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/etcd/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -853,20 +853,86 @@ const ( DM_VERSION_MAJOR = 0x4 DM_VERSION_MINOR = 0x32 DM_VERSION_PATCHLEVEL = 0x0 + DT_ADDRRNGHI = 0x6ffffeff + DT_ADDRRNGLO = 0x6ffffe00 DT_BLK = 0x6 DT_CHR = 0x2 + DT_DEBUG = 0x15 DT_DIR = 0x4 + DT_ENCODING = 0x20 DT_FIFO = 0x1 + DT_FINI = 0xd + DT_FLAGS_1 = 0x6ffffffb + DT_GNU_HASH = 0x6ffffef5 + DT_HASH = 0x4 + DT_HIOS = 0x6ffff000 + DT_HIPROC = 0x7fffffff + DT_INIT = 0xc + DT_JMPREL = 0x17 DT_LNK = 0xa + DT_LOOS = 0x6000000d + DT_LOPROC = 0x70000000 + DT_NEEDED = 0x1 + DT_NULL = 0x0 + DT_PLTGOT = 0x3 + DT_PLTREL = 0x14 + DT_PLTRELSZ = 0x2 DT_REG = 0x8 + DT_REL = 0x11 + DT_RELA = 0x7 + DT_RELACOUNT = 0x6ffffff9 + DT_RELAENT = 0x9 + DT_RELASZ = 0x8 + DT_RELCOUNT = 0x6ffffffa + DT_RELENT = 0x13 + DT_RELSZ = 0x12 + DT_RPATH = 0xf DT_SOCK = 0xc + DT_SONAME = 0xe + DT_STRSZ = 0xa + DT_STRTAB = 0x5 + DT_SYMBOLIC = 0x10 + DT_SYMENT = 0xb + DT_SYMTAB = 0x6 + DT_TEXTREL = 0x16 DT_UNKNOWN = 0x0 + DT_VALRNGHI = 0x6ffffdff + DT_VALRNGLO = 0x6ffffd00 + DT_VERDEF = 0x6ffffffc + DT_VERDEFNUM = 0x6ffffffd + DT_VERNEED = 0x6ffffffe + DT_VERNEEDNUM = 0x6fffffff + DT_VERSYM = 0x6ffffff0 DT_WHT = 0xe ECHO = 0x8 ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_SEMAPHORE = 0x1 EFIVARFS_MAGIC = 0xde5e81e4 EFS_SUPER_MAGIC = 0x414a53 + EI_CLASS = 0x4 + EI_DATA = 0x5 + EI_MAG0 = 0x0 + EI_MAG1 = 0x1 + EI_MAG2 = 0x2 + EI_MAG3 = 0x3 + EI_NIDENT = 0x10 + EI_OSABI = 0x7 + EI_PAD = 0x8 + EI_VERSION = 0x6 + ELFCLASS32 = 0x1 + ELFCLASS64 = 0x2 + ELFCLASSNONE = 0x0 + ELFCLASSNUM = 0x3 + ELFDATA2LSB = 0x1 + ELFDATA2MSB = 0x2 + ELFDATANONE = 0x0 + ELFMAG = "\177ELF" + ELFMAG0 = 0x7f + ELFMAG1 = 'E' + ELFMAG2 = 'L' + ELFMAG3 = 'F' + ELFOSABI_LINUX = 0x3 + ELFOSABI_NONE = 0x0 EM_386 = 0x3 EM_486 = 0x6 EM_68K = 0x4 @@ -1152,14 +1218,24 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + ET_CORE = 0x4 + ET_DYN = 0x3 + ET_EXEC = 0x2 + ET_HIPROC = 0xffff + ET_LOPROC = 0xff00 + ET_NONE = 0x0 + ET_REL = 0x1 EV_ABS = 0x3 EV_CNT = 0x20 + EV_CURRENT = 0x1 EV_FF = 0x15 EV_FF_STATUS = 0x17 EV_KEY = 0x1 EV_LED = 0x11 EV_MAX = 0x1f EV_MSC = 0x4 + EV_NONE = 0x0 + EV_NUM = 0x2 EV_PWR = 0x16 EV_REL = 0x2 EV_REP = 0x14 @@ -2276,7 +2352,167 @@ const ( NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 + NN_386_IOPERM = "LINUX" + NN_386_TLS = "LINUX" + NN_ARC_V2 = "LINUX" + NN_ARM_FPMR = "LINUX" + NN_ARM_GCS = "LINUX" + NN_ARM_HW_BREAK = "LINUX" + NN_ARM_HW_WATCH = "LINUX" + NN_ARM_PACA_KEYS = "LINUX" + NN_ARM_PACG_KEYS = "LINUX" + NN_ARM_PAC_ENABLED_KEYS = "LINUX" + NN_ARM_PAC_MASK = "LINUX" + NN_ARM_POE = "LINUX" + NN_ARM_SSVE = "LINUX" + NN_ARM_SVE = "LINUX" + NN_ARM_SYSTEM_CALL = "LINUX" + NN_ARM_TAGGED_ADDR_CTRL = "LINUX" + NN_ARM_TLS = "LINUX" + NN_ARM_VFP = "LINUX" + NN_ARM_ZA = "LINUX" + NN_ARM_ZT = "LINUX" + NN_AUXV = "CORE" + NN_FILE = "CORE" + NN_GNU_PROPERTY_TYPE_0 = "GNU" + NN_LOONGARCH_CPUCFG = "LINUX" + NN_LOONGARCH_CSR = "LINUX" + NN_LOONGARCH_HW_BREAK = "LINUX" + NN_LOONGARCH_HW_WATCH = "LINUX" + NN_LOONGARCH_LASX = "LINUX" + NN_LOONGARCH_LBT = "LINUX" + NN_LOONGARCH_LSX = "LINUX" + NN_MIPS_DSP = "LINUX" + NN_MIPS_FP_MODE = "LINUX" + NN_MIPS_MSA = "LINUX" + NN_PPC_DEXCR = "LINUX" + NN_PPC_DSCR = "LINUX" + NN_PPC_EBB = "LINUX" + NN_PPC_HASHKEYR = "LINUX" + NN_PPC_PKEY = "LINUX" + NN_PPC_PMU = "LINUX" + NN_PPC_PPR = "LINUX" + NN_PPC_SPE = "LINUX" + NN_PPC_TAR = "LINUX" + NN_PPC_TM_CDSCR = "LINUX" + NN_PPC_TM_CFPR = "LINUX" + NN_PPC_TM_CGPR = "LINUX" + NN_PPC_TM_CPPR = "LINUX" + NN_PPC_TM_CTAR = "LINUX" + NN_PPC_TM_CVMX = "LINUX" + NN_PPC_TM_CVSX = "LINUX" + NN_PPC_TM_SPR = "LINUX" + NN_PPC_VMX = "LINUX" + NN_PPC_VSX = "LINUX" + NN_PRFPREG = "CORE" + NN_PRPSINFO = "CORE" + NN_PRSTATUS = "CORE" + NN_PRXFPREG = "LINUX" + NN_RISCV_CSR = "LINUX" + NN_RISCV_TAGGED_ADDR_CTRL = "LINUX" + NN_RISCV_VECTOR = "LINUX" + NN_S390_CTRS = "LINUX" + NN_S390_GS_BC = "LINUX" + NN_S390_GS_CB = "LINUX" + NN_S390_HIGH_GPRS = "LINUX" + NN_S390_LAST_BREAK = "LINUX" + NN_S390_PREFIX = "LINUX" + NN_S390_PV_CPU_DATA = "LINUX" + NN_S390_RI_CB = "LINUX" + NN_S390_SYSTEM_CALL = "LINUX" + NN_S390_TDB = "LINUX" + NN_S390_TIMER = "LINUX" + NN_S390_TODCMP = "LINUX" + NN_S390_TODPREG = "LINUX" + NN_S390_VXRS_HIGH = "LINUX" + NN_S390_VXRS_LOW = "LINUX" + NN_SIGINFO = "CORE" + NN_TASKSTRUCT = "CORE" + NN_VMCOREDD = "LINUX" + NN_X86_SHSTK = "LINUX" + NN_X86_XSAVE_LAYOUT = "LINUX" + NN_X86_XSTATE = "LINUX" NSFS_MAGIC = 0x6e736673 + NT_386_IOPERM = 0x201 + NT_386_TLS = 0x200 + NT_ARC_V2 = 0x600 + NT_ARM_FPMR = 0x40e + NT_ARM_GCS = 0x410 + NT_ARM_HW_BREAK = 0x402 + NT_ARM_HW_WATCH = 0x403 + NT_ARM_PACA_KEYS = 0x407 + NT_ARM_PACG_KEYS = 0x408 + NT_ARM_PAC_ENABLED_KEYS = 0x40a + NT_ARM_PAC_MASK = 0x406 + NT_ARM_POE = 0x40f + NT_ARM_SSVE = 0x40b + NT_ARM_SVE = 0x405 + NT_ARM_SYSTEM_CALL = 0x404 + NT_ARM_TAGGED_ADDR_CTRL = 0x409 + NT_ARM_TLS = 0x401 + NT_ARM_VFP = 0x400 + NT_ARM_ZA = 0x40c + NT_ARM_ZT = 0x40d + NT_AUXV = 0x6 + NT_FILE = 0x46494c45 + NT_GNU_PROPERTY_TYPE_0 = 0x5 + NT_LOONGARCH_CPUCFG = 0xa00 + NT_LOONGARCH_CSR = 0xa01 + NT_LOONGARCH_HW_BREAK = 0xa05 + NT_LOONGARCH_HW_WATCH = 0xa06 + NT_LOONGARCH_LASX = 0xa03 + NT_LOONGARCH_LBT = 0xa04 + NT_LOONGARCH_LSX = 0xa02 + NT_MIPS_DSP = 0x800 + NT_MIPS_FP_MODE = 0x801 + NT_MIPS_MSA = 0x802 + NT_PPC_DEXCR = 0x111 + NT_PPC_DSCR = 0x105 + NT_PPC_EBB = 0x106 + NT_PPC_HASHKEYR = 0x112 + NT_PPC_PKEY = 0x110 + NT_PPC_PMU = 0x107 + NT_PPC_PPR = 0x104 + NT_PPC_SPE = 0x101 + NT_PPC_TAR = 0x103 + NT_PPC_TM_CDSCR = 0x10f + NT_PPC_TM_CFPR = 0x109 + NT_PPC_TM_CGPR = 0x108 + NT_PPC_TM_CPPR = 0x10e + NT_PPC_TM_CTAR = 0x10d + NT_PPC_TM_CVMX = 0x10a + NT_PPC_TM_CVSX = 0x10b + NT_PPC_TM_SPR = 0x10c + NT_PPC_VMX = 0x100 + NT_PPC_VSX = 0x102 + NT_PRFPREG = 0x2 + NT_PRPSINFO = 0x3 + NT_PRSTATUS = 0x1 + NT_PRXFPREG = 0x46e62b7f + NT_RISCV_CSR = 0x900 + NT_RISCV_TAGGED_ADDR_CTRL = 0x902 + NT_RISCV_VECTOR = 0x901 + NT_S390_CTRS = 0x304 + NT_S390_GS_BC = 0x30c + NT_S390_GS_CB = 0x30b + NT_S390_HIGH_GPRS = 0x300 + NT_S390_LAST_BREAK = 0x306 + NT_S390_PREFIX = 0x305 + NT_S390_PV_CPU_DATA = 0x30e + NT_S390_RI_CB = 0x30d + NT_S390_SYSTEM_CALL = 0x307 + NT_S390_TDB = 0x308 + NT_S390_TIMER = 0x301 + NT_S390_TODCMP = 0x302 + NT_S390_TODPREG = 0x303 + NT_S390_VXRS_HIGH = 0x30a + NT_S390_VXRS_LOW = 0x309 + NT_SIGINFO = 0x53494749 + NT_TASKSTRUCT = 0x4 + NT_VMCOREDD = 0x700 + NT_X86_SHSTK = 0x204 + NT_X86_XSAVE_LAYOUT = 0x205 + NT_X86_XSTATE = 0x202 OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 @@ -2463,6 +2699,59 @@ const ( PERF_RECORD_MISC_USER = 0x2 PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 + PF_ALG = 0x26 + PF_APPLETALK = 0x5 + PF_ASH = 0x12 + PF_ATMPVC = 0x8 + PF_ATMSVC = 0x14 + PF_AX25 = 0x3 + PF_BLUETOOTH = 0x1f + PF_BRIDGE = 0x7 + PF_CAIF = 0x25 + PF_CAN = 0x1d + PF_DECnet = 0xc + PF_ECONET = 0x13 + PF_FILE = 0x1 + PF_IB = 0x1b + PF_IEEE802154 = 0x24 + PF_INET = 0x2 + PF_INET6 = 0xa + PF_IPX = 0x4 + PF_IRDA = 0x17 + PF_ISDN = 0x22 + PF_IUCV = 0x20 + PF_KCM = 0x29 + PF_KEY = 0xf + PF_LLC = 0x1a + PF_LOCAL = 0x1 + PF_MAX = 0x2e + PF_MCTP = 0x2d + PF_MPLS = 0x1c + PF_NETBEUI = 0xd + PF_NETLINK = 0x10 + PF_NETROM = 0x6 + PF_NFC = 0x27 + PF_PACKET = 0x11 + PF_PHONET = 0x23 + PF_PPPOX = 0x18 + PF_QIPCRTR = 0x2a + PF_R = 0x4 + PF_RDS = 0x15 + PF_ROSE = 0xb + PF_ROUTE = 0x10 + PF_RXRPC = 0x21 + PF_SECURITY = 0xe + PF_SMC = 0x2b + PF_SNA = 0x16 + PF_TIPC = 0x1e + PF_UNIX = 0x1 + PF_UNSPEC = 0x0 + PF_VSOCK = 0x28 + PF_W = 0x2 + PF_WANPIPE = 0x19 + PF_X = 0x1 + PF_X25 = 0x9 + PF_XDP = 0x2c PID_FS_MAGIC = 0x50494446 PIPEFS_MAGIC = 0x50495045 PPPIOCGNPMODE = 0xc008744c @@ -2758,6 +3047,23 @@ const ( PTRACE_SYSCALL_INFO_NONE = 0x0 PTRACE_SYSCALL_INFO_SECCOMP = 0x3 PTRACE_TRACEME = 0x0 + PT_AARCH64_MEMTAG_MTE = 0x70000002 + PT_DYNAMIC = 0x2 + PT_GNU_EH_FRAME = 0x6474e550 + PT_GNU_PROPERTY = 0x6474e553 + PT_GNU_RELRO = 0x6474e552 + PT_GNU_STACK = 0x6474e551 + PT_HIOS = 0x6fffffff + PT_HIPROC = 0x7fffffff + PT_INTERP = 0x3 + PT_LOAD = 0x1 + PT_LOOS = 0x60000000 + PT_LOPROC = 0x70000000 + PT_NOTE = 0x4 + PT_NULL = 0x0 + PT_PHDR = 0x6 + PT_SHLIB = 0x5 + PT_TLS = 0x7 P_ALL = 0x0 P_PGID = 0x2 P_PID = 0x1 @@ -3091,6 +3397,47 @@ const ( SEEK_MAX = 0x4 SEEK_SET = 0x0 SELINUX_MAGIC = 0xf97cff8c + SHF_ALLOC = 0x2 + SHF_EXCLUDE = 0x8000000 + SHF_EXECINSTR = 0x4 + SHF_GROUP = 0x200 + SHF_INFO_LINK = 0x40 + SHF_LINK_ORDER = 0x80 + SHF_MASKOS = 0xff00000 + SHF_MASKPROC = 0xf0000000 + SHF_MERGE = 0x10 + SHF_ORDERED = 0x4000000 + SHF_OS_NONCONFORMING = 0x100 + SHF_RELA_LIVEPATCH = 0x100000 + SHF_RO_AFTER_INIT = 0x200000 + SHF_STRINGS = 0x20 + SHF_TLS = 0x400 + SHF_WRITE = 0x1 + SHN_ABS = 0xfff1 + SHN_COMMON = 0xfff2 + SHN_HIPROC = 0xff1f + SHN_HIRESERVE = 0xffff + SHN_LIVEPATCH = 0xff20 + SHN_LOPROC = 0xff00 + SHN_LORESERVE = 0xff00 + SHN_UNDEF = 0x0 + SHT_DYNAMIC = 0x6 + SHT_DYNSYM = 0xb + SHT_HASH = 0x5 + SHT_HIPROC = 0x7fffffff + SHT_HIUSER = 0xffffffff + SHT_LOPROC = 0x70000000 + SHT_LOUSER = 0x80000000 + SHT_NOBITS = 0x8 + SHT_NOTE = 0x7 + SHT_NULL = 0x0 + SHT_NUM = 0xc + SHT_PROGBITS = 0x1 + SHT_REL = 0x9 + SHT_RELA = 0x4 + SHT_SHLIB = 0xa + SHT_STRTAB = 0x3 + SHT_SYMTAB = 0x2 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -3317,6 +3664,16 @@ const ( STATX_UID = 0x8 STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 + STB_GLOBAL = 0x1 + STB_LOCAL = 0x0 + STB_WEAK = 0x2 + STT_COMMON = 0x5 + STT_FILE = 0x4 + STT_FUNC = 0x2 + STT_NOTYPE = 0x0 + STT_OBJECT = 0x1 + STT_SECTION = 0x3 + STT_TLS = 0x6 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 SYNC_FILE_RANGE_WRITE = 0x2 @@ -3553,6 +3910,8 @@ const ( UTIME_OMIT = 0x3ffffffe V9FS_MAGIC = 0x1021997 VERASE = 0x2 + VER_FLG_BASE = 0x1 + VER_FLG_WEAK = 0x2 VINTR = 0x0 VKILL = 0x3 VLNEXT = 0xf diff --git a/etcd/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/etcd/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 5cc1e8eb2f..8935d10a31 100644 --- a/etcd/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/etcd/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -2238,3 +2238,13 @@ func Mseal(b []byte, flags uint) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setMemPolicy(mode int, mask *CPUSet, size int) (err error) { + _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(unsafe.Pointer(mask)), uintptr(size)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/etcd/vendor/golang.org/x/sys/unix/ztypes_linux.go b/etcd/vendor/golang.org/x/sys/unix/ztypes_linux.go index 944e75a11c..c1a4670171 100644 --- a/etcd/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/etcd/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -3590,6 +3590,8 @@ type Nhmsg struct { Flags uint32 } +const SizeofNhmsg = 0x8 + type NexthopGrp struct { Id uint32 Weight uint8 @@ -3597,6 +3599,8 @@ type NexthopGrp struct { Resvd2 uint16 } +const SizeofNexthopGrp = 0x8 + const ( NHA_UNSPEC = 0x0 NHA_ID = 0x1 @@ -6332,3 +6336,30 @@ type SockDiagReq struct { } const RTM_NEWNVLAN = 0x70 + +const ( + MPOL_BIND = 0x2 + MPOL_DEFAULT = 0x0 + MPOL_F_ADDR = 0x2 + MPOL_F_MEMS_ALLOWED = 0x4 + MPOL_F_MOF = 0x8 + MPOL_F_MORON = 0x10 + MPOL_F_NODE = 0x1 + MPOL_F_NUMA_BALANCING = 0x2000 + MPOL_F_RELATIVE_NODES = 0x4000 + MPOL_F_SHARED = 0x1 + MPOL_F_STATIC_NODES = 0x8000 + MPOL_INTERLEAVE = 0x3 + MPOL_LOCAL = 0x4 + MPOL_MAX = 0x7 + MPOL_MF_INTERNAL = 0x10 + MPOL_MF_LAZY = 0x8 + MPOL_MF_MOVE_ALL = 0x4 + MPOL_MF_MOVE = 0x2 + MPOL_MF_STRICT = 0x1 + MPOL_MF_VALID = 0x7 + MPOL_MODE_FLAGS = 0xe000 + MPOL_PREFERRED = 0x1 + MPOL_PREFERRED_MANY = 0x5 + MPOL_WEIGHTED_INTERLEAVE = 0x6 +) diff --git a/etcd/vendor/golang.org/x/sys/windows/syscall_windows.go b/etcd/vendor/golang.org/x/sys/windows/syscall_windows.go index 640f6b153f..69439df2a4 100644 --- a/etcd/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/etcd/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -321,6 +321,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents +//sys FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot //sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW @@ -890,8 +892,12 @@ const socket_error = uintptr(^uint32(0)) //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx //sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex +//sys GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) = iphlpapi.GetIpForwardEntry2 +//sys GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) = iphlpapi.GetIpForwardTable2 //sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry +//sys FreeMibTable(memory unsafe.Pointer) = iphlpapi.FreeMibTable //sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange +//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2 //sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange //sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 @@ -914,6 +920,17 @@ type RawSockaddrInet6 struct { Scope_id uint32 } +// RawSockaddrInet is a union that contains an IPv4, an IPv6 address, or an address family. See +// https://learn.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet. +// +// A [*RawSockaddrInet] may be converted to a [*RawSockaddrInet4] or [*RawSockaddrInet6] using +// unsafe, depending on the address family. +type RawSockaddrInet struct { + Family uint16 + Port uint16 + Data [6]uint32 +} + type RawSockaddr struct { Family uint16 Data [14]int8 diff --git a/etcd/vendor/golang.org/x/sys/windows/types_windows.go b/etcd/vendor/golang.org/x/sys/windows/types_windows.go index 993a2297db..6e4f50eb48 100644 --- a/etcd/vendor/golang.org/x/sys/windows/types_windows.go +++ b/etcd/vendor/golang.org/x/sys/windows/types_windows.go @@ -65,6 +65,22 @@ var signals = [...]string{ 15: "terminated", } +// File flags for [os.OpenFile]. The O_ prefix is used to indicate +// that these flags are specific to the OpenFile function. +const ( + O_FILE_FLAG_OPEN_NO_RECALL = FILE_FLAG_OPEN_NO_RECALL + O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT + O_FILE_FLAG_SESSION_AWARE = FILE_FLAG_SESSION_AWARE + O_FILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS + O_FILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS + O_FILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE + O_FILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN + O_FILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS + O_FILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING + O_FILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED + O_FILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH +) + const ( FILE_READ_DATA = 0x00000001 FILE_READ_ATTRIBUTES = 0x00000080 @@ -2304,6 +2320,82 @@ type MibIfRow2 struct { OutQLen uint64 } +// IP_ADDRESS_PREFIX stores an IP address prefix. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-ip_address_prefix. +type IpAddressPrefix struct { + Prefix RawSockaddrInet + PrefixLength uint8 +} + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_origin. +const ( + NlroManual = 0 + NlroWellKnown = 1 + NlroDHCP = 2 + NlroRouterAdvertisement = 3 + Nlro6to4 = 4 +) + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_protocol. +const ( + MIB_IPPROTO_OTHER = 1 + MIB_IPPROTO_LOCAL = 2 + MIB_IPPROTO_NETMGMT = 3 + MIB_IPPROTO_ICMP = 4 + MIB_IPPROTO_EGP = 5 + MIB_IPPROTO_GGP = 6 + MIB_IPPROTO_HELLO = 7 + MIB_IPPROTO_RIP = 8 + MIB_IPPROTO_IS_IS = 9 + MIB_IPPROTO_ES_IS = 10 + MIB_IPPROTO_CISCO = 11 + MIB_IPPROTO_BBN = 12 + MIB_IPPROTO_OSPF = 13 + MIB_IPPROTO_BGP = 14 + MIB_IPPROTO_IDPR = 15 + MIB_IPPROTO_EIGRP = 16 + MIB_IPPROTO_DVMRP = 17 + MIB_IPPROTO_RPL = 18 + MIB_IPPROTO_DHCP = 19 + MIB_IPPROTO_NT_AUTOSTATIC = 10002 + MIB_IPPROTO_NT_STATIC = 10006 + MIB_IPPROTO_NT_STATIC_NON_DOD = 10007 +) + +// MIB_IPFORWARD_ROW2 stores information about an IP route entry. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_row2. +type MibIpForwardRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + DestinationPrefix IpAddressPrefix + NextHop RawSockaddrInet + SitePrefixLength uint8 + ValidLifetime uint32 + PreferredLifetime uint32 + Metric uint32 + Protocol uint32 + Loopback uint8 + AutoconfigureAddress uint8 + Publish uint8 + Immortal uint8 + Age uint32 + Origin uint32 +} + +// MIB_IPFORWARD_TABLE2 contains a table of IP route entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_table2. +type MibIpForwardTable2 struct { + NumEntries uint32 + Table [1]MibIpForwardRow2 +} + +// Rows returns the IP route entries in the table. +func (t *MibIpForwardTable2) Rows() []MibIpForwardRow2 { + return unsafe.Slice(&t.Table[0], t.NumEntries) +} + // MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See // https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. type MibUnicastIpAddressRow struct { diff --git a/etcd/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/etcd/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 641a5f4b77..f25b7308a1 100644 --- a/etcd/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/etcd/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -182,13 +182,17 @@ var ( procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") + procFreeMibTable = modiphlpapi.NewProc("FreeMibTable") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") + procGetIpForwardEntry2 = modiphlpapi.NewProc("GetIpForwardEntry2") + procGetIpForwardTable2 = modiphlpapi.NewProc("GetIpForwardTable2") procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") + procNotifyRouteChange2 = modiphlpapi.NewProc("NotifyRouteChange2") procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") @@ -238,6 +242,7 @@ var ( procFindResourceW = modkernel32.NewProc("FindResourceW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer") procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") procFormatMessageW = modkernel32.NewProc("FormatMessageW") @@ -284,6 +289,7 @@ var ( procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") + procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -1622,6 +1628,11 @@ func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { return } +func FreeMibTable(memory unsafe.Pointer) { + syscall.SyscallN(procFreeMibTable.Addr(), uintptr(memory)) + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.SyscallN(procGetAdaptersAddresses.Addr(), uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer))) if r0 != 0 { @@ -1662,6 +1673,22 @@ func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { return } +func GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardEntry2.Addr(), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardTable2.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row))) if r0 != 0 { @@ -1682,6 +1709,18 @@ func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsa return } +func NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procNotifyRouteChange2.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { var _p0 uint32 if initialNotification { @@ -2111,6 +2150,14 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { return } +func FlushConsoleInputBuffer(console Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFlushConsoleInputBuffer.Addr(), uintptr(console)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func FlushFileBuffers(handle Handle) (err error) { r1, _, e1 := syscall.SyscallN(procFlushFileBuffers.Addr(), uintptr(handle)) if r1 == 0 { @@ -2481,6 +2528,14 @@ func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err erro return } +func GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNumberOfConsoleInputEvents.Addr(), uintptr(console), uintptr(unsafe.Pointer(numevents))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { var _p0 uint32 if wait { diff --git a/etcd/vendor/golang.org/x/term/terminal.go b/etcd/vendor/golang.org/x/term/terminal.go index bddb2e2aeb..9255449b9b 100644 --- a/etcd/vendor/golang.org/x/term/terminal.go +++ b/etcd/vendor/golang.org/x/term/terminal.go @@ -413,7 +413,7 @@ func (t *Terminal) eraseNPreviousChars(n int) { } } -// countToLeftWord returns then number of characters from the cursor to the +// countToLeftWord returns the number of characters from the cursor to the // start of the previous word. func (t *Terminal) countToLeftWord() int { if t.pos == 0 { @@ -438,7 +438,7 @@ func (t *Terminal) countToLeftWord() int { return t.pos - pos } -// countToRightWord returns then number of characters from the cursor to the +// countToRightWord returns the number of characters from the cursor to the // start of the next word. func (t *Terminal) countToRightWord() int { pos := t.pos @@ -478,7 +478,7 @@ func visualLength(runes []rune) int { return length } -// histroryAt unlocks the terminal and relocks it while calling History.At. +// historyAt unlocks the terminal and relocks it while calling History.At. func (t *Terminal) historyAt(idx int) (string, bool) { t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer. defer t.lock.Lock() // panic in At (or Len) protection. diff --git a/etcd/vendor/golang.org/x/text/unicode/bidi/core.go b/etcd/vendor/golang.org/x/text/unicode/bidi/core.go index 9d2ae547b5..fb8273236d 100644 --- a/etcd/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/etcd/vendor/golang.org/x/text/unicode/bidi/core.go @@ -427,13 +427,6 @@ type isolatingRunSequence struct { func (i *isolatingRunSequence) Len() int { return len(i.indexes) } -func maxLevel(a, b level) level { - if a > b { - return a - } - return b -} - // Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, // either L or R, for each isolating run sequence. func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { @@ -474,8 +467,8 @@ func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { indexes: indexes, types: types, level: level, - sos: typeForLevel(maxLevel(prevLevel, level)), - eos: typeForLevel(maxLevel(succLevel, level)), + sos: typeForLevel(max(prevLevel, level)), + eos: typeForLevel(max(succLevel, level)), } } diff --git a/etcd/vendor/gopkg.in/evanphx/json-patch.v4/README.md b/etcd/vendor/gopkg.in/evanphx/json-patch.v4/README.md index 28e3516937..86fefd5bf7 100644 --- a/etcd/vendor/gopkg.in/evanphx/json-patch.v4/README.md +++ b/etcd/vendor/gopkg.in/evanphx/json-patch.v4/README.md @@ -4,7 +4,7 @@ well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ietf.org/html/rfc7396). [![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch) -[![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=master)](https://travis-ci.org/evanphx/json-patch) +[![Build Status](https://github.com/evanphx/json-patch/actions/workflows/go.yml/badge.svg)](https://github.com/evanphx/json-patch/actions/workflows/go.yml) [![Report Card](https://goreportcard.com/badge/github.com/evanphx/json-patch)](https://goreportcard.com/report/github.com/evanphx/json-patch) # Get It! @@ -14,9 +14,7 @@ well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ie go get -u github.com/evanphx/json-patch/v5 ``` -**Stable Versions**: -* Version 5: `go get -u gopkg.in/evanphx/json-patch.v5` -* Version 4: `go get -u gopkg.in/evanphx/json-patch.v4` +If you need version 4, use `go get -u gopkg.in/evanphx/json-patch.v4` (previous versions below `v3` are unavailable) @@ -314,4 +312,4 @@ go test -cover ./... ``` Builds for pull requests are tested automatically -using [TravisCI](https://travis-ci.org/evanphx/json-patch). +using [GitHub Actions](https://github.com/evanphx/json-patch/actions/workflows/go.yml). diff --git a/etcd/vendor/gopkg.in/evanphx/json-patch.v4/patch.go b/etcd/vendor/gopkg.in/evanphx/json-patch.v4/patch.go index dc2b7e51e6..95136681ba 100644 --- a/etcd/vendor/gopkg.in/evanphx/json-patch.v4/patch.go +++ b/etcd/vendor/gopkg.in/evanphx/json-patch.v4/patch.go @@ -3,11 +3,10 @@ package jsonpatch import ( "bytes" "encoding/json" + "errors" "fmt" "strconv" "strings" - - "github.com/pkg/errors" ) const ( @@ -277,7 +276,7 @@ func (o Operation) Path() (string, error) { return op, nil } - return "unknown", errors.Wrapf(ErrMissing, "operation missing path field") + return "unknown", fmt.Errorf("operation missing path field: %w", ErrMissing) } // From reads the "from" field of the Operation. @@ -294,7 +293,7 @@ func (o Operation) From() (string, error) { return op, nil } - return "unknown", errors.Wrapf(ErrMissing, "operation, missing from field") + return "unknown", fmt.Errorf("operation, missing from field: %w", ErrMissing) } func (o Operation) value() *lazyNode { @@ -319,7 +318,7 @@ func (o Operation) ValueInterface() (interface{}, error) { return v, nil } - return nil, errors.Wrapf(ErrMissing, "operation, missing value field") + return nil, fmt.Errorf("operation, missing value field: %w", ErrMissing) } func isArray(buf []byte) bool { @@ -359,7 +358,7 @@ func findObject(pd *container, path string) (container, string) { next, ok := doc.get(decodePatchKey(part)) - if next == nil || ok != nil { + if next == nil || ok != nil || next.raw == nil { return nil, "" } @@ -398,7 +397,7 @@ func (d *partialDoc) get(key string) (*lazyNode, error) { func (d *partialDoc) remove(key string) error { _, ok := (*d)[key] if !ok { - return errors.Wrapf(ErrMissing, "Unable to remove nonexistent key: %s", key) + return fmt.Errorf("Unable to remove nonexistent key: %s: %w", key, ErrMissing) } delete(*d, key) @@ -415,10 +414,10 @@ func (d *partialArray) set(key string, val *lazyNode) error { if idx < 0 { if !SupportNegativeIndices { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(*d) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(*d) } @@ -435,7 +434,7 @@ func (d *partialArray) add(key string, val *lazyNode) error { idx, err := strconv.Atoi(key) if err != nil { - return errors.Wrapf(err, "value was not a proper array index: '%s'", key) + return fmt.Errorf("value was not a proper array index: '%s': %w", key, err) } sz := len(*d) + 1 @@ -445,15 +444,15 @@ func (d *partialArray) add(key string, val *lazyNode) error { cur := *d if idx >= len(ary) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < 0 { if !SupportNegativeIndices { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(ary) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(ary) } @@ -475,16 +474,16 @@ func (d *partialArray) get(key string) (*lazyNode, error) { if idx < 0 { if !SupportNegativeIndices { - return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(*d) { - return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(*d) } if idx >= len(*d) { - return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } return (*d)[idx], nil @@ -499,15 +498,15 @@ func (d *partialArray) remove(key string) error { cur := *d if idx >= len(cur) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < 0 { if !SupportNegativeIndices { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } if idx < -len(cur) { - return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) } idx += len(cur) } @@ -525,18 +524,18 @@ func (d *partialArray) remove(key string) error { func (p Patch) add(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(ErrMissing, "add operation failed to decode path") + return fmt.Errorf("add operation failed to decode path: %w", ErrMissing) } con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "add operation does not apply: doc is missing path: \"%s\"", path) + return fmt.Errorf("add operation does not apply: doc is missing path: \"%s\": %w", path, ErrMissing) } err = con.add(key, op.value()) if err != nil { - return errors.Wrapf(err, "error in add for path: '%s'", path) + return fmt.Errorf("error in add for path: '%s': %w", path, err) } return nil @@ -545,18 +544,18 @@ func (p Patch) add(doc *container, op Operation) error { func (p Patch) remove(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(ErrMissing, "remove operation failed to decode path") + return fmt.Errorf("remove operation failed to decode path: %w", ErrMissing) } con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "remove operation does not apply: doc is missing path: \"%s\"", path) + return fmt.Errorf("remove operation does not apply: doc is missing path: \"%s\": %w", path, ErrMissing) } err = con.remove(key) if err != nil { - return errors.Wrapf(err, "error in remove for path: '%s'", path) + return fmt.Errorf("error in remove for path: '%s': %w", path, err) } return nil @@ -565,7 +564,7 @@ func (p Patch) remove(doc *container, op Operation) error { func (p Patch) replace(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(err, "replace operation failed to decode path") + return fmt.Errorf("replace operation failed to decode path: %w", err) } if path == "" { @@ -574,7 +573,7 @@ func (p Patch) replace(doc *container, op Operation) error { if val.which == eRaw { if !val.tryDoc() { if !val.tryAry() { - return errors.Wrapf(err, "replace operation value must be object or array") + return fmt.Errorf("replace operation value must be object or array: %w", err) } } } @@ -585,7 +584,7 @@ func (p Patch) replace(doc *container, op Operation) error { case eDoc: *doc = &val.doc case eRaw: - return errors.Wrapf(err, "replace operation hit impossible case") + return fmt.Errorf("replace operation hit impossible case: %w", err) } return nil @@ -594,17 +593,17 @@ func (p Patch) replace(doc *container, op Operation) error { con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing path: %s", path) + return fmt.Errorf("replace operation does not apply: doc is missing path: %s: %w", path, ErrMissing) } _, ok := con.get(key) if ok != nil { - return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing key: %s", path) + return fmt.Errorf("replace operation does not apply: doc is missing key: %s: %w", path, ErrMissing) } err = con.set(key, op.value()) if err != nil { - return errors.Wrapf(err, "error in remove for path: '%s'", path) + return fmt.Errorf("error in remove for path: '%s': %w", path, err) } return nil @@ -613,39 +612,39 @@ func (p Patch) replace(doc *container, op Operation) error { func (p Patch) move(doc *container, op Operation) error { from, err := op.From() if err != nil { - return errors.Wrapf(err, "move operation failed to decode from") + return fmt.Errorf("move operation failed to decode from: %w", err) } con, key := findObject(doc, from) if con == nil { - return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing from path: %s", from) + return fmt.Errorf("move operation does not apply: doc is missing from path: %s: %w", from, ErrMissing) } val, err := con.get(key) if err != nil { - return errors.Wrapf(err, "error in move for path: '%s'", key) + return fmt.Errorf("error in move for path: '%s': %w", key, err) } err = con.remove(key) if err != nil { - return errors.Wrapf(err, "error in move for path: '%s'", key) + return fmt.Errorf("error in move for path: '%s': %w", key, err) } path, err := op.Path() if err != nil { - return errors.Wrapf(err, "move operation failed to decode path") + return fmt.Errorf("move operation failed to decode path: %w", err) } con, key = findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing destination path: %s", path) + return fmt.Errorf("move operation does not apply: doc is missing destination path: %s: %w", path, ErrMissing) } err = con.add(key, val) if err != nil { - return errors.Wrapf(err, "error in move for path: '%s'", path) + return fmt.Errorf("error in move for path: '%s': %w", path, err) } return nil @@ -654,7 +653,7 @@ func (p Patch) move(doc *container, op Operation) error { func (p Patch) test(doc *container, op Operation) error { path, err := op.Path() if err != nil { - return errors.Wrapf(err, "test operation failed to decode path") + return fmt.Errorf("test operation failed to decode path: %w", err) } if path == "" { @@ -673,67 +672,67 @@ func (p Patch) test(doc *container, op Operation) error { return nil } - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } con, key := findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "test operation does not apply: is missing path: %s", path) + return fmt.Errorf("test operation does not apply: is missing path: %s: %w", path, ErrMissing) } val, err := con.get(key) if err != nil { - return errors.Wrapf(err, "error in test for path: '%s'", path) + return fmt.Errorf("error in test for path: '%s': %w", path, err) } if val == nil { - if op.value().raw == nil { + if op.value() == nil || op.value().raw == nil { return nil } - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } else if op.value() == nil { - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } if val.equal(op.value()) { return nil } - return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) } func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64) error { from, err := op.From() if err != nil { - return errors.Wrapf(err, "copy operation failed to decode from") + return fmt.Errorf("copy operation failed to decode from: %w", err) } con, key := findObject(doc, from) if con == nil { - return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing from path: %s", from) + return fmt.Errorf("copy operation does not apply: doc is missing from path: %s: %w", from, ErrMissing) } val, err := con.get(key) if err != nil { - return errors.Wrapf(err, "error in copy for from: '%s'", from) + return fmt.Errorf("error in copy for from: '%s': %w", from, err) } path, err := op.Path() if err != nil { - return errors.Wrapf(ErrMissing, "copy operation failed to decode path") + return fmt.Errorf("copy operation failed to decode path: %w", ErrMissing) } con, key = findObject(doc, path) if con == nil { - return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing destination path: %s", path) + return fmt.Errorf("copy operation does not apply: doc is missing destination path: %s: %w", path, ErrMissing) } valCopy, sz, err := deepCopy(val) if err != nil { - return errors.Wrapf(err, "error while performing deep copy") + return fmt.Errorf("error while performing deep copy: %w", err) } (*accumulatedCopySize) += int64(sz) @@ -743,7 +742,7 @@ func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64) er err = con.add(key, valCopy) if err != nil { - return errors.Wrapf(err, "error while adding value during copy") + return fmt.Errorf("error while adding value during copy: %w", err) } return nil diff --git a/etcd/vendor/modules.txt b/etcd/vendor/modules.txt index 80731d13e3..bc4211bc99 100644 --- a/etcd/vendor/modules.txt +++ b/etcd/vendor/modules.txt @@ -191,12 +191,12 @@ github.com/openshift/build-machinery-go/make/targets/golang github.com/openshift/build-machinery-go/make/targets/openshift github.com/openshift/build-machinery-go/make/targets/openshift/operator github.com/openshift/build-machinery-go/scripts -# github.com/openshift/library-go v0.0.0-20251112091634-ab97ebb73f0f +# github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 ## explicit; go 1.24.0 github.com/openshift/library-go/pkg/crypto github.com/openshift/library-go/pkg/operator/apiserver/audit -# github.com/openshift/microshift v0.0.0 => ../ -## explicit; go 1.24.0 +# github.com/openshift/microshift v0.0.0-00010101000000-000000000000 => ../ +## explicit; go 1.25.0 github.com/openshift/microshift/pkg/config github.com/openshift/microshift/pkg/config/apiserver github.com/openshift/microshift/pkg/util @@ -241,7 +241,7 @@ github.com/sirupsen/logrus # github.com/soheilhy/cmux v0.1.5 ## explicit; go 1.11 github.com/soheilhy/cmux -# github.com/spf13/cobra v1.9.1 +# github.com/spf13/cobra v1.10.0 ## explicit; go 1.15 github.com/spf13/cobra # github.com/spf13/pflag v1.0.10 @@ -450,18 +450,18 @@ go.uber.org/zap/internal/pool go.uber.org/zap/internal/stacktrace go.uber.org/zap/zapcore go.uber.org/zap/zapgrpc -# go.yaml.in/yaml/v2 v2.4.2 +# go.yaml.in/yaml/v2 v2.4.3 ## explicit; go 1.15 go.yaml.in/yaml/v2 # go.yaml.in/yaml/v3 v3.0.4 ## explicit; go 1.16 go.yaml.in/yaml/v3 -# golang.org/x/crypto v0.42.0 +# golang.org/x/crypto v0.45.0 ## explicit; go 1.24.0 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish -# golang.org/x/net v0.43.0 -## explicit; go 1.23.0 +# golang.org/x/net v0.47.0 +## explicit; go 1.24.0 golang.org/x/net/context golang.org/x/net/html golang.org/x/net/html/atom @@ -479,19 +479,19 @@ golang.org/x/net/websocket ## explicit; go 1.23.0 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.17.0 +# golang.org/x/sync v0.18.0 ## explicit; go 1.24.0 golang.org/x/sync/errgroup -# golang.org/x/sys v0.36.0 +# golang.org/x/sys v0.38.0 ## explicit; go 1.24.0 golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/term v0.35.0 +# golang.org/x/term v0.37.0 ## explicit; go 1.24.0 golang.org/x/term -# golang.org/x/text v0.29.0 +# golang.org/x/text v0.31.0 ## explicit; go 1.24.0 golang.org/x/text/encoding golang.org/x/text/encoding/internal @@ -628,7 +628,7 @@ google.golang.org/protobuf/types/known/fieldmaskpb google.golang.org/protobuf/types/known/structpb google.golang.org/protobuf/types/known/timestamppb google.golang.org/protobuf/types/known/wrapperspb -# gopkg.in/evanphx/json-patch.v4 v4.12.0 +# gopkg.in/evanphx/json-patch.v4 v4.13.0 ## explicit gopkg.in/evanphx/json-patch.v4 # gopkg.in/inf.v0 v0.9.1 @@ -963,8 +963,8 @@ k8s.io/klog/v2/internal/severity k8s.io/klog/v2/internal/sloghandler k8s.io/klog/v2/internal/verbosity k8s.io/klog/v2/textlogger -# k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b -## explicit; go 1.23 +# k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 +## explicit; go 1.23.0 k8s.io/kube-openapi/pkg/cached k8s.io/kube-openapi/pkg/common k8s.io/kube-openapi/pkg/handler3 @@ -995,7 +995,7 @@ k8s.io/utils/exec k8s.io/utils/internal/third_party/forked/golang/net k8s.io/utils/net k8s.io/utils/ptr -# sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 +# sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 ## explicit; go 1.23 sigs.k8s.io/json sigs.k8s.io/json/internal/golang/encoding/json diff --git a/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go b/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go index d538ac119b..3fe528bbf3 100644 --- a/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go +++ b/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go @@ -52,8 +52,8 @@ import ( // - bool, for JSON booleans // - float64, for JSON numbers // - string, for JSON strings -// - []interface{}, for JSON arrays -// - map[string]interface{}, for JSON objects +// - []any, for JSON arrays +// - map[string]any, for JSON objects // - nil for JSON null // // To unmarshal a JSON array into a slice, Unmarshal resets the slice length @@ -117,9 +117,6 @@ func Unmarshal(data []byte, v any, opts ...UnmarshalOpt) error { // The input can be assumed to be a valid encoding of // a JSON value. UnmarshalJSON must copy the JSON data // if it wishes to retain the data after returning. -// -// By convention, to approximate the behavior of [Unmarshal] itself, -// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. type Unmarshaler interface { UnmarshalJSON([]byte) error } @@ -132,7 +129,7 @@ type UnmarshalTypeError struct { Type reflect.Type // type of Go value it could not be assigned to Offset int64 // error occurred after reading Offset bytes Struct string // name of the struct type containing the field - Field string // the full path from root node to the field + Field string // the full path from root node to the field, include embedded struct } func (e *UnmarshalTypeError) Error() string { @@ -281,7 +278,11 @@ func (d *decodeState) addErrorContext(err error) error { switch err := err.(type) { case *UnmarshalTypeError: err.Struct = d.errorContext.Struct.Name() - err.Field = strings.Join(d.errorContext.FieldStack, ".") + fieldStack := d.errorContext.FieldStack + if err.Field != "" { + fieldStack = append(fieldStack, err.Field) + } + err.Field = strings.Join(fieldStack, ".") } } return err @@ -492,9 +493,9 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm } // Prevent infinite loop if v is an interface pointing to its own address: - // var v interface{} + // var v any // v = &v - if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v { + if v.Elem().Kind() == reflect.Interface && v.Elem().Elem().Equal(v) { v = v.Elem() break } @@ -784,7 +785,10 @@ func (d *decodeState) object(v reflect.Value) error { } subv = v destring = f.quoted - for _, i := range f.index { + if d.errorContext == nil { + d.errorContext = new(errorContext) + } + for i, ind := range f.index { if subv.Kind() == reflect.Pointer { if subv.IsNil() { // If a struct embeds a pointer to an unexported type, @@ -804,13 +808,16 @@ func (d *decodeState) object(v reflect.Value) error { } subv = subv.Elem() } - subv = subv.Field(i) - } - if d.errorContext == nil { - d.errorContext = new(errorContext) + if i < len(f.index)-1 { + d.errorContext.FieldStack = append( + d.errorContext.FieldStack, + subv.Type().Field(ind).Name, + ) + } + subv = subv.Field(ind) } - d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name) d.errorContext.Struct = t + d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name) d.appendStrictFieldStackKey(f.name) } else if d.disallowUnknownFields { d.saveStrictError(d.newFieldError(unknownStrictErrType, string(key))) @@ -1118,7 +1125,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool // in an empty interface. They are not strictly necessary, // but they avoid the weight of reflection in this common case. -// valueInterface is like value but returns interface{} +// valueInterface is like value but returns any. func (d *decodeState) valueInterface() (val any) { switch d.opcode { default: @@ -1135,7 +1142,7 @@ func (d *decodeState) valueInterface() (val any) { return } -// arrayInterface is like array but returns []interface{}. +// arrayInterface is like array but returns []any. func (d *decodeState) arrayInterface() []any { origStrictFieldStackLen := len(d.strictFieldStack) defer func() { @@ -1170,7 +1177,7 @@ func (d *decodeState) arrayInterface() []any { return v } -// objectInterface is like object but returns map[string]interface{}. +// objectInterface is like object but returns map[string]any. func (d *decodeState) objectInterface() map[string]any { origStrictFieldStackLen := len(d.strictFieldStack) defer func() { diff --git a/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go b/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go index eb73bff58b..4e3a1a2f10 100644 --- a/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go +++ b/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go @@ -71,8 +71,8 @@ import ( // // The "omitempty" option specifies that the field should be omitted // from the encoding if the field has an empty value, defined as -// false, 0, a nil pointer, a nil interface value, and any empty array, -// slice, map, or string. +// false, 0, a nil pointer, a nil interface value, and any array, +// slice, map, or string of length zero. // // As a special case, if the field tag is "-", the field is always omitted. // Note that a field with name "-" can still be generated using the tag "-,". @@ -98,6 +98,17 @@ import ( // // Field appears in JSON as key "-". // Field int `json:"-,"` // +// The "omitzero" option specifies that the field should be omitted +// from the encoding if the field has a zero value, according to rules: +// +// 1) If the field type has an "IsZero() bool" method, that will be used to +// determine whether the value is zero. +// +// 2) Otherwise, the value is zero if it is the zero value for its type. +// +// If both "omitempty" and "omitzero" are specified, the field will be omitted +// if the value is either empty or zero (or both). +// // The "string" option signals that a field is stored as JSON inside a // JSON-encoded string. It applies only to fields of string, floating point, // integer, or boolean types. This extra level of encoding is sometimes used @@ -690,7 +701,8 @@ FieldLoop: fv = fv.Field(i) } - if f.omitEmpty && isEmptyValue(fv) { + if (f.omitEmpty && isEmptyValue(fv)) || + (f.omitZero && (f.isZero == nil && fv.IsZero() || (f.isZero != nil && f.isZero(fv)))) { continue } e.WriteByte(next) @@ -808,7 +820,7 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { // Here we use a struct to memorize the pointer to the first element of the slice // and its length. ptr := struct { - ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe + ptr any // always an unsafe.Pointer, but avoids a dependency on package unsafe len int }{v.UnsafePointer(), v.Len()} if _, ok := e.ptrSeen[ptr]; ok { @@ -1039,11 +1051,19 @@ type field struct { index []int typ reflect.Type omitEmpty bool + omitZero bool + isZero func(reflect.Value) bool quoted bool encoder encoderFunc } +type isZeroer interface { + IsZero() bool +} + +var isZeroerType = reflect.TypeFor[isZeroer]() + // typeFields returns a list of fields that JSON should recognize for the given type. // The algorithm is breadth-first search over the set of structs to include - the top struct // and then any reachable anonymous structs. @@ -1135,6 +1155,7 @@ func typeFields(t reflect.Type) structFields { index: index, typ: ft, omitEmpty: opts.Contains("omitempty"), + omitZero: opts.Contains("omitzero"), quoted: quoted, } field.nameBytes = []byte(field.name) @@ -1144,6 +1165,40 @@ func typeFields(t reflect.Type) structFields { field.nameEscHTML = `"` + string(nameEscBuf) + `":` field.nameNonEsc = `"` + field.name + `":` + if field.omitZero { + t := sf.Type + // Provide a function that uses a type's IsZero method. + switch { + case t.Kind() == reflect.Interface && t.Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + // Avoid panics calling IsZero on a nil interface or + // non-nil interface with nil pointer. + return v.IsNil() || + (v.Elem().Kind() == reflect.Pointer && v.Elem().IsNil()) || + v.Interface().(isZeroer).IsZero() + } + case t.Kind() == reflect.Pointer && t.Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + // Avoid panics calling IsZero on nil pointer. + return v.IsNil() || v.Interface().(isZeroer).IsZero() + } + case t.Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + return v.Interface().(isZeroer).IsZero() + } + case reflect.PointerTo(t).Implements(isZeroerType): + field.isZero = func(v reflect.Value) bool { + if !v.CanAddr() { + // Temporarily box v so we can take the address. + v2 := reflect.New(v.Type()).Elem() + v2.Set(v) + v = v2 + } + return v.Addr().Interface().(isZeroer).IsZero() + } + } + } + fields = append(fields, field) if count[f.typ] > 1 { // If there were multiple instances, add a second, diff --git a/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go b/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go index 48fc4d9453..cc2108b927 100644 --- a/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go +++ b/etcd/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go @@ -31,8 +31,8 @@ func NewDecoder(r io.Reader) *Decoder { return &Decoder{r: r} } -// UseNumber causes the Decoder to unmarshal a number into an interface{} as a -// [Number] instead of as a float64. +// UseNumber causes the Decoder to unmarshal a number into an +// interface value as a [Number] instead of as a float64. func (dec *Decoder) UseNumber() { dec.d.useNumber = true } // DisallowUnknownFields causes the Decoder to return an error when the destination From b5ef1dbbefd82e4746af51e38099ca8aa73d9f42 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:12:38 +0100 Subject: [PATCH 10/15] update component images --- packaging/crio.conf.d/10-microshift_amd64.conf | 2 +- packaging/crio.conf.d/10-microshift_arm64.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/crio.conf.d/10-microshift_amd64.conf b/packaging/crio.conf.d/10-microshift_amd64.conf index 2a2212312c..00cc8bed3b 100644 --- a/packaging/crio.conf.d/10-microshift_amd64.conf +++ b/packaging/crio.conf.d/10-microshift_amd64.conf @@ -2,6 +2,6 @@ # for community builds on top of OKD, this setting has no effect [crio.image] global_auth_file="/etc/crio/openshift-pull-secret" -pause_image = "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:89d38d074f3fefeafe47171f755345c5ef521324af0f32683bf9a69068ee6d90" +pause_image = "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:7513507ca94673ee17e2bde9edd2335b8bea7a72ac17a32ba0d60808742b7527" pause_image_auth_file = "/etc/crio/openshift-pull-secret" pause_command = "/usr/bin/pod" diff --git a/packaging/crio.conf.d/10-microshift_arm64.conf b/packaging/crio.conf.d/10-microshift_arm64.conf index 136304104c..16c0a3b990 100644 --- a/packaging/crio.conf.d/10-microshift_arm64.conf +++ b/packaging/crio.conf.d/10-microshift_arm64.conf @@ -2,6 +2,6 @@ # for community builds on top of OKD, this setting has no effect [crio.image] global_auth_file="/etc/crio/openshift-pull-secret" -pause_image = "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:e95d5626e35158343ffe994f18588fb91a6baa7ce513b8a17e095d16e6b0293c" +pause_image = "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f119f20eded8102499fb9a65a990d7e3e8e47f866efe70db6597718dd2a42b20" pause_image_auth_file = "/etc/crio/openshift-pull-secret" pause_command = "/usr/bin/pod" From f59c8b695e089e3c0934778bf2b07924d5ed443a Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:12:46 +0100 Subject: [PATCH 11/15] update manifests --- .../multus/kustomization.aarch64.yaml | 4 +- .../multus/kustomization.x86_64.yaml | 4 +- .../multus/release-multus-aarch64.json | 6 +- .../multus/release-multus-x86_64.json | 6 +- .../components/openshift-dns/dns/service.yaml | 1 + .../0000_50_olm_00-catalogsources.crd.yaml | 5 +- ..._50_olm_00-clusterserviceversions.crd.yaml | 77 +++++++++++++++++-- .../0000_50_olm_00-installplans.crd.yaml | 2 +- .../0000_50_olm_00-olmconfigs.crd.yaml | 2 +- ...0000_50_olm_00-operatorconditions.crd.yaml | 2 +- .../0000_50_olm_00-operatorgroups.crd.yaml | 2 +- .../0000_50_olm_00-operators.crd.yaml | 2 +- .../0000_50_olm_00-subscriptions.crd.yaml | 25 +++++- .../kustomization.aarch64.yaml | 10 +-- .../kustomization.x86_64.yaml | 10 +-- .../kustomization.yaml | 3 + .../release-olm-aarch64.json | 8 +- .../release-olm-x86_64.json | 8 +- assets/release/release-aarch64.json | 18 ++--- assets/release/release-x86_64.json | 18 ++--- 20 files changed, 149 insertions(+), 64 deletions(-) diff --git a/assets/components/multus/kustomization.aarch64.yaml b/assets/components/multus/kustomization.aarch64.yaml index c9ff38bd61..6e974bed3b 100644 --- a/assets/components/multus/kustomization.aarch64.yaml +++ b/assets/components/multus/kustomization.aarch64.yaml @@ -2,7 +2,7 @@ images: - name: multus-cni-microshift newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:18382b50036fed824eaa818406de54f31a19d506d84ba69076647709c0bebd0c + digest: sha256:5059097d17fbc06dbe7a9e7f0d61116eeb2750fcc2debc54842916cc35181a06 - name: containernetworking-plugins-microshift newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:476c31c3adc585ec503b0717bc8898fdaa0d5c51d4ad3acf80acfb8140cc182f + digest: sha256:267c37338b0fddc68fd1b7657c722ee0238675ef85b0f274e69fdf96d9df26c6 diff --git a/assets/components/multus/kustomization.x86_64.yaml b/assets/components/multus/kustomization.x86_64.yaml index e1c7209f25..09d51e153e 100644 --- a/assets/components/multus/kustomization.x86_64.yaml +++ b/assets/components/multus/kustomization.x86_64.yaml @@ -2,7 +2,7 @@ images: - name: multus-cni-microshift newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:0db85138bfe4a129e0b85a203ca0c8400145d8fa2e234c467d8496d89a0e66fb + digest: sha256:e9b425020d10f9f7ab0ddf27b082dd69e7b5c97f498608f9761f88b533d593d8 - name: containernetworking-plugins-microshift newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:31264e37769680f66240b51d02b4cbcf12565a9d0ce961a7c23bf90e9e463a99 + digest: sha256:474aa143fb27219d5be46488f70a56e0fdf25864276fbcfd48c64d10329ab341 diff --git a/assets/components/multus/release-multus-aarch64.json b/assets/components/multus/release-multus-aarch64.json index fb03d56263..2a9f76bdc9 100644 --- a/assets/components/multus/release-multus-aarch64.json +++ b/assets/components/multus/release-multus-aarch64.json @@ -1,9 +1,9 @@ { "release": { - "base": "4.22.0-0.nightly-arm64-2026-02-05-082424" + "base": "4.22.0-0.nightly-arm64-2026-02-17-232712" }, "images": { - "multus-cni-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:18382b50036fed824eaa818406de54f31a19d506d84ba69076647709c0bebd0c", - "containernetworking-plugins-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:476c31c3adc585ec503b0717bc8898fdaa0d5c51d4ad3acf80acfb8140cc182f" + "multus-cni-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:5059097d17fbc06dbe7a9e7f0d61116eeb2750fcc2debc54842916cc35181a06", + "containernetworking-plugins-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:267c37338b0fddc68fd1b7657c722ee0238675ef85b0f274e69fdf96d9df26c6" } } diff --git a/assets/components/multus/release-multus-x86_64.json b/assets/components/multus/release-multus-x86_64.json index 7d6e4c9f96..b80bb25ebc 100644 --- a/assets/components/multus/release-multus-x86_64.json +++ b/assets/components/multus/release-multus-x86_64.json @@ -1,9 +1,9 @@ { "release": { - "base": "4.22.0-0.nightly-2026-02-05-115400" + "base": "4.22.0-0.nightly-2026-02-17-112443" }, "images": { - "multus-cni-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:0db85138bfe4a129e0b85a203ca0c8400145d8fa2e234c467d8496d89a0e66fb", - "containernetworking-plugins-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:31264e37769680f66240b51d02b4cbcf12565a9d0ce961a7c23bf90e9e463a99" + "multus-cni-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:e9b425020d10f9f7ab0ddf27b082dd69e7b5c97f498608f9761f88b533d593d8", + "containernetworking-plugins-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:474aa143fb27219d5be46488f70a56e0fdf25864276fbcfd48c64d10329ab341" } } diff --git a/assets/components/openshift-dns/dns/service.yaml b/assets/components/openshift-dns/dns/service.yaml index 3849d98bce..a53188dcc6 100644 --- a/assets/components/openshift-dns/dns/service.yaml +++ b/assets/components/openshift-dns/dns/service.yaml @@ -1,6 +1,7 @@ kind: Service apiVersion: v1 spec: + trafficDistribution: PreferSameNode ports: - name: dns port: 53 diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-catalogsources.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-catalogsources.crd.yaml index e0bde39811..d0455ae902 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-catalogsources.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-catalogsources.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" @@ -1049,9 +1049,10 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators). type: string tolerationSeconds: description: |- diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-clusterserviceversions.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-clusterserviceversions.crd.yaml index b2ed5a0f71..b3ffad4856 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-clusterserviceversions.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-clusterserviceversions.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" @@ -2560,7 +2560,9 @@ spec: type: integer format: int32 resizePolicy: - description: Resources resize policy for the container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. type: array items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -5633,7 +5635,9 @@ spec: type: integer format: int32 resizePolicy: - description: Resources resize policy for the container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. type: array items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -6390,8 +6394,8 @@ spec: will be made available to those containers which consume them by name. - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. + This is a stable field but requires that the + DynamicResourceAllocation feature gate is enabled. This field is immutable. type: array @@ -6845,9 +6849,10 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators). type: string tolerationSeconds: description: |- @@ -7609,7 +7614,7 @@ spec: resources: description: |- resources represents the minimum resources the volume should have. - If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + Users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources @@ -8446,6 +8451,24 @@ spec: signerName: description: Kubelet's generated CSRs will be addressed to this signer. type: string + userAnnotations: + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of + the PodCertificateRequest objects that Kubelet creates. + + Entries are subject to the same validation as object metadata annotations, + with the addition that all keys must be domain-prefixed. No restrictions + are placed on values, except an overall size limitation on the entire field. + + Signers should document the keys and values they support. Signers should + deny requests that contain keys they do not recognize. + type: object + additionalProperties: + type: string secret: description: secret information about the secret data to project type: object @@ -8844,6 +8867,42 @@ spec: x-kubernetes-list-map-keys: - name x-kubernetes-list-type: map + workloadRef: + description: |- + WorkloadRef provides a reference to the Workload object that this Pod belongs to. + This field is used by the scheduler to identify the PodGroup and apply the + correct group scheduling policies. The Workload object referenced + by this field may not exist at the time the Pod is created. + This field is immutable, but a Workload object with the same name + may be recreated with different policies. Doing this during pod scheduling + may result in the placement not conforming to the expected policies. + type: object + required: + - name + - podGroup + properties: + name: + description: |- + Name defines the name of the Workload object this Pod belongs to. + Workload must be in the same namespace as the Pod. + If it doesn't match any existing Workload, the Pod will remain unschedulable + until a Workload object is created and observed by the kube-scheduler. + It must be a DNS subdomain. + type: string + podGroup: + description: |- + PodGroup is the name of the PodGroup within the Workload that this Pod + belongs to. If it doesn't match any existing PodGroup within the Workload, + the Pod will remain unschedulable until the Workload object is recreated + and observed by the kube-scheduler. It must be a DNS label. + type: string + podGroupReplicaKey: + description: |- + PodGroupReplicaKey specifies the replica key of the PodGroup to which this + Pod belongs. It is used to distinguish pods belonging to different replicas + of the same pod group. The pod group policy is applied separately to each replica. + When set, it must be a DNS label. + type: string permissions: type: array items: @@ -9159,7 +9218,9 @@ spec: type: string x-kubernetes-map-type: atomic reinvocationPolicy: - description: ReinvocationPolicyType specifies what type of policy the admission hook uses. + description: |- + ReinvocationPolicyType specifies what type of policy is used when other admission plugins also perform + modifications. type: string rules: type: array diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-installplans.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-installplans.crd.yaml index 08f6701336..6f3936c69e 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-installplans.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-installplans.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-olmconfigs.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-olmconfigs.crd.yaml index ec2291246b..90af18a959 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-olmconfigs.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-olmconfigs.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorconditions.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorconditions.crd.yaml index 2f5a208669..797a47b740 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorconditions.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorconditions.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorgroups.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorgroups.crd.yaml index acf2160ddc..1409d8aa27 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorgroups.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operatorgroups.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operators.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operators.crd.yaml index c571a3264a..f1c29977d1 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operators.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-operators.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" diff --git a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-subscriptions.crd.yaml b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-subscriptions.crd.yaml index 87ce80f720..790b096871 100644 --- a/assets/optional/operator-lifecycle-manager/0000_50_olm_00-subscriptions.crd.yaml +++ b/assets/optional/operator-lifecycle-manager/0000_50_olm_00-subscriptions.crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.0 include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" capability.openshift.io/name: "OperatorLifecycleManager" @@ -1301,9 +1301,10 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators). type: string tolerationSeconds: description: |- @@ -1947,7 +1948,7 @@ spec: resources: description: |- resources represents the minimum resources the volume should have. - If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + Users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources @@ -2784,6 +2785,24 @@ spec: signerName: description: Kubelet's generated CSRs will be addressed to this signer. type: string + userAnnotations: + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of + the PodCertificateRequest objects that Kubelet creates. + + Entries are subject to the same validation as object metadata annotations, + with the addition that all keys must be domain-prefixed. No restrictions + are placed on values, except an overall size limitation on the entire field. + + Signers should document the keys and values they support. Signers should + deny requests that contain keys they do not recognize. + type: object + additionalProperties: + type: string secret: description: secret information about the secret data to project type: object diff --git a/assets/optional/operator-lifecycle-manager/kustomization.aarch64.yaml b/assets/optional/operator-lifecycle-manager/kustomization.aarch64.yaml index 09a54125de..07c1d2efaa 100644 --- a/assets/optional/operator-lifecycle-manager/kustomization.aarch64.yaml +++ b/assets/optional/operator-lifecycle-manager/kustomization.aarch64.yaml @@ -2,13 +2,13 @@ images: - name: quay.io/operator-framework/olm newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:9d3d8d0887ab9d994634f902885f362e1140cc206e47198d1ca593a60fc6f161 + digest: sha256:9cae71a754b76203d01e23ec9c6730c1ce9be6c37a7451243d27bf419ceaddd8 - name: quay.io/operator-framework/configmap-operator-registry newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:cdf1049fa246fa36a79e0e4d4baaf5c97a0576002218f2fc10b6448b9260e61f + digest: sha256:10632a362e40bcfb78e901778b63d17f1360a2564833ea3de832a14a8b8b82f5 - name: quay.io/openshift/origin-kube-rbac-proxy newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:9393b7488ecc8616f74897f4b23f7f5aad1a3aa1201d231251ccb3a2036b9ef6 + digest: sha256:6a446c1612ba15b607869bc616cb6c1b5ed7966141f3a344d10968806e430c8b patches: - patch: |- @@ -16,12 +16,12 @@ patches: path: /spec/template/spec/containers/0/env/- value: name: OPERATOR_REGISTRY_IMAGE - value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:cdf1049fa246fa36a79e0e4d4baaf5c97a0576002218f2fc10b6448b9260e61f + value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:10632a362e40bcfb78e901778b63d17f1360a2564833ea3de832a14a8b8b82f5 - op: add path: /spec/template/spec/containers/0/env/- value: name: OLM_IMAGE - value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9d3d8d0887ab9d994634f902885f362e1140cc206e47198d1ca593a60fc6f161 + value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9cae71a754b76203d01e23ec9c6730c1ce9be6c37a7451243d27bf419ceaddd8 target: kind: Deployment labelSelector: app=catalog-operator diff --git a/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml b/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml index 4e5adf9f40..af85db5586 100644 --- a/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml +++ b/assets/optional/operator-lifecycle-manager/kustomization.x86_64.yaml @@ -2,13 +2,13 @@ images: - name: quay.io/operator-framework/olm newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:a7cf23b5d9ec933b8ae281acf568521ea54816c57baddcdeda1df3aa85171a02 + digest: sha256:5cacff5077abbababa5336b6ebb334377382817184b8ce7cfda87b589544b4cc - name: quay.io/operator-framework/configmap-operator-registry newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:a2f2eaae95ddbd87b1c20a58edf725c515ccee4befe7aa78f69fefec2289f87f + digest: sha256:2469bfae8f97154da2cb84eb19f75fe7918c316a22240c29865d296f326c1914 - name: quay.io/openshift/origin-kube-rbac-proxy newName: quay.io/openshift-release-dev/ocp-v4.0-art-dev - digest: sha256:024a086dee9aed18b6e0348e728b06711853061962fe042a9f89b91f53d1bf8c + digest: sha256:74536a9ae64f64aa25dcd7ff3a529b2bddb76cef69847e6a4fbc5716b2f05a53 patches: - patch: |- @@ -16,12 +16,12 @@ patches: path: /spec/template/spec/containers/0/env/- value: name: OPERATOR_REGISTRY_IMAGE - value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a2f2eaae95ddbd87b1c20a58edf725c515ccee4befe7aa78f69fefec2289f87f + value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:2469bfae8f97154da2cb84eb19f75fe7918c316a22240c29865d296f326c1914 - op: add path: /spec/template/spec/containers/0/env/- value: name: OLM_IMAGE - value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a7cf23b5d9ec933b8ae281acf568521ea54816c57baddcdeda1df3aa85171a02 + value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:5cacff5077abbababa5336b6ebb334377382817184b8ce7cfda87b589544b4cc target: kind: Deployment labelSelector: app=catalog-operator diff --git a/assets/optional/operator-lifecycle-manager/kustomization.yaml b/assets/optional/operator-lifecycle-manager/kustomization.yaml index 6738615fc6..206174302a 100644 --- a/assets/optional/operator-lifecycle-manager/kustomization.yaml +++ b/assets/optional/operator-lifecycle-manager/kustomization.yaml @@ -10,6 +10,9 @@ resources: - 0000_50_olm_00-operatorgroups.crd.yaml - 0000_50_olm_00-operators.crd.yaml - 0000_50_olm_00-packageserver.pdb.yaml + - 0000_50_olm_00-pprof-config.yaml + - 0000_50_olm_00-pprof-rbac.yaml + - 0000_50_olm_00-pprof-secret.yaml - 0000_50_olm_00-subscriptions.crd.yaml - 0000_50_olm_01-networkpolicies.yaml - 0000_50_olm_02-olm-operator.serviceaccount.yaml diff --git a/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json b/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json index 60e8f87c36..45d6b3f6b4 100644 --- a/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json +++ b/assets/optional/operator-lifecycle-manager/release-olm-aarch64.json @@ -1,10 +1,10 @@ { "release": { - "base": "4.22.0-0.nightly-arm64-2026-02-05-082424" + "base": "4.22.0-0.nightly-arm64-2026-02-17-232712" }, "images": { - "operator-lifecycle-manager": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9d3d8d0887ab9d994634f902885f362e1140cc206e47198d1ca593a60fc6f161", - "operator-registry": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:cdf1049fa246fa36a79e0e4d4baaf5c97a0576002218f2fc10b6448b9260e61f", - "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9393b7488ecc8616f74897f4b23f7f5aad1a3aa1201d231251ccb3a2036b9ef6" + "operator-lifecycle-manager": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9cae71a754b76203d01e23ec9c6730c1ce9be6c37a7451243d27bf419ceaddd8", + "operator-registry": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:10632a362e40bcfb78e901778b63d17f1360a2564833ea3de832a14a8b8b82f5", + "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:6a446c1612ba15b607869bc616cb6c1b5ed7966141f3a344d10968806e430c8b" } } diff --git a/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json b/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json index b7f0b6da1c..d46c015625 100644 --- a/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json +++ b/assets/optional/operator-lifecycle-manager/release-olm-x86_64.json @@ -1,10 +1,10 @@ { "release": { - "base": "4.22.0-0.nightly-2026-02-05-115400" + "base": "4.22.0-0.nightly-2026-02-17-112443" }, "images": { - "operator-lifecycle-manager": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a7cf23b5d9ec933b8ae281acf568521ea54816c57baddcdeda1df3aa85171a02", - "operator-registry": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a2f2eaae95ddbd87b1c20a58edf725c515ccee4befe7aa78f69fefec2289f87f", - "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:024a086dee9aed18b6e0348e728b06711853061962fe042a9f89b91f53d1bf8c" + "operator-lifecycle-manager": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:5cacff5077abbababa5336b6ebb334377382817184b8ce7cfda87b589544b4cc", + "operator-registry": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:2469bfae8f97154da2cb84eb19f75fe7918c316a22240c29865d296f326c1914", + "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:74536a9ae64f64aa25dcd7ff3a529b2bddb76cef69847e6a4fbc5716b2f05a53" } } diff --git a/assets/release/release-aarch64.json b/assets/release/release-aarch64.json index 529ace6634..ba13b88eeb 100644 --- a/assets/release/release-aarch64.json +++ b/assets/release/release-aarch64.json @@ -1,16 +1,16 @@ { "release": { - "base": "4.22.0-0.nightly-arm64-2026-02-05-082424" + "base": "4.22.0-0.nightly-arm64-2026-02-17-232712" }, "images": { - "cli": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a6af2b68b2eec4026080790521abcd5b1ba599e59caf42d053f8a18d8bec09a7", - "coredns": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:8ee3f8034bf2d07aefcb75b1ffe5c7222290f324aa7234895aa87e6bdd09e237", - "haproxy-router": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:3436721bfc2a010877c4476e450e283820d7dd53777ed1be9a78b969a913f179", - "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9393b7488ecc8616f74897f4b23f7f5aad1a3aa1201d231251ccb3a2036b9ef6", - "ovn-kubernetes-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f3b010cb1c627955c37942bbb35323f631ac4c827329d410a8f7f868d6998083", - "pod": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:e95d5626e35158343ffe994f18588fb91a6baa7ce513b8a17e095d16e6b0293c", - "service-ca-operator": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:774023f17193a125c5e6e8a6bba53ca21ea19c80e840a7110c94ba3f5c4ecb02", + "cli": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:b3942ad8c93f5222836244549cbad53c745f3b16699824319f2a020257457703", + "coredns": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:8a5d616c836eafa3dd9f7f56bc8592d8077486da4a08064a473ef8e34a8be2e9", + "haproxy-router": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:73921004aa9c53caddc8fda86f36ad0cf857943be302c4389f12e13601bd8113", + "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:6a446c1612ba15b607869bc616cb6c1b5ed7966141f3a344d10968806e430c8b", + "ovn-kubernetes-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a3133d0ca6104900cb738b95305a23ccb3f675a1d60ad6a49d90379a724477fc", + "pod": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f119f20eded8102499fb9a65a990d7e3e8e47f866efe70db6597718dd2a42b20", + "service-ca-operator": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f1a1f77684c7ce10cbbf0dc9d434dfe4930fa43badd03643075e3c00dedda93c", "lvms_operator": "registry.redhat.io/lvms4/lvms-rhel9-operator@sha256:3766640b19c336b443619ecdb35f36b479c79ea71b21de97febf024a5eaf6c84", - "csi-snapshot-controller": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:fca9e70ea3d71025d969a5e14fc0272f4bd0c25012db2bd86f5fd5e5bd917d7d" + "csi-snapshot-controller": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:536d16747670ce324de4dbb9f4bf7a3ee5871e6b70dc2639fbf2a1397bc4a329" } } diff --git a/assets/release/release-x86_64.json b/assets/release/release-x86_64.json index 148cea3c68..27f79e34c9 100644 --- a/assets/release/release-x86_64.json +++ b/assets/release/release-x86_64.json @@ -1,16 +1,16 @@ { "release": { - "base": "4.22.0-0.nightly-2026-02-05-115400" + "base": "4.22.0-0.nightly-2026-02-17-112443" }, "images": { - "cli": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:191385c8b2fdab6b1bdbbf8bc7eca917d70e5e8d60019f304de6c46fbdcccf6d", - "coredns": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1d83a353d3f75275640cc6b9c613d8d8eb99f18e4b8ffa79b83728b7dfbecaca", - "haproxy-router": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:3c9ef4de05d8cfe9799f9134856dca64adb00fb2d8757ae4fcf42f6abefecec8", - "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:024a086dee9aed18b6e0348e728b06711853061962fe042a9f89b91f53d1bf8c", - "ovn-kubernetes-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:02a5485f93b3c117a165caf5057886cc30bf11ba4fa2a8250c21b4694ae4c9ab", - "pod": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:89d38d074f3fefeafe47171f755345c5ef521324af0f32683bf9a69068ee6d90", - "service-ca-operator": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:47e2e3c31c7955bafff142e64fb4810a02d40ed6d8e63552410cce04ed1484a2", + "cli": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:12fcf0dfc2aef1d52a1a211a0edfb5a4d7f1992de99c84d6ee112c2ced50b1b6", + "coredns": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9060aa9a30b0ec7a2f99e40278fbf0f3a82b9371b256615604b9cfb019d89891", + "haproxy-router": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:d87740f4ff9ed6ead0e9af1ea0c9a58fd28676a3931eae9be1067409a84e7704", + "kube-rbac-proxy": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:74536a9ae64f64aa25dcd7ff3a529b2bddb76cef69847e6a4fbc5716b2f05a53", + "ovn-kubernetes-microshift": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:13229c22b269d9eeab4a94ed138813043a7c894453fe21e1366962c4f6a40293", + "pod": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:7513507ca94673ee17e2bde9edd2335b8bea7a72ac17a32ba0d60808742b7527", + "service-ca-operator": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9b2bcab31455a22c66cbd0c8d67ea55f14fe7833f9ea2553d05ecdec76591f76", "lvms_operator": "registry.redhat.io/lvms4/lvms-rhel9-operator@sha256:58804d8baf922927b66cec9424d431a3bdb341d207024ce40cc8f0123bac03ee", - "csi-snapshot-controller": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f390128b70d502c35ae3f34f0acc6a57398ebf9d17490a83bc2bc942f75cf88a" + "csi-snapshot-controller": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:364ab6bc32abe7c7ad3558a26456dfe3064391768bc6dbfe12b0b10471fc0300" } } From fdbeb063a0d72137392181641af78ab5c06f0595 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:12:48 +0100 Subject: [PATCH 12/15] update buildfiles --- Makefile.kube_git.var | 2 +- Makefile.version.aarch64.var | 2 +- Makefile.version.x86_64.var | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.kube_git.var b/Makefile.kube_git.var index 2871ba4ea2..677e48a233 100644 --- a/Makefile.kube_git.var +++ b/Makefile.kube_git.var @@ -1,5 +1,5 @@ KUBE_GIT_MAJOR=1 KUBE_GIT_MINOR=34 KUBE_GIT_VERSION=v1.34.2 -KUBE_GIT_COMMIT=9d521311f5fb67dc43f49eeb728ee2c80976835a +KUBE_GIT_COMMIT=047d96223dd843e9d54bed59bc212d2e9122c56a KUBE_GIT_TREE_STATE=clean diff --git a/Makefile.version.aarch64.var b/Makefile.version.aarch64.var index 397442990f..3ffad689b4 100644 --- a/Makefile.version.aarch64.var +++ b/Makefile.version.aarch64.var @@ -1 +1 @@ -OCP_VERSION := 4.22.0-0.nightly-arm64-2026-02-05-082424 +OCP_VERSION := 4.22.0-0.nightly-arm64-2026-02-17-232712 diff --git a/Makefile.version.x86_64.var b/Makefile.version.x86_64.var index d15390635b..77d5443753 100644 --- a/Makefile.version.x86_64.var +++ b/Makefile.version.x86_64.var @@ -1 +1 @@ -OCP_VERSION := 4.22.0-0.nightly-2026-02-05-115400 +OCP_VERSION := 4.22.0-0.nightly-2026-02-17-112443 From 3771e31c33291508f362b89c4f7f6e91af712943 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:14:05 +0100 Subject: [PATCH 13/15] Manual fix for olm kustomization --- assets/optional/operator-lifecycle-manager/kustomization.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/assets/optional/operator-lifecycle-manager/kustomization.yaml b/assets/optional/operator-lifecycle-manager/kustomization.yaml index 206174302a..6738615fc6 100644 --- a/assets/optional/operator-lifecycle-manager/kustomization.yaml +++ b/assets/optional/operator-lifecycle-manager/kustomization.yaml @@ -10,9 +10,6 @@ resources: - 0000_50_olm_00-operatorgroups.crd.yaml - 0000_50_olm_00-operators.crd.yaml - 0000_50_olm_00-packageserver.pdb.yaml - - 0000_50_olm_00-pprof-config.yaml - - 0000_50_olm_00-pprof-rbac.yaml - - 0000_50_olm_00-pprof-secret.yaml - 0000_50_olm_00-subscriptions.crd.yaml - 0000_50_olm_01-networkpolicies.yaml - 0000_50_olm_02-olm-operator.serviceaccount.yaml From acf710efd9c634848d273976c9b52fc33f50bfe6 Mon Sep 17 00:00:00 2001 From: Jon Cope Date: Tue, 17 Feb 2026 11:15:48 -0600 Subject: [PATCH 14/15] bump builder image version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 286560609e..0286fef873 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ GO_TEST_PACKAGES=./cmd/... ./pkg/... export CGO_ENABLED ?= 1 # Specify OCP build tools image tag when building rpm with podman -RPM_BUILDER_IMAGE_TAG := rhel-9-golang-1.24-openshift-4.20 +RPM_BUILDER_IMAGE_TAG := rhel-9-golang-1.25-openshift-4.22 all: generate-config microshift etcd From f5521ac6f3f92d5d015520b01337ffeb844690c5 Mon Sep 17 00:00:00 2001 From: Pablo Acevedo Montserrat Date: Wed, 18 Feb 2026 12:38:20 +0100 Subject: [PATCH 15/15] Bump golangci-lint to match go 1.25 --- .golangci.yaml | 10 ++++++++++ cmd/generate-config/util.go | 2 +- pkg/assets/unstructured.go | 16 ++++++++-------- pkg/cmd/showConfig.go | 3 ++- pkg/cmd/version.go | 4 ++-- pkg/components/controllers.go | 2 +- pkg/healthcheck/debug_info.go | 1 + pkg/mdns/controller.go | 3 ++- pkg/mdns/server/resolver.go | 3 ++- pkg/servicemanager/manager.go | 2 +- pkg/telemetry/telemetry.go | 9 ++++----- pkg/util/cryptomaterial/certchains/signers.go | 3 ++- pkg/version/version.go | 1 + scripts/fetch_tools.sh | 6 +++--- 14 files changed, 40 insertions(+), 25 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 76c007d9f4..ad93cf67f1 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -34,6 +34,8 @@ linters: - nlreturn # Replaced by whitespace. - wsl + # We do not enforce godoc comments. + - godoclint # https://golangci-lint.run/usage/linters/ enable: - asasalint @@ -107,6 +109,14 @@ linters: text: 'G301: Expect directory permissions to be 0750 or less' - path: 'pkg/components/storage\.go' text: 'G302: Expect file permissions to be 0600 or less' + - path: 'pkg/config/node\.go' + text: 'G703: Path traversal via taint analysis' + - path: 'pkg/controllers/kube-apiserver\.go' + text: 'G703: Path traversal via taint analysis' + - path: 'pkg/telemetry/telemetry\.go' + text: 'G704: SSRF via taint analysis' + - path: 'pkg/util/cryptomaterial/certchains/signers\.go' + text: 'toBuilder returns interface' settings: cyclop: max-complexity: 20 diff --git a/cmd/generate-config/util.go b/cmd/generate-config/util.go index 3d8e9b7dd0..2a8ed77ecb 100644 --- a/cmd/generate-config/util.go +++ b/cmd/generate-config/util.go @@ -145,7 +145,7 @@ func parseJSONValue(jsonType interface{}) (value string, node []*yaml.Node) { } func schemaKeyToOrderedArray[K string | int, V any](schemaProperties map[K]V) []K { - var ordered = []K{} + var ordered = make([]K, 0, len(schemaProperties)) for k := range schemaProperties { ordered = append(ordered, k) } diff --git a/pkg/assets/unstructured.go b/pkg/assets/unstructured.go index 2450e17b29..a65f2cf71e 100644 --- a/pkg/assets/unstructured.go +++ b/pkg/assets/unstructured.go @@ -52,14 +52,6 @@ var configClientCache = make(map[string]configClientCacheEntry, 1) var configClientCacheLock sync.RWMutex type unstructuredClient struct { - base dynamic.Interface - mapper meta.ResettableRESTMapper - - Client dynamic.ResourceInterface - Discovery discovery.AggregatedDiscoveryInterface - - unstructured *unstructured.Unstructured - // modify is a function that modifies the existing object based on the required object. // The first argument is a pointer to a boolean that should be set to true if the object was modified. // i.e. `*modified = true` @@ -68,6 +60,14 @@ type unstructuredClient struct { // If Not set, the object will only have its metadata fields updated. // If set, the object will be modified based on the function. ModifyOnExists + + base dynamic.Interface + mapper meta.ResettableRESTMapper + + Client dynamic.ResourceInterface + Discovery discovery.AggregatedDiscoveryInterface + + unstructured *unstructured.Unstructured } func unstructuredConfigAndClient(kubeconfigPath string) (configClientCacheEntry, error) { diff --git a/pkg/cmd/showConfig.go b/pkg/cmd/showConfig.go index 469f376b46..dd1ef3df98 100644 --- a/pkg/cmd/showConfig.go +++ b/pkg/cmd/showConfig.go @@ -12,8 +12,9 @@ import ( ) type showConfigOptions struct { - Mode string genericclioptions.IOStreams + + Mode string } func NewShowConfigCommand(ioStreams genericclioptions.IOStreams) *cobra.Command { diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index c76b1e017c..193f700573 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -14,9 +14,9 @@ import ( ) type VersionOptions struct { - Output string - genericclioptions.IOStreams + + Output string } func NewVersionOptions(ioStreams genericclioptions.IOStreams) *VersionOptions { diff --git a/pkg/components/controllers.go b/pkg/components/controllers.go index ca18b4d748..e9bdf7af50 100644 --- a/pkg/components/controllers.go +++ b/pkg/components/controllers.go @@ -349,7 +349,7 @@ func startDNSController(ctx context.Context, cfg *config.Config, kubeconfigPath // type list. Also quote/escape any characters that are special to HAProxy (\,', and "). // See http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#2.2 func getMIMETypes(mimeTypes []operatorv1.CompressionMIMEType) []string { - mimes := []string{} + mimes := make([]string, 0, len(mimeTypes)) for _, m := range mimeTypes { mimeType := string(m) diff --git a/pkg/healthcheck/debug_info.go b/pkg/healthcheck/debug_info.go index cb995139a3..3474c8bd9a 100644 --- a/pkg/healthcheck/debug_info.go +++ b/pkg/healthcheck/debug_info.go @@ -129,6 +129,7 @@ type unpulledImage struct { type failedImage struct { unpulledImage + Message string } diff --git a/pkg/mdns/controller.go b/pkg/mdns/controller.go index 62e7c901ef..43c6640415 100644 --- a/pkg/mdns/controller.go +++ b/pkg/mdns/controller.go @@ -16,6 +16,7 @@ import ( type MicroShiftmDNSController struct { sync.Mutex + NodeName string NodeIP string KubeConfig string @@ -127,7 +128,7 @@ func ipInAddrs(ip string, addrs []net.Addr) bool { } func addrsToStrings(addrs []net.Addr) []string { - var ipAddrs = make([]string, 0) + var ipAddrs = make([]string, 0, len(addrs)) for _, a := range addrs { ipAddr, _, _ := net.ParseCIDR(a.String()) diff --git a/pkg/mdns/server/resolver.go b/pkg/mdns/server/resolver.go index 179c05e704..86ca595c67 100644 --- a/pkg/mdns/server/resolver.go +++ b/pkg/mdns/server/resolver.go @@ -26,6 +26,7 @@ const defaultTTL = 120 type Resolver struct { sync.Mutex + domain map[string][]net.IP } @@ -38,7 +39,7 @@ func NewResolver() *Resolver { func (r *Resolver) AddDomain(name string, ipStrs []string) { r.Lock() defer r.Unlock() - var ips = make([]net.IP, 0) + var ips = make([]net.IP, 0, len(ipStrs)) for _, ip := range ipStrs { ips = append(ips, net.ParseIP(ip)) diff --git a/pkg/servicemanager/manager.go b/pkg/servicemanager/manager.go index 2ec2b0ba63..cf5c049292 100644 --- a/pkg/servicemanager/manager.go +++ b/pkg/servicemanager/manager.go @@ -78,7 +78,7 @@ func (m *ServiceManager) Run(ctx context.Context, ready chan<- struct{}, stopped for _, service := range services { // Compile a list of ready channels of the service's dependencies (if any). - depsReadyList := []<-chan struct{}{} + depsReadyList := make([]<-chan struct{}, 0, len(service.Dependencies())) for _, dependency := range service.Dependencies() { depsReadyList = append(depsReadyList, readyMap[dependency]) } diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index e1a9fa44e9..5ffe4f2332 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -325,12 +325,11 @@ func computeMicroShiftVersionMetric() (Metric, error) { } func convertMetricsToWriteRequest(metrics []Metric) *prompb.WriteRequest { - timeSeriesList := make([]prompb.TimeSeries, 0) - metricMetadataList := make([]prompb.MetricMetadata, 0) + timeSeriesList := make([]prompb.TimeSeries, 0, len(metrics)) + metricMetadataList := make([]prompb.MetricMetadata, 0, len(metrics)) for _, metric := range metrics { - labels := []prompb.Label{ - {Name: "__name__", Value: metric.Name}, - } + labels := make([]prompb.Label, 0, 1+len(metric.Labels)) + labels = append(labels, prompb.Label{Name: "__name__", Value: metric.Name}) for _, label := range metric.Labels { labels = append(labels, prompb.Label{ Name: label.Name, diff --git a/pkg/util/cryptomaterial/certchains/signers.go b/pkg/util/cryptomaterial/certchains/signers.go index c78ae6a03b..130b706b34 100644 --- a/pkg/util/cryptomaterial/certchains/signers.go +++ b/pkg/util/cryptomaterial/certchains/signers.go @@ -63,6 +63,7 @@ type CertificateSigner struct { type signedCertificateInfo struct { CSRInfo + tlsConfig *crypto.TLSCertificateConfig } @@ -228,7 +229,7 @@ func (s *CertificateSigner) AddToBundles(bundlePaths ...string) error { return nil } -func (s *CertificateSigner) toBuilder() CertificateSignerBuilder { //nolint:ireturn +func (s *CertificateSigner) toBuilder() CertificateSignerBuilder { signer := NewCertificateSigner(s.signerName, s.signerDir, s.signerValidity) for _, subCA := range s.subCAs { diff --git a/pkg/version/version.go b/pkg/version/version.go index 2be5fadeb5..befcfd2422 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -35,6 +35,7 @@ const BuildVariantCommunity = "community" type Info struct { version.Info + BuildVariant string Patch string `json:"patch"` } diff --git a/scripts/fetch_tools.sh b/scripts/fetch_tools.sh index f451762fb3..4d39f4b308 100755 --- a/scripts/fetch_tools.sh +++ b/scripts/fetch_tools.sh @@ -54,10 +54,10 @@ _install() { } gettool_golangci-lint() { - local ver="2.1.6" + local ver="2.10.1" declare -A checksums=( - ["x86_64"]="e55e0eb515936c0fbd178bce504798a9bd2f0b191e5e357768b18fd5415ee541" - ["aarch64"]="582eb73880f4408d7fb89f12b502d577bd7b0b63d8c681da92bb6b9d934d4363") + ["x86_64"]="dfa775874cf0561b404a02a8f4481fc69b28091da95aa697259820d429b09c99" + ["aarch64"]="6652b42ae02915eb2f9cb2a2e0cac99514c8eded8388d88ae3e06e1a52c00de8") declare -A arch_map=( ["x86_64"]="amd64"