Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -62,7 +62,7 @@ require ( |
| 62 | 62 |
github.com/miekg/dns v1.1.61 |
| 63 | 63 |
github.com/mistifyio/go-zfs/v3 v3.0.1 |
| 64 | 64 |
github.com/mitchellh/copystructure v1.2.0 |
| 65 |
- github.com/moby/buildkit v0.21.1 |
|
| 65 |
+ github.com/moby/buildkit v0.22.0-rc1 |
|
| 66 | 66 |
github.com/moby/docker-image-spec v1.3.1 |
| 67 | 67 |
github.com/moby/go-archive v0.1.0 |
| 68 | 68 |
github.com/moby/ipvs v1.1.0 |
| ... | ... |
@@ -146,6 +146,7 @@ require ( |
| 146 | 146 |
github.com/cespare/xxhash/v2 v2.3.0 // indirect |
| 147 | 147 |
github.com/cilium/ebpf v0.17.3 // indirect |
| 148 | 148 |
github.com/container-storage-interface/spec v1.5.0 // indirect |
| 149 |
+ github.com/containerd/accelerated-container-image v1.2.3 // indirect |
|
| 149 | 150 |
github.com/containerd/console v1.0.4 // indirect |
| 150 | 151 |
github.com/containerd/errdefs/pkg v0.3.0 // indirect |
| 151 | 152 |
github.com/containerd/go-cni v1.1.12 // indirect |
| ... | ... |
@@ -208,7 +209,7 @@ require ( |
| 208 | 208 |
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect |
| 209 | 209 |
github.com/tinylib/msgp v1.1.8 // indirect |
| 210 | 210 |
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 // indirect |
| 211 |
- github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583 // indirect |
|
| 211 |
+ github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144 // indirect |
|
| 212 | 212 |
github.com/tonistiigi/go-actions-cache v0.0.0-20250228231703-3e9a6642607f // indirect |
| 213 | 213 |
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 // indirect |
| 214 | 214 |
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect |
| ... | ... |
@@ -119,6 +119,8 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUo |
| 119 | 119 |
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= |
| 120 | 120 |
github.com/container-storage-interface/spec v1.5.0 h1:lvKxe3uLgqQeVQcrnL2CPQKISoKjTJxojEs9cBk+HXo= |
| 121 | 121 |
github.com/container-storage-interface/spec v1.5.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s= |
| 122 |
+github.com/containerd/accelerated-container-image v1.2.3 h1:tAIoP7Z7b2xGhb7QCM5Fa+2xqWfPqRmyi5lodbsGGRA= |
|
| 123 |
+github.com/containerd/accelerated-container-image v1.2.3/go.mod h1:EvKVWor6ZQNUyYp0MZm5hw4k21ropuz7EegM+m/Jb/Q= |
|
| 122 | 124 |
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= |
| 123 | 125 |
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= |
| 124 | 126 |
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= |
| ... | ... |
@@ -175,8 +177,8 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi |
| 175 | 175 |
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= |
| 176 | 176 |
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= |
| 177 | 177 |
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= |
| 178 |
-github.com/docker/cli v28.0.4+incompatible h1:pBJSJeNd9QeIWPjRcV91RVJihd/TXB77q1ef64XEu4A= |
|
| 179 |
-github.com/docker/cli v28.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= |
|
| 178 |
+github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k= |
|
| 179 |
+github.com/docker/cli v28.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= |
|
| 180 | 180 |
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= |
| 181 | 181 |
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= |
| 182 | 182 |
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= |
| ... | ... |
@@ -383,8 +385,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F |
| 383 | 383 |
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= |
| 384 | 384 |
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= |
| 385 | 385 |
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= |
| 386 |
-github.com/moby/buildkit v0.21.1 h1:wTjVLfirh7skZt9piaIlNo8WdiPjza1CDl2EArDV9bA= |
|
| 387 |
-github.com/moby/buildkit v0.21.1/go.mod h1:mBq0D44uCyz2PdX8T/qym5LBbkBO3GGv0wqgX9ABYYw= |
|
| 386 |
+github.com/moby/buildkit v0.22.0-rc1 h1:Q47jZZws7+0WhucTcm35NRV8NcO6n1SwIikzfqcGKLo= |
|
| 387 |
+github.com/moby/buildkit v0.22.0-rc1/go.mod h1:j4pP5hxiTWcz7xuTK2cyxQislHl/N2WWHzOy43DlLJw= |
|
| 388 | 388 |
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= |
| 389 | 389 |
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= |
| 390 | 390 |
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= |
| ... | ... |
@@ -555,8 +557,8 @@ github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= |
| 555 | 555 |
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= |
| 556 | 556 |
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 h1:r0p7fK56l8WPequOaR3i9LBqfPtEdXIQbUTzT55iqT4= |
| 557 | 557 |
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY= |
| 558 |
-github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583 h1:mK+ZskNt7SG4dxfKIi27C7qHAQzyjAVt1iyTf0hmsNc= |
|
| 559 |
-github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98= |
|
| 558 |
+github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144 h1:k9tdF32oJYwtjzMx+D26M6eYiCaAPdJ7tyN7tF1oU5Q= |
|
| 559 |
+github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98= |
|
| 560 | 560 |
github.com/tonistiigi/go-actions-cache v0.0.0-20250228231703-3e9a6642607f h1:q/SWz3Bz0KtAsqaBo73CHVXjaz5O8PDnmD2JHVhgYnE= |
| 561 | 561 |
github.com/tonistiigi/go-actions-cache v0.0.0-20250228231703-3e9a6642607f/go.mod h1:h0oRlVs3NoFIHysRQ4rU1+RG4QmU0M2JVSwTYrB4igk= |
| 562 | 562 |
github.com/tonistiigi/go-archvariant v1.0.0 h1:5LC1eDWiBNflnTF1prCiX09yfNHIxDC/aukdhCdTyb0= |
| 563 | 563 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,201 @@ |
| 0 |
+ Apache License |
|
| 1 |
+ Version 2.0, January 2004 |
|
| 2 |
+ http://www.apache.org/licenses/ |
|
| 3 |
+ |
|
| 4 |
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
|
| 5 |
+ |
|
| 6 |
+ 1. Definitions. |
|
| 7 |
+ |
|
| 8 |
+ "License" shall mean the terms and conditions for use, reproduction, |
|
| 9 |
+ and distribution as defined by Sections 1 through 9 of this document. |
|
| 10 |
+ |
|
| 11 |
+ "Licensor" shall mean the copyright owner or entity authorized by |
|
| 12 |
+ the copyright owner that is granting the License. |
|
| 13 |
+ |
|
| 14 |
+ "Legal Entity" shall mean the union of the acting entity and all |
|
| 15 |
+ other entities that control, are controlled by, or are under common |
|
| 16 |
+ control with that entity. For the purposes of this definition, |
|
| 17 |
+ "control" means (i) the power, direct or indirect, to cause the |
|
| 18 |
+ direction or management of such entity, whether by contract or |
|
| 19 |
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the |
|
| 20 |
+ outstanding shares, or (iii) beneficial ownership of such entity. |
|
| 21 |
+ |
|
| 22 |
+ "You" (or "Your") shall mean an individual or Legal Entity |
|
| 23 |
+ exercising permissions granted by this License. |
|
| 24 |
+ |
|
| 25 |
+ "Source" form shall mean the preferred form for making modifications, |
|
| 26 |
+ including but not limited to software source code, documentation |
|
| 27 |
+ source, and configuration files. |
|
| 28 |
+ |
|
| 29 |
+ "Object" form shall mean any form resulting from mechanical |
|
| 30 |
+ transformation or translation of a Source form, including but |
|
| 31 |
+ not limited to compiled object code, generated documentation, |
|
| 32 |
+ and conversions to other media types. |
|
| 33 |
+ |
|
| 34 |
+ "Work" shall mean the work of authorship, whether in Source or |
|
| 35 |
+ Object form, made available under the License, as indicated by a |
|
| 36 |
+ copyright notice that is included in or attached to the work |
|
| 37 |
+ (an example is provided in the Appendix below). |
|
| 38 |
+ |
|
| 39 |
+ "Derivative Works" shall mean any work, whether in Source or Object |
|
| 40 |
+ form, that is based on (or derived from) the Work and for which the |
|
| 41 |
+ editorial revisions, annotations, elaborations, or other modifications |
|
| 42 |
+ represent, as a whole, an original work of authorship. For the purposes |
|
| 43 |
+ of this License, Derivative Works shall not include works that remain |
|
| 44 |
+ separable from, or merely link (or bind by name) to the interfaces of, |
|
| 45 |
+ the Work and Derivative Works thereof. |
|
| 46 |
+ |
|
| 47 |
+ "Contribution" shall mean any work of authorship, including |
|
| 48 |
+ the original version of the Work and any modifications or additions |
|
| 49 |
+ to that Work or Derivative Works thereof, that is intentionally |
|
| 50 |
+ submitted to Licensor for inclusion in the Work by the copyright owner |
|
| 51 |
+ or by an individual or Legal Entity authorized to submit on behalf of |
|
| 52 |
+ the copyright owner. For the purposes of this definition, "submitted" |
|
| 53 |
+ means any form of electronic, verbal, or written communication sent |
|
| 54 |
+ to the Licensor or its representatives, including but not limited to |
|
| 55 |
+ communication on electronic mailing lists, source code control systems, |
|
| 56 |
+ and issue tracking systems that are managed by, or on behalf of, the |
|
| 57 |
+ Licensor for the purpose of discussing and improving the Work, but |
|
| 58 |
+ excluding communication that is conspicuously marked or otherwise |
|
| 59 |
+ designated in writing by the copyright owner as "Not a Contribution." |
|
| 60 |
+ |
|
| 61 |
+ "Contributor" shall mean Licensor and any individual or Legal Entity |
|
| 62 |
+ on behalf of whom a Contribution has been received by Licensor and |
|
| 63 |
+ subsequently incorporated within the Work. |
|
| 64 |
+ |
|
| 65 |
+ 2. Grant of Copyright License. Subject to the terms and conditions of |
|
| 66 |
+ this License, each Contributor hereby grants to You a perpetual, |
|
| 67 |
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|
| 68 |
+ copyright license to reproduce, prepare Derivative Works of, |
|
| 69 |
+ publicly display, publicly perform, sublicense, and distribute the |
|
| 70 |
+ Work and such Derivative Works in Source or Object form. |
|
| 71 |
+ |
|
| 72 |
+ 3. Grant of Patent License. Subject to the terms and conditions of |
|
| 73 |
+ this License, each Contributor hereby grants to You a perpetual, |
|
| 74 |
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|
| 75 |
+ (except as stated in this section) patent license to make, have made, |
|
| 76 |
+ use, offer to sell, sell, import, and otherwise transfer the Work, |
|
| 77 |
+ where such license applies only to those patent claims licensable |
|
| 78 |
+ by such Contributor that are necessarily infringed by their |
|
| 79 |
+ Contribution(s) alone or by combination of their Contribution(s) |
|
| 80 |
+ with the Work to which such Contribution(s) was submitted. If You |
|
| 81 |
+ institute patent litigation against any entity (including a |
|
| 82 |
+ cross-claim or counterclaim in a lawsuit) alleging that the Work |
|
| 83 |
+ or a Contribution incorporated within the Work constitutes direct |
|
| 84 |
+ or contributory patent infringement, then any patent licenses |
|
| 85 |
+ granted to You under this License for that Work shall terminate |
|
| 86 |
+ as of the date such litigation is filed. |
|
| 87 |
+ |
|
| 88 |
+ 4. Redistribution. You may reproduce and distribute copies of the |
|
| 89 |
+ Work or Derivative Works thereof in any medium, with or without |
|
| 90 |
+ modifications, and in Source or Object form, provided that You |
|
| 91 |
+ meet the following conditions: |
|
| 92 |
+ |
|
| 93 |
+ (a) You must give any other recipients of the Work or |
|
| 94 |
+ Derivative Works a copy of this License; and |
|
| 95 |
+ |
|
| 96 |
+ (b) You must cause any modified files to carry prominent notices |
|
| 97 |
+ stating that You changed the files; and |
|
| 98 |
+ |
|
| 99 |
+ (c) You must retain, in the Source form of any Derivative Works |
|
| 100 |
+ that You distribute, all copyright, patent, trademark, and |
|
| 101 |
+ attribution notices from the Source form of the Work, |
|
| 102 |
+ excluding those notices that do not pertain to any part of |
|
| 103 |
+ the Derivative Works; and |
|
| 104 |
+ |
|
| 105 |
+ (d) If the Work includes a "NOTICE" text file as part of its |
|
| 106 |
+ distribution, then any Derivative Works that You distribute must |
|
| 107 |
+ include a readable copy of the attribution notices contained |
|
| 108 |
+ within such NOTICE file, excluding those notices that do not |
|
| 109 |
+ pertain to any part of the Derivative Works, in at least one |
|
| 110 |
+ of the following places: within a NOTICE text file distributed |
|
| 111 |
+ as part of the Derivative Works; within the Source form or |
|
| 112 |
+ documentation, if provided along with the Derivative Works; or, |
|
| 113 |
+ within a display generated by the Derivative Works, if and |
|
| 114 |
+ wherever such third-party notices normally appear. The contents |
|
| 115 |
+ of the NOTICE file are for informational purposes only and |
|
| 116 |
+ do not modify the License. You may add Your own attribution |
|
| 117 |
+ notices within Derivative Works that You distribute, alongside |
|
| 118 |
+ or as an addendum to the NOTICE text from the Work, provided |
|
| 119 |
+ that such additional attribution notices cannot be construed |
|
| 120 |
+ as modifying the License. |
|
| 121 |
+ |
|
| 122 |
+ You may add Your own copyright statement to Your modifications and |
|
| 123 |
+ may provide additional or different license terms and conditions |
|
| 124 |
+ for use, reproduction, or distribution of Your modifications, or |
|
| 125 |
+ for any such Derivative Works as a whole, provided Your use, |
|
| 126 |
+ reproduction, and distribution of the Work otherwise complies with |
|
| 127 |
+ the conditions stated in this License. |
|
| 128 |
+ |
|
| 129 |
+ 5. Submission of Contributions. Unless You explicitly state otherwise, |
|
| 130 |
+ any Contribution intentionally submitted for inclusion in the Work |
|
| 131 |
+ by You to the Licensor shall be under the terms and conditions of |
|
| 132 |
+ this License, without any additional terms or conditions. |
|
| 133 |
+ Notwithstanding the above, nothing herein shall supersede or modify |
|
| 134 |
+ the terms of any separate license agreement you may have executed |
|
| 135 |
+ with Licensor regarding such Contributions. |
|
| 136 |
+ |
|
| 137 |
+ 6. Trademarks. This License does not grant permission to use the trade |
|
| 138 |
+ names, trademarks, service marks, or product names of the Licensor, |
|
| 139 |
+ except as required for reasonable and customary use in describing the |
|
| 140 |
+ origin of the Work and reproducing the content of the NOTICE file. |
|
| 141 |
+ |
|
| 142 |
+ 7. Disclaimer of Warranty. Unless required by applicable law or |
|
| 143 |
+ agreed to in writing, Licensor provides the Work (and each |
|
| 144 |
+ Contributor provides its Contributions) on an "AS IS" BASIS, |
|
| 145 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
|
| 146 |
+ implied, including, without limitation, any warranties or conditions |
|
| 147 |
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
|
| 148 |
+ PARTICULAR PURPOSE. You are solely responsible for determining the |
|
| 149 |
+ appropriateness of using or redistributing the Work and assume any |
|
| 150 |
+ risks associated with Your exercise of permissions under this License. |
|
| 151 |
+ |
|
| 152 |
+ 8. Limitation of Liability. In no event and under no legal theory, |
|
| 153 |
+ whether in tort (including negligence), contract, or otherwise, |
|
| 154 |
+ unless required by applicable law (such as deliberate and grossly |
|
| 155 |
+ negligent acts) or agreed to in writing, shall any Contributor be |
|
| 156 |
+ liable to You for damages, including any direct, indirect, special, |
|
| 157 |
+ incidental, or consequential damages of any character arising as a |
|
| 158 |
+ result of this License or out of the use or inability to use the |
|
| 159 |
+ Work (including but not limited to damages for loss of goodwill, |
|
| 160 |
+ work stoppage, computer failure or malfunction, or any and all |
|
| 161 |
+ other commercial damages or losses), even if such Contributor |
|
| 162 |
+ has been advised of the possibility of such damages. |
|
| 163 |
+ |
|
| 164 |
+ 9. Accepting Warranty or Additional Liability. While redistributing |
|
| 165 |
+ the Work or Derivative Works thereof, You may choose to offer, |
|
| 166 |
+ and charge a fee for, acceptance of support, warranty, indemnity, |
|
| 167 |
+ or other liability obligations and/or rights consistent with this |
|
| 168 |
+ License. However, in accepting such obligations, You may act only |
|
| 169 |
+ on Your own behalf and on Your sole responsibility, not on behalf |
|
| 170 |
+ of any other Contributor, and only if You agree to indemnify, |
|
| 171 |
+ defend, and hold each Contributor harmless for any liability |
|
| 172 |
+ incurred by, or claims asserted against, such Contributor by reason |
|
| 173 |
+ of your accepting any such warranty or additional liability. |
|
| 174 |
+ |
|
| 175 |
+ END OF TERMS AND CONDITIONS |
|
| 176 |
+ |
|
| 177 |
+ APPENDIX: How to apply the Apache License to your work. |
|
| 178 |
+ |
|
| 179 |
+ To apply the Apache License to your work, attach the following |
|
| 180 |
+ boilerplate notice, with the fields enclosed by brackets "[]" |
|
| 181 |
+ replaced with your own identifying information. (Don't include |
|
| 182 |
+ the brackets!) The text should be enclosed in the appropriate |
|
| 183 |
+ comment syntax for the file format. We also recommend that a |
|
| 184 |
+ file or class name and description of purpose be included on the |
|
| 185 |
+ same "printed page" as the copyright notice for easier |
|
| 186 |
+ identification within third-party archives. |
|
| 187 |
+ |
|
| 188 |
+ Copyright [yyyy] [name of copyright owner] |
|
| 189 |
+ |
|
| 190 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 191 |
+ you may not use this file except in compliance with the License. |
|
| 192 |
+ You may obtain a copy of the License at |
|
| 193 |
+ |
|
| 194 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 195 |
+ |
|
| 196 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 197 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 198 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 199 |
+ See the License for the specific language governing permissions and |
|
| 200 |
+ limitations under the License. |
|
| 0 | 201 |
\ No newline at end of file |
| 1 | 202 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,133 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The Accelerated Container Image Authors |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package label |
|
| 17 |
+ |
|
| 18 |
+// support on-demand loading by the labels |
|
| 19 |
+const ( |
|
| 20 |
+ // TargetSnapshotRef is the interface to know that Prepare |
|
| 21 |
+ // action is to pull image, not for container Writable snapshot. |
|
| 22 |
+ // |
|
| 23 |
+ // NOTE: Only available in >= containerd 1.4.0 and containerd.Pull |
|
| 24 |
+ // with Unpack option. |
|
| 25 |
+ // |
|
| 26 |
+ // FIXME(fuweid): With containerd design, we don't know that what purpose |
|
| 27 |
+ // snapshotter.Prepare does for. For unpacked image, prepare is for |
|
| 28 |
+ // container's rootfs. For pulling image, the prepare is for committed. |
|
| 29 |
+ // With label "containerd.io/snapshot.ref" in preparing, snapshotter |
|
| 30 |
+ // author will know it is for pulling image. It will be useful. |
|
| 31 |
+ // |
|
| 32 |
+ // The label is only propagated during pulling image. So, is it possible |
|
| 33 |
+ // to propagate by image.Unpack()? |
|
| 34 |
+ TargetSnapshotRef = "containerd.io/snapshot.ref" |
|
| 35 |
+ |
|
| 36 |
+ // TargetImageRef is the label to mark where the snapshot comes from. |
|
| 37 |
+ // |
|
| 38 |
+ // TODO(fuweid): Is it possible to use it in upstream? |
|
| 39 |
+ TargetImageRef = "containerd.io/snapshot/image-ref" |
|
| 40 |
+ |
|
| 41 |
+ // OverlayBDBlobDigest is the annotation key in the manifest to |
|
| 42 |
+ // describe the digest of blob in OverlayBD format. |
|
| 43 |
+ // |
|
| 44 |
+ // NOTE: The annotation is part of image layer blob's descriptor. |
|
| 45 |
+ OverlayBDBlobDigest = "containerd.io/snapshot/overlaybd/blob-digest" |
|
| 46 |
+ |
|
| 47 |
+ // OverlayBDBlobSize is the annotation key in the manifest to |
|
| 48 |
+ // describe the size of blob in OverlayBD format. |
|
| 49 |
+ // |
|
| 50 |
+ // NOTE: The annotation is part of image layer blob's descriptor. |
|
| 51 |
+ OverlayBDBlobSize = "containerd.io/snapshot/overlaybd/blob-size" |
|
| 52 |
+ |
|
| 53 |
+ // OverlayBDBlobFsType is the annotation key in the manifest to |
|
| 54 |
+ // describe the filesystem type to be mounted as of blob in OverlayBD format. |
|
| 55 |
+ // |
|
| 56 |
+ // NOTE: The annotation is part of image layer blob's descriptor. |
|
| 57 |
+ OverlayBDBlobFsType = "containerd.io/snapshot/overlaybd/blob-fs-type" |
|
| 58 |
+ |
|
| 59 |
+ // AccelerationLayer is the annotation key in the manifest to indicate |
|
| 60 |
+ // whether a top layer is acceleration layer or not. |
|
| 61 |
+ AccelerationLayer = "containerd.io/snapshot/overlaybd/acceleration-layer" |
|
| 62 |
+ |
|
| 63 |
+ // RecordTrace tells snapshotter to record trace |
|
| 64 |
+ RecordTrace = "containerd.io/snapshot/overlaybd/record-trace" |
|
| 65 |
+ |
|
| 66 |
+ // RecordTracePath is the file path to record trace |
|
| 67 |
+ RecordTracePath = "containerd.io/snapshot/overlaybd/record-trace-path" |
|
| 68 |
+ |
|
| 69 |
+ // ZFileConfig is the config of ZFile |
|
| 70 |
+ ZFileConfig = "containerd.io/snapshot/overlaybd/zfile-config" |
|
| 71 |
+ |
|
| 72 |
+ // OverlayBD virtual block device size |
|
| 73 |
+ OverlayBDVsize = "containerd.io/snapshot/overlaybd/vsize" |
|
| 74 |
+ |
|
| 75 |
+ // CRIImageRef is the image-ref from cri |
|
| 76 |
+ CRIImageRef = "containerd.io/snapshot/cri.image-ref" |
|
| 77 |
+ |
|
| 78 |
+ // TurboOCIDigest is the index annotation key for image layer digest |
|
| 79 |
+ FastOCIDigest = "containerd.io/snapshot/overlaybd/fastoci/target-digest" // legacy |
|
| 80 |
+ TurboOCIDigest = "containerd.io/snapshot/overlaybd/turbo-oci/target-digest" |
|
| 81 |
+ |
|
| 82 |
+ // TurboOCIMediaType is the index annotation key for image layer media type |
|
| 83 |
+ FastOCIMediaType = "containerd.io/snapshot/overlaybd/fastoci/target-media-type" // legacy |
|
| 84 |
+ TurboOCIMediaType = "containerd.io/snapshot/overlaybd/turbo-oci/target-media-type" |
|
| 85 |
+ |
|
| 86 |
+ // DownloadRemoteBlob is a label for download remote blob |
|
| 87 |
+ DownloadRemoteBlob = "containerd.io/snapshot/overlaybd/download-remote-blob" |
|
| 88 |
+ |
|
| 89 |
+ RemoteLabel = "containerd.io/snapshot/remote" |
|
| 90 |
+ RemoteLabelVal = "remote snapshot" |
|
| 91 |
+ |
|
| 92 |
+ // OverlayBDVersion is the version number of overlaybd blob |
|
| 93 |
+ OverlayBDVersion = "containerd.io/snapshot/overlaybd/version" |
|
| 94 |
+ |
|
| 95 |
+ // LayerToTurboOCI is used to convert local layer to turboOCI with tar index |
|
| 96 |
+ LayerToTurboOCI = "containerd.io/snapshot/overlaybd/convert2turbo-oci" |
|
| 97 |
+ |
|
| 98 |
+ SnapshotType = "containerd.io/snapshot/type" |
|
| 99 |
+ |
|
| 100 |
+ // RootfsQuotaLabel sets container rootfs diskquota |
|
| 101 |
+ RootfsQuotaLabel = "containerd.io/snapshot/disk_quota" |
|
| 102 |
+) |
|
| 103 |
+ |
|
| 104 |
+// used in filterAnnotationsForSave (https://github.com/moby/buildkit/blob/v0.11/cache/refs.go#L882) |
|
| 105 |
+var OverlayBDAnnotations = []string{
|
|
| 106 |
+ LocalOverlayBDPath, |
|
| 107 |
+ OverlayBDBlobDigest, |
|
| 108 |
+ OverlayBDBlobSize, |
|
| 109 |
+ OverlayBDBlobFsType, |
|
| 110 |
+} |
|
| 111 |
+ |
|
| 112 |
+// interface |
|
| 113 |
+const ( |
|
| 114 |
+ // SupportReadWriteMode is used to support writable block device |
|
| 115 |
+ // for active snapshotter. |
|
| 116 |
+ // |
|
| 117 |
+ // By default, multiple active snapshotters can share one block device |
|
| 118 |
+ // from parent snapshotter(committed). Like image builder and |
|
| 119 |
+ // sandboxed-like container runtime(KataContainer, Firecracker), those |
|
| 120 |
+ // cases want to use the block device alone or as writable. |
|
| 121 |
+ // There are two ways to provide writable devices: |
|
| 122 |
+ // - 'dir' mark the snapshotter |
|
| 123 |
+ // as wriable block device and mount it on rootfs. |
|
| 124 |
+ // - 'dev' mark the snapshotter |
|
| 125 |
+ // as wriable block device without mount. |
|
| 126 |
+ SupportReadWriteMode = "containerd.io/snapshot/overlaybd.writable" |
|
| 127 |
+ |
|
| 128 |
+ // LocalOverlayBDPath is used to export the commit file path. |
|
| 129 |
+ // |
|
| 130 |
+ // NOTE: Only used in image build. |
|
| 131 |
+ LocalOverlayBDPath = "containerd.io/snapshot/overlaybd.localcommitpath" |
|
| 132 |
+) |
| 0 | 133 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,45 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The Accelerated Container Image Authors |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package types |
|
| 17 |
+ |
|
| 18 |
+// OverlayBDBSConfig is the config of overlaybd target. |
|
| 19 |
+type OverlayBDBSConfig struct {
|
|
| 20 |
+ RepoBlobURL string `json:"repoBlobUrl"` |
|
| 21 |
+ Lowers []OverlayBDBSConfigLower `json:"lowers"` |
|
| 22 |
+ Upper OverlayBDBSConfigUpper `json:"upper"` |
|
| 23 |
+ ResultFile string `json:"resultFile"` |
|
| 24 |
+ AccelerationLayer bool `json:"accelerationLayer,omitempty"` |
|
| 25 |
+ RecordTracePath string `json:"recordTracePath,omitempty"` |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+// OverlayBDBSConfigLower |
|
| 29 |
+type OverlayBDBSConfigLower struct {
|
|
| 30 |
+ GzipIndex string `json:"gzipIndex,omitempty"` |
|
| 31 |
+ File string `json:"file,omitempty"` |
|
| 32 |
+ Digest string `json:"digest,omitempty"` |
|
| 33 |
+ TargetFile string `json:"targetFile,omitempty"` |
|
| 34 |
+ TargetDigest string `json:"targetDigest,omitempty"` |
|
| 35 |
+ Size int64 `json:"size,omitempty"` |
|
| 36 |
+ Dir string `json:"dir,omitempty"` |
|
| 37 |
+} |
|
| 38 |
+ |
|
| 39 |
+type OverlayBDBSConfigUpper struct {
|
|
| 40 |
+ Index string `json:"index,omitempty"` |
|
| 41 |
+ Data string `json:"data,omitempty"` |
|
| 42 |
+ Target string `json:"target,omitempty"` |
|
| 43 |
+ GzipIndex string `json:"gzipIndex,omitempty"` |
|
| 44 |
+} |
| 0 | 45 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,258 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The Accelerated Container Image Authors |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package utils |
|
| 17 |
+ |
|
| 18 |
+import ( |
|
| 19 |
+ "context" |
|
| 20 |
+ "encoding/json" |
|
| 21 |
+ "fmt" |
|
| 22 |
+ "os" |
|
| 23 |
+ "os/exec" |
|
| 24 |
+ "path" |
|
| 25 |
+ "path/filepath" |
|
| 26 |
+ "strings" |
|
| 27 |
+ |
|
| 28 |
+ sn "github.com/containerd/accelerated-container-image/pkg/types" |
|
| 29 |
+ "github.com/containerd/log" |
|
| 30 |
+ "github.com/pkg/errors" |
|
| 31 |
+) |
|
| 32 |
+ |
|
| 33 |
+const ( |
|
| 34 |
+ obdBinCreate = "/opt/overlaybd/bin/overlaybd-create" |
|
| 35 |
+ obdBinCommit = "/opt/overlaybd/bin/overlaybd-commit" |
|
| 36 |
+ obdBinApply = "/opt/overlaybd/bin/overlaybd-apply" |
|
| 37 |
+ obdBinTurboOCIApply = "/opt/overlaybd/bin/turboOCI-apply" |
|
| 38 |
+ |
|
| 39 |
+ dataFile = "writable_data" |
|
| 40 |
+ idxFile = "writable_index" |
|
| 41 |
+ sealedFile = "overlaybd.sealed" |
|
| 42 |
+ commitTempFile = "overlaybd.commit.temp" |
|
| 43 |
+ commitFile = "overlaybd.commit" |
|
| 44 |
+) |
|
| 45 |
+ |
|
| 46 |
+type ConvertOption struct {
|
|
| 47 |
+ // src options |
|
| 48 |
+ // (TODO) LayerPath string // path of layer.tgz or layer.tar |
|
| 49 |
+ TarMetaPath string // path of layer.tar.meta |
|
| 50 |
+ |
|
| 51 |
+ Config sn.OverlayBDBSConfig |
|
| 52 |
+ Workdir string |
|
| 53 |
+ |
|
| 54 |
+ // output options |
|
| 55 |
+ Ext4FSMetaPath string |
|
| 56 |
+ // (TODO) GzipIndexPath string |
|
| 57 |
+} |
|
| 58 |
+ |
|
| 59 |
+var defaultServiceTemplate = ` |
|
| 60 |
+{
|
|
| 61 |
+ "registryFsVersion": "v2", |
|
| 62 |
+ "logPath": "", |
|
| 63 |
+ "logLevel": 1, |
|
| 64 |
+ "cacheConfig": {
|
|
| 65 |
+ "cacheType": "file", |
|
| 66 |
+ "cacheDir": "%s", |
|
| 67 |
+ "cacheSizeGB": 4 |
|
| 68 |
+ }, |
|
| 69 |
+ "gzipCacheConfig": {
|
|
| 70 |
+ "enable": false |
|
| 71 |
+ }, |
|
| 72 |
+ "credentialConfig": {
|
|
| 73 |
+ "mode": "file", |
|
| 74 |
+ "path": "" |
|
| 75 |
+ }, |
|
| 76 |
+ "ioEngine": 0, |
|
| 77 |
+ "download": {
|
|
| 78 |
+ "enable": false |
|
| 79 |
+ }, |
|
| 80 |
+ "enableAudit": false |
|
| 81 |
+} |
|
| 82 |
+` |
|
| 83 |
+ |
|
| 84 |
+func Create(ctx context.Context, dir string, opts ...string) error {
|
|
| 85 |
+ dataPath := path.Join(dir, dataFile) |
|
| 86 |
+ indexPath := path.Join(dir, idxFile) |
|
| 87 |
+ os.RemoveAll(dataPath) |
|
| 88 |
+ os.RemoveAll(indexPath) |
|
| 89 |
+ args := append([]string{dataPath, indexPath}, opts...)
|
|
| 90 |
+ log.G(ctx).Debugf("%s %s", obdBinCreate, strings.Join(args, " "))
|
|
| 91 |
+ out, err := exec.CommandContext(ctx, obdBinCreate, args...).CombinedOutput() |
|
| 92 |
+ if err != nil {
|
|
| 93 |
+ return errors.Wrapf(err, "failed to overlaybd-create: %s", out) |
|
| 94 |
+ } |
|
| 95 |
+ return nil |
|
| 96 |
+} |
|
| 97 |
+ |
|
| 98 |
+func Seal(ctx context.Context, dir, toDir string, opts ...string) error {
|
|
| 99 |
+ args := append([]string{
|
|
| 100 |
+ "--seal", |
|
| 101 |
+ path.Join(dir, dataFile), |
|
| 102 |
+ path.Join(dir, idxFile), |
|
| 103 |
+ }, opts...) |
|
| 104 |
+ log.G(ctx).Debugf("%s %s", obdBinCommit, strings.Join(args, " "))
|
|
| 105 |
+ out, err := exec.CommandContext(ctx, obdBinCommit, args...).CombinedOutput() |
|
| 106 |
+ if err != nil {
|
|
| 107 |
+ return errors.Wrapf(err, "failed to seal writable overlaybd: %s", out) |
|
| 108 |
+ } |
|
| 109 |
+ if err := os.Rename(path.Join(dir, dataFile), path.Join(toDir, sealedFile)); err != nil {
|
|
| 110 |
+ return errors.Wrapf(err, "failed to rename sealed overlaybd file") |
|
| 111 |
+ } |
|
| 112 |
+ os.RemoveAll(path.Join(dir, idxFile)) |
|
| 113 |
+ return nil |
|
| 114 |
+} |
|
| 115 |
+ |
|
| 116 |
+func Commit(ctx context.Context, dir, toDir string, sealed bool, opts ...string) error {
|
|
| 117 |
+ var args []string |
|
| 118 |
+ if sealed {
|
|
| 119 |
+ args = append([]string{
|
|
| 120 |
+ "--commit_sealed", |
|
| 121 |
+ path.Join(dir, sealedFile), |
|
| 122 |
+ path.Join(toDir, commitTempFile), |
|
| 123 |
+ }, opts...) |
|
| 124 |
+ } else {
|
|
| 125 |
+ args = append([]string{
|
|
| 126 |
+ path.Join(dir, dataFile), |
|
| 127 |
+ path.Join(dir, idxFile), |
|
| 128 |
+ path.Join(toDir, commitFile), |
|
| 129 |
+ }, opts...) |
|
| 130 |
+ } |
|
| 131 |
+ log.G(ctx).Debugf("%s %s", obdBinCommit, strings.Join(args, " "))
|
|
| 132 |
+ out, err := exec.CommandContext(ctx, obdBinCommit, args...).CombinedOutput() |
|
| 133 |
+ if err != nil {
|
|
| 134 |
+ return errors.Wrapf(err, "failed to overlaybd-commit: %s", out) |
|
| 135 |
+ } |
|
| 136 |
+ if sealed {
|
|
| 137 |
+ return os.Rename(path.Join(toDir, commitTempFile), path.Join(toDir, commitFile)) |
|
| 138 |
+ } |
|
| 139 |
+ return nil |
|
| 140 |
+} |
|
| 141 |
+ |
|
| 142 |
+func ApplyOverlaybd(ctx context.Context, dir string, opts ...string) error {
|
|
| 143 |
+ |
|
| 144 |
+ args := append([]string{
|
|
| 145 |
+ path.Join(dir, "layer.tar"), |
|
| 146 |
+ path.Join(dir, "config.json")}, opts...) |
|
| 147 |
+ log.G(ctx).Debugf("%s %s", obdBinApply, strings.Join(args, " "))
|
|
| 148 |
+ out, err := exec.CommandContext(ctx, obdBinApply, args...).CombinedOutput() |
|
| 149 |
+ if err != nil {
|
|
| 150 |
+ return errors.Wrapf(err, "failed to overlaybd-apply[native]: %s", out) |
|
| 151 |
+ } |
|
| 152 |
+ return nil |
|
| 153 |
+} |
|
| 154 |
+ |
|
| 155 |
+func ApplyTurboOCI(ctx context.Context, dir, gzipMetaFile string, opts ...string) error {
|
|
| 156 |
+ |
|
| 157 |
+ args := append([]string{
|
|
| 158 |
+ path.Join(dir, "layer.tar"), |
|
| 159 |
+ path.Join(dir, "config.json"), |
|
| 160 |
+ "--gz_index_path", path.Join(dir, gzipMetaFile)}, opts...) |
|
| 161 |
+ log.G(ctx).Debugf("%s %s", obdBinApply, strings.Join(args, " "))
|
|
| 162 |
+ out, err := exec.CommandContext(ctx, obdBinTurboOCIApply, args...).CombinedOutput() |
|
| 163 |
+ if err != nil {
|
|
| 164 |
+ return errors.Wrapf(err, "failed to overlaybd-apply[turboOCI]: %s", out) |
|
| 165 |
+ } |
|
| 166 |
+ return nil |
|
| 167 |
+} |
|
| 168 |
+ |
|
| 169 |
+func GenerateTarMeta(ctx context.Context, srcTarFile string, dstTarMeta string) error {
|
|
| 170 |
+ |
|
| 171 |
+ if _, err := os.Stat(srcTarFile); os.IsNotExist(err) {
|
|
| 172 |
+ return nil |
|
| 173 |
+ } else if err != nil {
|
|
| 174 |
+ return fmt.Errorf("error stating tar file: %w", err)
|
|
| 175 |
+ } |
|
| 176 |
+ log.G(ctx).Infof("generate layer meta for %s", srcTarFile)
|
|
| 177 |
+ if err := exec.Command(obdBinTurboOCIApply, srcTarFile, dstTarMeta, "--export").Run(); err != nil {
|
|
| 178 |
+ return fmt.Errorf("failed to convert tar file to overlaybd device: %w", err)
|
|
| 179 |
+ } |
|
| 180 |
+ return nil |
|
| 181 |
+} |
|
| 182 |
+ |
|
| 183 |
+// ConvertLayer produce a turbooci layer, target is path of ext4.fs.meta |
|
| 184 |
+func ConvertLayer(ctx context.Context, opt *ConvertOption, fs_type string) error {
|
|
| 185 |
+ if opt.Workdir == "" {
|
|
| 186 |
+ opt.Workdir = "tmp_conv" |
|
| 187 |
+ } |
|
| 188 |
+ |
|
| 189 |
+ if err := os.MkdirAll(opt.Workdir, 0755); err != nil {
|
|
| 190 |
+ return fmt.Errorf("failed to create work dir: %w", err)
|
|
| 191 |
+ } |
|
| 192 |
+ |
|
| 193 |
+ pathWritableData := filepath.Join(opt.Workdir, "writable_data") |
|
| 194 |
+ pathWritableIndex := filepath.Join(opt.Workdir, "writable_index") |
|
| 195 |
+ pathFakeTarget := filepath.Join(opt.Workdir, "fake_target") |
|
| 196 |
+ pathService := filepath.Join(opt.Workdir, "service.json") |
|
| 197 |
+ pathConfig := filepath.Join(opt.Workdir, "config.v1.json") |
|
| 198 |
+ |
|
| 199 |
+ // overlaybd-create |
|
| 200 |
+ args := []string{pathWritableData, pathWritableIndex, "256", "-s", "--turboOCI"}
|
|
| 201 |
+ if fs_type != "erofs" && len(opt.Config.Lowers) == 0 {
|
|
| 202 |
+ args = append(args, "--mkfs") |
|
| 203 |
+ } |
|
| 204 |
+ if out, err := exec.CommandContext(ctx, obdBinCreate, args...).CombinedOutput(); err != nil {
|
|
| 205 |
+ return fmt.Errorf("failed to overlaybd-create: %w, output: %s", err, out)
|
|
| 206 |
+ } |
|
| 207 |
+ file, err := os.Create(pathFakeTarget) |
|
| 208 |
+ if err != nil {
|
|
| 209 |
+ return fmt.Errorf("failed to create fake target: %w", err)
|
|
| 210 |
+ } |
|
| 211 |
+ file.Close() |
|
| 212 |
+ opt.Config.Upper = sn.OverlayBDBSConfigUpper{
|
|
| 213 |
+ Data: pathWritableData, |
|
| 214 |
+ Index: pathWritableIndex, |
|
| 215 |
+ Target: pathFakeTarget, |
|
| 216 |
+ } |
|
| 217 |
+ |
|
| 218 |
+ // turboOCI-apply |
|
| 219 |
+ if err := os.WriteFile(pathService, []byte(fmt.Sprintf(defaultServiceTemplate, |
|
| 220 |
+ filepath.Join(opt.Workdir, "cache"))), 0644, |
|
| 221 |
+ ); err != nil {
|
|
| 222 |
+ return fmt.Errorf("failed to write service.json: %w", err)
|
|
| 223 |
+ } |
|
| 224 |
+ configBytes, err := json.Marshal(opt.Config) |
|
| 225 |
+ if err != nil {
|
|
| 226 |
+ return fmt.Errorf("failed to marshal overlaybd config: %w", err)
|
|
| 227 |
+ } |
|
| 228 |
+ if err := os.WriteFile(pathConfig, configBytes, 0644); err != nil {
|
|
| 229 |
+ return fmt.Errorf("failed to write overlaybd config: %w", err)
|
|
| 230 |
+ } |
|
| 231 |
+ args = []string{
|
|
| 232 |
+ opt.TarMetaPath, pathConfig, |
|
| 233 |
+ "--service_config_path", pathService, |
|
| 234 |
+ "--fstype", fs_type, |
|
| 235 |
+ } |
|
| 236 |
+ if fs_type != "erofs" {
|
|
| 237 |
+ args = append(args, "--import") |
|
| 238 |
+ } |
|
| 239 |
+ |
|
| 240 |
+ log.G(ctx).Debugf("%s %s", obdBinTurboOCIApply, strings.Join(args, " "))
|
|
| 241 |
+ if out, err := exec.CommandContext(ctx, obdBinTurboOCIApply, |
|
| 242 |
+ args..., |
|
| 243 |
+ ).CombinedOutput(); err != nil {
|
|
| 244 |
+ return fmt.Errorf("failed to turboOCI-apply: %w, output: %s", err, out)
|
|
| 245 |
+ } |
|
| 246 |
+ |
|
| 247 |
+ // overlaybd-commit |
|
| 248 |
+ if out, err := exec.CommandContext(ctx, obdBinCommit, |
|
| 249 |
+ pathWritableData, |
|
| 250 |
+ pathWritableIndex, |
|
| 251 |
+ opt.Ext4FSMetaPath, |
|
| 252 |
+ "-z", "--turboOCI", |
|
| 253 |
+ ).CombinedOutput(); err != nil {
|
|
| 254 |
+ return fmt.Errorf("failed to overlaybd-commit: %w, output: %s", err, out)
|
|
| 255 |
+ } |
|
| 256 |
+ return nil |
|
| 257 |
+} |
| 0 | 258 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,83 @@ |
| 0 |
+//go:build !windows |
|
| 1 |
+ |
|
| 2 |
+/* |
|
| 3 |
+ Copyright The Accelerated Container Image Authors |
|
| 4 |
+ |
|
| 5 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ you may not use this file except in compliance with the License. |
|
| 7 |
+ You may obtain a copy of the License at |
|
| 8 |
+ |
|
| 9 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ |
|
| 11 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ See the License for the specific language governing permissions and |
|
| 15 |
+ limitations under the License. |
|
| 16 |
+*/ |
|
| 17 |
+ |
|
| 18 |
+// Based on https://github.com/containerd/continuity/blob/main/fs/du_unix.go |
|
| 19 |
+// Used to calculate the usage of the block dir, excluding the block/mountpoint dir. |
|
| 20 |
+ |
|
| 21 |
+package utils |
|
| 22 |
+ |
|
| 23 |
+import ( |
|
| 24 |
+ "context" |
|
| 25 |
+ "os" |
|
| 26 |
+ "path/filepath" |
|
| 27 |
+ "syscall" |
|
| 28 |
+ |
|
| 29 |
+ "github.com/containerd/continuity/fs" |
|
| 30 |
+) |
|
| 31 |
+ |
|
| 32 |
+const blocksUnitSize = 512 |
|
| 33 |
+ |
|
| 34 |
+type inode struct {
|
|
| 35 |
+ dev, ino uint64 |
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+func newInode(stat *syscall.Stat_t) inode {
|
|
| 39 |
+ return inode{
|
|
| 40 |
+ dev: uint64(stat.Dev), //nolint: unconvert // dev is uint32 on darwin/bsd, uint64 on linux/solaris/freebsd |
|
| 41 |
+ ino: uint64(stat.Ino), //nolint: unconvert // ino is uint32 on bsd, uint64 on darwin/linux/solaris/freebsd |
|
| 42 |
+ } |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+func DiskUsageWithoutMountpoint(ctx context.Context, roots ...string) (fs.Usage, error) {
|
|
| 46 |
+ var ( |
|
| 47 |
+ size int64 |
|
| 48 |
+ inodes = map[inode]struct{}{} // expensive!
|
|
| 49 |
+ ) |
|
| 50 |
+ |
|
| 51 |
+ for _, root := range roots {
|
|
| 52 |
+ if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
|
|
| 53 |
+ if fi.Name() == "mountpoint" {
|
|
| 54 |
+ return filepath.SkipDir |
|
| 55 |
+ } |
|
| 56 |
+ if err != nil {
|
|
| 57 |
+ return err |
|
| 58 |
+ } |
|
| 59 |
+ |
|
| 60 |
+ select {
|
|
| 61 |
+ case <-ctx.Done(): |
|
| 62 |
+ return ctx.Err() |
|
| 63 |
+ default: |
|
| 64 |
+ } |
|
| 65 |
+ stat := fi.Sys().(*syscall.Stat_t) |
|
| 66 |
+ inoKey := newInode(stat) |
|
| 67 |
+ if _, ok := inodes[inoKey]; !ok {
|
|
| 68 |
+ inodes[inoKey] = struct{}{}
|
|
| 69 |
+ size += stat.Blocks * blocksUnitSize |
|
| 70 |
+ } |
|
| 71 |
+ |
|
| 72 |
+ return nil |
|
| 73 |
+ }); err != nil {
|
|
| 74 |
+ return fs.Usage{}, err
|
|
| 75 |
+ } |
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ return fs.Usage{
|
|
| 79 |
+ Inodes: int64(len(inodes)), |
|
| 80 |
+ Size: size, |
|
| 81 |
+ }, nil |
|
| 82 |
+} |
| ... | ... |
@@ -1,13 +1,19 @@ |
| 1 | 1 |
package cache |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "bufio" |
|
| 4 | 5 |
"context" |
| 5 | 6 |
"fmt" |
| 7 |
+ "io" |
|
| 6 | 8 |
"maps" |
| 7 | 9 |
"os" |
| 10 |
+ "path" |
|
| 8 | 11 |
"slices" |
| 9 | 12 |
"strconv" |
| 10 | 13 |
|
| 14 |
+ obdlabel "github.com/containerd/accelerated-container-image/pkg/label" |
|
| 15 |
+ obdcmd "github.com/containerd/accelerated-container-image/pkg/utils" |
|
| 16 |
+ "github.com/containerd/containerd/v2/core/content" |
|
| 11 | 17 |
"github.com/containerd/containerd/v2/core/diff" |
| 12 | 18 |
"github.com/containerd/containerd/v2/core/leases" |
| 13 | 19 |
"github.com/containerd/containerd/v2/core/mount" |
| ... | ... |
@@ -70,7 +76,6 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool |
| 70 | 70 |
switch sr.kind() {
|
| 71 | 71 |
case Merge: |
| 72 | 72 |
for _, parent := range sr.mergeParents {
|
| 73 |
- parent := parent |
|
| 74 | 73 |
eg.Go(func() error {
|
| 75 | 74 |
return computeBlobChain(ctx, parent, createIfNeeded, comp, s, filter) |
| 76 | 75 |
}) |
| ... | ... |
@@ -109,7 +114,6 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool |
| 109 | 109 |
}() |
| 110 | 110 |
|
| 111 | 111 |
compressorFunc, finalize := comp.Type.Compress(ctx, comp) |
| 112 |
- mediaType := comp.Type.MediaType() |
|
| 113 | 112 |
|
| 114 | 113 |
var lowerRef *immutableRef |
| 115 | 114 |
switch sr.kind() {
|
| ... | ... |
@@ -181,6 +185,21 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool |
| 181 | 181 |
enableOverlay = false |
| 182 | 182 |
} |
| 183 | 183 |
} |
| 184 |
+ |
|
| 185 |
+ mediaType := comp.Type.MediaType() |
|
| 186 |
+ if sr.cm.Snapshotter.Name() == "overlaybd" {
|
|
| 187 |
+ snStat, err := sr.cm.Snapshotter.Stat(ctx, sr.getSnapshotID()) |
|
| 188 |
+ if err != nil {
|
|
| 189 |
+ return nil, errors.Wrapf(err, "failed to Stat overlaybd") |
|
| 190 |
+ } |
|
| 191 |
+ if bdPath := snStat.Labels[obdlabel.LocalOverlayBDPath]; bdPath != "" {
|
|
| 192 |
+ if err := commitOverlayBD(ctx, sr, &desc); err != nil {
|
|
| 193 |
+ return nil, err |
|
| 194 |
+ } |
|
| 195 |
+ mediaType = desc.MediaType |
|
| 196 |
+ enableOverlay = false |
|
| 197 |
+ } |
|
| 198 |
+ } |
|
| 184 | 199 |
if enableOverlay {
|
| 185 | 200 |
computed, ok, err := sr.tryComputeOverlayBlob(ctx, lower, upper, mediaType, sr.ID(), compressorFunc) |
| 186 | 201 |
if !ok || err != nil {
|
| ... | ... |
@@ -351,7 +370,7 @@ func (sr *immutableRef) computeChainMetadata(ctx context.Context, filter map[str |
| 351 | 351 |
} |
| 352 | 352 |
diffID := sr.getDiffID() |
| 353 | 353 |
chainID = diffID |
| 354 |
- blobChainID = imagespecidentity.ChainID([]digest.Digest{digest.Digest(sr.getBlob()), diffID})
|
|
| 354 |
+ blobChainID = imagespecidentity.ChainID([]digest.Digest{sr.getBlob(), diffID})
|
|
| 355 | 355 |
case Layer: |
| 356 | 356 |
if _, ok := filter[sr.ID()]; !ok {
|
| 357 | 357 |
return nil |
| ... | ... |
@@ -368,9 +387,9 @@ func (sr *immutableRef) computeChainMetadata(ctx context.Context, filter map[str |
| 368 | 368 |
return errors.Errorf("failed to set blobchain for reference with non-addressable parent %q", sr.layerParent.GetDescription())
|
| 369 | 369 |
} |
| 370 | 370 |
} |
| 371 |
- diffID := digest.Digest(sr.getDiffID()) |
|
| 371 |
+ diffID := sr.getDiffID() |
|
| 372 | 372 |
chainID = imagespecidentity.ChainID([]digest.Digest{chainID, diffID})
|
| 373 |
- blobID := imagespecidentity.ChainID([]digest.Digest{digest.Digest(sr.getBlob()), diffID})
|
|
| 373 |
+ blobID := imagespecidentity.ChainID([]digest.Digest{sr.getBlob(), diffID})
|
|
| 374 | 374 |
blobChainID = imagespecidentity.ChainID([]digest.Digest{blobChainID, blobID})
|
| 375 | 375 |
case Merge: |
| 376 | 376 |
baseInput := sr.mergeParents[0] |
| ... | ... |
@@ -386,9 +405,9 @@ func (sr *immutableRef) computeChainMetadata(ctx context.Context, filter map[str |
| 386 | 386 |
// not enough information to compute chain at this time |
| 387 | 387 |
return nil |
| 388 | 388 |
} |
| 389 |
- diffID := digest.Digest(layer.getDiffID()) |
|
| 389 |
+ diffID := layer.getDiffID() |
|
| 390 | 390 |
chainID = imagespecidentity.ChainID([]digest.Digest{chainID, diffID})
|
| 391 |
- blobID := imagespecidentity.ChainID([]digest.Digest{digest.Digest(layer.getBlob()), diffID})
|
|
| 391 |
+ blobID := imagespecidentity.ChainID([]digest.Digest{layer.getBlob(), diffID})
|
|
| 392 | 392 |
blobChainID = imagespecidentity.ChainID([]digest.Digest{blobChainID, blobID})
|
| 393 | 393 |
} |
| 394 | 394 |
} |
| ... | ... |
@@ -397,7 +416,7 @@ func (sr *immutableRef) computeChainMetadata(ctx context.Context, filter map[str |
| 397 | 397 |
// this diff is its own blob |
| 398 | 398 |
diffID := sr.getDiffID() |
| 399 | 399 |
chainID = diffID |
| 400 |
- blobChainID = imagespecidentity.ChainID([]digest.Digest{digest.Digest(sr.getBlob()), diffID})
|
|
| 400 |
+ blobChainID = imagespecidentity.ChainID([]digest.Digest{sr.getBlob(), diffID})
|
|
| 401 | 401 |
} else {
|
| 402 | 402 |
// re-using upper blob |
| 403 | 403 |
chainID = sr.diffParents.upper.getChainID() |
| ... | ... |
@@ -498,3 +517,50 @@ func ensureCompression(ctx context.Context, ref *immutableRef, comp compression. |
| 498 | 498 |
} |
| 499 | 499 |
return nil |
| 500 | 500 |
} |
| 501 |
+ |
|
| 502 |
+func commitOverlayBD(ctx context.Context, sr *immutableRef, desc *ocispecs.Descriptor) error {
|
|
| 503 |
+ snStat, err := sr.cm.Snapshotter.Stat(ctx, sr.getSnapshotID()) |
|
| 504 |
+ if err != nil {
|
|
| 505 |
+ return errors.Wrapf(err, "failed to Stat overlaybd") |
|
| 506 |
+ } |
|
| 507 |
+ bdPath := snStat.Labels[obdlabel.LocalOverlayBDPath] |
|
| 508 |
+ if bdPath == "" {
|
|
| 509 |
+ return errors.New("missing overlaybd path label")
|
|
| 510 |
+ } |
|
| 511 |
+ dir := path.Dir(bdPath) |
|
| 512 |
+ commitPath := path.Join(dir, "overlaybd.commit") |
|
| 513 |
+ err = obdcmd.Commit(ctx, dir, dir, true, "-t", "-z", "-f") |
|
| 514 |
+ if err != nil {
|
|
| 515 |
+ return errors.Wrapf(err, "failed to overlaybd-commit") |
|
| 516 |
+ } |
|
| 517 |
+ cw, err := sr.cm.ContentStore.Writer(ctx, content.WithRef(sr.ID())) |
|
| 518 |
+ if err != nil {
|
|
| 519 |
+ return errors.Wrapf(err, "failed to open writer") |
|
| 520 |
+ } |
|
| 521 |
+ fi, err := os.Open(commitPath) |
|
| 522 |
+ if err != nil {
|
|
| 523 |
+ return errors.Wrapf(err, "failed to open overlaybd commit file") |
|
| 524 |
+ } |
|
| 525 |
+ sz, err := io.Copy(cw, bufio.NewReader(fi)) |
|
| 526 |
+ if err != nil {
|
|
| 527 |
+ return errors.Wrapf(err, "failed to do io.Copy()") |
|
| 528 |
+ } |
|
| 529 |
+ dgst := cw.Digest() |
|
| 530 |
+ labels := map[string]string{
|
|
| 531 |
+ labels.LabelUncompressed: dgst.String(), |
|
| 532 |
+ obdlabel.OverlayBDBlobDigest: dgst.String(), |
|
| 533 |
+ obdlabel.OverlayBDBlobSize: fmt.Sprintf("%d", sz),
|
|
| 534 |
+ } |
|
| 535 |
+ err = cw.Commit(ctx, sz, dgst, content.WithLabels(labels)) |
|
| 536 |
+ if err != nil {
|
|
| 537 |
+ return errors.Wrapf(err, "failed to do cw.Commit") |
|
| 538 |
+ } |
|
| 539 |
+ desc.Digest = dgst |
|
| 540 |
+ desc.Size = sz |
|
| 541 |
+ desc.MediaType = ocispecs.MediaTypeImageLayer |
|
| 542 |
+ desc.Annotations = map[string]string{
|
|
| 543 |
+ obdlabel.OverlayBDBlobDigest: string(desc.Digest), |
|
| 544 |
+ obdlabel.OverlayBDBlobSize: fmt.Sprintf("%d", desc.Size),
|
|
| 545 |
+ } |
|
| 546 |
+ return nil |
|
| 547 |
+} |
| ... | ... |
@@ -45,7 +45,7 @@ func (sr *immutableRef) tryComputeOverlayBlob(ctx context.Context, lower, upper |
| 45 | 45 |
|
| 46 | 46 |
defer func() {
|
| 47 | 47 |
if cw != nil {
|
| 48 |
- ctx = context.WithoutCancel(ctx) |
|
| 48 |
+ ctx := context.WithoutCancel(ctx) |
|
| 49 | 49 |
// after commit success cw will be set to nil, if cw isn't nil, error |
| 50 | 50 |
// happened before commit, we should abort this ingest, and because the |
| 51 | 51 |
// error may incured by ctx cancel, use a new context here. And since |
| ... | ... |
@@ -399,7 +399,7 @@ func (cc *cacheContext) HandleChange(kind fsutil.ChangeKind, p string, fi os.Fil |
| 399 | 399 |
for _, l := range links {
|
| 400 | 400 |
pp := convertKeyToPath(l) |
| 401 | 401 |
cc.txn.Insert(l, cr) |
| 402 |
- d := path.Dir(string(pp)) |
|
| 402 |
+ d := path.Dir(pp) |
|
| 403 | 403 |
if d == "/" {
|
| 404 | 404 |
d = "" |
| 405 | 405 |
} |
| ... | ... |
@@ -569,8 +569,8 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o |
| 569 | 569 |
// |
| 570 | 570 |
// When wildcards are enabled, this translation applies to the |
| 571 | 571 |
// portion of 'p' before any wildcards. |
| 572 |
- if strings.HasPrefix(fn, resolvedPrefix) {
|
|
| 573 |
- fn = origPrefix + strings.TrimPrefix(fn, resolvedPrefix) |
|
| 572 |
+ if after, ok := strings.CutPrefix(fn, resolvedPrefix); ok {
|
|
| 573 |
+ fn = origPrefix + after |
|
| 574 | 574 |
} |
| 575 | 575 |
|
| 576 | 576 |
for len(parentDirHeaders) != 0 {
|
| ... | ... |
@@ -774,11 +774,11 @@ func splitWildcards(p string) (d1, d2 string) {
|
| 774 | 774 |
|
| 775 | 775 |
func containsWildcards(name string) bool {
|
| 776 | 776 |
for i := 0; i < len(name); i++ {
|
| 777 |
- ch := name[i] |
|
| 778 |
- if ch == '\\' {
|
|
| 779 |
- i++ |
|
| 780 |
- } else if ch == '*' || ch == '?' || ch == '[' {
|
|
| 777 |
+ switch name[i] {
|
|
| 778 |
+ case '*', '?', '[': |
|
| 781 | 779 |
return true |
| 780 |
+ case '\\': |
|
| 781 |
+ i++ |
|
| 782 | 782 |
} |
| 783 | 783 |
} |
| 784 | 784 |
return false |
| ... | ... |
@@ -887,10 +887,7 @@ func (cc *cacheContext) checksum(ctx context.Context, root *iradix.Node[*CacheRe |
| 887 | 887 |
iter.SeekLowerBound(append(slices.Clone(next), 0)) |
| 888 | 888 |
subk := next |
| 889 | 889 |
ok := true |
| 890 |
- for {
|
|
| 891 |
- if !ok || !bytes.HasPrefix(subk, next) {
|
|
| 892 |
- break |
|
| 893 |
- } |
|
| 890 |
+ for ok && bytes.HasPrefix(subk, next) {
|
|
| 894 | 891 |
h.Write(bytes.TrimPrefix(subk, k)) |
| 895 | 892 |
|
| 896 | 893 |
// We do not follow trailing links when checksumming a directory's |
| ... | ... |
@@ -3,7 +3,7 @@ package contenthash |
| 3 | 3 |
import ( |
| 4 | 4 |
"archive/tar" |
| 5 | 5 |
"io" |
| 6 |
- "sort" |
|
| 6 |
+ "slices" |
|
| 7 | 7 |
"strconv" |
| 8 | 8 |
"strings" |
| 9 | 9 |
) |
| ... | ... |
@@ -49,14 +49,13 @@ func v1TarHeaderSelect(h *tar.Header) (orderedHeaders [][2]string) {
|
| 49 | 49 |
// Get extended attributes. |
| 50 | 50 |
xAttrKeys := make([]string, 0, len(h.PAXRecords)) |
| 51 | 51 |
for k := range pax {
|
| 52 |
- if strings.HasPrefix(k, "SCHILY.xattr.") {
|
|
| 53 |
- k = strings.TrimPrefix(k, "SCHILY.xattr.") |
|
| 52 |
+ if k, ok := strings.CutPrefix(k, "SCHILY.xattr."); ok {
|
|
| 54 | 53 |
if k == "security.capability" || !strings.HasPrefix(k, "security.") && !strings.HasPrefix(k, "system.") {
|
| 55 | 54 |
xAttrKeys = append(xAttrKeys, k) |
| 56 | 55 |
} |
| 57 | 56 |
} |
| 58 | 57 |
} |
| 59 |
- sort.Strings(xAttrKeys) |
|
| 58 |
+ slices.Sort(xAttrKeys) |
|
| 60 | 59 |
|
| 61 | 60 |
// Make the slice with enough capacity to hold the 11 basic headers |
| 62 | 61 |
// we want from the v0 selector plus however many xattrs we have. |
| ... | ... |
@@ -7,7 +7,7 @@ import ( |
| 7 | 7 |
"fmt" |
| 8 | 8 |
"io" |
| 9 | 9 |
"path" |
| 10 |
- "sort" |
|
| 10 |
+ "slices" |
|
| 11 | 11 |
|
| 12 | 12 |
cdcompression "github.com/containerd/containerd/v2/pkg/archive/compression" |
| 13 | 13 |
"github.com/moby/buildkit/session" |
| ... | ... |
@@ -69,7 +69,7 @@ func (sr *immutableRef) FileList(ctx context.Context, s session.Group) ([]string |
| 69 | 69 |
name := path.Clean(hdr.Name) |
| 70 | 70 |
files = append(files, name) |
| 71 | 71 |
} |
| 72 |
- sort.Strings(files) |
|
| 72 |
+ slices.Sort(files) |
|
| 73 | 73 |
|
| 74 | 74 |
dt, err = json.Marshal(files) |
| 75 | 75 |
if err != nil {
|
| ... | ... |
@@ -1,17 +1,20 @@ |
| 1 | 1 |
package cache |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "cmp" |
|
| 4 | 5 |
"context" |
| 5 | 6 |
"fmt" |
| 6 | 7 |
"maps" |
| 7 |
- "sort" |
|
| 8 |
+ "slices" |
|
| 8 | 9 |
"strings" |
| 9 | 10 |
"sync" |
| 10 | 11 |
"time" |
| 11 | 12 |
|
| 13 |
+ obdlabel "github.com/containerd/accelerated-container-image/pkg/label" |
|
| 12 | 14 |
"github.com/containerd/containerd/v2/core/content" |
| 13 | 15 |
"github.com/containerd/containerd/v2/core/diff" |
| 14 | 16 |
"github.com/containerd/containerd/v2/core/leases" |
| 17 |
+ "github.com/containerd/containerd/v2/core/snapshots" |
|
| 15 | 18 |
"github.com/containerd/containerd/v2/pkg/filters" |
| 16 | 19 |
"github.com/containerd/containerd/v2/pkg/gc" |
| 17 | 20 |
"github.com/containerd/containerd/v2/pkg/labels" |
| ... | ... |
@@ -627,6 +630,10 @@ func (cm *cacheManager) New(ctx context.Context, s ImmutableRef, sess session.Gr |
| 627 | 627 |
}); rerr != nil {
|
| 628 | 628 |
return nil, rerr |
| 629 | 629 |
} |
| 630 |
+ } else if cm.Snapshotter.Name() == "overlaybd" && parent != nil {
|
|
| 631 |
+ // Snapshotter will create a R/W block device directly as rootfs with this label |
|
| 632 |
+ rwLabels := map[string]string{obdlabel.SupportReadWriteMode: "dev"}
|
|
| 633 |
+ err = cm.Snapshotter.Prepare(ctx, snapshotID, parentSnapshotID, snapshots.WithLabels(rwLabels)) |
|
| 630 | 634 |
} else {
|
| 631 | 635 |
err = cm.Snapshotter.Prepare(ctx, snapshotID, parentSnapshotID) |
| 632 | 636 |
} |
| ... | ... |
@@ -1426,10 +1433,7 @@ func (cm *cacheManager) DiskUsage(ctx context.Context, opt client.DiskUsageInfo) |
| 1426 | 1426 |
} |
| 1427 | 1427 |
cm.mu.Unlock() |
| 1428 | 1428 |
|
| 1429 |
- for {
|
|
| 1430 |
- if len(rescan) == 0 {
|
|
| 1431 |
- break |
|
| 1432 |
- } |
|
| 1429 |
+ for len(rescan) != 0 {
|
|
| 1433 | 1430 |
for id := range rescan {
|
| 1434 | 1431 |
v := m[id] |
| 1435 | 1432 |
if v.refs == 0 {
|
| ... | ... |
@@ -1667,23 +1671,23 @@ type deleteRecord struct {
|
| 1667 | 1667 |
*cacheRecord |
| 1668 | 1668 |
lastUsedAt *time.Time |
| 1669 | 1669 |
usageCount int |
| 1670 |
- lastUsedAtIndex int |
|
| 1671 |
- usageCountIndex int |
|
| 1670 |
+ lastUsedAtIndex float64 |
|
| 1671 |
+ usageCountIndex float64 |
|
| 1672 | 1672 |
released bool |
| 1673 | 1673 |
} |
| 1674 | 1674 |
|
| 1675 | 1675 |
func sortDeleteRecords(toDelete []*deleteRecord) {
|
| 1676 |
- sort.Slice(toDelete, func(i, j int) bool {
|
|
| 1677 |
- if toDelete[i].lastUsedAt == nil {
|
|
| 1678 |
- return true |
|
| 1676 |
+ slices.SortFunc(toDelete, func(a, b *deleteRecord) int {
|
|
| 1677 |
+ if a.lastUsedAt == nil {
|
|
| 1678 |
+ return -1 |
|
| 1679 | 1679 |
} |
| 1680 |
- if toDelete[j].lastUsedAt == nil {
|
|
| 1681 |
- return false |
|
| 1680 |
+ if b.lastUsedAt == nil {
|
|
| 1681 |
+ return 1 |
|
| 1682 | 1682 |
} |
| 1683 |
- return toDelete[i].lastUsedAt.Before(*toDelete[j].lastUsedAt) |
|
| 1683 |
+ return a.lastUsedAt.Compare(*b.lastUsedAt) |
|
| 1684 | 1684 |
}) |
| 1685 | 1685 |
|
| 1686 |
- maxLastUsedIndex := 0 |
|
| 1686 |
+ maxLastUsedIndex := 1.0 |
|
| 1687 | 1687 |
var val time.Time |
| 1688 | 1688 |
for _, v := range toDelete {
|
| 1689 | 1689 |
if v.lastUsedAt != nil && v.lastUsedAt.After(val) {
|
| ... | ... |
@@ -1693,11 +1697,11 @@ func sortDeleteRecords(toDelete []*deleteRecord) {
|
| 1693 | 1693 |
v.lastUsedAtIndex = maxLastUsedIndex |
| 1694 | 1694 |
} |
| 1695 | 1695 |
|
| 1696 |
- sort.Slice(toDelete, func(i, j int) bool {
|
|
| 1697 |
- return toDelete[i].usageCount < toDelete[j].usageCount |
|
| 1696 |
+ slices.SortFunc(toDelete, func(a, b *deleteRecord) int {
|
|
| 1697 |
+ return a.usageCount - b.usageCount |
|
| 1698 | 1698 |
}) |
| 1699 | 1699 |
|
| 1700 |
- maxUsageCountIndex := 0 |
|
| 1700 |
+ maxUsageCountIndex := 1.0 |
|
| 1701 | 1701 |
var count int |
| 1702 | 1702 |
for _, v := range toDelete {
|
| 1703 | 1703 |
if v.usageCount != count {
|
| ... | ... |
@@ -1707,11 +1711,11 @@ func sortDeleteRecords(toDelete []*deleteRecord) {
|
| 1707 | 1707 |
v.usageCountIndex = maxUsageCountIndex |
| 1708 | 1708 |
} |
| 1709 | 1709 |
|
| 1710 |
- sort.Slice(toDelete, func(i, j int) bool {
|
|
| 1711 |
- return float64(toDelete[i].lastUsedAtIndex)/float64(maxLastUsedIndex)+ |
|
| 1712 |
- float64(toDelete[i].usageCountIndex)/float64(maxUsageCountIndex) < |
|
| 1713 |
- float64(toDelete[j].lastUsedAtIndex)/float64(maxLastUsedIndex)+ |
|
| 1714 |
- float64(toDelete[j].usageCountIndex)/float64(maxUsageCountIndex) |
|
| 1710 |
+ slices.SortFunc(toDelete, func(a, b *deleteRecord) int {
|
|
| 1711 |
+ return cmp.Compare( |
|
| 1712 |
+ a.lastUsedAtIndex/maxLastUsedIndex+a.usageCountIndex/maxUsageCountIndex, |
|
| 1713 |
+ b.lastUsedAtIndex/maxLastUsedIndex+b.usageCountIndex/maxUsageCountIndex, |
|
| 1714 |
+ ) |
|
| 1715 | 1715 |
}) |
| 1716 | 1716 |
} |
| 1717 | 1717 |
|
| ... | ... |
@@ -406,11 +406,11 @@ func (md *cacheMetadata) getLastUsed() (int, *time.Time) {
|
| 406 | 406 |
if v == nil {
|
| 407 | 407 |
return usageCount, nil |
| 408 | 408 |
} |
| 409 |
- var lastUsedTs int64 |
|
| 410 |
- if err := v.Unmarshal(&lastUsedTs); err != nil || lastUsedTs == 0 {
|
|
| 409 |
+ var lastUsedTS int64 |
|
| 410 |
+ if err := v.Unmarshal(&lastUsedTS); err != nil || lastUsedTS == 0 {
|
|
| 411 | 411 |
return usageCount, nil |
| 412 | 412 |
} |
| 413 |
- tm := time.Unix(lastUsedTs/1e9, lastUsedTs%1e9) |
|
| 413 |
+ tm := time.Unix(lastUsedTS/1e9, lastUsedTS%1e9) |
|
| 414 | 414 |
return usageCount, &tm |
| 415 | 415 |
} |
| 416 | 416 |
|
| ... | ... |
@@ -223,7 +223,7 @@ func MigrateV2(ctx context.Context, from, to string, cs content.Store, s snapsho |
| 223 | 223 |
|
| 224 | 224 |
if blob := md.getBlob(); blob != "" {
|
| 225 | 225 |
if _, err := cs.Update(ctx, content.Info{
|
| 226 |
- Digest: digest.Digest(blob), |
|
| 226 |
+ Digest: blob, |
|
| 227 | 227 |
}, "labels.containerd.io/gc.root"); err != nil {
|
| 228 | 228 |
return err |
| 229 | 229 |
} |
| ... | ... |
@@ -30,7 +30,7 @@ func descHandlersOf(opts ...RefOption) DescHandlers {
|
| 30 | 30 |
|
| 31 | 31 |
type DescHandlerKey digest.Digest |
| 32 | 32 |
|
| 33 |
-type NeedsRemoteProviderError []digest.Digest //nolint:errname |
|
| 33 |
+type NeedsRemoteProviderError []digest.Digest |
|
| 34 | 34 |
|
| 35 | 35 |
func (m NeedsRemoteProviderError) Error() string {
|
| 36 | 36 |
return fmt.Sprintf("missing descriptor handlers for lazy blobs %+v", []digest.Digest(m))
|
| ... | ... |
@@ -11,6 +11,7 @@ import ( |
| 11 | 11 |
"sync" |
| 12 | 12 |
"time" |
| 13 | 13 |
|
| 14 |
+ obdlabel "github.com/containerd/accelerated-container-image/pkg/label" |
|
| 14 | 15 |
"github.com/containerd/containerd/v2/core/content" |
| 15 | 16 |
"github.com/containerd/containerd/v2/core/images" |
| 16 | 17 |
"github.com/containerd/containerd/v2/core/leases" |
| ... | ... |
@@ -45,7 +46,7 @@ import ( |
| 45 | 45 |
"golang.org/x/sync/errgroup" |
| 46 | 46 |
) |
| 47 | 47 |
|
| 48 |
-var additionalAnnotations = append(compression.EStargzAnnotations, labels.LabelUncompressed) |
|
| 48 |
+var additionalAnnotations = append(append(compression.EStargzAnnotations, obdlabel.OverlayBDAnnotations...), labels.LabelUncompressed) |
|
| 49 | 49 |
|
| 50 | 50 |
// Ref is a reference to cacheable objects. |
| 51 | 51 |
type Ref interface {
|
| ... | ... |
@@ -188,7 +189,7 @@ func (p parentRefs) release(ctx context.Context) (rerr error) {
|
| 188 | 188 |
return rerr |
| 189 | 189 |
} |
| 190 | 190 |
|
| 191 |
-func (p parentRefs) clone() parentRefs {
|
|
| 191 |
+func (p parentRefs) cloneParentRefs() parentRefs {
|
|
| 192 | 192 |
switch {
|
| 193 | 193 |
case p.layerParent != nil: |
| 194 | 194 |
p.layerParent = p.layerParent.clone() |
| ... | ... |
@@ -361,12 +362,12 @@ func (cr *cacheRecord) size(ctx context.Context) (int64, error) {
|
| 361 | 361 |
} |
| 362 | 362 |
if dgst := cr.getBlob(); dgst != "" {
|
| 363 | 363 |
added := make(map[digest.Digest]struct{})
|
| 364 |
- info, err := cr.cm.ContentStore.Info(ctx, digest.Digest(dgst)) |
|
| 364 |
+ info, err := cr.cm.ContentStore.Info(ctx, dgst) |
|
| 365 | 365 |
if err == nil {
|
| 366 | 366 |
usage.Size += info.Size |
| 367 |
- added[digest.Digest(dgst)] = struct{}{}
|
|
| 367 |
+ added[dgst] = struct{}{}
|
|
| 368 | 368 |
} |
| 369 |
- walkBlobVariantsOnly(ctx, cr.cm.ContentStore, digest.Digest(dgst), func(desc ocispecs.Descriptor) bool {
|
|
| 369 |
+ walkBlobVariantsOnly(ctx, cr.cm.ContentStore, dgst, func(desc ocispecs.Descriptor) bool {
|
|
| 370 | 370 |
if _, ok := added[desc.Digest]; !ok {
|
| 371 | 371 |
if info, err := cr.cm.ContentStore.Info(ctx, desc.Digest); err == nil {
|
| 372 | 372 |
usage.Size += info.Size |
| ... | ... |
@@ -423,7 +424,11 @@ func (cr *cacheRecord) mount(ctx context.Context) (_ snapshot.Mountable, rerr er |
| 423 | 423 |
// Return the mount direct from View rather than setting it using the Mounts call below. |
| 424 | 424 |
// The two are equivalent for containerd snapshotters but the moby snapshotter requires |
| 425 | 425 |
// the use of the mountable returned by View in this case. |
| 426 |
- mnts, err := cr.cm.Snapshotter.View(ctx, mountSnapshotID, cr.getSnapshotID()) |
|
| 426 |
+ labels := make(map[string]string) |
|
| 427 |
+ if cr.cm.Snapshotter.Name() == "overlaybd" {
|
|
| 428 |
+ labels["containerd.io/snapshot/overlaybd.writable"] = "dev" |
|
| 429 |
+ } |
|
| 430 |
+ mnts, err := cr.cm.Snapshotter.View(ctx, mountSnapshotID, cr.getSnapshotID(), snapshots.WithLabels(labels)) |
|
| 427 | 431 |
if err != nil && !cerrdefs.IsAlreadyExists(err) {
|
| 428 | 432 |
return nil, err |
| 429 | 433 |
} |
| ... | ... |
@@ -472,7 +477,7 @@ func (cr *cacheRecord) remove(ctx context.Context, removeSnapshot bool) (rerr er |
| 472 | 472 |
if err := cr.cm.MetadataStore.Clear(cr.ID()); err != nil {
|
| 473 | 473 |
return errors.Wrapf(err, "failed to delete metadata of %s", cr.ID()) |
| 474 | 474 |
} |
| 475 |
- if err := cr.parentRefs.release(ctx); err != nil {
|
|
| 475 |
+ if err := cr.release(ctx); err != nil {
|
|
| 476 | 476 |
return errors.Wrapf(err, "failed to release parents of %s", cr.ID()) |
| 477 | 477 |
} |
| 478 | 478 |
return nil |
| ... | ... |
@@ -1018,6 +1023,10 @@ func (sr *immutableRef) Extract(ctx context.Context, s session.Group) (rerr erro |
| 1018 | 1018 |
return err |
| 1019 | 1019 |
} |
| 1020 | 1020 |
return rerr |
| 1021 |
+ } else if sr.cm.Snapshotter.Name() == "overlaybd" {
|
|
| 1022 |
+ if rerr = sr.prepareRemoteSnapshotsOverlaybdMode(ctx); rerr == nil {
|
|
| 1023 |
+ return sr.unlazy(ctx, sr.descHandlers, sr.progress, s, true, false) |
|
| 1024 |
+ } |
|
| 1021 | 1025 |
} |
| 1022 | 1026 |
|
| 1023 | 1027 |
return sr.unlazy(ctx, sr.descHandlers, sr.progress, s, true, false) |
| ... | ... |
@@ -1026,7 +1035,6 @@ func (sr *immutableRef) Extract(ctx context.Context, s session.Group) (rerr erro |
| 1026 | 1026 |
func (sr *immutableRef) withRemoteSnapshotLabelsStargzMode(ctx context.Context, s session.Group, f func()) error {
|
| 1027 | 1027 |
dhs := sr.descHandlers |
| 1028 | 1028 |
for _, r := range sr.layerChain() {
|
| 1029 |
- r := r |
|
| 1030 | 1029 |
info, err := r.cm.Snapshotter.Stat(ctx, r.getSnapshotID()) |
| 1031 | 1030 |
if err != nil && !cerrdefs.IsNotFound(err) {
|
| 1032 | 1031 |
return err |
| ... | ... |
@@ -1035,7 +1043,7 @@ func (sr *immutableRef) withRemoteSnapshotLabelsStargzMode(ctx context.Context, |
| 1035 | 1035 |
} else if _, ok := info.Labels["containerd.io/snapshot/remote"]; !ok {
|
| 1036 | 1036 |
continue // This isn't a remote snapshot; skip |
| 1037 | 1037 |
} |
| 1038 |
- dh := dhs[digest.Digest(r.getBlob())] |
|
| 1038 |
+ dh := dhs[r.getBlob()] |
|
| 1039 | 1039 |
if dh == nil {
|
| 1040 | 1040 |
continue // no info passed; skip |
| 1041 | 1041 |
} |
| ... | ... |
@@ -1069,13 +1077,12 @@ func (sr *immutableRef) prepareRemoteSnapshotsStargzMode(ctx context.Context, s |
| 1069 | 1069 |
_, err := g.Do(ctx, sr.ID()+"-prepare-remote-snapshot", func(ctx context.Context) (_ *leaseutil.LeaseRef, rerr error) {
|
| 1070 | 1070 |
dhs := sr.descHandlers |
| 1071 | 1071 |
for _, r := range sr.layerChain() {
|
| 1072 |
- r := r |
|
| 1073 | 1072 |
snapshotID := r.getSnapshotID() |
| 1074 | 1073 |
if _, err := r.cm.Snapshotter.Stat(ctx, snapshotID); err == nil {
|
| 1075 | 1074 |
continue |
| 1076 | 1075 |
} |
| 1077 | 1076 |
|
| 1078 |
- dh := dhs[digest.Digest(r.getBlob())] |
|
| 1077 |
+ dh := dhs[r.getBlob()] |
|
| 1079 | 1078 |
if dh == nil {
|
| 1080 | 1079 |
// We cannot prepare remote snapshots without descHandler. |
| 1081 | 1080 |
return nil, nil |
| ... | ... |
@@ -1145,6 +1152,54 @@ func (sr *immutableRef) prepareRemoteSnapshotsStargzMode(ctx context.Context, s |
| 1145 | 1145 |
return err |
| 1146 | 1146 |
} |
| 1147 | 1147 |
|
| 1148 |
+func (sr *immutableRef) prepareRemoteSnapshotsOverlaybdMode(ctx context.Context) error {
|
|
| 1149 |
+ _, err := g.Do(ctx, sr.ID()+"-prepare-remote-snapshot", func(ctx context.Context) (_ *leaseutil.LeaseRef, rerr error) {
|
|
| 1150 |
+ dhs := sr.descHandlers |
|
| 1151 |
+ for _, r := range sr.layerChain() {
|
|
| 1152 |
+ snapshotID := r.getSnapshotID() |
|
| 1153 |
+ if _, err := r.cm.Snapshotter.Stat(ctx, snapshotID); err == nil {
|
|
| 1154 |
+ continue |
|
| 1155 |
+ } |
|
| 1156 |
+ dh := dhs[digest.Digest(r.getBlob())] |
|
| 1157 |
+ if dh == nil {
|
|
| 1158 |
+ // We cannot prepare remote snapshots without descHandler. |
|
| 1159 |
+ return nil, nil |
|
| 1160 |
+ } |
|
| 1161 |
+ defaultLabels := snapshots.FilterInheritedLabels(dh.SnapshotLabels) |
|
| 1162 |
+ if defaultLabels == nil {
|
|
| 1163 |
+ defaultLabels = make(map[string]string) |
|
| 1164 |
+ } |
|
| 1165 |
+ defaultLabels["containerd.io/snapshot.ref"] = snapshotID |
|
| 1166 |
+ // Prepare remote snapshots |
|
| 1167 |
+ var ( |
|
| 1168 |
+ key = fmt.Sprintf("tmp-%s %s", identity.NewID(), r.getChainID())
|
|
| 1169 |
+ opts = []snapshots.Opt{
|
|
| 1170 |
+ snapshots.WithLabels(defaultLabels), |
|
| 1171 |
+ } |
|
| 1172 |
+ ) |
|
| 1173 |
+ parentID := "" |
|
| 1174 |
+ if r.layerParent != nil {
|
|
| 1175 |
+ parentID = r.layerParent.getSnapshotID() |
|
| 1176 |
+ } |
|
| 1177 |
+ if err := r.cm.Snapshotter.Prepare(ctx, key, parentID, opts...); err != nil {
|
|
| 1178 |
+ if cerrdefs.IsAlreadyExists(err) {
|
|
| 1179 |
+ // Check if the targeting snapshot ID has been prepared as |
|
| 1180 |
+ // a remote snapshot in the snapshotter. |
|
| 1181 |
+ _, err := r.cm.Snapshotter.Stat(ctx, snapshotID) |
|
| 1182 |
+ if err == nil { // usable as remote snapshot without unlazying.
|
|
| 1183 |
+ // Try the next layer as well. |
|
| 1184 |
+ continue |
|
| 1185 |
+ } |
|
| 1186 |
+ } |
|
| 1187 |
+ } |
|
| 1188 |
+ // This layer and all upper layers cannot be prepared without unlazying. |
|
| 1189 |
+ break |
|
| 1190 |
+ } |
|
| 1191 |
+ return nil, nil |
|
| 1192 |
+ }) |
|
| 1193 |
+ return err |
|
| 1194 |
+} |
|
| 1195 |
+ |
|
| 1148 | 1196 |
func makeTmpLabelsStargzMode(labels map[string]string, s session.Group) (fields []string, res map[string]string) {
|
| 1149 | 1197 |
res = make(map[string]string) |
| 1150 | 1198 |
// Append unique ID to labels for avoiding collision of labels among calls |
| ... | ... |
@@ -1319,7 +1374,12 @@ func (sr *immutableRef) unlazyLayer(ctx context.Context, dhs DescHandlers, pg pr |
| 1319 | 1319 |
|
| 1320 | 1320 |
key := fmt.Sprintf("extract-%s %s", identity.NewID(), sr.getChainID())
|
| 1321 | 1321 |
|
| 1322 |
- err = sr.cm.Snapshotter.Prepare(ctx, key, parentID) |
|
| 1322 |
+ if sr.cm.Snapshotter.Name() == "overlaybd" {
|
|
| 1323 |
+ err = sr.cm.Snapshotter.Prepare(ctx, key, parentID, |
|
| 1324 |
+ snapshots.WithLabels(map[string]string{"containerd.io/snapshot.ref": string(sr.getChainID())}))
|
|
| 1325 |
+ } else {
|
|
| 1326 |
+ err = sr.cm.Snapshotter.Prepare(ctx, key, parentID) |
|
| 1327 |
+ } |
|
| 1323 | 1328 |
if err != nil {
|
| 1324 | 1329 |
return err |
| 1325 | 1330 |
} |
| ... | ... |
@@ -1479,7 +1539,7 @@ func (sr *mutableRef) commit() (_ *immutableRef, rerr error) {
|
| 1479 | 1479 |
rec := &cacheRecord{
|
| 1480 | 1480 |
mu: sr.mu, |
| 1481 | 1481 |
cm: sr.cm, |
| 1482 |
- parentRefs: sr.parentRefs.clone(), |
|
| 1482 |
+ parentRefs: sr.cloneParentRefs(), |
|
| 1483 | 1483 |
equalMutable: sr, |
| 1484 | 1484 |
refs: make(map[ref]struct{}),
|
| 1485 | 1485 |
cacheMetadata: md, |
| ... | ... |
@@ -1635,16 +1695,16 @@ func readonlyOverlay(opt []string) []string {
|
| 1635 | 1635 |
out := make([]string, 0, len(opt)) |
| 1636 | 1636 |
upper := "" |
| 1637 | 1637 |
for _, o := range opt {
|
| 1638 |
- if strings.HasPrefix(o, "upperdir=") {
|
|
| 1639 |
- upper = strings.TrimPrefix(o, "upperdir=") |
|
| 1638 |
+ if after, ok := strings.CutPrefix(o, "upperdir="); ok {
|
|
| 1639 |
+ upper = after |
|
| 1640 | 1640 |
} else if !strings.HasPrefix(o, "workdir=") {
|
| 1641 | 1641 |
out = append(out, o) |
| 1642 | 1642 |
} |
| 1643 | 1643 |
} |
| 1644 | 1644 |
if upper != "" {
|
| 1645 | 1645 |
for i, o := range out {
|
| 1646 |
- if strings.HasPrefix(o, "lowerdir=") {
|
|
| 1647 |
- out[i] = "lowerdir=" + upper + ":" + strings.TrimPrefix(o, "lowerdir=") |
|
| 1646 |
+ if after, ok := strings.CutPrefix(o, "lowerdir="); ok {
|
|
| 1647 |
+ out[i] = "lowerdir=" + upper + ":" + after |
|
| 1648 | 1648 |
} |
| 1649 | 1649 |
} |
| 1650 | 1650 |
} |
| ... | ... |
@@ -121,7 +121,6 @@ func getAvailableBlobs(ctx context.Context, cs content.Store, chain *solver.Remo |
| 121 | 121 |
} |
| 122 | 122 |
var res []*solver.Remote |
| 123 | 123 |
for _, desc := range descs {
|
| 124 |
- desc := desc |
|
| 125 | 124 |
if len(parents) == 0 { // bottommost ref
|
| 126 | 125 |
res = append(res, &solver.Remote{
|
| 127 | 126 |
Descriptors: []ocispecs.Descriptor{desc},
|
| ... | ... |
@@ -277,7 +276,6 @@ func (mp *lazyMultiProvider) Info(ctx context.Context, dgst digest.Digest) (cont |
| 277 | 277 |
func (mp *lazyMultiProvider) Unlazy(ctx context.Context) error {
|
| 278 | 278 |
eg, egctx := errgroup.WithContext(ctx) |
| 279 | 279 |
for _, p := range mp.plist {
|
| 280 |
- p := p |
|
| 281 | 280 |
eg.Go(func() error {
|
| 282 | 281 |
return p.Unlazy(egctx) |
| 283 | 282 |
}) |
| ... | ... |
@@ -83,7 +83,7 @@ func NewExportableCache(oci bool, imageManifest bool) (*ExportableCache, error) |
| 83 | 83 |
if imageManifest {
|
| 84 | 84 |
mediaType = ocispecs.MediaTypeImageManifest |
| 85 | 85 |
if !oci {
|
| 86 |
- return nil, errors.Errorf("invalid configuration for remote cache")
|
|
| 86 |
+ return nil, errors.Errorf("invalid configuration for remote cache, OCI mediatypes are required for image-manifest cache format")
|
|
| 87 | 87 |
} |
| 88 | 88 |
} else {
|
| 89 | 89 |
if oci {
|
| ... | ... |
@@ -137,7 +137,7 @@ func readBlob(ctx context.Context, provider content.Provider, desc ocispecs.Desc |
| 137 | 137 |
if err != nil {
|
| 138 | 138 |
// NOTE: even if err == EOF, we might have got expected dt here. |
| 139 | 139 |
// For instance, http.Response.Body is known to return non-zero bytes with EOF. |
| 140 |
- if err == io.EOF {
|
|
| 140 |
+ if errors.Is(err, io.EOF) {
|
|
| 141 | 141 |
if dtDigest := desc.Digest.Algorithm().FromBytes(dt); dtDigest != desc.Digest {
|
| 142 | 142 |
err = errors.Wrapf(err, "got EOF, expected %s (%d bytes), got %s (%d bytes)", |
| 143 | 143 |
desc.Digest, desc.Size, dtDigest, len(dt)) |
| ... | ... |
@@ -58,7 +58,10 @@ func ResolveCacheExporterFunc(sm *session.Manager) remotecache.ResolveCacheExpor |
| 58 | 58 |
return nil, errors.Wrapf(err, "failed to parse %s", attrImageManifest) |
| 59 | 59 |
} |
| 60 | 60 |
imageManifest = b |
| 61 |
+ } else if !ociMediatypes {
|
|
| 62 |
+ imageManifest = false |
|
| 61 | 63 |
} |
| 64 |
+ |
|
| 62 | 65 |
csID := contentStoreIDPrefix + store |
| 63 | 66 |
cs, err := getContentStore(ctx, sm, g, csID) |
| 64 | 67 |
if err != nil {
|
| ... | ... |
@@ -106,7 +109,7 @@ func getContentStore(ctx context.Context, sm *session.Manager, g session.Group, |
| 106 | 106 |
return nil, errors.New("local cache exporter/importer requires session")
|
| 107 | 107 |
} |
| 108 | 108 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 109 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 109 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 110 | 110 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 111 | 111 |
|
| 112 | 112 |
caller, err := sm.Get(timeoutCtx, sessionID, false) |
| ... | ... |
@@ -8,6 +8,8 @@ import ( |
| 8 | 8 |
"github.com/containerd/containerd/v2/core/content" |
| 9 | 9 |
"github.com/containerd/containerd/v2/core/remotes/docker" |
| 10 | 10 |
"github.com/containerd/containerd/v2/core/snapshots" |
| 11 |
+ "github.com/containerd/containerd/v2/pkg/snapshotters" |
|
| 12 |
+ |
|
| 11 | 13 |
"github.com/distribution/reference" |
| 12 | 14 |
"github.com/moby/buildkit/cache/remotecache" |
| 13 | 15 |
"github.com/moby/buildkit/session" |
| ... | ... |
@@ -76,6 +78,8 @@ func ResolveCacheExporterFunc(sm *session.Manager, hosts docker.RegistryHosts) r |
| 76 | 76 |
return nil, errors.Wrapf(err, "failed to parse %s", attrImageManifest) |
| 77 | 77 |
} |
| 78 | 78 |
imageManifest = b |
| 79 |
+ } else if !ociMediatypes {
|
|
| 80 |
+ imageManifest = false |
|
| 79 | 81 |
} |
| 80 | 82 |
insecure := false |
| 81 | 83 |
if v, ok := attrs[attrInsecure]; ok {
|
| ... | ... |
@@ -165,6 +169,7 @@ func (dsl *withDistributionSourceLabel) SnapshotLabels(descs []ocispecs.Descript |
| 165 | 165 |
labels = make(map[string]string) |
| 166 | 166 |
} |
| 167 | 167 |
maps.Copy(labels, estargz.SnapshotLabels(dsl.ref, descs, index)) |
| 168 |
+ labels[snapshotters.TargetRefLabel] = dsl.ref |
|
| 168 | 169 |
return labels |
| 169 | 170 |
} |
| 170 | 171 |
|
| ... | ... |
@@ -226,10 +226,7 @@ func (c *item) LinkFrom(rec solver.CacheExporterRecord, index int, selector stri |
| 226 | 226 |
return |
| 227 | 227 |
} |
| 228 | 228 |
|
| 229 |
- for {
|
|
| 230 |
- if index < len(c.links) {
|
|
| 231 |
- break |
|
| 232 |
- } |
|
| 229 |
+ for index >= len(c.links) {
|
|
| 233 | 230 |
c.links = append(c.links, map[link]struct{}{})
|
| 234 | 231 |
} |
| 235 | 232 |
|
| ... | ... |
@@ -1,8 +1,10 @@ |
| 1 | 1 |
package cacheimport |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "cmp" |
|
| 4 | 5 |
"context" |
| 5 | 6 |
"fmt" |
| 7 |
+ "slices" |
|
| 6 | 8 |
"sort" |
| 7 | 9 |
|
| 8 | 10 |
cerrdefs "github.com/containerd/errdefs" |
| ... | ... |
@@ -28,13 +30,8 @@ func sortConfig(cc *CacheConfig) {
|
| 28 | 28 |
unsortedLayers[i] = il |
| 29 | 29 |
sortedLayers[i] = il |
| 30 | 30 |
} |
| 31 |
- sort.Slice(sortedLayers, func(i, j int) bool {
|
|
| 32 |
- li := sortedLayers[i].l |
|
| 33 |
- lj := sortedLayers[j].l |
|
| 34 |
- if li.Blob == lj.Blob {
|
|
| 35 |
- return li.ParentIndex < lj.ParentIndex |
|
| 36 |
- } |
|
| 37 |
- return li.Blob < lj.Blob |
|
| 31 |
+ slices.SortFunc(sortedLayers, func(a, b *indexedLayer) int {
|
|
| 32 |
+ return cmp.Or(cmp.Compare(a.l.Blob, b.l.Blob), cmp.Compare(a.l.ParentIndex, b.l.ParentIndex)) |
|
| 38 | 33 |
}) |
| 39 | 34 |
for i, l := range sortedLayers {
|
| 40 | 35 |
l.newIndex = i |
| ... | ... |
@@ -101,8 +98,8 @@ func sortConfig(cc *CacheConfig) {
|
| 101 | 101 |
for k := range inputs {
|
| 102 | 102 |
r.r.Inputs[j][k].LinkIndex = unsortedRecords[r.r.Inputs[j][k].LinkIndex].newIndex |
| 103 | 103 |
} |
| 104 |
- sort.Slice(inputs, func(i, j int) bool {
|
|
| 105 |
- return inputs[i].LinkIndex < inputs[j].LinkIndex |
|
| 104 |
+ slices.SortFunc(inputs, func(a, b CacheInput) int {
|
|
| 105 |
+ return cmp.Compare(a.LinkIndex, b.LinkIndex) |
|
| 106 | 106 |
}) |
| 107 | 107 |
} |
| 108 | 108 |
records[i] = r.r |
| ... | ... |
@@ -62,7 +62,8 @@ func ReadFile(ctx context.Context, mount snapshot.Mountable, req ReadRequest) ([ |
| 62 | 62 |
// The filename here is internal to the mount, so we can restore |
| 63 | 63 |
// the request base path for error reporting. |
| 64 | 64 |
// See os.DirFS.Open for details. |
| 65 |
- if pe, ok := err.(*os.PathError); ok {
|
|
| 65 |
+ pe := &os.PathError{}
|
|
| 66 |
+ if errors.As(err, &pe) {
|
|
| 66 | 67 |
pe.Path = req.Filename |
| 67 | 68 |
} |
| 68 | 69 |
return errors.WithStack(err) |
| ... | ... |
@@ -151,7 +151,8 @@ func New(ctx context.Context, address string, opts ...ClientOpt) (*Client, error |
| 151 | 151 |
gopts = append(gopts, grpc.WithStreamInterceptor(grpcerrors.StreamClientInterceptor)) |
| 152 | 152 |
gopts = append(gopts, customDialOptions...) |
| 153 | 153 |
|
| 154 |
- //nolint:staticcheck // ignore SA1019 NewClient has different behavior and needs to be tested |
|
| 154 |
+ // ignore SA1019 NewClient has different behavior and needs to be tested |
|
| 155 |
+ //nolint:staticcheck |
|
| 155 | 156 |
conn, err := grpc.DialContext(ctx, address, gopts...) |
| 156 | 157 |
if err != nil {
|
| 157 | 158 |
return nil, errors.Wrapf(err, "failed to dial %q . make sure buildkitd is running", address) |
| ... | ... |
@@ -1,8 +1,9 @@ |
| 1 | 1 |
package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "cmp" |
|
| 4 | 5 |
"context" |
| 5 |
- "sort" |
|
| 6 |
+ "slices" |
|
| 6 | 7 |
"time" |
| 7 | 8 |
|
| 8 | 9 |
controlapi "github.com/moby/buildkit/api/services/control" |
| ... | ... |
@@ -60,13 +61,9 @@ func (c *Client) DiskUsage(ctx context.Context, opts ...DiskUsageOption) ([]*Usa |
| 60 | 60 |
}) |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
- sort.Slice(du, func(i, j int) bool {
|
|
| 64 |
- if du[i].Size == du[j].Size {
|
|
| 65 |
- return du[i].ID > du[j].ID |
|
| 66 |
- } |
|
| 67 |
- return du[i].Size > du[j].Size |
|
| 63 |
+ slices.SortFunc(du, func(a, b *UsageInfo) int {
|
|
| 64 |
+ return cmp.Or(cmp.Compare(a.Size, b.Size), cmp.Compare(a.ID, b.ID)) |
|
| 68 | 65 |
}) |
| 69 |
- |
|
| 70 | 66 |
return du, nil |
| 71 | 67 |
} |
| 72 | 68 |
|
| ... | ... |
@@ -240,7 +240,7 @@ func (d *DefinitionOp) Inputs() []Output {
|
| 240 | 240 |
d.mu.Unlock() |
| 241 | 241 |
|
| 242 | 242 |
inputs = append(inputs, &output{vertex: vtx, platform: platform, getIndex: func() (pb.OutputIndex, error) {
|
| 243 |
- return pb.OutputIndex(vtx.index), nil |
|
| 243 |
+ return vtx.index, nil |
|
| 244 | 244 |
}}) |
| 245 | 245 |
} |
| 246 | 246 |
|
| ... | ... |
@@ -5,7 +5,7 @@ import ( |
| 5 | 5 |
_ "crypto/sha256" // for opencontainers/go-digest |
| 6 | 6 |
"fmt" |
| 7 | 7 |
"net" |
| 8 |
- "sort" |
|
| 8 |
+ "slices" |
|
| 9 | 9 |
"strings" |
| 10 | 10 |
|
| 11 | 11 |
"github.com/moby/buildkit/solver/pb" |
| ... | ... |
@@ -143,8 +143,8 @@ func (e *ExecOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, [] |
| 143 | 143 |
return "", nil, nil, nil, err |
| 144 | 144 |
} |
| 145 | 145 |
// make sure mounts are sorted |
| 146 |
- sort.Slice(e.mounts, func(i, j int) bool {
|
|
| 147 |
- return e.mounts[i].target < e.mounts[j].target |
|
| 146 |
+ slices.SortFunc(e.mounts, func(a, b *mount) int {
|
|
| 147 |
+ return strings.Compare(a.target, b.target) |
|
| 148 | 148 |
}) |
| 149 | 149 |
|
| 150 | 150 |
env, err := getEnv(e.base)(ctx, c) |
| ... | ... |
@@ -170,7 +170,10 @@ func (e *ExecOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, [] |
| 170 | 170 |
} else if e.constraints.Platform != nil {
|
| 171 | 171 |
os = e.constraints.Platform.OS |
| 172 | 172 |
} |
| 173 |
- env = env.SetDefault("PATH", system.DefaultPathEnv(os))
|
|
| 173 |
+ // don't set PATH on Windows. #5445 |
|
| 174 |
+ if os != "windows" {
|
|
| 175 |
+ env = env.SetDefault("PATH", system.DefaultPathEnv(os))
|
|
| 176 |
+ } |
|
| 174 | 177 |
} else {
|
| 175 | 178 |
addCap(&e.constraints, pb.CapExecMetaSetsDefaultPath) |
| 176 | 179 |
} |
| ... | ... |
@@ -477,10 +480,9 @@ func (e *ExecOp) Inputs() (inputs []Output) {
|
| 477 | 477 |
// make sure mounts are sorted |
| 478 | 478 |
// the same sort occurs in (*ExecOp).Marshal, and this |
| 479 | 479 |
// sort must be the same |
| 480 |
- sort.Slice(e.mounts, func(i int, j int) bool {
|
|
| 481 |
- return e.mounts[i].target < e.mounts[j].target |
|
| 480 |
+ slices.SortFunc(e.mounts, func(a, b *mount) int {
|
|
| 481 |
+ return strings.Compare(a.target, b.target) |
|
| 482 | 482 |
}) |
| 483 |
- |
|
| 484 | 483 |
seen := map[Output]struct{}{}
|
| 485 | 484 |
for _, m := range e.mounts {
|
| 486 | 485 |
if m.source != nil {
|
| ... | ... |
@@ -497,8 +499,8 @@ func (e *ExecOp) Inputs() (inputs []Output) {
|
| 497 | 497 |
func (e *ExecOp) getMountIndexFn(m *mount) func() (pb.OutputIndex, error) {
|
| 498 | 498 |
return func() (pb.OutputIndex, error) {
|
| 499 | 499 |
// make sure mounts are sorted |
| 500 |
- sort.Slice(e.mounts, func(i, j int) bool {
|
|
| 501 |
- return e.mounts[i].target < e.mounts[j].target |
|
| 500 |
+ slices.SortFunc(e.mounts, func(a, b *mount) int {
|
|
| 501 |
+ return strings.Compare(a.target, b.target) |
|
| 502 | 502 |
}) |
| 503 | 503 |
|
| 504 | 504 |
i := 0 |
| ... | ... |
@@ -136,7 +136,7 @@ func Image(ref string, opts ...ImageOption) State {
|
| 136 | 136 |
} else if info.metaResolver != nil {
|
| 137 | 137 |
if _, ok := r.(reference.Digested); ok || !info.resolveDigest {
|
| 138 | 138 |
return NewState(src.Output()).Async(func(ctx context.Context, st State, c *Constraints) (State, error) {
|
| 139 |
- p := info.Constraints.Platform |
|
| 139 |
+ p := info.Platform |
|
| 140 | 140 |
if p == nil {
|
| 141 | 141 |
p = c.Platform |
| 142 | 142 |
} |
| ... | ... |
@@ -153,7 +153,7 @@ func Image(ref string, opts ...ImageOption) State {
|
| 153 | 153 |
}) |
| 154 | 154 |
} |
| 155 | 155 |
return Scratch().Async(func(ctx context.Context, _ State, c *Constraints) (State, error) {
|
| 156 |
- p := info.Constraints.Platform |
|
| 156 |
+ p := info.Platform |
|
| 157 | 157 |
if p == nil {
|
| 158 | 158 |
p = c.Platform |
| 159 | 159 |
} |
| ... | ... |
@@ -18,9 +18,9 @@ func (c *Client) Prune(ctx context.Context, ch chan UsageInfo, opts ...PruneOpti |
| 18 | 18 |
req := &controlapi.PruneRequest{
|
| 19 | 19 |
Filter: info.Filter, |
| 20 | 20 |
KeepDuration: int64(info.KeepDuration), |
| 21 |
- ReservedSpace: int64(info.ReservedSpace), |
|
| 22 |
- MaxUsedSpace: int64(info.MaxUsedSpace), |
|
| 23 |
- MinFreeSpace: int64(info.MinFreeSpace), |
|
| 21 |
+ ReservedSpace: info.ReservedSpace, |
|
| 22 |
+ MaxUsedSpace: info.MaxUsedSpace, |
|
| 23 |
+ MinFreeSpace: info.MinFreeSpace, |
|
| 24 | 24 |
} |
| 25 | 25 |
if info.All {
|
| 26 | 26 |
req.All = true |
| ... | ... |
@@ -33,7 +33,7 @@ func (c *Client) Prune(ctx context.Context, ch chan UsageInfo, opts ...PruneOpti |
| 33 | 33 |
for {
|
| 34 | 34 |
d, err := cl.Recv() |
| 35 | 35 |
if err != nil {
|
| 36 |
- if err == io.EOF {
|
|
| 36 |
+ if errors.Is(err, io.EOF) {
|
|
| 37 | 37 |
return nil |
| 38 | 38 |
} |
| 39 | 39 |
return err |
| ... | ... |
@@ -322,7 +322,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG |
| 322 | 322 |
for {
|
| 323 | 323 |
resp, err := stream.Recv() |
| 324 | 324 |
if err != nil {
|
| 325 |
- if err == io.EOF {
|
|
| 325 |
+ if errors.Is(err, io.EOF) {
|
|
| 326 | 326 |
return nil |
| 327 | 327 |
} |
| 328 | 328 |
return errors.Wrap(err, "failed to receive status") |
| ... | ... |
@@ -356,7 +356,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG |
| 356 | 356 |
return nil, err |
| 357 | 357 |
} |
| 358 | 358 |
var manifestDesc ocispecs.Descriptor |
| 359 |
- if err = json.Unmarshal([]byte(manifestDescDt), &manifestDesc); err != nil {
|
|
| 359 |
+ if err = json.Unmarshal(manifestDescDt, &manifestDesc); err != nil {
|
|
| 360 | 360 |
return nil, err |
| 361 | 361 |
} |
| 362 | 362 |
for _, storePath := range storesToUpdate {
|
| ... | ... |
@@ -402,8 +402,7 @@ func prepareSyncedFiles(def *llb.Definition, localMounts map[string]fsutil.FS) ( |
| 402 | 402 |
return nil, errors.Wrap(err, "failed to parse llb proto op") |
| 403 | 403 |
} |
| 404 | 404 |
if src := op.GetSource(); src != nil {
|
| 405 |
- if strings.HasPrefix(src.Identifier, "local://") {
|
|
| 406 |
- name := strings.TrimPrefix(src.Identifier, "local://") |
|
| 405 |
+ if name, ok := strings.CutPrefix(src.Identifier, "local://"); ok {
|
|
| 407 | 406 |
mount, ok := localMounts[name] |
| 408 | 407 |
if !ok {
|
| 409 | 408 |
return nil, errors.Errorf("local directory %s not enabled", name)
|
| ... | ... |
@@ -104,7 +104,7 @@ type NetworkConfig struct {
|
| 104 | 104 |
type OCIConfig struct {
|
| 105 | 105 |
Enabled *bool `toml:"enabled"` |
| 106 | 106 |
Labels map[string]string `toml:"labels"` |
| 107 |
- Platforms []string `toml:"platforms"` |
|
| 107 |
+ Platforms []string `toml:"platforms,omitempty"` |
|
| 108 | 108 |
Snapshotter string `toml:"snapshotter"` |
| 109 | 109 |
Rootless bool `toml:"rootless"` |
| 110 | 110 |
NoProcessSandbox bool `toml:"noProcessSandbox"` |
| ... | ... |
@@ -138,7 +138,7 @@ type ContainerdConfig struct {
|
| 138 | 138 |
Address string `toml:"address"` |
| 139 | 139 |
Enabled *bool `toml:"enabled"` |
| 140 | 140 |
Labels map[string]string `toml:"labels"` |
| 141 |
- Platforms []string `toml:"platforms"` |
|
| 141 |
+ Platforms []string `toml:"platforms,omitempty"` |
|
| 142 | 142 |
Namespace string `toml:"namespace"` |
| 143 | 143 |
Runtime ContainerdRuntime `toml:"runtime"` |
| 144 | 144 |
GCConfig |
| ... | ... |
@@ -60,7 +60,7 @@ func (gwf *GatewayForwarder) lookupForwarder(ctx context.Context) (gateway.LLBBr |
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 | 62 |
ctx, cancel := context.WithCancelCause(ctx) |
| 63 |
- ctx, _ = context.WithTimeoutCause(ctx, 3*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 63 |
+ ctx, _ = context.WithTimeoutCause(ctx, 3*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 64 | 64 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 65 | 65 |
|
| 66 | 66 |
go func() {
|
| ... | ... |
@@ -5,13 +5,13 @@ import ( |
| 5 | 5 |
"syscall" |
| 6 | 6 |
) |
| 7 | 7 |
|
| 8 |
-type internalErr struct {
|
|
| 8 |
+type internalError struct {
|
|
| 9 | 9 |
error |
| 10 | 10 |
} |
| 11 | 11 |
|
| 12 |
-func (internalErr) System() {}
|
|
| 12 |
+func (internalError) System() {}
|
|
| 13 | 13 |
|
| 14 |
-func (err internalErr) Unwrap() error {
|
|
| 14 |
+func (err internalError) Unwrap() error {
|
|
| 15 | 15 |
return err.error |
| 16 | 16 |
} |
| 17 | 17 |
|
| ... | ... |
@@ -19,13 +19,13 @@ type system interface {
|
| 19 | 19 |
System() |
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 |
-var _ system = internalErr{}
|
|
| 22 |
+var _ system = internalError{}
|
|
| 23 | 23 |
|
| 24 | 24 |
func Internal(err error) error {
|
| 25 | 25 |
if err == nil {
|
| 26 | 26 |
return nil |
| 27 | 27 |
} |
| 28 |
- return internalErr{err}
|
|
| 28 |
+ return internalError{err}
|
|
| 29 | 29 |
} |
| 30 | 30 |
|
| 31 | 31 |
func IsInternal(err error) bool {
|
| ... | ... |
@@ -399,7 +399,7 @@ func (w *containerdExecutor) runProcess(ctx context.Context, p ctd.Process, resi |
| 399 | 399 |
ctxDone = nil |
| 400 | 400 |
var killCtx context.Context |
| 401 | 401 |
killCtx, cancel = context.WithCancelCause(context.Background()) |
| 402 |
- killCtx, _ = context.WithTimeoutCause(killCtx, 10*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 402 |
+ killCtx, _ = context.WithTimeoutCause(killCtx, 10*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 403 | 403 |
killCtxDone = killCtx.Done() |
| 404 | 404 |
p.Kill(killCtx, syscall.SIGKILL) |
| 405 | 405 |
io.Cancel() |
| ... | ... |
@@ -122,7 +122,7 @@ func (s *Sampler[T]) run() {
|
| 122 | 122 |
ss.err = nil |
| 123 | 123 |
} |
| 124 | 124 |
dur := ss.last.Sub(ss.first) |
| 125 |
- if time.Duration(ss.interval)*time.Duration(s.maxSamples) <= dur {
|
|
| 125 |
+ if ss.interval*time.Duration(s.maxSamples) <= dur {
|
|
| 126 | 126 |
ss.interval *= 2 |
| 127 | 127 |
} |
| 128 | 128 |
} |
| ... | ... |
@@ -546,7 +546,7 @@ func (k procKiller) Kill(ctx context.Context) (err error) {
|
| 546 | 546 |
// this timeout is generally a no-op, the Kill ctx should already have a |
| 547 | 547 |
// shorter timeout but here as a fail-safe for future refactoring. |
| 548 | 548 |
ctx, cancel := context.WithCancelCause(ctx) |
| 549 |
- ctx, _ = context.WithTimeoutCause(ctx, 10*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 549 |
+ ctx, _ = context.WithTimeoutCause(ctx, 10*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 550 | 550 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 551 | 551 |
|
| 552 | 552 |
if k.pidfile == "" {
|
| ... | ... |
@@ -634,13 +634,13 @@ func runcProcessHandle(ctx context.Context, killer procKiller) (*procHandle, con |
| 634 | 634 |
for {
|
| 635 | 635 |
select {
|
| 636 | 636 |
case <-ctx.Done(): |
| 637 |
- killCtx, timeout := context.WithCancelCause(context.Background()) |
|
| 638 |
- killCtx, _ = context.WithTimeoutCause(killCtx, 7*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 637 |
+ killCtx, timeout := context.WithCancelCause(context.Background()) //nolint:govet |
|
| 638 |
+ killCtx, _ = context.WithTimeoutCause(killCtx, 7*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 639 | 639 |
if err := p.killer.Kill(killCtx); err != nil {
|
| 640 | 640 |
select {
|
| 641 | 641 |
case <-killCtx.Done(): |
| 642 | 642 |
cancel(errors.WithStack(context.Cause(ctx))) |
| 643 |
- return |
|
| 643 |
+ return //nolint:govet |
|
| 644 | 644 |
default: |
| 645 | 645 |
} |
| 646 | 646 |
} |
| ... | ... |
@@ -693,7 +693,7 @@ func (p *procHandle) WaitForReady(ctx context.Context) error {
|
| 693 | 693 |
// callback is non-nil it will be called after receiving the pid. |
| 694 | 694 |
func (p *procHandle) WaitForStart(ctx context.Context, startedCh <-chan int, started func()) error {
|
| 695 | 695 |
ctx, cancel := context.WithCancelCause(ctx) |
| 696 |
- ctx, _ = context.WithTimeoutCause(ctx, 10*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 696 |
+ ctx, _ = context.WithTimeoutCause(ctx, 10*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 697 | 697 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 698 | 698 |
select {
|
| 699 | 699 |
case <-ctx.Done(): |
| ... | ... |
@@ -129,7 +129,7 @@ func (w *runcExecutor) callWithIO(ctx context.Context, process executor.ProcessI |
| 129 | 129 |
if errors.As(err, &ptmClosedError) {
|
| 130 | 130 |
if ptmClosedError.Op == "read" && |
| 131 | 131 |
ptmClosedError.Path == "/dev/ptmx" && |
| 132 |
- ptmClosedError.Err == syscall.EIO {
|
|
| 132 |
+ errors.Is(ptmClosedError.Err, syscall.EIO) {
|
|
| 133 | 133 |
return nil |
| 134 | 134 |
} |
| 135 | 135 |
} |
| ... | ... |
@@ -33,7 +33,7 @@ func MountStubsCleaner(ctx context.Context, dir string, mounts []Mount, recursiv |
| 33 | 33 |
|
| 34 | 34 |
for {
|
| 35 | 35 |
_, err = os.Lstat(realPath) |
| 36 |
- if !(errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR)) {
|
|
| 36 |
+ if !errors.Is(err, os.ErrNotExist) && !errors.Is(err, syscall.ENOTDIR) {
|
|
| 37 | 37 |
break |
| 38 | 38 |
} |
| 39 | 39 |
paths = append(paths, realPath) |
| ... | ... |
@@ -20,7 +20,7 @@ import ( |
| 20 | 20 |
func ReadAll(ctx context.Context, s session.Group, att exporter.Attestation) ([]byte, error) {
|
| 21 | 21 |
var content []byte |
| 22 | 22 |
if att.ContentFunc != nil {
|
| 23 |
- data, err := att.ContentFunc() |
|
| 23 |
+ data, err := att.ContentFunc(ctx) |
|
| 24 | 24 |
if err != nil {
|
| 25 | 25 |
return nil, err |
| 26 | 26 |
} |
| ... | ... |
@@ -166,7 +166,7 @@ func unbundle(root string, bundle exporter.Attestation) ([]exporter.Attestation, |
| 166 | 166 |
Kind: gatewaypb.AttestationKind_InToto, |
| 167 | 167 |
Metadata: bundle.Metadata, |
| 168 | 168 |
Path: path.Join(bundle.Path, entry.Name()), |
| 169 |
- ContentFunc: func() ([]byte, error) { return predicate, nil },
|
|
| 169 |
+ ContentFunc: func(context.Context) ([]byte, error) { return predicate, nil },
|
|
| 170 | 170 |
InToto: result.InTotoAttestation{
|
| 171 | 171 |
PredicateType: stmt.PredicateType, |
| 172 | 172 |
Subjects: subjects, |
| ... | ... |
@@ -118,7 +118,7 @@ func supplementSBOM(ctx context.Context, s session.Group, target cache.Immutable |
| 118 | 118 |
return exporter.Attestation{
|
| 119 | 119 |
Kind: att.Kind, |
| 120 | 120 |
Path: att.Path, |
| 121 |
- ContentFunc: func() ([]byte, error) { return content, nil },
|
|
| 121 |
+ ContentFunc: func(context.Context) ([]byte, error) { return content, nil },
|
|
| 122 | 122 |
InToto: att.InToto, |
| 123 | 123 |
}, nil |
| 124 | 124 |
} |
| ... | ... |
@@ -14,6 +14,7 @@ import ( |
| 14 | 14 |
"github.com/containerd/containerd/v2/core/images" |
| 15 | 15 |
"github.com/containerd/containerd/v2/core/leases" |
| 16 | 16 |
"github.com/containerd/containerd/v2/core/remotes/docker" |
| 17 |
+ remoteserrors "github.com/containerd/containerd/v2/core/remotes/errors" |
|
| 17 | 18 |
"github.com/containerd/containerd/v2/pkg/epoch" |
| 18 | 19 |
"github.com/containerd/containerd/v2/pkg/labels" |
| 19 | 20 |
"github.com/containerd/containerd/v2/pkg/rootfs" |
| ... | ... |
@@ -333,7 +334,6 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source |
| 333 | 333 |
} |
| 334 | 334 |
eg, ctx := errgroup.WithContext(ctx) |
| 335 | 335 |
for _, ref := range refs {
|
| 336 |
- ref := ref |
|
| 337 | 336 |
eg.Go(func() error {
|
| 338 | 337 |
remotes, err := ref.GetRemotes(ctx, false, e.opts.RefCfg, false, session.NewGroup(sessionID)) |
| 339 | 338 |
if err != nil {
|
| ... | ... |
@@ -356,6 +356,13 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source |
| 356 | 356 |
if e.push {
|
| 357 | 357 |
err = e.pushImage(ctx, src, sessionID, targetName, desc.Digest) |
| 358 | 358 |
if err != nil {
|
| 359 |
+ var statusErr remoteserrors.ErrUnexpectedStatus |
|
| 360 |
+ if errors.As(err, &statusErr) {
|
|
| 361 |
+ var dErr docker.Errors |
|
| 362 |
+ if err1 := json.Unmarshal(statusErr.Body, &dErr); err1 == nil && len(dErr) > 0 {
|
|
| 363 |
+ err = &formattedDockerError{dErr: dErr}
|
|
| 364 |
+ } |
|
| 365 |
+ } |
|
| 359 | 366 |
return nil, nil, errors.Wrapf(err, "failed to push %v", targetName) |
| 360 | 367 |
} |
| 361 | 368 |
} |
| ... | ... |
@@ -543,3 +550,36 @@ func (d *descriptorReference) Descriptor() ocispecs.Descriptor {
|
| 543 | 543 |
func (d *descriptorReference) Release() error {
|
| 544 | 544 |
return d.release(context.TODO()) |
| 545 | 545 |
} |
| 546 |
+ |
|
| 547 |
+type formattedDockerError struct {
|
|
| 548 |
+ dErr docker.Errors |
|
| 549 |
+} |
|
| 550 |
+ |
|
| 551 |
+func (e *formattedDockerError) Error() string {
|
|
| 552 |
+ format := func(err error) string {
|
|
| 553 |
+ out := err.Error() |
|
| 554 |
+ var dErr docker.Error |
|
| 555 |
+ if errors.As(err, &dErr) {
|
|
| 556 |
+ if v, ok := dErr.Detail.(string); ok && v != "" {
|
|
| 557 |
+ out += " - " + v |
|
| 558 |
+ } |
|
| 559 |
+ } |
|
| 560 |
+ return out |
|
| 561 |
+ } |
|
| 562 |
+ switch len(e.dErr) {
|
|
| 563 |
+ case 0: |
|
| 564 |
+ return "<nil>" |
|
| 565 |
+ case 1: |
|
| 566 |
+ return format(e.dErr[0]) |
|
| 567 |
+ default: |
|
| 568 |
+ msg := "errors:\n" |
|
| 569 |
+ for _, err := range e.dErr {
|
|
| 570 |
+ msg += format(err) + "\n" |
|
| 571 |
+ } |
|
| 572 |
+ return msg |
|
| 573 |
+ } |
|
| 574 |
+} |
|
| 575 |
+ |
|
| 576 |
+func (e *formattedDockerError) Unwrap() error {
|
|
| 577 |
+ return e.dErr |
|
| 578 |
+} |
| ... | ... |
@@ -683,7 +683,10 @@ func defaultImageConfig() ([]byte, error) {
|
| 683 | 683 |
img.Variant = pl.Variant |
| 684 | 684 |
img.RootFS.Type = "layers" |
| 685 | 685 |
img.Config.WorkingDir = "/" |
| 686 |
- img.Config.Env = []string{"PATH=" + system.DefaultPathEnv(pl.OS)}
|
|
| 686 |
+ // don't set default PATH on Windows. #5445 |
|
| 687 |
+ if pl.OS != "windows" {
|
|
| 688 |
+ img.Config.Env = []string{"PATH=" + system.DefaultPathEnv(pl.OS)}
|
|
| 689 |
+ } |
|
| 687 | 690 |
dt, err := json.Marshal(img) |
| 688 | 691 |
return dt, errors.Wrap(err, "failed to create empty image config") |
| 689 | 692 |
} |
| ... | ... |
@@ -80,7 +80,7 @@ func (e *localExporter) Config() *exporter.Config {
|
| 80 | 80 |
|
| 81 | 81 |
func (e *localExporterInstance) Export(ctx context.Context, inp *exporter.Source, _ exptypes.InlineCache, sessionID string) (map[string]string, exporter.DescriptorReference, error) {
|
| 82 | 82 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 83 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 83 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 84 | 84 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 85 | 85 |
|
| 86 | 86 |
if e.opts.Epoch == nil {
|
| ... | ... |
@@ -217,7 +217,7 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source |
| 217 | 217 |
} |
| 218 | 218 |
|
| 219 | 219 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 220 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 220 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 221 | 221 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 222 | 222 |
|
| 223 | 223 |
caller, err := e.opt.SessionManager.Get(timeoutCtx, sessionID, false) |
| ... | ... |
@@ -235,7 +235,6 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source |
| 235 | 235 |
eg, egCtx := errgroup.WithContext(ctx) |
| 236 | 236 |
mprovider := contentutil.NewMultiProvider(e.opt.ImageWriter.ContentStore()) |
| 237 | 237 |
for _, ref := range refs {
|
| 238 |
- ref := ref |
|
| 239 | 238 |
eg.Go(func() error {
|
| 240 | 239 |
remotes, err := ref.GetRemotes(egCtx, false, e.opts.RefCfg, false, session.NewGroup(sessionID)) |
| 241 | 240 |
if err != nil {
|
| ... | ... |
@@ -164,7 +164,7 @@ func (e *localExporterInstance) Export(ctx context.Context, inp *exporter.Source |
| 164 | 164 |
} |
| 165 | 165 |
|
| 166 | 166 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 167 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 167 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 168 | 168 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 169 | 169 |
|
| 170 | 170 |
caller, err := e.opt.SessionManager.Get(timeoutCtx, sessionID, false) |
| ... | ... |
@@ -32,8 +32,8 @@ func CaptureFrontendOpts[T comparable](m map[string]string, res *result.Result[T |
| 32 | 32 |
|
| 33 | 33 |
req.Labels = map[string]string{}
|
| 34 | 34 |
for k, v := range m {
|
| 35 |
- if strings.HasPrefix(k, labelsPrefix) {
|
|
| 36 |
- req.Labels[strings.TrimPrefix(k, labelsPrefix)] = v |
|
| 35 |
+ if after, ok := strings.CutPrefix(k, labelsPrefix); ok {
|
|
| 36 |
+ req.Labels[after] = v |
|
| 37 | 37 |
} |
| 38 | 38 |
} |
| 39 | 39 |
req.Request = m[keyRequestID] |
| ... | ... |
@@ -3,7 +3,7 @@ package verifier |
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
"fmt" |
| 6 |
- "sort" |
|
| 6 |
+ "slices" |
|
| 7 | 7 |
"strings" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/containerd/platforms" |
| ... | ... |
@@ -115,10 +115,10 @@ func CheckInvalidPlatforms[T comparable](ctx context.Context, res *result.Result |
| 115 | 115 |
} |
| 116 | 116 |
|
| 117 | 117 |
func platformsString(ps []exptypes.Platform) string {
|
| 118 |
- var ss []string |
|
| 119 |
- for _, p := range ps {
|
|
| 120 |
- ss = append(ss, platforms.FormatAll(platforms.Normalize(p.Platform))) |
|
| 118 |
+ ss := make([]string, len(ps)) |
|
| 119 |
+ for i, p := range ps {
|
|
| 120 |
+ ss[i] = platforms.FormatAll(platforms.Normalize(p.Platform)) |
|
| 121 | 121 |
} |
| 122 |
- sort.Strings(ss) |
|
| 122 |
+ slices.Sort(ss) |
|
| 123 | 123 |
return strings.Join(ss, ",") |
| 124 | 124 |
} |
| ... | ... |
@@ -43,12 +43,12 @@ func Validate(values map[string]map[string]string) (map[string]map[string]string |
| 43 | 43 |
func Parse(values map[string]string) (map[string]map[string]string, error) {
|
| 44 | 44 |
attests := make(map[string]string) |
| 45 | 45 |
for k, v := range values {
|
| 46 |
- if strings.HasPrefix(k, "attest:") {
|
|
| 47 |
- attests[strings.ToLower(strings.TrimPrefix(k, "attest:"))] = v |
|
| 46 |
+ if after, ok := strings.CutPrefix(k, "attest:"); ok {
|
|
| 47 |
+ attests[strings.ToLower(after)] = v |
|
| 48 | 48 |
continue |
| 49 | 49 |
} |
| 50 |
- if strings.HasPrefix(k, "build-arg:BUILDKIT_ATTEST_") {
|
|
| 51 |
- attests[strings.ToLower(strings.TrimPrefix(k, "build-arg:BUILDKIT_ATTEST_"))] = v |
|
| 50 |
+ if after, ok := strings.CutPrefix(k, "build-arg:BUILDKIT_ATTEST_"); ok {
|
|
| 51 |
+ attests[strings.ToLower(after)] = v |
|
| 52 | 52 |
continue |
| 53 | 53 |
} |
| 54 | 54 |
} |
| ... | ... |
@@ -103,7 +103,7 @@ func Build(ctx context.Context, c client.Client) (_ *client.Result, err error) {
|
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 | 105 |
defer func() {
|
| 106 |
- var el *parser.ErrorLocation |
|
| 106 |
+ var el *parser.LocationError |
|
| 107 | 107 |
if errors.As(err, &el) {
|
| 108 | 108 |
for _, l := range el.Locations {
|
| 109 | 109 |
err = wrapSource(err, src.SourceMap, l) |
| ... | ... |
@@ -14,7 +14,6 @@ import ( |
| 14 | 14 |
"regexp" |
| 15 | 15 |
"runtime" |
| 16 | 16 |
"slices" |
| 17 |
- "sort" |
|
| 18 | 17 |
"strconv" |
| 19 | 18 |
"strings" |
| 20 | 19 |
"sync" |
| ... | ... |
@@ -138,7 +137,7 @@ func DockerfileLint(ctx context.Context, dt []byte, opt ConvertOpt) (*lint.LintR |
| 138 | 138 |
|
| 139 | 139 |
_, err := toDispatchState(ctx, dt, opt) |
| 140 | 140 |
|
| 141 |
- var errLoc *parser.ErrorLocation |
|
| 141 |
+ var errLoc *parser.LocationError |
|
| 142 | 142 |
if err != nil {
|
| 143 | 143 |
buildErr := &lint.BuildError{
|
| 144 | 144 |
Message: err.Error(), |
| ... | ... |
@@ -680,7 +679,10 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS |
| 680 | 680 |
if d.platform != nil {
|
| 681 | 681 |
osName = d.platform.OS |
| 682 | 682 |
} |
| 683 |
- d.image.Config.Env = append(d.image.Config.Env, "PATH="+system.DefaultPathEnv(osName)) |
|
| 683 |
+ // except for Windows, leave that to the OS. #5445 |
|
| 684 |
+ if osName != "windows" {
|
|
| 685 |
+ d.image.Config.Env = append(d.image.Config.Env, "PATH="+system.DefaultPathEnv(osName)) |
|
| 686 |
+ } |
|
| 684 | 687 |
} |
| 685 | 688 |
|
| 686 | 689 |
// initialize base metadata from image conf |
| ... | ... |
@@ -1219,7 +1221,7 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE |
| 1219 | 1219 |
// Run command can potentially access any file. Mark the full filesystem as used. |
| 1220 | 1220 |
d.paths["/"] = struct{}{}
|
| 1221 | 1221 |
|
| 1222 |
- var args []string = c.CmdLine |
|
| 1222 |
+ var args = c.CmdLine |
|
| 1223 | 1223 |
if len(c.Files) > 0 {
|
| 1224 | 1224 |
if len(args) != 1 || !c.PrependShell {
|
| 1225 | 1225 |
return errors.Errorf("parsing produced an invalid run command: %v", args)
|
| ... | ... |
@@ -1400,6 +1402,9 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo |
| 1400 | 1400 |
if user := d.image.Config.User; user != "" {
|
| 1401 | 1401 |
mkdirOpt = append(mkdirOpt, llb.WithUser(user)) |
| 1402 | 1402 |
} |
| 1403 |
+ if d.epoch != nil {
|
|
| 1404 |
+ mkdirOpt = append(mkdirOpt, llb.WithCreatedTime(*d.epoch)) |
|
| 1405 |
+ } |
|
| 1403 | 1406 |
platform := opt.targetPlatform |
| 1404 | 1407 |
if d.platform != nil {
|
| 1405 | 1408 |
platform = *d.platform |
| ... | ... |
@@ -1705,7 +1710,7 @@ func dispatchOnbuild(d *dispatchState, c *instructions.OnbuildCommand) error {
|
| 1705 | 1705 |
func dispatchCmd(d *dispatchState, c *instructions.CmdCommand, lint *linter.Linter) error {
|
| 1706 | 1706 |
validateUsedOnce(c, &d.cmd, lint) |
| 1707 | 1707 |
|
| 1708 |
- var args []string = c.CmdLine |
|
| 1708 |
+ var args = c.CmdLine |
|
| 1709 | 1709 |
if c.PrependShell {
|
| 1710 | 1710 |
if len(d.image.Config.Shell) == 0 {
|
| 1711 | 1711 |
msg := linter.RuleJSONArgsRecommended.Format(c.Name()) |
| ... | ... |
@@ -1721,7 +1726,7 @@ func dispatchCmd(d *dispatchState, c *instructions.CmdCommand, lint *linter.Lint |
| 1721 | 1721 |
func dispatchEntrypoint(d *dispatchState, c *instructions.EntrypointCommand, lint *linter.Linter) error {
|
| 1722 | 1722 |
validateUsedOnce(c, &d.entrypoint, lint) |
| 1723 | 1723 |
|
| 1724 |
- var args []string = c.CmdLine |
|
| 1724 |
+ var args = c.CmdLine |
|
| 1725 | 1725 |
if c.PrependShell {
|
| 1726 | 1726 |
if len(d.image.Config.Shell) == 0 {
|
| 1727 | 1727 |
msg := linter.RuleJSONArgsRecommended.Format(c.Name()) |
| ... | ... |
@@ -2383,8 +2388,8 @@ func mergeLocations(locations ...[]parser.Range) []parser.Range {
|
| 2383 | 2383 |
return allRanges |
| 2384 | 2384 |
} |
| 2385 | 2385 |
|
| 2386 |
- sort.Slice(allRanges, func(i, j int) bool {
|
|
| 2387 |
- return allRanges[i].Start.Line < allRanges[j].Start.Line |
|
| 2386 |
+ slices.SortFunc(allRanges, func(a, b parser.Range) int {
|
|
| 2387 |
+ return a.Start.Line - b.Start.Line |
|
| 2388 | 2388 |
}) |
| 2389 | 2389 |
|
| 2390 | 2390 |
location := []parser.Range{}
|
| ... | ... |
@@ -37,6 +37,9 @@ func emptyImage(platform ocispecs.Platform) dockerspec.DockerOCIImage {
|
| 37 | 37 |
img.Variant = platform.Variant |
| 38 | 38 |
img.RootFS.Type = "layers" |
| 39 | 39 |
img.Config.WorkingDir = "/" |
| 40 |
- img.Config.Env = []string{"PATH=" + system.DefaultPathEnv(platform.OS)}
|
|
| 40 |
+ // don't set path for Windows, leave it to the OS. #5445 |
|
| 41 |
+ if platform.OS != "windows" {
|
|
| 42 |
+ img.Config.Env = []string{"PATH=" + system.DefaultPathEnv(platform.OS)}
|
|
| 43 |
+ } |
|
| 41 | 44 |
return img |
| 42 | 45 |
} |
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
"fmt" |
| 9 | 9 |
"regexp" |
| 10 | 10 |
"slices" |
| 11 |
- "sort" |
|
| 12 | 11 |
"strconv" |
| 13 | 12 |
"strings" |
| 14 | 13 |
"time" |
| ... | ... |
@@ -688,7 +687,7 @@ func parseExpose(req parseRequest) (*ExposeCommand, error) {
|
| 688 | 688 |
return nil, err |
| 689 | 689 |
} |
| 690 | 690 |
|
| 691 |
- sort.Strings(portsTab) |
|
| 691 |
+ slices.Sort(portsTab) |
|
| 692 | 692 |
return &ExposeCommand{
|
| 693 | 693 |
Ports: portsTab, |
| 694 | 694 |
withNameAndCode: newWithNameAndCode(req), |
| ... | ... |
@@ -832,8 +831,8 @@ func getComment(comments []string, name string) string {
|
| 832 | 832 |
return "" |
| 833 | 833 |
} |
| 834 | 834 |
for _, line := range comments {
|
| 835 |
- if strings.HasPrefix(line, name+" ") {
|
|
| 836 |
- return strings.TrimPrefix(line, name+" ") |
|
| 835 |
+ if after, ok := strings.CutPrefix(line, name+" "); ok {
|
|
| 836 |
+ return after |
|
| 837 | 837 |
} |
| 838 | 838 |
} |
| 839 | 839 |
return "" |
| ... | ... |
@@ -55,7 +55,7 @@ func (lc *Linter) Run(rule LinterRuleI, location []parser.Range, txt ...string) |
| 55 | 55 |
rulename := rule.RuleName() |
| 56 | 56 |
if rule.IsExperimental() {
|
| 57 | 57 |
_, experimentalOk := lc.ExperimentalRules[rulename] |
| 58 |
- if !(lc.ExperimentalAll || experimentalOk) {
|
|
| 58 |
+ if !lc.ExperimentalAll && !experimentalOk {
|
|
| 59 | 59 |
return |
| 60 | 60 |
} |
| 61 | 61 |
} else {
|
| ... | ... |
@@ -5,14 +5,14 @@ import ( |
| 5 | 5 |
"github.com/pkg/errors" |
| 6 | 6 |
) |
| 7 | 7 |
|
| 8 |
-// ErrorLocation gives a location in source code that caused the error |
|
| 9 |
-type ErrorLocation struct {
|
|
| 8 |
+// LocationError gives a location in source code that caused the error |
|
| 9 |
+type LocationError struct {
|
|
| 10 | 10 |
Locations [][]Range |
| 11 | 11 |
error |
| 12 | 12 |
} |
| 13 | 13 |
|
| 14 | 14 |
// Unwrap unwraps to the next error |
| 15 |
-func (e *ErrorLocation) Unwrap() error {
|
|
| 15 |
+func (e *LocationError) Unwrap() error {
|
|
| 16 | 16 |
return e.error |
| 17 | 17 |
} |
| 18 | 18 |
|
| ... | ... |
@@ -45,7 +45,7 @@ func setLocation(err error, location []Range, add bool) error {
|
| 45 | 45 |
if err == nil {
|
| 46 | 46 |
return nil |
| 47 | 47 |
} |
| 48 |
- var el *ErrorLocation |
|
| 48 |
+ var el *LocationError |
|
| 49 | 49 |
if errors.As(err, &el) {
|
| 50 | 50 |
if add {
|
| 51 | 51 |
el.Locations = append(el.Locations, location) |
| ... | ... |
@@ -54,7 +54,7 @@ func setLocation(err error, location []Range, add bool) error {
|
| 54 | 54 |
} |
| 55 | 55 |
return err |
| 56 | 56 |
} |
| 57 |
- return stack.Enable(&ErrorLocation{
|
|
| 57 |
+ return stack.Enable(&LocationError{
|
|
| 58 | 58 |
error: err, |
| 59 | 59 |
Locations: [][]Range{location},
|
| 60 | 60 |
}) |
| ... | ... |
@@ -318,7 +318,7 @@ func parseMaybeJSON(rest string, d *directives) (*Node, map[string]bool, error) |
| 318 | 318 |
if err == nil {
|
| 319 | 319 |
return node, attrs, nil |
| 320 | 320 |
} |
| 321 |
- if err == errDockerfileNotStringArray {
|
|
| 321 |
+ if errors.Is(err, errDockerfileNotStringArray) {
|
|
| 322 | 322 |
return nil, nil, err |
| 323 | 323 |
} |
| 324 | 324 |
|
| ... | ... |
@@ -336,7 +336,7 @@ func parseMaybeJSONToList(rest string, d *directives) (*Node, map[string]bool, e |
| 336 | 336 |
if err == nil {
|
| 337 | 337 |
return node, attrs, nil |
| 338 | 338 |
} |
| 339 |
- if err == errDockerfileNotStringArray {
|
|
| 339 |
+ if errors.Is(err, errDockerfileNotStringArray) {
|
|
| 340 | 340 |
return nil, nil, err |
| 341 | 341 |
} |
| 342 | 342 |
|
| ... | ... |
@@ -114,7 +114,7 @@ type Heredoc struct {
|
| 114 | 114 |
var ( |
| 115 | 115 |
dispatch map[string]func(string, *directives) (*Node, map[string]bool, error) |
| 116 | 116 |
reWhitespace = regexp.MustCompile(`[\t\v\f\r ]+`) |
| 117 |
- reHeredoc = regexp.MustCompile(`^(\d*)<<(-?)([^<]*)$`) |
|
| 117 |
+ reHeredoc = regexp.MustCompile(`^(\d*)<<(-?)\s*([^<]*)$`) |
|
| 118 | 118 |
reLeadingTabs = regexp.MustCompile(`(?m)^\t+`) |
| 119 | 119 |
) |
| 120 | 120 |
|
| ... | ... |
@@ -556,8 +556,8 @@ func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
| 556 | 556 |
} |
| 557 | 557 |
|
| 558 | 558 |
func handleScannerError(err error) error {
|
| 559 |
- switch err {
|
|
| 560 |
- case bufio.ErrTooLong: |
|
| 559 |
+ switch {
|
|
| 560 |
+ case errors.Is(err, bufio.ErrTooLong): |
|
| 561 | 561 |
return errors.Errorf("dockerfile line greater than max allowed size of %d", bufio.MaxScanTokenSize-1)
|
| 562 | 562 |
default: |
| 563 | 563 |
return err |
| ... | ... |
@@ -177,6 +177,7 @@ func (sw *shellWord) processStopOn(stopChar rune, rawEscapes bool) (string, []st |
| 177 | 177 |
// no need to initialize all the time |
| 178 | 178 |
var charFuncMapping = map[rune]func() (string, error){
|
| 179 | 179 |
'$': sw.processDollar, |
| 180 |
+ '<': sw.processPossibleHeredoc, |
|
| 180 | 181 |
} |
| 181 | 182 |
if !sw.SkipProcessQuotes {
|
| 182 | 183 |
charFuncMapping['\''] = sw.processSingleQuote |
| ... | ... |
@@ -512,6 +513,25 @@ func (sw *shellWord) processName() string {
|
| 512 | 512 |
return name.String() |
| 513 | 513 |
} |
| 514 | 514 |
|
| 515 |
+func (sw *shellWord) processPossibleHeredoc() (string, error) {
|
|
| 516 |
+ sw.scanner.Next() |
|
| 517 |
+ if sw.scanner.Peek() != '<' {
|
|
| 518 |
+ return "<", nil // not a heredoc |
|
| 519 |
+ } |
|
| 520 |
+ sw.scanner.Next() |
|
| 521 |
+ |
|
| 522 |
+ // heredoc might have whitespace between << and word terminator |
|
| 523 |
+ var space bytes.Buffer |
|
| 524 |
+ nextCh := sw.scanner.Peek() |
|
| 525 |
+ for isWhitespace(nextCh) {
|
|
| 526 |
+ space.WriteRune(nextCh) |
|
| 527 |
+ sw.scanner.Next() |
|
| 528 |
+ nextCh = sw.scanner.Peek() |
|
| 529 |
+ } |
|
| 530 |
+ result := "<<" + space.String() |
|
| 531 |
+ return result, nil |
|
| 532 |
+} |
|
| 533 |
+ |
|
| 515 | 534 |
// isSpecialParam checks if the provided character is a special parameters, |
| 516 | 535 |
// as defined in http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02 |
| 517 | 536 |
func isSpecialParam(char rune) bool {
|
| ... | ... |
@@ -677,3 +697,11 @@ func trimSuffix(pattern, word string, greedy bool) (string, error) {
|
| 677 | 677 |
} |
| 678 | 678 |
return reverseString(str), nil |
| 679 | 679 |
} |
| 680 |
+ |
|
| 681 |
+func isWhitespace(r rune) bool {
|
|
| 682 |
+ switch r {
|
|
| 683 |
+ case '\t', '\r', ' ': |
|
| 684 |
+ return true |
|
| 685 |
+ } |
|
| 686 |
+ return false |
|
| 687 |
+} |
| ... | ... |
@@ -128,8 +128,8 @@ func parseSourceDateEpoch(v string) (*time.Time, error) {
|
| 128 | 128 |
func parseLocalSessionIDs(opt map[string]string) map[string]string {
|
| 129 | 129 |
m := map[string]string{}
|
| 130 | 130 |
for k, v := range opt {
|
| 131 |
- if strings.HasPrefix(k, localSessionIDPrefix) {
|
|
| 132 |
- m[strings.TrimPrefix(k, localSessionIDPrefix)] = v |
|
| 131 |
+ if after, ok := strings.CutPrefix(k, localSessionIDPrefix); ok {
|
|
| 132 |
+ m[after] = v |
|
| 133 | 133 |
} |
| 134 | 134 |
} |
| 135 | 135 |
return m |
| ... | ... |
@@ -138,8 +138,8 @@ func parseLocalSessionIDs(opt map[string]string) map[string]string {
|
| 138 | 138 |
func filter(opt map[string]string, key string) map[string]string {
|
| 139 | 139 |
m := map[string]string{}
|
| 140 | 140 |
for k, v := range opt {
|
| 141 |
- if strings.HasPrefix(k, key) {
|
|
| 142 |
- m[strings.TrimPrefix(k, key)] = v |
|
| 141 |
+ if after, ok := strings.CutPrefix(k, key); ok {
|
|
| 142 |
+ m[after] = v |
|
| 143 | 143 |
} |
| 144 | 144 |
} |
| 145 | 145 |
return m |
| ... | ... |
@@ -22,7 +22,6 @@ func (bc *Client) Build(ctx context.Context, fn BuildFunc) (*ResultBuilder, erro |
| 22 | 22 |
|
| 23 | 23 |
targets := make([]*ocispecs.Platform, 0, len(bc.TargetPlatforms)) |
| 24 | 24 |
for _, p := range bc.TargetPlatforms {
|
| 25 |
- p := p |
|
| 26 | 25 |
targets = append(targets, &p) |
| 27 | 26 |
} |
| 28 | 27 |
if len(targets) == 0 {
|
| ... | ... |
@@ -106,7 +105,6 @@ func (rb *ResultBuilder) Finalize() (*client.Result, error) {
|
| 106 | 106 |
func (rb *ResultBuilder) EachPlatform(ctx context.Context, fn func(ctx context.Context, id string, p ocispecs.Platform) error) error {
|
| 107 | 107 |
eg, ctx := errgroup.WithContext(ctx) |
| 108 | 108 |
for _, p := range rb.expPlatforms.Platforms {
|
| 109 |
- p := p |
|
| 110 | 109 |
eg.Go(func() error {
|
| 111 | 110 |
return fn(ctx, p.ID, p.Platform) |
| 112 | 111 |
}) |
| ... | ... |
@@ -13,6 +13,12 @@ import ( |
| 13 | 13 |
digest "github.com/opencontainers/go-digest" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
+const ( |
|
| 17 |
+ // KeySource is the option key used by the gateway frontend to represent |
|
| 18 |
+ // the source for the external frontend |
|
| 19 |
+ KeySource = "source" |
|
| 20 |
+) |
|
| 21 |
+ |
|
| 16 | 22 |
type Result = result.Result[solver.ResultProxy] |
| 17 | 23 |
|
| 18 | 24 |
type Attestation = result.Attestation[solver.ResultProxy] |
| ... | ... |
@@ -1,11 +1,12 @@ |
| 1 | 1 |
package container |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "cmp" |
|
| 4 | 5 |
"context" |
| 5 | 6 |
"fmt" |
| 6 | 7 |
"path/filepath" |
| 7 | 8 |
"runtime" |
| 8 |
- "sort" |
|
| 9 |
+ "slices" |
|
| 9 | 10 |
"strings" |
| 10 | 11 |
"sync" |
| 11 | 12 |
"syscall" |
| ... | ... |
@@ -20,10 +21,8 @@ import ( |
| 20 | 20 |
"github.com/moby/buildkit/session" |
| 21 | 21 |
"github.com/moby/buildkit/snapshot" |
| 22 | 22 |
"github.com/moby/buildkit/solver/llbsolver/mounts" |
| 23 |
- "github.com/moby/buildkit/solver/pb" |
|
| 24 | 23 |
opspb "github.com/moby/buildkit/solver/pb" |
| 25 | 24 |
"github.com/moby/buildkit/util/stack" |
| 26 |
- utilsystem "github.com/moby/buildkit/util/system" |
|
| 27 | 25 |
"github.com/moby/buildkit/worker" |
| 28 | 26 |
"github.com/pkg/errors" |
| 29 | 27 |
"golang.org/x/sync/errgroup" |
| ... | ... |
@@ -79,9 +78,9 @@ func NewContainer(ctx context.Context, cm cache.Manager, exec executor.Executor, |
| 79 | 79 |
mnts = append(mnts, m.Mount) |
| 80 | 80 |
if m.WorkerRef != nil {
|
| 81 | 81 |
refs = append(refs, m.WorkerRef) |
| 82 |
- m.Mount.Input = int64(len(refs) - 1) |
|
| 82 |
+ m.Input = int64(len(refs) - 1) |
|
| 83 | 83 |
} else {
|
| 84 |
- m.Mount.Input = int64(opspb.Empty) |
|
| 84 |
+ m.Input = int64(opspb.Empty) |
|
| 85 | 85 |
} |
| 86 | 86 |
} |
| 87 | 87 |
|
| ... | ... |
@@ -106,13 +105,11 @@ func NewContainer(ctx context.Context, cm cache.Manager, exec executor.Executor, |
| 106 | 106 |
ctr.mounts = p.Mounts |
| 107 | 107 |
|
| 108 | 108 |
for _, o := range p.OutputRefs {
|
| 109 |
- o := o |
|
| 110 | 109 |
ctr.cleanup = append(ctr.cleanup, func() error {
|
| 111 | 110 |
return o.Ref.Release(context.TODO()) |
| 112 | 111 |
}) |
| 113 | 112 |
} |
| 114 | 113 |
for _, active := range p.Actives {
|
| 115 |
- active := active |
|
| 116 | 114 |
ctr.cleanup = append(ctr.cleanup, func() error {
|
| 117 | 115 |
return active.Ref.Release(context.TODO()) |
| 118 | 116 |
}) |
| ... | ... |
@@ -276,8 +273,8 @@ func PrepareMounts(ctx context.Context, mm *mounts.MountManager, cm cache.Manage |
| 276 | 276 |
} |
| 277 | 277 |
|
| 278 | 278 |
// sort mounts so parents are mounted first |
| 279 |
- sort.Slice(p.Mounts, func(i, j int) bool {
|
|
| 280 |
- return p.Mounts[i].Dest < p.Mounts[j].Dest |
|
| 279 |
+ slices.SortFunc(p.Mounts, func(a, b executor.Mount) int {
|
|
| 280 |
+ return cmp.Compare(a.Dest, b.Dest) |
|
| 281 | 281 |
}) |
| 282 | 282 |
|
| 283 | 283 |
return p, nil |
| ... | ... |
@@ -327,7 +324,7 @@ func (gwCtr *gatewayContainer) Start(ctx context.Context, req client.StartReques |
| 327 | 327 |
if procInfo.Meta.Cwd == "" {
|
| 328 | 328 |
procInfo.Meta.Cwd = "/" |
| 329 | 329 |
} |
| 330 |
- procInfo.Meta.Env = addDefaultEnvvar(procInfo.Meta.Env, "PATH", utilsystem.DefaultPathEnv(gwCtr.platform.OS)) |
|
| 330 |
+ procInfo.Meta.Env = addDefaultEnvvar(procInfo.Meta.Env, "PATH", system.DefaultPathEnv(gwCtr.platform.OS)) |
|
| 331 | 331 |
if req.Tty {
|
| 332 | 332 |
procInfo.Meta.Env = addDefaultEnvvar(procInfo.Meta.Env, "TERM", "xterm") |
| 333 | 333 |
} |
| ... | ... |
@@ -377,7 +374,7 @@ func (gwCtr *gatewayContainer) Start(ctx context.Context, req client.StartReques |
| 377 | 377 |
return gwProc, nil |
| 378 | 378 |
} |
| 379 | 379 |
|
| 380 |
-func (gwCtr *gatewayContainer) loadSecretEnv(ctx context.Context, secretEnv []*pb.SecretEnv) ([]string, error) {
|
|
| 380 |
+func (gwCtr *gatewayContainer) loadSecretEnv(ctx context.Context, secretEnv []*opspb.SecretEnv) ([]string, error) {
|
|
| 381 | 381 |
out := make([]string, 0, len(secretEnv)) |
| 382 | 382 |
for _, sopt := range secretEnv {
|
| 383 | 383 |
id := sopt.ID |
| ... | ... |
@@ -393,7 +390,7 @@ func (gwCtr *gatewayContainer) loadSecretEnv(ctx context.Context, secretEnv []*p |
| 393 | 393 |
} |
| 394 | 394 |
return nil |
| 395 | 395 |
}) |
| 396 |
- if err != nil && !(errors.Is(err, secrets.ErrNotFound) && sopt.Optional) {
|
|
| 396 |
+ if err != nil && (!errors.Is(err, secrets.ErrNotFound) || !sopt.Optional) {
|
|
| 397 | 397 |
return nil, err |
| 398 | 398 |
} |
| 399 | 399 |
out = append(out, fmt.Sprintf("%s=%s", sopt.Name, string(dt)))
|
| ... | ... |
@@ -59,15 +59,7 @@ type BridgeClient struct {
|
| 59 | 59 |
} |
| 60 | 60 |
|
| 61 | 61 |
func (c *BridgeClient) Solve(ctx context.Context, req client.SolveRequest) (*client.Result, error) {
|
| 62 |
- res, err := c.FrontendLLBBridge.Solve(ctx, frontend.SolveRequest{
|
|
| 63 |
- Evaluate: req.Evaluate, |
|
| 64 |
- Definition: req.Definition, |
|
| 65 |
- Frontend: req.Frontend, |
|
| 66 |
- FrontendOpt: req.FrontendOpt, |
|
| 67 |
- FrontendInputs: req.FrontendInputs, |
|
| 68 |
- CacheImports: req.CacheImports, |
|
| 69 |
- SourcePolicies: req.SourcePolicies, |
|
| 70 |
- }, c.sid) |
|
| 62 |
+ res, err := c.FrontendLLBBridge.Solve(ctx, req, c.sid) |
|
| 71 | 63 |
if err != nil {
|
| 72 | 64 |
return nil, c.wrapSolveError(err) |
| 73 | 65 |
} |
| ... | ... |
@@ -63,8 +63,7 @@ import ( |
| 63 | 63 |
) |
| 64 | 64 |
|
| 65 | 65 |
const ( |
| 66 |
- keySource = "source" |
|
| 67 |
- keyDevel = "gateway-devel" |
|
| 66 |
+ keyDevel = "gateway-devel" |
|
| 68 | 67 |
) |
| 69 | 68 |
|
| 70 | 69 |
func NewGatewayFrontend(workers worker.Infos, allowedRepositories []string) (frontend.Frontend, error) {
|
| ... | ... |
@@ -92,8 +91,8 @@ type gatewayFrontend struct {
|
| 92 | 92 |
func filterPrefix(opts map[string]string, pfx string) map[string]string {
|
| 93 | 93 |
m := map[string]string{}
|
| 94 | 94 |
for k, v := range opts {
|
| 95 |
- if strings.HasPrefix(k, pfx) {
|
|
| 96 |
- m[strings.TrimPrefix(k, pfx)] = v |
|
| 95 |
+ if after, ok := strings.CutPrefix(k, pfx); ok {
|
|
| 96 |
+ m[after] = v |
|
| 97 | 97 |
} |
| 98 | 98 |
} |
| 99 | 99 |
return m |
| ... | ... |
@@ -122,7 +121,7 @@ func (gf *gatewayFrontend) checkSourceIsAllowed(source string) error {
|
| 122 | 122 |
} |
| 123 | 123 |
|
| 124 | 124 |
func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, exec executor.Executor, opts map[string]string, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) (*frontend.Result, error) {
|
| 125 |
- source, ok := opts[keySource] |
|
| 125 |
+ source, ok := opts[frontend.KeySource] |
|
| 126 | 126 |
if !ok {
|
| 127 | 127 |
return nil, errors.Errorf("no source specified for gateway")
|
| 128 | 128 |
} |
| ... | ... |
@@ -1573,7 +1572,7 @@ func (lbf *llbBridgeForwarder) ExecProcess(srv pb.LLBBridge_ExecProcessServer) e |
| 1573 | 1573 |
}() |
| 1574 | 1574 |
dest := &outputWriter{
|
| 1575 | 1575 |
stream: srv, |
| 1576 |
- fd: uint32(fd), |
|
| 1576 |
+ fd: fd, |
|
| 1577 | 1577 |
processID: pid, |
| 1578 | 1578 |
} |
| 1579 | 1579 |
_, err := io.Copy(dest, file) |
| ... | ... |
@@ -1587,7 +1586,7 @@ func (lbf *llbBridgeForwarder) ExecProcess(srv pb.LLBBridge_ExecProcessServer) e |
| 1587 | 1587 |
ProcessID: pid, |
| 1588 | 1588 |
Input: &pb.ExecMessage_File{
|
| 1589 | 1589 |
File: &pb.FdMessage{
|
| 1590 |
- Fd: uint32(fd), |
|
| 1590 |
+ Fd: fd, |
|
| 1591 | 1591 |
EOF: true, |
| 1592 | 1592 |
}, |
| 1593 | 1593 |
}, |
| ... | ... |
@@ -44,7 +44,7 @@ type GrpcClient interface {
|
| 44 | 44 |
|
| 45 | 45 |
func New(ctx context.Context, opts map[string]string, session, product string, c pb.LLBBridgeClient, w []client.WorkerInfo) (GrpcClient, error) {
|
| 46 | 46 |
pingCtx, pingCancel := context.WithCancelCause(ctx) |
| 47 |
- pingCtx, _ = context.WithTimeoutCause(pingCtx, 15*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 47 |
+ pingCtx, _ = context.WithTimeoutCause(pingCtx, 15*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 48 | 48 |
defer pingCancel(errors.WithStack(context.Canceled)) |
| 49 | 49 |
resp, err := c.Ping(pingCtx, &pb.PingRequest{})
|
| 50 | 50 |
if err != nil {
|
| ... | ... |
@@ -32,7 +32,7 @@ type bufferedWriteCloser struct {
|
| 32 | 32 |
} |
| 33 | 33 |
|
| 34 | 34 |
func (bwc *bufferedWriteCloser) Close() error {
|
| 35 |
- if err := bwc.Writer.Flush(); err != nil {
|
|
| 35 |
+ if err := bwc.Flush(); err != nil {
|
|
| 36 | 36 |
return errors.WithStack(err) |
| 37 | 37 |
} |
| 38 | 38 |
return bwc.Closer.Close() |
| ... | ... |
@@ -59,10 +59,10 @@ func (wc *streamWriterCloser) Write(dt []byte) (int, error) {
|
| 59 | 59 |
return n1 + n2, nil |
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 |
- if err := wc.ClientStream.SendMsg(&BytesMessage{Data: dt}); err != nil {
|
|
| 62 |
+ if err := wc.SendMsg(&BytesMessage{Data: dt}); err != nil {
|
|
| 63 | 63 |
// SendMsg return EOF on remote errors |
| 64 | 64 |
if errors.Is(err, io.EOF) {
|
| 65 |
- if err := errors.WithStack(wc.ClientStream.RecvMsg(struct{}{})); err != nil {
|
|
| 65 |
+ if err := errors.WithStack(wc.RecvMsg(struct{}{})); err != nil {
|
|
| 66 | 66 |
return 0, err |
| 67 | 67 |
} |
| 68 | 68 |
} |
| ... | ... |
@@ -72,12 +72,12 @@ func (wc *streamWriterCloser) Write(dt []byte) (int, error) {
|
| 72 | 72 |
} |
| 73 | 73 |
|
| 74 | 74 |
func (wc *streamWriterCloser) Close() error {
|
| 75 |
- if err := wc.ClientStream.CloseSend(); err != nil {
|
|
| 75 |
+ if err := wc.CloseSend(); err != nil {
|
|
| 76 | 76 |
return errors.WithStack(err) |
| 77 | 77 |
} |
| 78 | 78 |
// block until receiver is done |
| 79 | 79 |
var bm BytesMessage |
| 80 |
- if err := wc.ClientStream.RecvMsg(&bm); err != io.EOF {
|
|
| 80 |
+ if err := wc.RecvMsg(&bm); !errors.Is(err, io.EOF) {
|
|
| 81 | 81 |
return errors.WithStack(err) |
| 82 | 82 |
} |
| 83 | 83 |
return nil |
| ... | ... |
@@ -336,8 +336,8 @@ func (sp *SyncTarget) DiffCopy(stream FileSend_DiffCopyServer) (err error) {
|
| 336 | 336 |
opts, _ := metadata.FromIncomingContext(stream.Context()) // if no metadata continue with empty object |
| 337 | 337 |
md := map[string]string{}
|
| 338 | 338 |
for k, v := range opts {
|
| 339 |
- if strings.HasPrefix(k, keyExporterMetaPrefix) {
|
|
| 340 |
- md[strings.TrimPrefix(k, keyExporterMetaPrefix)] = strings.Join(v, ",") |
|
| 339 |
+ if after, ok0 := strings.CutPrefix(k, keyExporterMetaPrefix); ok0 {
|
|
| 340 |
+ md[after] = strings.Join(v, ",") |
|
| 341 | 341 |
} |
| 342 | 342 |
} |
| 343 | 343 |
wc, err := f(md) |
| ... | ... |
@@ -73,7 +73,7 @@ func (sm *Manager) Any(ctx context.Context, g Group, f func(context.Context, str |
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 | 75 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 76 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 76 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 77 | 77 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 78 | 78 |
c, err := sm.Get(timeoutCtx, id, false) |
| 79 | 79 |
if err != nil {
|
| ... | ... |
@@ -94,7 +94,7 @@ func monitorHealth(ctx context.Context, cc *grpc.ClientConn, cancelConn func(err |
| 94 | 94 |
timeout := time.Duration(math.Max(float64(defaultHealthcheckDuration), float64(lastHealthcheckDuration)*1.5)) |
| 95 | 95 |
|
| 96 | 96 |
ctx, cancel := context.WithCancelCause(ctx) |
| 97 |
- ctx, _ = context.WithTimeoutCause(ctx, timeout, errors.WithStack(context.DeadlineExceeded)) |
|
| 97 |
+ ctx, _ = context.WithTimeoutCause(ctx, timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 98 | 98 |
_, err := healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{})
|
| 99 | 99 |
cancel(errors.WithStack(context.Canceled)) |
| 100 | 100 |
|
| ... | ... |
@@ -2,6 +2,7 @@ package grpchijack |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
+ "errors" |
|
| 5 | 6 |
"io" |
| 6 | 7 |
"net" |
| 7 | 8 |
"strings" |
| ... | ... |
@@ -112,7 +113,7 @@ func (c *conn) Close() (err error) {
|
| 112 | 112 |
m.Data = c.buf |
| 113 | 113 |
err = c.stream.RecvMsg(m) |
| 114 | 114 |
if err != nil {
|
| 115 |
- if err != io.EOF {
|
|
| 115 |
+ if !errors.Is(err, io.EOF) {
|
|
| 116 | 116 |
c.readMu.Unlock() |
| 117 | 117 |
return |
| 118 | 118 |
} |
| ... | ... |
@@ -21,7 +21,7 @@ func Copy(ctx context.Context, conn io.ReadWriteCloser, stream Stream, closeStre |
| 21 | 21 |
p := &BytesMessage{}
|
| 22 | 22 |
for {
|
| 23 | 23 |
if err := stream.RecvMsg(p); err != nil {
|
| 24 |
- if err == io.EOF {
|
|
| 24 |
+ if errors.Is(err, io.EOF) {
|
|
| 25 | 25 |
// indicates client performed CloseSend, but they may still be |
| 26 | 26 |
// reading data |
| 27 | 27 |
if closeWriter, ok := conn.(interface {
|
| ... | ... |
@@ -55,7 +55,7 @@ func Copy(ctx context.Context, conn io.ReadWriteCloser, stream Stream, closeStre |
| 55 | 55 |
buf := make([]byte, 32*1024) |
| 56 | 56 |
n, err := conn.Read(buf) |
| 57 | 57 |
switch {
|
| 58 |
- case err == io.EOF: |
|
| 58 |
+ case errors.Is(err, io.EOF): |
|
| 59 | 59 |
if closeStream != nil {
|
| 60 | 60 |
closeStream() |
| 61 | 61 |
} |
| ... | ... |
@@ -40,7 +40,7 @@ func (s *server) run(ctx context.Context, l net.Listener, id string) error {
|
| 40 | 40 |
|
| 41 | 41 |
opts := make(map[string][]string) |
| 42 | 42 |
opts[KeySSHID] = []string{id}
|
| 43 |
- ctx = metadata.NewOutgoingContext(ctx, opts) |
|
| 43 |
+ ctx := metadata.NewOutgoingContext(ctx, opts) |
|
| 44 | 44 |
|
| 45 | 45 |
stream, err := client.ForwardAgent(ctx) |
| 46 | 46 |
if err != nil {
|
| ... | ... |
@@ -166,10 +166,10 @@ func applierFor(dest Mountable, tryCrossSnapshotLink, userxattr bool) (_ *applie |
| 166 | 166 |
|
| 167 | 167 |
if overlay.IsOverlayMountType(mnt) {
|
| 168 | 168 |
for _, opt := range mnt.Options {
|
| 169 |
- if strings.HasPrefix(opt, "upperdir=") {
|
|
| 170 |
- a.root = strings.TrimPrefix(opt, "upperdir=") |
|
| 171 |
- } else if strings.HasPrefix(opt, "lowerdir=") {
|
|
| 172 |
- a.lowerdirs = strings.Split(strings.TrimPrefix(opt, "lowerdir="), ":") |
|
| 169 |
+ if after, ok := strings.CutPrefix(opt, "upperdir="); ok {
|
|
| 170 |
+ a.root = after |
|
| 171 |
+ } else if after, ok := strings.CutPrefix(opt, "lowerdir="); ok {
|
|
| 172 |
+ a.lowerdirs = strings.Split(after, ":") |
|
| 173 | 173 |
} |
| 174 | 174 |
} |
| 175 | 175 |
if a.root == "" {
|
| ... | ... |
@@ -307,8 +307,8 @@ func (s *Store) emptyBranchWithParents(tx *bolt.Tx, id []byte) error {
|
| 307 | 307 |
} |
| 308 | 308 |
|
| 309 | 309 |
// intentionally ignoring errors |
| 310 |
- tx.Bucket([]byte(linksBucket)).DeleteBucket([]byte(id)) |
|
| 311 |
- tx.Bucket([]byte(resultBucket)).DeleteBucket([]byte(id)) |
|
| 310 |
+ tx.Bucket([]byte(linksBucket)).DeleteBucket(id) |
|
| 311 |
+ tx.Bucket([]byte(resultBucket)).DeleteBucket(id) |
|
| 312 | 312 |
|
| 313 | 313 |
return nil |
| 314 | 314 |
} |
| ... | ... |
@@ -360,7 +360,7 @@ func (s *Store) WalkLinks(id string, link solver.CacheInfoLink, fn func(id strin |
| 360 | 360 |
} |
| 361 | 361 |
index := bytes.Join([][]byte{dt, {}}, []byte("@"))
|
| 362 | 362 |
c := b.Cursor() |
| 363 |
- k, _ := c.Seek([]byte(index)) |
|
| 363 |
+ k, _ := c.Seek(index) |
|
| 364 | 364 |
for {
|
| 365 | 365 |
if k != nil && bytes.HasPrefix(k, index) {
|
| 366 | 366 |
target := bytes.TrimPrefix(k, index) |
| ... | ... |
@@ -388,7 +388,7 @@ func (c *cacheManager) ensurePersistentKey(k *CacheKey) error {
|
| 388 | 388 |
for _, ck := range deps {
|
| 389 | 389 |
l := CacheInfoLink{
|
| 390 | 390 |
Input: Index(i), |
| 391 |
- Output: Index(k.Output()), |
|
| 391 |
+ Output: k.Output(), |
|
| 392 | 392 |
Digest: k.Digest(), |
| 393 | 393 |
Selector: ck.Selector, |
| 394 | 394 |
} |
| ... | ... |
@@ -415,7 +415,7 @@ func (c *cacheManager) getIDFromDeps(k *CacheKey) string {
|
| 415 | 415 |
m2 := make(map[string]struct{})
|
| 416 | 416 |
if err := c.backend.WalkLinks(c.getID(ck.CacheKey.CacheKey), CacheInfoLink{
|
| 417 | 417 |
Input: Index(i), |
| 418 |
- Output: Index(k.Output()), |
|
| 418 |
+ Output: k.Output(), |
|
| 419 | 419 |
Digest: k.Digest(), |
| 420 | 420 |
Selector: ck.Selector, |
| 421 | 421 |
}, func(id string) error {
|
| ... | ... |
@@ -131,7 +131,6 @@ func (cm *combinedCacheManager) Records(ctx context.Context, ck *CacheKey) ([]*C |
| 131 | 131 |
|
| 132 | 132 |
eg, _ := errgroup.WithContext(context.TODO()) |
| 133 | 133 |
for _, c := range cms {
|
| 134 |
- c := c |
|
| 135 | 134 |
eg.Go(func() error {
|
| 136 | 135 |
recs, err := c.Records(ctx, ck) |
| 137 | 136 |
if err != nil {
|
| ... | ... |
@@ -154,19 +154,20 @@ func debugSchedulerPreUnparkSlow(e *edge, inc []pipeSender, updates, allPipes [] |
| 154 | 154 |
} |
| 155 | 155 |
|
| 156 | 156 |
for i, up := range updates {
|
| 157 |
- if up == e.cacheMapReq {
|
|
| 157 |
+ switch up {
|
|
| 158 |
+ case e.cacheMapReq: |
|
| 158 | 159 |
log. |
| 159 | 160 |
WithField("update_index", i).
|
| 160 | 161 |
WithField("update_pointer", up).
|
| 161 | 162 |
WithField("update_complete", up.Status().Completed).
|
| 162 | 163 |
Debug("> update cacheMapReq")
|
| 163 |
- } else if up == e.execReq {
|
|
| 164 |
+ case e.execReq: |
|
| 164 | 165 |
log. |
| 165 | 166 |
WithField("update_index", i).
|
| 166 | 167 |
WithField("update_pointer", up).
|
| 167 | 168 |
WithField("update_complete", up.Status().Completed).
|
| 168 | 169 |
Debug("> update execReq")
|
| 169 |
- } else {
|
|
| 170 |
+ default: |
|
| 170 | 171 |
st, ok := up.Status().Value.(*edgeState) |
| 171 | 172 |
if ok {
|
| 172 | 173 |
index := -1 |
| ... | ... |
@@ -658,7 +658,7 @@ func (e *edge) processDepReq(dep *dep) (depChanged bool) {
|
| 658 | 658 |
newKeys := state.keys[len(dep.keys):] |
| 659 | 659 |
if e.cacheMap != nil {
|
| 660 | 660 |
e.probeCache(dep, withSelector(newKeys, e.cacheMap.Deps[dep.index].Selector)) |
| 661 |
- dep.edgeState.keys = state.keys |
|
| 661 |
+ dep.keys = state.keys |
|
| 662 | 662 |
if e.allDepsHaveKeys(false) {
|
| 663 | 663 |
e.keysDidChange = true |
| 664 | 664 |
} |
| ... | ... |
@@ -119,6 +119,59 @@ func (x *Source) GetRanges() []*pb.Range {
|
| 119 | 119 |
return nil |
| 120 | 120 |
} |
| 121 | 121 |
|
| 122 |
+type Frontend struct {
|
|
| 123 |
+ state protoimpl.MessageState |
|
| 124 |
+ sizeCache protoimpl.SizeCache |
|
| 125 |
+ unknownFields protoimpl.UnknownFields |
|
| 126 |
+ |
|
| 127 |
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // frontend name e.g. dockerfile.v0 or gateway.v0 |
|
| 128 |
+ Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` // used by the gateway frontend to identify the source, which corresponds to the image name |
|
| 129 |
+} |
|
| 130 |
+ |
|
| 131 |
+func (x *Frontend) Reset() {
|
|
| 132 |
+ *x = Frontend{}
|
|
| 133 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[2] |
|
| 134 |
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
|
| 135 |
+ ms.StoreMessageInfo(mi) |
|
| 136 |
+} |
|
| 137 |
+ |
|
| 138 |
+func (x *Frontend) String() string {
|
|
| 139 |
+ return protoimpl.X.MessageStringOf(x) |
|
| 140 |
+} |
|
| 141 |
+ |
|
| 142 |
+func (*Frontend) ProtoMessage() {}
|
|
| 143 |
+ |
|
| 144 |
+func (x *Frontend) ProtoReflect() protoreflect.Message {
|
|
| 145 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[2] |
|
| 146 |
+ if x != nil {
|
|
| 147 |
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
|
| 148 |
+ if ms.LoadMessageInfo() == nil {
|
|
| 149 |
+ ms.StoreMessageInfo(mi) |
|
| 150 |
+ } |
|
| 151 |
+ return ms |
|
| 152 |
+ } |
|
| 153 |
+ return mi.MessageOf(x) |
|
| 154 |
+} |
|
| 155 |
+ |
|
| 156 |
+// Deprecated: Use Frontend.ProtoReflect.Descriptor instead. |
|
| 157 |
+func (*Frontend) Descriptor() ([]byte, []int) {
|
|
| 158 |
+ return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{2}
|
|
| 159 |
+} |
|
| 160 |
+ |
|
| 161 |
+func (x *Frontend) GetName() string {
|
|
| 162 |
+ if x != nil {
|
|
| 163 |
+ return x.Name |
|
| 164 |
+ } |
|
| 165 |
+ return "" |
|
| 166 |
+} |
|
| 167 |
+ |
|
| 168 |
+func (x *Frontend) GetSource() string {
|
|
| 169 |
+ if x != nil {
|
|
| 170 |
+ return x.Source |
|
| 171 |
+ } |
|
| 172 |
+ return "" |
|
| 173 |
+} |
|
| 174 |
+ |
|
| 122 | 175 |
type FrontendCap struct {
|
| 123 | 176 |
state protoimpl.MessageState |
| 124 | 177 |
sizeCache protoimpl.SizeCache |
| ... | ... |
@@ -129,7 +182,7 @@ type FrontendCap struct {
|
| 129 | 129 |
|
| 130 | 130 |
func (x *FrontendCap) Reset() {
|
| 131 | 131 |
*x = FrontendCap{}
|
| 132 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[2] |
|
| 132 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[3] |
|
| 133 | 133 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 134 | 134 |
ms.StoreMessageInfo(mi) |
| 135 | 135 |
} |
| ... | ... |
@@ -141,7 +194,7 @@ func (x *FrontendCap) String() string {
|
| 141 | 141 |
func (*FrontendCap) ProtoMessage() {}
|
| 142 | 142 |
|
| 143 | 143 |
func (x *FrontendCap) ProtoReflect() protoreflect.Message {
|
| 144 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[2] |
|
| 144 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[3] |
|
| 145 | 145 |
if x != nil {
|
| 146 | 146 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 147 | 147 |
if ms.LoadMessageInfo() == nil {
|
| ... | ... |
@@ -154,7 +207,7 @@ func (x *FrontendCap) ProtoReflect() protoreflect.Message {
|
| 154 | 154 |
|
| 155 | 155 |
// Deprecated: Use FrontendCap.ProtoReflect.Descriptor instead. |
| 156 | 156 |
func (*FrontendCap) Descriptor() ([]byte, []int) {
|
| 157 |
- return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{2}
|
|
| 157 |
+ return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{3}
|
|
| 158 | 158 |
} |
| 159 | 159 |
|
| 160 | 160 |
func (x *FrontendCap) GetName() string {
|
| ... | ... |
@@ -174,7 +227,7 @@ type Subrequest struct {
|
| 174 | 174 |
|
| 175 | 175 |
func (x *Subrequest) Reset() {
|
| 176 | 176 |
*x = Subrequest{}
|
| 177 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[3] |
|
| 177 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[4] |
|
| 178 | 178 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 179 | 179 |
ms.StoreMessageInfo(mi) |
| 180 | 180 |
} |
| ... | ... |
@@ -186,7 +239,7 @@ func (x *Subrequest) String() string {
|
| 186 | 186 |
func (*Subrequest) ProtoMessage() {}
|
| 187 | 187 |
|
| 188 | 188 |
func (x *Subrequest) ProtoReflect() protoreflect.Message {
|
| 189 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[3] |
|
| 189 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[4] |
|
| 190 | 190 |
if x != nil {
|
| 191 | 191 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 192 | 192 |
if ms.LoadMessageInfo() == nil {
|
| ... | ... |
@@ -199,7 +252,7 @@ func (x *Subrequest) ProtoReflect() protoreflect.Message {
|
| 199 | 199 |
|
| 200 | 200 |
// Deprecated: Use Subrequest.ProtoReflect.Descriptor instead. |
| 201 | 201 |
func (*Subrequest) Descriptor() ([]byte, []int) {
|
| 202 |
- return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{3}
|
|
| 202 |
+ return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{4}
|
|
| 203 | 203 |
} |
| 204 | 204 |
|
| 205 | 205 |
func (x *Subrequest) GetName() string {
|
| ... | ... |
@@ -227,7 +280,7 @@ type Solve struct {
|
| 227 | 227 |
|
| 228 | 228 |
func (x *Solve) Reset() {
|
| 229 | 229 |
*x = Solve{}
|
| 230 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[4] |
|
| 230 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[5] |
|
| 231 | 231 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 232 | 232 |
ms.StoreMessageInfo(mi) |
| 233 | 233 |
} |
| ... | ... |
@@ -239,7 +292,7 @@ func (x *Solve) String() string {
|
| 239 | 239 |
func (*Solve) ProtoMessage() {}
|
| 240 | 240 |
|
| 241 | 241 |
func (x *Solve) ProtoReflect() protoreflect.Message {
|
| 242 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[4] |
|
| 242 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[5] |
|
| 243 | 243 |
if x != nil {
|
| 244 | 244 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 245 | 245 |
if ms.LoadMessageInfo() == nil {
|
| ... | ... |
@@ -252,7 +305,7 @@ func (x *Solve) ProtoReflect() protoreflect.Message {
|
| 252 | 252 |
|
| 253 | 253 |
// Deprecated: Use Solve.ProtoReflect.Descriptor instead. |
| 254 | 254 |
func (*Solve) Descriptor() ([]byte, []int) {
|
| 255 |
- return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{4}
|
|
| 255 |
+ return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{5}
|
|
| 256 | 256 |
} |
| 257 | 257 |
|
| 258 | 258 |
func (x *Solve) GetInputIDs() []string {
|
| ... | ... |
@@ -331,7 +384,7 @@ type FileAction struct {
|
| 331 | 331 |
|
| 332 | 332 |
func (x *FileAction) Reset() {
|
| 333 | 333 |
*x = FileAction{}
|
| 334 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[5] |
|
| 334 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[6] |
|
| 335 | 335 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 336 | 336 |
ms.StoreMessageInfo(mi) |
| 337 | 337 |
} |
| ... | ... |
@@ -343,7 +396,7 @@ func (x *FileAction) String() string {
|
| 343 | 343 |
func (*FileAction) ProtoMessage() {}
|
| 344 | 344 |
|
| 345 | 345 |
func (x *FileAction) ProtoReflect() protoreflect.Message {
|
| 346 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[5] |
|
| 346 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[6] |
|
| 347 | 347 |
if x != nil {
|
| 348 | 348 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 349 | 349 |
if ms.LoadMessageInfo() == nil {
|
| ... | ... |
@@ -356,7 +409,7 @@ func (x *FileAction) ProtoReflect() protoreflect.Message {
|
| 356 | 356 |
|
| 357 | 357 |
// Deprecated: Use FileAction.ProtoReflect.Descriptor instead. |
| 358 | 358 |
func (*FileAction) Descriptor() ([]byte, []int) {
|
| 359 |
- return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{5}
|
|
| 359 |
+ return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{6}
|
|
| 360 | 360 |
} |
| 361 | 361 |
|
| 362 | 362 |
func (x *FileAction) GetIndex() int64 {
|
| ... | ... |
@@ -377,7 +430,7 @@ type ContentCache struct {
|
| 377 | 377 |
|
| 378 | 378 |
func (x *ContentCache) Reset() {
|
| 379 | 379 |
*x = ContentCache{}
|
| 380 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[6] |
|
| 380 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[7] |
|
| 381 | 381 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 382 | 382 |
ms.StoreMessageInfo(mi) |
| 383 | 383 |
} |
| ... | ... |
@@ -389,7 +442,7 @@ func (x *ContentCache) String() string {
|
| 389 | 389 |
func (*ContentCache) ProtoMessage() {}
|
| 390 | 390 |
|
| 391 | 391 |
func (x *ContentCache) ProtoReflect() protoreflect.Message {
|
| 392 |
- mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[6] |
|
| 392 |
+ mi := &file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[7] |
|
| 393 | 393 |
if x != nil {
|
| 394 | 394 |
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
| 395 | 395 |
if ms.LoadMessageInfo() == nil {
|
| ... | ... |
@@ -402,7 +455,7 @@ func (x *ContentCache) ProtoReflect() protoreflect.Message {
|
| 402 | 402 |
|
| 403 | 403 |
// Deprecated: Use ContentCache.ProtoReflect.Descriptor instead. |
| 404 | 404 |
func (*ContentCache) Descriptor() ([]byte, []int) {
|
| 405 |
- return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{6}
|
|
| 405 |
+ return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP(), []int{7}
|
|
| 406 | 406 |
} |
| 407 | 407 |
|
| 408 | 408 |
func (x *ContentCache) GetIndex() int64 {
|
| ... | ... |
@@ -429,39 +482,42 @@ var file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDesc = []byte{
|
| 429 | 429 |
0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x21, |
| 430 | 430 |
0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, |
| 431 | 431 |
0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, |
| 432 |
- 0x73, 0x22, 0x21, 0x0a, 0x0b, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x43, 0x61, 0x70, |
|
| 433 |
- 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, |
|
| 434 |
- 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x20, 0x0a, 0x0a, 0x53, 0x75, 0x62, 0x72, 0x65, 0x71, 0x75, 0x65, |
|
| 435 |
- 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, |
|
| 436 |
- 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xbf, 0x02, 0x0a, 0x05, 0x53, 0x6f, 0x6c, 0x76, 0x65, |
|
| 437 |
- 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, |
|
| 438 |
- 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x44, 0x73, 0x12, 0x1a, 0x0a, 0x08, |
|
| 439 |
- 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, |
|
| 440 |
- 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x73, 0x12, 0x16, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, |
|
| 441 |
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, |
|
| 442 |
- 0x12, 0x29, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, |
|
| 443 |
- 0x2e, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x41, 0x63, 0x74, |
|
| 444 |
- 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x63, |
|
| 445 |
- 0x61, 0x63, 0x68, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x72, 0x72, |
|
| 446 |
- 0x64, 0x65, 0x66, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x63, 0x68, |
|
| 447 |
- 0x65, 0x48, 0x00, 0x52, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x64, 0x65, |
|
| 448 |
- 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, |
|
| 449 |
- 0x1f, 0x2e, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x2e, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x2e, |
|
| 450 |
- 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, |
|
| 451 |
- 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x3e, 0x0a, |
|
| 452 |
- 0x10, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, |
|
| 453 |
- 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, |
|
| 454 |
- 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, |
|
| 455 |
- 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x09, 0x0a, |
|
| 456 |
- 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x22, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, |
|
| 457 |
- 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, |
|
| 458 |
- 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x24, 0x0a, 0x0c, |
|
| 459 |
- 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x14, 0x0a, 0x05, |
|
| 460 |
- 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, |
|
| 461 |
- 0x65, 0x78, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, |
|
| 462 |
- 0x2f, 0x6d, 0x6f, 0x62, 0x79, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2f, 0x73, |
|
| 463 |
- 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2f, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x62, 0x06, 0x70, |
|
| 464 |
- 0x72, 0x6f, 0x74, 0x6f, 0x33, |
|
| 432 |
+ 0x73, 0x22, 0x36, 0x0a, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, |
|
| 433 |
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, |
|
| 434 |
+ 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, |
|
| 435 |
+ 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x21, 0x0a, 0x0b, 0x46, 0x72, 0x6f, |
|
| 436 |
+ 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x43, 0x61, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, |
|
| 437 |
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x20, 0x0a, 0x0a, |
|
| 438 |
+ 0x53, 0x75, 0x62, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, |
|
| 439 |
+ 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xbf, |
|
| 440 |
+ 0x02, 0x0a, 0x05, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x70, 0x75, |
|
| 441 |
+ 0x74, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x70, 0x75, |
|
| 442 |
+ 0x74, 0x49, 0x44, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x73, |
|
| 443 |
+ 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x73, |
|
| 444 |
+ 0x12, 0x16, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x70, |
|
| 445 |
+ 0x62, 0x2e, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x29, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, |
|
| 446 |
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, |
|
| 447 |
+ 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x66, |
|
| 448 |
+ 0x69, 0x6c, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, 0x05, 0x20, 0x01, |
|
| 449 |
+ 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x2e, 0x43, 0x6f, 0x6e, |
|
| 450 |
+ 0x74, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x48, 0x00, 0x52, 0x05, 0x63, 0x61, 0x63, |
|
| 451 |
+ 0x68, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, |
|
| 452 |
+ 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, |
|
| 453 |
+ 0x73, 0x2e, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, |
|
| 454 |
+ 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, |
|
| 455 |
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, |
|
| 456 |
+ 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, |
|
| 457 |
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, |
|
| 458 |
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, |
|
| 459 |
+ 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, |
|
| 460 |
+ 0x22, 0x22, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, |
|
| 461 |
+ 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x69, |
|
| 462 |
+ 0x6e, 0x64, 0x65, 0x78, 0x22, 0x24, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x43, |
|
| 463 |
+ 0x61, 0x63, 0x68, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, |
|
| 464 |
+ 0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, |
|
| 465 |
+ 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, 0x62, 0x79, 0x2f, 0x62, 0x75, |
|
| 466 |
+ 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2f, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2f, 0x65, 0x72, |
|
| 467 |
+ 0x72, 0x64, 0x65, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, |
|
| 465 | 468 |
} |
| 466 | 469 |
|
| 467 | 470 |
var ( |
| ... | ... |
@@ -476,27 +532,28 @@ func file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescGZIP() [] |
| 476 | 476 |
return file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDescData |
| 477 | 477 |
} |
| 478 | 478 |
|
| 479 |
-var file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes = make([]protoimpl.MessageInfo, 8) |
|
| 479 |
+var file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes = make([]protoimpl.MessageInfo, 9) |
|
| 480 | 480 |
var file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_goTypes = []any{
|
| 481 | 481 |
(*Vertex)(nil), // 0: errdefs.Vertex |
| 482 | 482 |
(*Source)(nil), // 1: errdefs.Source |
| 483 |
- (*FrontendCap)(nil), // 2: errdefs.FrontendCap |
|
| 484 |
- (*Subrequest)(nil), // 3: errdefs.Subrequest |
|
| 485 |
- (*Solve)(nil), // 4: errdefs.Solve |
|
| 486 |
- (*FileAction)(nil), // 5: errdefs.FileAction |
|
| 487 |
- (*ContentCache)(nil), // 6: errdefs.ContentCache |
|
| 488 |
- nil, // 7: errdefs.Solve.DescriptionEntry |
|
| 489 |
- (*pb.SourceInfo)(nil), // 8: pb.SourceInfo |
|
| 490 |
- (*pb.Range)(nil), // 9: pb.Range |
|
| 491 |
- (*pb.Op)(nil), // 10: pb.Op |
|
| 483 |
+ (*Frontend)(nil), // 2: errdefs.Frontend |
|
| 484 |
+ (*FrontendCap)(nil), // 3: errdefs.FrontendCap |
|
| 485 |
+ (*Subrequest)(nil), // 4: errdefs.Subrequest |
|
| 486 |
+ (*Solve)(nil), // 5: errdefs.Solve |
|
| 487 |
+ (*FileAction)(nil), // 6: errdefs.FileAction |
|
| 488 |
+ (*ContentCache)(nil), // 7: errdefs.ContentCache |
|
| 489 |
+ nil, // 8: errdefs.Solve.DescriptionEntry |
|
| 490 |
+ (*pb.SourceInfo)(nil), // 9: pb.SourceInfo |
|
| 491 |
+ (*pb.Range)(nil), // 10: pb.Range |
|
| 492 |
+ (*pb.Op)(nil), // 11: pb.Op |
|
| 492 | 493 |
} |
| 493 | 494 |
var file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_depIdxs = []int32{
|
| 494 |
- 8, // 0: errdefs.Source.info:type_name -> pb.SourceInfo |
|
| 495 |
- 9, // 1: errdefs.Source.ranges:type_name -> pb.Range |
|
| 496 |
- 10, // 2: errdefs.Solve.op:type_name -> pb.Op |
|
| 497 |
- 5, // 3: errdefs.Solve.file:type_name -> errdefs.FileAction |
|
| 498 |
- 6, // 4: errdefs.Solve.cache:type_name -> errdefs.ContentCache |
|
| 499 |
- 7, // 5: errdefs.Solve.description:type_name -> errdefs.Solve.DescriptionEntry |
|
| 495 |
+ 9, // 0: errdefs.Source.info:type_name -> pb.SourceInfo |
|
| 496 |
+ 10, // 1: errdefs.Source.ranges:type_name -> pb.Range |
|
| 497 |
+ 11, // 2: errdefs.Solve.op:type_name -> pb.Op |
|
| 498 |
+ 6, // 3: errdefs.Solve.file:type_name -> errdefs.FileAction |
|
| 499 |
+ 7, // 4: errdefs.Solve.cache:type_name -> errdefs.ContentCache |
|
| 500 |
+ 8, // 5: errdefs.Solve.description:type_name -> errdefs.Solve.DescriptionEntry |
|
| 500 | 501 |
6, // [6:6] is the sub-list for method output_type |
| 501 | 502 |
6, // [6:6] is the sub-list for method input_type |
| 502 | 503 |
6, // [6:6] is the sub-list for extension type_name |
| ... | ... |
@@ -509,7 +566,7 @@ func file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_init() {
|
| 509 | 509 |
if File_github_com_moby_buildkit_solver_errdefs_errdefs_proto != nil {
|
| 510 | 510 |
return |
| 511 | 511 |
} |
| 512 |
- file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[4].OneofWrappers = []any{
|
|
| 512 |
+ file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_msgTypes[5].OneofWrappers = []any{
|
|
| 513 | 513 |
(*Solve_File)(nil), |
| 514 | 514 |
(*Solve_Cache)(nil), |
| 515 | 515 |
} |
| ... | ... |
@@ -519,7 +576,7 @@ func file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_init() {
|
| 519 | 519 |
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
| 520 | 520 |
RawDescriptor: file_github_com_moby_buildkit_solver_errdefs_errdefs_proto_rawDesc, |
| 521 | 521 |
NumEnums: 0, |
| 522 |
- NumMessages: 8, |
|
| 522 |
+ NumMessages: 9, |
|
| 523 | 523 |
NumExtensions: 0, |
| 524 | 524 |
NumServices: 0, |
| 525 | 525 |
}, |
| ... | ... |
@@ -15,6 +15,11 @@ message Source {
|
| 15 | 15 |
repeated pb.Range ranges = 2; |
| 16 | 16 |
} |
| 17 | 17 |
|
| 18 |
+message Frontend {
|
|
| 19 |
+ string name = 1; // frontend name e.g. dockerfile.v0 or gateway.v0 |
|
| 20 |
+ string source = 2; // used by the gateway frontend to identify the source, which corresponds to the image name |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 18 | 23 |
message FrontendCap {
|
| 19 | 24 |
string name = 1; |
| 20 | 25 |
} |
| ... | ... |
@@ -61,6 +61,24 @@ func (m *Source) CloneMessageVT() proto.Message {
|
| 61 | 61 |
return m.CloneVT() |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
+func (m *Frontend) CloneVT() *Frontend {
|
|
| 65 |
+ if m == nil {
|
|
| 66 |
+ return (*Frontend)(nil) |
|
| 67 |
+ } |
|
| 68 |
+ r := new(Frontend) |
|
| 69 |
+ r.Name = m.Name |
|
| 70 |
+ r.Source = m.Source |
|
| 71 |
+ if len(m.unknownFields) > 0 {
|
|
| 72 |
+ r.unknownFields = make([]byte, len(m.unknownFields)) |
|
| 73 |
+ copy(r.unknownFields, m.unknownFields) |
|
| 74 |
+ } |
|
| 75 |
+ return r |
|
| 76 |
+} |
|
| 77 |
+ |
|
| 78 |
+func (m *Frontend) CloneMessageVT() proto.Message {
|
|
| 79 |
+ return m.CloneVT() |
|
| 80 |
+} |
|
| 81 |
+ |
|
| 64 | 82 |
func (m *FrontendCap) CloneVT() *FrontendCap {
|
| 65 | 83 |
if m == nil {
|
| 66 | 84 |
return (*FrontendCap)(nil) |
| ... | ... |
@@ -239,6 +257,28 @@ func (this *Source) EqualMessageVT(thatMsg proto.Message) bool {
|
| 239 | 239 |
} |
| 240 | 240 |
return this.EqualVT(that) |
| 241 | 241 |
} |
| 242 |
+func (this *Frontend) EqualVT(that *Frontend) bool {
|
|
| 243 |
+ if this == that {
|
|
| 244 |
+ return true |
|
| 245 |
+ } else if this == nil || that == nil {
|
|
| 246 |
+ return false |
|
| 247 |
+ } |
|
| 248 |
+ if this.Name != that.Name {
|
|
| 249 |
+ return false |
|
| 250 |
+ } |
|
| 251 |
+ if this.Source != that.Source {
|
|
| 252 |
+ return false |
|
| 253 |
+ } |
|
| 254 |
+ return string(this.unknownFields) == string(that.unknownFields) |
|
| 255 |
+} |
|
| 256 |
+ |
|
| 257 |
+func (this *Frontend) EqualMessageVT(thatMsg proto.Message) bool {
|
|
| 258 |
+ that, ok := thatMsg.(*Frontend) |
|
| 259 |
+ if !ok {
|
|
| 260 |
+ return false |
|
| 261 |
+ } |
|
| 262 |
+ return this.EqualVT(that) |
|
| 263 |
+} |
|
| 242 | 264 |
func (this *FrontendCap) EqualVT(that *FrontendCap) bool {
|
| 243 | 265 |
if this == that {
|
| 244 | 266 |
return true |
| ... | ... |
@@ -519,6 +559,53 @@ func (m *Source) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
| 519 | 519 |
return len(dAtA) - i, nil |
| 520 | 520 |
} |
| 521 | 521 |
|
| 522 |
+func (m *Frontend) MarshalVT() (dAtA []byte, err error) {
|
|
| 523 |
+ if m == nil {
|
|
| 524 |
+ return nil, nil |
|
| 525 |
+ } |
|
| 526 |
+ size := m.SizeVT() |
|
| 527 |
+ dAtA = make([]byte, size) |
|
| 528 |
+ n, err := m.MarshalToSizedBufferVT(dAtA[:size]) |
|
| 529 |
+ if err != nil {
|
|
| 530 |
+ return nil, err |
|
| 531 |
+ } |
|
| 532 |
+ return dAtA[:n], nil |
|
| 533 |
+} |
|
| 534 |
+ |
|
| 535 |
+func (m *Frontend) MarshalToVT(dAtA []byte) (int, error) {
|
|
| 536 |
+ size := m.SizeVT() |
|
| 537 |
+ return m.MarshalToSizedBufferVT(dAtA[:size]) |
|
| 538 |
+} |
|
| 539 |
+ |
|
| 540 |
+func (m *Frontend) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
|
| 541 |
+ if m == nil {
|
|
| 542 |
+ return 0, nil |
|
| 543 |
+ } |
|
| 544 |
+ i := len(dAtA) |
|
| 545 |
+ _ = i |
|
| 546 |
+ var l int |
|
| 547 |
+ _ = l |
|
| 548 |
+ if m.unknownFields != nil {
|
|
| 549 |
+ i -= len(m.unknownFields) |
|
| 550 |
+ copy(dAtA[i:], m.unknownFields) |
|
| 551 |
+ } |
|
| 552 |
+ if len(m.Source) > 0 {
|
|
| 553 |
+ i -= len(m.Source) |
|
| 554 |
+ copy(dAtA[i:], m.Source) |
|
| 555 |
+ i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Source))) |
|
| 556 |
+ i-- |
|
| 557 |
+ dAtA[i] = 0x12 |
|
| 558 |
+ } |
|
| 559 |
+ if len(m.Name) > 0 {
|
|
| 560 |
+ i -= len(m.Name) |
|
| 561 |
+ copy(dAtA[i:], m.Name) |
|
| 562 |
+ i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) |
|
| 563 |
+ i-- |
|
| 564 |
+ dAtA[i] = 0xa |
|
| 565 |
+ } |
|
| 566 |
+ return len(dAtA) - i, nil |
|
| 567 |
+} |
|
| 568 |
+ |
|
| 522 | 569 |
func (m *FrontendCap) MarshalVT() (dAtA []byte, err error) {
|
| 523 | 570 |
if m == nil {
|
| 524 | 571 |
return nil, nil |
| ... | ... |
@@ -844,6 +931,24 @@ func (m *Source) SizeVT() (n int) {
|
| 844 | 844 |
return n |
| 845 | 845 |
} |
| 846 | 846 |
|
| 847 |
+func (m *Frontend) SizeVT() (n int) {
|
|
| 848 |
+ if m == nil {
|
|
| 849 |
+ return 0 |
|
| 850 |
+ } |
|
| 851 |
+ var l int |
|
| 852 |
+ _ = l |
|
| 853 |
+ l = len(m.Name) |
|
| 854 |
+ if l > 0 {
|
|
| 855 |
+ n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) |
|
| 856 |
+ } |
|
| 857 |
+ l = len(m.Source) |
|
| 858 |
+ if l > 0 {
|
|
| 859 |
+ n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) |
|
| 860 |
+ } |
|
| 861 |
+ n += len(m.unknownFields) |
|
| 862 |
+ return n |
|
| 863 |
+} |
|
| 864 |
+ |
|
| 847 | 865 |
func (m *FrontendCap) SizeVT() (n int) {
|
| 848 | 866 |
if m == nil {
|
| 849 | 867 |
return 0 |
| ... | ... |
@@ -1167,6 +1272,121 @@ func (m *Source) UnmarshalVT(dAtA []byte) error {
|
| 1167 | 1167 |
} |
| 1168 | 1168 |
return nil |
| 1169 | 1169 |
} |
| 1170 |
+func (m *Frontend) UnmarshalVT(dAtA []byte) error {
|
|
| 1171 |
+ l := len(dAtA) |
|
| 1172 |
+ iNdEx := 0 |
|
| 1173 |
+ for iNdEx < l {
|
|
| 1174 |
+ preIndex := iNdEx |
|
| 1175 |
+ var wire uint64 |
|
| 1176 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1177 |
+ if shift >= 64 {
|
|
| 1178 |
+ return protohelpers.ErrIntOverflow |
|
| 1179 |
+ } |
|
| 1180 |
+ if iNdEx >= l {
|
|
| 1181 |
+ return io.ErrUnexpectedEOF |
|
| 1182 |
+ } |
|
| 1183 |
+ b := dAtA[iNdEx] |
|
| 1184 |
+ iNdEx++ |
|
| 1185 |
+ wire |= uint64(b&0x7F) << shift |
|
| 1186 |
+ if b < 0x80 {
|
|
| 1187 |
+ break |
|
| 1188 |
+ } |
|
| 1189 |
+ } |
|
| 1190 |
+ fieldNum := int32(wire >> 3) |
|
| 1191 |
+ wireType := int(wire & 0x7) |
|
| 1192 |
+ if wireType == 4 {
|
|
| 1193 |
+ return fmt.Errorf("proto: Frontend: wiretype end group for non-group")
|
|
| 1194 |
+ } |
|
| 1195 |
+ if fieldNum <= 0 {
|
|
| 1196 |
+ return fmt.Errorf("proto: Frontend: illegal tag %d (wire type %d)", fieldNum, wire)
|
|
| 1197 |
+ } |
|
| 1198 |
+ switch fieldNum {
|
|
| 1199 |
+ case 1: |
|
| 1200 |
+ if wireType != 2 {
|
|
| 1201 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
|
|
| 1202 |
+ } |
|
| 1203 |
+ var stringLen uint64 |
|
| 1204 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1205 |
+ if shift >= 64 {
|
|
| 1206 |
+ return protohelpers.ErrIntOverflow |
|
| 1207 |
+ } |
|
| 1208 |
+ if iNdEx >= l {
|
|
| 1209 |
+ return io.ErrUnexpectedEOF |
|
| 1210 |
+ } |
|
| 1211 |
+ b := dAtA[iNdEx] |
|
| 1212 |
+ iNdEx++ |
|
| 1213 |
+ stringLen |= uint64(b&0x7F) << shift |
|
| 1214 |
+ if b < 0x80 {
|
|
| 1215 |
+ break |
|
| 1216 |
+ } |
|
| 1217 |
+ } |
|
| 1218 |
+ intStringLen := int(stringLen) |
|
| 1219 |
+ if intStringLen < 0 {
|
|
| 1220 |
+ return protohelpers.ErrInvalidLength |
|
| 1221 |
+ } |
|
| 1222 |
+ postIndex := iNdEx + intStringLen |
|
| 1223 |
+ if postIndex < 0 {
|
|
| 1224 |
+ return protohelpers.ErrInvalidLength |
|
| 1225 |
+ } |
|
| 1226 |
+ if postIndex > l {
|
|
| 1227 |
+ return io.ErrUnexpectedEOF |
|
| 1228 |
+ } |
|
| 1229 |
+ m.Name = string(dAtA[iNdEx:postIndex]) |
|
| 1230 |
+ iNdEx = postIndex |
|
| 1231 |
+ case 2: |
|
| 1232 |
+ if wireType != 2 {
|
|
| 1233 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType)
|
|
| 1234 |
+ } |
|
| 1235 |
+ var stringLen uint64 |
|
| 1236 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1237 |
+ if shift >= 64 {
|
|
| 1238 |
+ return protohelpers.ErrIntOverflow |
|
| 1239 |
+ } |
|
| 1240 |
+ if iNdEx >= l {
|
|
| 1241 |
+ return io.ErrUnexpectedEOF |
|
| 1242 |
+ } |
|
| 1243 |
+ b := dAtA[iNdEx] |
|
| 1244 |
+ iNdEx++ |
|
| 1245 |
+ stringLen |= uint64(b&0x7F) << shift |
|
| 1246 |
+ if b < 0x80 {
|
|
| 1247 |
+ break |
|
| 1248 |
+ } |
|
| 1249 |
+ } |
|
| 1250 |
+ intStringLen := int(stringLen) |
|
| 1251 |
+ if intStringLen < 0 {
|
|
| 1252 |
+ return protohelpers.ErrInvalidLength |
|
| 1253 |
+ } |
|
| 1254 |
+ postIndex := iNdEx + intStringLen |
|
| 1255 |
+ if postIndex < 0 {
|
|
| 1256 |
+ return protohelpers.ErrInvalidLength |
|
| 1257 |
+ } |
|
| 1258 |
+ if postIndex > l {
|
|
| 1259 |
+ return io.ErrUnexpectedEOF |
|
| 1260 |
+ } |
|
| 1261 |
+ m.Source = string(dAtA[iNdEx:postIndex]) |
|
| 1262 |
+ iNdEx = postIndex |
|
| 1263 |
+ default: |
|
| 1264 |
+ iNdEx = preIndex |
|
| 1265 |
+ skippy, err := protohelpers.Skip(dAtA[iNdEx:]) |
|
| 1266 |
+ if err != nil {
|
|
| 1267 |
+ return err |
|
| 1268 |
+ } |
|
| 1269 |
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
|
|
| 1270 |
+ return protohelpers.ErrInvalidLength |
|
| 1271 |
+ } |
|
| 1272 |
+ if (iNdEx + skippy) > l {
|
|
| 1273 |
+ return io.ErrUnexpectedEOF |
|
| 1274 |
+ } |
|
| 1275 |
+ m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) |
|
| 1276 |
+ iNdEx += skippy |
|
| 1277 |
+ } |
|
| 1278 |
+ } |
|
| 1279 |
+ |
|
| 1280 |
+ if iNdEx > l {
|
|
| 1281 |
+ return io.ErrUnexpectedEOF |
|
| 1282 |
+ } |
|
| 1283 |
+ return nil |
|
| 1284 |
+} |
|
| 1170 | 1285 |
func (m *FrontendCap) UnmarshalVT(dAtA []byte) error {
|
| 1171 | 1286 |
l := len(dAtA) |
| 1172 | 1287 |
iNdEx := 0 |
| 1173 | 1288 |
deleted file mode 100644 |
| ... | ... |
@@ -1,41 +0,0 @@ |
| 1 |
-package errdefs |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- fmt "fmt" |
|
| 5 |
- |
|
| 6 |
- "github.com/containerd/typeurl/v2" |
|
| 7 |
- "github.com/moby/buildkit/util/grpcerrors" |
|
| 8 |
-) |
|
| 9 |
- |
|
| 10 |
-func init() {
|
|
| 11 |
- typeurl.Register((*FrontendCap)(nil), "github.com/moby/buildkit", "errdefs.FrontendCap+json") |
|
| 12 |
-} |
|
| 13 |
- |
|
| 14 |
-type UnsupportedFrontendCapError struct {
|
|
| 15 |
- *FrontendCap |
|
| 16 |
- error |
|
| 17 |
-} |
|
| 18 |
- |
|
| 19 |
-func (e *UnsupportedFrontendCapError) Error() string {
|
|
| 20 |
- msg := fmt.Sprintf("unsupported frontend capability %s", e.FrontendCap.Name)
|
|
| 21 |
- if e.error != nil {
|
|
| 22 |
- msg += ": " + e.error.Error() |
|
| 23 |
- } |
|
| 24 |
- return msg |
|
| 25 |
-} |
|
| 26 |
- |
|
| 27 |
-func (e *UnsupportedFrontendCapError) Unwrap() error {
|
|
| 28 |
- return e.error |
|
| 29 |
-} |
|
| 30 |
- |
|
| 31 |
-func (e *UnsupportedFrontendCapError) ToProto() grpcerrors.TypedErrorProto {
|
|
| 32 |
- return e.FrontendCap |
|
| 33 |
-} |
|
| 34 |
- |
|
| 35 |
-func NewUnsupportedFrontendCapError(name string) error {
|
|
| 36 |
- return &UnsupportedFrontendCapError{FrontendCap: &FrontendCap{Name: name}}
|
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-func (v *FrontendCap) WrapError(err error) error {
|
|
| 40 |
- return &UnsupportedFrontendCapError{error: err, FrontendCap: v}
|
|
| 41 |
-} |
| 42 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,50 @@ |
| 0 |
+package errdefs |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "errors" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/containerd/typeurl/v2" |
|
| 7 |
+ "github.com/moby/buildkit/util/grpcerrors" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+func init() {
|
|
| 11 |
+ typeurl.Register((*Frontend)(nil), "github.com/moby/buildkit", "errdefs.Frontend+json") |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+type FrontendError struct {
|
|
| 15 |
+ *Frontend |
|
| 16 |
+ error |
|
| 17 |
+} |
|
| 18 |
+ |
|
| 19 |
+func (e *FrontendError) Error() string {
|
|
| 20 |
+ // These can be nested, so avoid adding any details to the error message |
|
| 21 |
+ // if we already have an error. Otherwise the resulting error message |
|
| 22 |
+ // can be very long and not very useful. |
|
| 23 |
+ if e.error != nil {
|
|
| 24 |
+ return e.error.Error() |
|
| 25 |
+ } |
|
| 26 |
+ return fmt.Sprintf("frontend %s failed", e.Name)
|
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+func (e *FrontendError) Unwrap() error {
|
|
| 30 |
+ return e.error |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+func (e *FrontendError) ToProto() grpcerrors.TypedErrorProto {
|
|
| 34 |
+ return e.Frontend |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+func (v *Frontend) WrapError(err error) error {
|
|
| 38 |
+ return &FrontendError{error: err, Frontend: v}
|
|
| 39 |
+} |
|
| 40 |
+ |
|
| 41 |
+func Frontends(err error) []*Frontend {
|
|
| 42 |
+ var out []*Frontend |
|
| 43 |
+ var es *FrontendError |
|
| 44 |
+ if errors.As(err, &es) {
|
|
| 45 |
+ out = Frontends(es.Unwrap()) |
|
| 46 |
+ out = append(out, es.CloneVT()) |
|
| 47 |
+ } |
|
| 48 |
+ return out |
|
| 49 |
+} |
| 0 | 50 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,41 @@ |
| 0 |
+package errdefs |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ fmt "fmt" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/containerd/typeurl/v2" |
|
| 6 |
+ "github.com/moby/buildkit/util/grpcerrors" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func init() {
|
|
| 10 |
+ typeurl.Register((*FrontendCap)(nil), "github.com/moby/buildkit", "errdefs.FrontendCap+json") |
|
| 11 |
+} |
|
| 12 |
+ |
|
| 13 |
+type UnsupportedFrontendCapError struct {
|
|
| 14 |
+ *FrontendCap |
|
| 15 |
+ error |
|
| 16 |
+} |
|
| 17 |
+ |
|
| 18 |
+func (e *UnsupportedFrontendCapError) Error() string {
|
|
| 19 |
+ msg := fmt.Sprintf("unsupported frontend capability %s", e.Name)
|
|
| 20 |
+ if e.error != nil {
|
|
| 21 |
+ msg += ": " + e.error.Error() |
|
| 22 |
+ } |
|
| 23 |
+ return msg |
|
| 24 |
+} |
|
| 25 |
+ |
|
| 26 |
+func (e *UnsupportedFrontendCapError) Unwrap() error {
|
|
| 27 |
+ return e.error |
|
| 28 |
+} |
|
| 29 |
+ |
|
| 30 |
+func (e *UnsupportedFrontendCapError) ToProto() grpcerrors.TypedErrorProto {
|
|
| 31 |
+ return e.FrontendCap |
|
| 32 |
+} |
|
| 33 |
+ |
|
| 34 |
+func NewUnsupportedFrontendCapError(name string) error {
|
|
| 35 |
+ return &UnsupportedFrontendCapError{FrontendCap: &FrontendCap{Name: name}}
|
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+func (v *FrontendCap) WrapError(err error) error {
|
|
| 39 |
+ return &UnsupportedFrontendCapError{error: err, FrontendCap: v}
|
|
| 40 |
+} |
| ... | ... |
@@ -14,7 +14,7 @@ func init() {
|
| 14 | 14 |
typeurl.Register((*Solve)(nil), "github.com/moby/buildkit", "errdefs.Solve+json") |
| 15 | 15 |
} |
| 16 | 16 |
|
| 17 |
-//nolint:revive |
|
| 17 |
+//nolint:revive,staticcheck |
|
| 18 | 18 |
type IsSolve_Subject isSolve_Subject |
| 19 | 19 |
|
| 20 | 20 |
// SolveError will be returned when an error is encountered during a solve that |
| ... | ... |
@@ -14,34 +14,34 @@ func WithSource(err error, src *Source) error {
|
| 14 | 14 |
if err == nil {
|
| 15 | 15 |
return nil |
| 16 | 16 |
} |
| 17 |
- return &ErrorSource{Source: src, error: err}
|
|
| 17 |
+ return &SourceError{Source: src, error: err}
|
|
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 |
-type ErrorSource struct {
|
|
| 20 |
+type SourceError struct {
|
|
| 21 | 21 |
*Source |
| 22 | 22 |
error |
| 23 | 23 |
} |
| 24 | 24 |
|
| 25 |
-func (e *ErrorSource) Unwrap() error {
|
|
| 25 |
+func (e *SourceError) Unwrap() error {
|
|
| 26 | 26 |
return e.error |
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 |
-func (e *ErrorSource) ToProto() grpcerrors.TypedErrorProto {
|
|
| 29 |
+func (e *SourceError) ToProto() grpcerrors.TypedErrorProto {
|
|
| 30 | 30 |
return e.Source |
| 31 | 31 |
} |
| 32 | 32 |
|
| 33 | 33 |
func Sources(err error) []*Source {
|
| 34 | 34 |
var out []*Source |
| 35 |
- var es *ErrorSource |
|
| 35 |
+ var es *SourceError |
|
| 36 | 36 |
if errors.As(err, &es) {
|
| 37 | 37 |
out = Sources(es.Unwrap()) |
| 38 |
- out = append(out, es.Source.CloneVT()) |
|
| 38 |
+ out = append(out, es.CloneVT()) |
|
| 39 | 39 |
} |
| 40 | 40 |
return out |
| 41 | 41 |
} |
| 42 | 42 |
|
| 43 | 43 |
func (s *Source) WrapError(err error) error {
|
| 44 |
- return &ErrorSource{error: err, Source: s}
|
|
| 44 |
+ return &SourceError{error: err, Source: s}
|
|
| 45 | 45 |
} |
| 46 | 46 |
|
| 47 | 47 |
func (s *Source) Print(w io.Writer) error {
|
| ... | ... |
@@ -69,10 +69,7 @@ func (s *Source) Print(w io.Writer) error {
|
| 69 | 69 |
var p int |
| 70 | 70 |
|
| 71 | 71 |
prepadStart := start |
| 72 |
- for {
|
|
| 73 |
- if p >= pad {
|
|
| 74 |
- break |
|
| 75 |
- } |
|
| 72 |
+ for p < pad {
|
|
| 76 | 73 |
if start > 1 {
|
| 77 | 74 |
start-- |
| 78 | 75 |
p++ |
| ... | ... |
@@ -17,7 +17,7 @@ type UnsupportedSubrequestError struct {
|
| 17 | 17 |
} |
| 18 | 18 |
|
| 19 | 19 |
func (e *UnsupportedSubrequestError) Error() string {
|
| 20 |
- msg := fmt.Sprintf("unsupported request %s", e.Subrequest.Name)
|
|
| 20 |
+ msg := fmt.Sprintf("unsupported request %s", e.Name)
|
|
| 21 | 21 |
if e.error != nil {
|
| 22 | 22 |
msg += ": " + e.error.Error() |
| 23 | 23 |
} |
| ... | ... |
@@ -97,7 +97,7 @@ func (ei *edgeIndex) LoadOrStore(k *CacheKey, e *edge) *edge {
|
| 97 | 97 |
} |
| 98 | 98 |
} |
| 99 | 99 |
|
| 100 |
- if old != nil && !(!isIgnoreCache(old) && isIgnoreCache(e)) {
|
|
| 100 |
+ if old != nil && (isIgnoreCache(old) || !isIgnoreCache(e)) {
|
|
| 101 | 101 |
ei.enforceLinked(oldID, k) |
| 102 | 102 |
return old |
| 103 | 103 |
} |
| ... | ... |
@@ -190,7 +190,7 @@ func (ei *edgeIndex) getAllMatches(k *CacheKey) []string {
|
| 190 | 190 |
if i == 0 {
|
| 191 | 191 |
for _, d := range dd {
|
| 192 | 192 |
ll := CacheInfoLink{Input: Index(i), Digest: k.Digest(), Output: k.Output(), Selector: d.Selector}
|
| 193 |
- for _, ckID := range d.CacheKey.CacheKey.indexIDs {
|
|
| 193 |
+ for _, ckID := range d.CacheKey.indexIDs {
|
|
| 194 | 194 |
item, ok := ei.items[ckID] |
| 195 | 195 |
if ok {
|
| 196 | 196 |
for l := range item.links[ll] {
|
| ... | ... |
@@ -210,7 +210,7 @@ func (ei *edgeIndex) getAllMatches(k *CacheKey) []string {
|
| 210 | 210 |
found := false |
| 211 | 211 |
for _, d := range dd {
|
| 212 | 212 |
ll := CacheInfoLink{Input: Index(i), Digest: k.Digest(), Output: k.Output(), Selector: d.Selector}
|
| 213 |
- for _, ckID := range d.CacheKey.CacheKey.indexIDs {
|
|
| 213 |
+ for _, ckID := range d.CacheKey.indexIDs {
|
|
| 214 | 214 |
if item, ok := ei.items[ckID]; ok {
|
| 215 | 215 |
if l, ok := item.links[ll]; ok {
|
| 216 | 216 |
if _, ok := l[m]; ok {
|
| ... | ... |
@@ -625,7 +625,7 @@ func (jl *Solver) NewJob(id string) (*Job, error) {
|
| 625 | 625 |
|
| 626 | 626 |
func (jl *Solver) Get(id string) (*Job, error) {
|
| 627 | 627 |
ctx, cancel := context.WithCancelCause(context.Background()) |
| 628 |
- ctx, _ = context.WithTimeoutCause(ctx, 6*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 628 |
+ ctx, _ = context.WithTimeoutCause(ctx, 6*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 629 | 629 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 630 | 630 |
|
| 631 | 631 |
go func() {
|
| ... | ... |
@@ -265,7 +265,7 @@ func (rp *resultProxy) wrapError(err error) error {
|
| 265 | 265 |
var ve *errdefs.VertexError |
| 266 | 266 |
if errors.As(err, &ve) {
|
| 267 | 267 |
if rp.req.Definition.Source != nil {
|
| 268 |
- locs, ok := rp.req.Definition.Source.Locations[string(ve.Digest)] |
|
| 268 |
+ locs, ok := rp.req.Definition.Source.Locations[ve.Digest] |
|
| 269 | 269 |
if ok {
|
| 270 | 270 |
for _, loc := range locs.Locations {
|
| 271 | 271 |
err = errdefs.WithSource(err, &errdefs.Source{
|
| ... | ... |
@@ -157,49 +157,41 @@ func (m *Manager) parseDevice(dev *pb.CDIDevice, all []string) ([]string, error) |
| 157 | 157 |
|
| 158 | 158 |
kind, name, _ := strings.Cut(dev.Name, "=") |
| 159 | 159 |
|
| 160 |
- // validate kind |
|
| 161 |
- if vendor, class := parser.ParseQualifier(kind); vendor == "" {
|
|
| 162 |
- return nil, errors.Errorf("invalid device %q", dev.Name)
|
|
| 163 |
- } else if err := parser.ValidateVendorName(vendor); err != nil {
|
|
| 164 |
- return nil, errors.Wrapf(err, "invalid device %q", dev.Name) |
|
| 165 |
- } else if err := parser.ValidateClassName(class); err != nil {
|
|
| 166 |
- return nil, errors.Wrapf(err, "invalid device %q", dev.Name) |
|
| 167 |
- } |
|
| 168 |
- |
|
| 169 |
- switch name {
|
|
| 170 |
- case "": |
|
| 171 |
- // first device of kind if no name is specified |
|
| 172 |
- for _, d := range all {
|
|
| 173 |
- if strings.HasPrefix(d, kind+"=") {
|
|
| 174 |
- out = append(out, d) |
|
| 175 |
- break |
|
| 176 |
- } |
|
| 177 |
- } |
|
| 178 |
- case "*": |
|
| 179 |
- // all devices of kind if the name is a wildcard |
|
| 180 |
- for _, d := range all {
|
|
| 181 |
- if strings.HasPrefix(d, kind+"=") {
|
|
| 182 |
- out = append(out, d) |
|
| 160 |
+ vendor, _ := parser.ParseQualifier(kind) |
|
| 161 |
+ if vendor != "" {
|
|
| 162 |
+ switch name {
|
|
| 163 |
+ case "": |
|
| 164 |
+ // first device of kind if no name is specified |
|
| 165 |
+ for _, d := range all {
|
|
| 166 |
+ if strings.HasPrefix(d, kind+"=") {
|
|
| 167 |
+ out = append(out, d) |
|
| 168 |
+ break |
|
| 169 |
+ } |
|
| 183 | 170 |
} |
| 184 |
- } |
|
| 185 |
- default: |
|
| 186 |
- // the specified device |
|
| 187 |
- for _, d := range all {
|
|
| 188 |
- if d == dev.Name {
|
|
| 189 |
- out = append(out, d) |
|
| 190 |
- break |
|
| 171 |
+ case "*": |
|
| 172 |
+ // all devices of kind if the name is a wildcard |
|
| 173 |
+ for _, d := range all {
|
|
| 174 |
+ if strings.HasPrefix(d, kind+"=") {
|
|
| 175 |
+ out = append(out, d) |
|
| 176 |
+ } |
|
| 191 | 177 |
} |
| 192 |
- } |
|
| 193 |
- if len(out) == 0 {
|
|
| 194 |
- // check class annotation if name unknown |
|
| 178 |
+ default: |
|
| 179 |
+ // the specified device |
|
| 195 | 180 |
for _, d := range all {
|
| 196 |
- if !strings.HasPrefix(d, kind+"=") {
|
|
| 197 |
- continue |
|
| 181 |
+ if d == dev.Name {
|
|
| 182 |
+ out = append(out, d) |
|
| 183 |
+ break |
|
| 198 | 184 |
} |
| 199 |
- if a := deviceAnnotations(m.cache.GetDevice(d)); a != nil {
|
|
| 200 |
- if class, ok := a[deviceAnnotationClass]; ok && class == name {
|
|
| 201 |
- out = append(out, d) |
|
| 202 |
- } |
|
| 185 |
+ } |
|
| 186 |
+ } |
|
| 187 |
+ } |
|
| 188 |
+ |
|
| 189 |
+ // check class annotation if device qualifier invalid or no device found |
|
| 190 |
+ if vendor == "" || len(out) == 0 {
|
|
| 191 |
+ for _, d := range all {
|
|
| 192 |
+ if a := deviceAnnotations(m.cache.GetDevice(d)); a != nil {
|
|
| 193 |
+ if class, ok := a[deviceAnnotationClass]; ok && class == dev.Name {
|
|
| 194 |
+ out = append(out, d) |
|
| 203 | 195 |
} |
| 204 | 196 |
} |
| 205 | 197 |
} |
| ... | ... |
@@ -271,7 +263,7 @@ func deviceAnnotations(dev *cdi.Device) map[string]string {
|
| 271 | 271 |
// spec annotations |
| 272 | 272 |
maps.Copy(out, dev.GetSpec().Annotations) |
| 273 | 273 |
// device annotations |
| 274 |
- maps.Copy(out, dev.Device.Annotations) |
|
| 274 |
+ maps.Copy(out, dev.Annotations) |
|
| 275 | 275 |
return out |
| 276 | 276 |
} |
| 277 | 277 |
|
| ... | ... |
@@ -6,8 +6,9 @@ import ( |
| 6 | 6 |
"time" |
| 7 | 7 |
|
| 8 | 8 |
"github.com/containerd/continuity/fs" |
| 9 |
- archive "github.com/moby/go-archive" |
|
| 9 |
+ "github.com/moby/go-archive" |
|
| 10 | 10 |
"github.com/moby/go-archive/chrootarchive" |
| 11 |
+ "github.com/moby/go-archive/compression" |
|
| 11 | 12 |
"github.com/moby/sys/user" |
| 12 | 13 |
copy "github.com/tonistiigi/fsutil/copy" |
| 13 | 14 |
) |
| ... | ... |
@@ -57,7 +58,7 @@ func isArchivePath(path string) bool {
|
| 57 | 57 |
return false |
| 58 | 58 |
} |
| 59 | 59 |
defer file.Close() |
| 60 |
- rdr, err := archive.DecompressStream(file) |
|
| 60 |
+ rdr, err := compression.DecompressStream(file) |
|
| 61 | 61 |
if err != nil {
|
| 62 | 62 |
return false |
| 63 | 63 |
} |
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
"io" |
| 9 | 9 |
"os" |
| 10 | 10 |
"slices" |
| 11 |
- "sort" |
|
| 12 | 11 |
"strconv" |
| 13 | 12 |
"strings" |
| 14 | 13 |
"sync" |
| ... | ... |
@@ -336,8 +335,8 @@ func (h *HistoryQueue) gc() error {
|
| 336 | 336 |
} |
| 337 | 337 |
|
| 338 | 338 |
// sort array by newest records first |
| 339 |
- sort.Slice(records, func(i, j int) bool {
|
|
| 340 |
- return records[i].CompletedAt.AsTime().After(records[j].CompletedAt.AsTime()) |
|
| 339 |
+ slices.SortFunc(records, func(a, b *controlapi.BuildHistoryRecord) int {
|
|
| 340 |
+ return -a.CompletedAt.AsTime().Compare(b.CompletedAt.AsTime()) |
|
| 341 | 341 |
}) |
| 342 | 342 |
|
| 343 | 343 |
h.mu.Lock() |
| ... | ... |
@@ -449,7 +448,7 @@ func (h *HistoryQueue) addResource(ctx context.Context, l leases.Lease, desc *co |
| 449 | 449 |
return err |
| 450 | 450 |
} |
| 451 | 451 |
defer lr.Discard() |
| 452 |
- ok, err := h.migrateBlobV2(ctx, string(desc.Digest), detectSkipLayers) |
|
| 452 |
+ ok, err := h.migrateBlobV2(ctx, desc.Digest, detectSkipLayers) |
|
| 453 | 453 |
if err != nil {
|
| 454 | 454 |
return err |
| 455 | 455 |
} |
| ... | ... |
@@ -459,7 +458,7 @@ func (h *HistoryQueue) addResource(ctx context.Context, l leases.Lease, desc *co |
| 459 | 459 |
} |
| 460 | 460 |
} |
| 461 | 461 |
return h.hLeaseManager.AddResource(ctx, l, leases.Resource{
|
| 462 |
- ID: string(desc.Digest), |
|
| 462 |
+ ID: desc.Digest, |
|
| 463 | 463 |
Type: "content", |
| 464 | 464 |
}) |
| 465 | 465 |
} |
| ... | ... |
@@ -462,7 +462,10 @@ func (e *ExecOp) Exec(ctx context.Context, g session.Group, inputs []solver.Resu |
| 462 | 462 |
if e.platform != nil {
|
| 463 | 463 |
currentOS = e.platform.OS |
| 464 | 464 |
} |
| 465 |
- meta.Env = addDefaultEnvvar(meta.Env, "PATH", utilsystem.DefaultPathEnv(currentOS)) |
|
| 465 |
+ // don't set PATH for Windows. #5445 |
|
| 466 |
+ if currentOS != "windows" {
|
|
| 467 |
+ meta.Env = addDefaultEnvvar(meta.Env, "PATH", utilsystem.DefaultPathEnv(currentOS)) |
|
| 468 |
+ } |
|
| 466 | 469 |
|
| 467 | 470 |
secretEnv, err := e.loadSecretEnv(ctx, g) |
| 468 | 471 |
if err != nil {
|
| ... | ... |
@@ -563,7 +566,7 @@ func (e *ExecOp) loadSecretEnv(ctx context.Context, g session.Group) ([]string, |
| 563 | 563 |
} |
| 564 | 564 |
return nil |
| 565 | 565 |
}) |
| 566 |
- if err != nil && !(errors.Is(err, secrets.ErrNotFound) && sopt.Optional) {
|
|
| 566 |
+ if err != nil && (!errors.Is(err, secrets.ErrNotFound) || !sopt.Optional) {
|
|
| 567 | 567 |
return nil, err |
| 568 | 568 |
} |
| 569 | 569 |
out = append(out, fmt.Sprintf("%s=%s", sopt.Name, string(dt)))
|
| ... | ... |
@@ -2,13 +2,13 @@ package ops |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"bytes" |
| 5 |
+ "cmp" |
|
| 5 | 6 |
"context" |
| 6 | 7 |
"encoding/json" |
| 7 | 8 |
"fmt" |
| 8 | 9 |
"path" |
| 9 | 10 |
"runtime" |
| 10 | 11 |
"slices" |
| 11 |
- "sort" |
|
| 12 | 12 |
"sync" |
| 13 | 13 |
|
| 14 | 14 |
"github.com/moby/buildkit/cache" |
| ... | ... |
@@ -151,9 +151,8 @@ func (f *fileOp) CacheMap(ctx context.Context, g session.Group, index int) (*sol |
| 151 | 151 |
for _, k := range m {
|
| 152 | 152 |
dgsts = append(dgsts, []byte(k.Path)) |
| 153 | 153 |
} |
| 154 |
- sort.Slice(dgsts, func(i, j int) bool {
|
|
| 155 |
- return bytes.Compare(dgsts[i], dgsts[j]) > 0 |
|
| 156 |
- }) |
|
| 154 |
+ slices.SortFunc(dgsts, bytes.Compare) |
|
| 155 |
+ slices.Reverse(dgsts) // historical reasons |
|
| 157 | 156 |
cm.Deps[idx].Selector = digest.FromBytes(bytes.Join(dgsts, []byte{0}))
|
| 158 | 157 |
|
| 159 | 158 |
cm.Deps[idx].ComputeDigestFunc = opsutils.NewContentHashFunc(dedupeSelectors(m)) |
| ... | ... |
@@ -261,10 +260,9 @@ func dedupeSelectors(m []opsutils.Selector) []opsutils.Selector {
|
| 261 | 261 |
} |
| 262 | 262 |
} |
| 263 | 263 |
|
| 264 |
- sort.Slice(selectors, func(i, j int) bool {
|
|
| 265 |
- return selectors[i].Path < selectors[j].Path |
|
| 264 |
+ slices.SortFunc(selectors, func(i, j opsutils.Selector) int {
|
|
| 265 |
+ return cmp.Compare(i.Path, j.Path) |
|
| 266 | 266 |
}) |
| 267 |
- |
|
| 268 | 267 |
return selectors |
| 269 | 268 |
} |
| 270 | 269 |
|
| ... | ... |
@@ -66,8 +66,8 @@ func ProvenanceProcessor(attrs map[string]string) llbsolver.Processor {
|
| 66 | 66 |
PredicateType: slsa02.PredicateSLSAProvenance, |
| 67 | 67 |
}, |
| 68 | 68 |
Path: filename, |
| 69 |
- ContentFunc: func() ([]byte, error) {
|
|
| 70 |
- pr, err := pc.Predicate() |
|
| 69 |
+ ContentFunc: func(ctx context.Context) ([]byte, error) {
|
|
| 70 |
+ pr, err := pc.Predicate(ctx) |
|
| 71 | 71 |
if err != nil {
|
| 72 | 72 |
return nil, err |
| 73 | 73 |
} |
| ... | ... |
@@ -17,6 +17,7 @@ import ( |
| 17 | 17 |
"github.com/moby/buildkit/exporter/containerimage/exptypes" |
| 18 | 18 |
"github.com/moby/buildkit/frontend" |
| 19 | 19 |
"github.com/moby/buildkit/solver" |
| 20 |
+ "github.com/moby/buildkit/solver/errdefs" |
|
| 20 | 21 |
"github.com/moby/buildkit/solver/llbsolver/ops" |
| 21 | 22 |
"github.com/moby/buildkit/solver/llbsolver/provenance" |
| 22 | 23 |
provenancetypes "github.com/moby/buildkit/solver/llbsolver/provenance/types" |
| ... | ... |
@@ -167,14 +168,18 @@ func (b *provenanceBridge) Solve(ctx context.Context, req frontend.SolveRequest, |
| 167 | 167 |
b.builds = append(b.builds, resultWithBridge{res: res, bridge: b})
|
| 168 | 168 |
b.mu.Unlock() |
| 169 | 169 |
} else if req.Frontend != "" {
|
| 170 |
- f, ok := b.llbBridge.frontends[req.Frontend] |
|
| 170 |
+ f, ok := b.frontends[req.Frontend] |
|
| 171 | 171 |
if !ok {
|
| 172 | 172 |
return nil, errors.Errorf("invalid frontend: %s", req.Frontend)
|
| 173 | 173 |
} |
| 174 | 174 |
wb := &provenanceBridge{llbBridge: b.llbBridge, req: &req}
|
| 175 |
- res, err = f.Solve(ctx, wb, b.llbBridge, req.FrontendOpt, req.FrontendInputs, sid, b.llbBridge.sm) |
|
| 175 |
+ res, err = f.Solve(ctx, wb, b.llbBridge, req.FrontendOpt, req.FrontendInputs, sid, b.sm) |
|
| 176 | 176 |
if err != nil {
|
| 177 |
- return nil, err |
|
| 177 |
+ fe := errdefs.Frontend{
|
|
| 178 |
+ Name: req.Frontend, |
|
| 179 |
+ Source: req.FrontendOpt[frontend.KeySource], |
|
| 180 |
+ } |
|
| 181 |
+ return nil, fe.WrapError(err) |
|
| 178 | 182 |
} |
| 179 | 183 |
wb.builds = append(wb.builds, resultWithBridge{res: res, bridge: wb})
|
| 180 | 184 |
b.mu.Lock() |
| ... | ... |
@@ -328,7 +333,7 @@ type ProvenanceCreator struct {
|
| 328 | 328 |
pr *provenancetypes.ProvenancePredicate |
| 329 | 329 |
j *solver.Job |
| 330 | 330 |
sampler *resources.SysSampler |
| 331 |
- addLayers func() error |
|
| 331 |
+ addLayers func(context.Context) error |
|
| 332 | 332 |
} |
| 333 | 333 |
|
| 334 | 334 |
func NewProvenanceCreator(ctx context.Context, cp *provenance.Capture, res solver.ResultProxy, attrs map[string]string, j *solver.Job, usage *resources.SysSampler) (*ProvenanceCreator, error) {
|
| ... | ... |
@@ -372,7 +377,7 @@ func NewProvenanceCreator(ctx context.Context, cp *provenance.Capture, res solve |
| 372 | 372 |
|
| 373 | 373 |
pr.Builder.ID = attrs["builder-id"] |
| 374 | 374 |
|
| 375 |
- var addLayers func() error |
|
| 375 |
+ var addLayers func(context.Context) error |
|
| 376 | 376 |
|
| 377 | 377 |
switch mode {
|
| 378 | 378 |
case "min": |
| ... | ... |
@@ -403,7 +408,7 @@ func NewProvenanceCreator(ctx context.Context, cp *provenance.Capture, res solve |
| 403 | 403 |
return nil, errors.Errorf("invalid worker ref %T", r.Sys())
|
| 404 | 404 |
} |
| 405 | 405 |
|
| 406 |
- addLayers = func() error {
|
|
| 406 |
+ addLayers = func(ctx context.Context) error {
|
|
| 407 | 407 |
e := newCacheExporter() |
| 408 | 408 |
|
| 409 | 409 |
if wref.ImmutableRef != nil {
|
| ... | ... |
@@ -455,12 +460,12 @@ func NewProvenanceCreator(ctx context.Context, cp *provenance.Capture, res solve |
| 455 | 455 |
return pc, nil |
| 456 | 456 |
} |
| 457 | 457 |
|
| 458 |
-func (p *ProvenanceCreator) Predicate() (*provenancetypes.ProvenancePredicate, error) {
|
|
| 458 |
+func (p *ProvenanceCreator) Predicate(ctx context.Context) (*provenancetypes.ProvenancePredicate, error) {
|
|
| 459 | 459 |
end := p.j.RegisterCompleteTime() |
| 460 | 460 |
p.pr.Metadata.BuildFinishedOn = &end |
| 461 | 461 |
|
| 462 | 462 |
if p.addLayers != nil {
|
| 463 |
- if err := p.addLayers(); err != nil {
|
|
| 463 |
+ if err := p.addLayers(ctx); err != nil {
|
|
| 464 | 464 |
return nil, err |
| 465 | 465 |
} |
| 466 | 466 |
} |
| ... | ... |
@@ -1,7 +1,8 @@ |
| 1 | 1 |
package provenance |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "sort" |
|
| 4 |
+ "cmp" |
|
| 5 |
+ "slices" |
|
| 5 | 6 |
|
| 6 | 7 |
distreference "github.com/distribution/reference" |
| 7 | 8 |
resourcestypes "github.com/moby/buildkit/executor/resources/types" |
| ... | ... |
@@ -56,23 +57,23 @@ func (c *Capture) Merge(c2 *Capture) error {
|
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 | 58 |
func (c *Capture) Sort() {
|
| 59 |
- sort.Slice(c.Sources.Images, func(i, j int) bool {
|
|
| 60 |
- return c.Sources.Images[i].Ref < c.Sources.Images[j].Ref |
|
| 59 |
+ slices.SortFunc(c.Sources.Images, func(a, b provenancetypes.ImageSource) int {
|
|
| 60 |
+ return cmp.Compare(a.Ref, b.Ref) |
|
| 61 | 61 |
}) |
| 62 |
- sort.Slice(c.Sources.Local, func(i, j int) bool {
|
|
| 63 |
- return c.Sources.Local[i].Name < c.Sources.Local[j].Name |
|
| 62 |
+ slices.SortFunc(c.Sources.Local, func(a, b provenancetypes.LocalSource) int {
|
|
| 63 |
+ return cmp.Compare(a.Name, b.Name) |
|
| 64 | 64 |
}) |
| 65 |
- sort.Slice(c.Sources.Git, func(i, j int) bool {
|
|
| 66 |
- return c.Sources.Git[i].URL < c.Sources.Git[j].URL |
|
| 65 |
+ slices.SortFunc(c.Sources.Git, func(a, b provenancetypes.GitSource) int {
|
|
| 66 |
+ return cmp.Compare(a.URL, b.URL) |
|
| 67 | 67 |
}) |
| 68 |
- sort.Slice(c.Sources.HTTP, func(i, j int) bool {
|
|
| 69 |
- return c.Sources.HTTP[i].URL < c.Sources.HTTP[j].URL |
|
| 68 |
+ slices.SortFunc(c.Sources.HTTP, func(a, b provenancetypes.HTTPSource) int {
|
|
| 69 |
+ return cmp.Compare(a.URL, b.URL) |
|
| 70 | 70 |
}) |
| 71 |
- sort.Slice(c.Secrets, func(i, j int) bool {
|
|
| 72 |
- return c.Secrets[i].ID < c.Secrets[j].ID |
|
| 71 |
+ slices.SortFunc(c.Secrets, func(a, b provenancetypes.Secret) int {
|
|
| 72 |
+ return cmp.Compare(a.ID, b.ID) |
|
| 73 | 73 |
}) |
| 74 |
- sort.Slice(c.SSH, func(i, j int) bool {
|
|
| 75 |
- return c.SSH[i].ID < c.SSH[j].ID |
|
| 74 |
+ slices.SortFunc(c.SSH, func(a, b provenancetypes.SSH) int {
|
|
| 75 |
+ return cmp.Compare(a.ID, b.ID) |
|
| 76 | 76 |
}) |
| 77 | 77 |
} |
| 78 | 78 |
|
| ... | ... |
@@ -207,7 +207,7 @@ func (s *Solver) recordBuildHistory(ctx context.Context, id string, req frontend |
| 207 | 207 |
} |
| 208 | 208 |
|
| 209 | 209 |
ctx, cancel := context.WithCancelCause(ctx) |
| 210 |
- ctx, _ = context.WithTimeoutCause(ctx, 300*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 210 |
+ ctx, _ = context.WithTimeoutCause(ctx, 300*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 211 | 211 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 212 | 212 |
|
| 213 | 213 |
var mu sync.Mutex |
| ... | ... |
@@ -237,7 +237,7 @@ func (s *Solver) recordBuildHistory(ctx context.Context, id string, req frontend |
| 237 | 237 |
if err != nil {
|
| 238 | 238 |
return nil, nil, err |
| 239 | 239 |
} |
| 240 |
- pr, err := prc.Predicate() |
|
| 240 |
+ pr, err := prc.Predicate(ctx) |
|
| 241 | 241 |
if err != nil {
|
| 242 | 242 |
return nil, nil, err |
| 243 | 243 |
} |
| ... | ... |
@@ -676,7 +676,7 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro |
| 676 | 676 |
|
| 677 | 677 |
func (s *Solver) getSessionExporters(ctx context.Context, sessionID string, id int, inp *exporter.Source) ([]exporter.ExporterInstance, error) {
|
| 678 | 678 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 679 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 679 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 680 | 680 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 681 | 681 |
|
| 682 | 682 |
caller, err := s.sm.Get(timeoutCtx, sessionID, false) |
| ... | ... |
@@ -753,10 +753,10 @@ func runCacheExporters(ctx context.Context, exporters []RemoteCacheExporter, j * |
| 753 | 753 |
i, exp := i, exp |
| 754 | 754 |
eg.Go(func() (err error) {
|
| 755 | 755 |
id := fmt.Sprint(j.SessionID, "-cache-", i) |
| 756 |
- err = inBuilderContext(ctx, j, exp.Exporter.Name(), id, func(ctx context.Context, _ session.Group) error {
|
|
| 756 |
+ err = inBuilderContext(ctx, j, exp.Name(), id, func(ctx context.Context, _ session.Group) error {
|
|
| 757 | 757 |
prepareDone := progress.OneOff(ctx, "preparing build cache for export") |
| 758 | 758 |
if err := result.EachRef(cached, inp, func(res solver.CachedResult, ref cache.ImmutableRef) error {
|
| 759 |
- ctx = withDescHandlerCacheOpts(ctx, ref) |
|
| 759 |
+ ctx := withDescHandlerCacheOpts(ctx, ref) |
|
| 760 | 760 |
|
| 761 | 761 |
// Configure compression |
| 762 | 762 |
compressionConfig := exp.Config().Compression |
| ... | ... |
@@ -2,8 +2,9 @@ package solver |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
+ "errors" |
|
| 5 | 6 |
"io" |
| 6 |
- "sort" |
|
| 7 |
+ "slices" |
|
| 7 | 8 |
"time" |
| 8 | 9 |
|
| 9 | 10 |
"github.com/moby/buildkit/util/bklog" |
| ... | ... |
@@ -26,7 +27,7 @@ func (j *Job) Status(ctx context.Context, ch chan *client.SolveStatus) error {
|
| 26 | 26 |
for {
|
| 27 | 27 |
p, err := pr.Read(ctx) |
| 28 | 28 |
if err != nil {
|
| 29 |
- if err == io.EOF {
|
|
| 29 |
+ if errors.Is(err, io.EOF) {
|
|
| 30 | 30 |
return nil |
| 31 | 31 |
} |
| 32 | 32 |
return err |
| ... | ... |
@@ -77,20 +78,20 @@ func (j *Job) Status(ctx context.Context, ch chan *client.SolveStatus) error {
|
| 77 | 77 |
ss.Warnings = append(ss.Warnings, &v) |
| 78 | 78 |
} |
| 79 | 79 |
} |
| 80 |
- sort.Slice(ss.Vertexes, func(i, j int) bool {
|
|
| 81 |
- if ss.Vertexes[i].Started == nil {
|
|
| 82 |
- return true |
|
| 80 |
+ slices.SortFunc(ss.Vertexes, func(a, b *client.Vertex) int {
|
|
| 81 |
+ if a.Started == nil {
|
|
| 82 |
+ return -1 |
|
| 83 | 83 |
} |
| 84 |
- if ss.Vertexes[j].Started == nil {
|
|
| 85 |
- return false |
|
| 84 |
+ if b.Started == nil {
|
|
| 85 |
+ return 1 |
|
| 86 | 86 |
} |
| 87 |
- return ss.Vertexes[i].Started.Before(*ss.Vertexes[j].Started) |
|
| 87 |
+ return a.Started.Compare(*b.Started) |
|
| 88 | 88 |
}) |
| 89 |
- sort.Slice(ss.Statuses, func(i, j int) bool {
|
|
| 90 |
- return ss.Statuses[i].Timestamp.Before(ss.Statuses[j].Timestamp) |
|
| 89 |
+ slices.SortFunc(ss.Statuses, func(a, b *client.VertexStatus) int {
|
|
| 90 |
+ return a.Timestamp.Compare(b.Timestamp) |
|
| 91 | 91 |
}) |
| 92 |
- sort.Slice(ss.Logs, func(i, j int) bool {
|
|
| 93 |
- return ss.Logs[i].Timestamp.Before(ss.Logs[j].Timestamp) |
|
| 92 |
+ slices.SortFunc(ss.Logs, func(a, b *client.VertexLog) int {
|
|
| 93 |
+ return a.Timestamp.Compare(b.Timestamp) |
|
| 94 | 94 |
}) |
| 95 | 95 |
|
| 96 | 96 |
select {
|
| ... | ... |
@@ -48,7 +48,7 @@ type splitResult struct {
|
| 48 | 48 |
|
| 49 | 49 |
func (r *splitResult) Release(ctx context.Context) error {
|
| 50 | 50 |
if atomic.AddInt64(&r.released, 1) > 1 {
|
| 51 |
- err := errors.Errorf("releasing already released reference %+v", r.Result.ID())
|
|
| 51 |
+ err := errors.Errorf("releasing already released reference %+v", r.ID())
|
|
| 52 | 52 |
bklog.G(ctx).Error(err) |
| 53 | 53 |
return err |
| 54 | 54 |
} |
| ... | ... |
@@ -1,6 +1,8 @@ |
| 1 | 1 |
package result |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 5 |
+ |
|
| 4 | 6 |
pb "github.com/moby/buildkit/frontend/gateway/pb" |
| 5 | 7 |
digest "github.com/opencontainers/go-digest" |
| 6 | 8 |
) |
| ... | ... |
@@ -23,7 +25,7 @@ type Attestation[T any] struct {
|
| 23 | 23 |
|
| 24 | 24 |
Ref T |
| 25 | 25 |
Path string |
| 26 |
- ContentFunc func() ([]byte, error) |
|
| 26 |
+ ContentFunc func(context.Context) ([]byte, error) |
|
| 27 | 27 |
|
| 28 | 28 |
InToto InTotoAttestation |
| 29 | 29 |
} |
| ... | ... |
@@ -125,7 +125,7 @@ func (r *ociLayoutResolver) info(ctx context.Context, ref reference.Spec) (conte |
| 125 | 125 |
func (r *ociLayoutResolver) withCaller(ctx context.Context, f func(context.Context, session.Caller) error) error {
|
| 126 | 126 |
if r.store.SessionID != "" {
|
| 127 | 127 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 128 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 128 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 129 | 129 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 130 | 130 |
|
| 131 | 131 |
caller, err := r.sm.Get(timeoutCtx, r.store.SessionID, false) |
| ... | ... |
@@ -13,6 +13,7 @@ import ( |
| 13 | 13 |
"github.com/containerd/containerd/v2/core/remotes" |
| 14 | 14 |
"github.com/containerd/containerd/v2/core/remotes/docker" |
| 15 | 15 |
"github.com/containerd/containerd/v2/core/snapshots" |
| 16 |
+ "github.com/containerd/containerd/v2/pkg/snapshotters" |
|
| 16 | 17 |
cerrdefs "github.com/containerd/errdefs" |
| 17 | 18 |
"github.com/moby/buildkit/cache" |
| 18 | 19 |
"github.com/moby/buildkit/client" |
| ... | ... |
@@ -88,11 +89,11 @@ func (p *puller) CacheKey(ctx context.Context, g session.Group, index int) (cach |
| 88 | 88 |
switch p.ResolverType {
|
| 89 | 89 |
case ResolverTypeRegistry: |
| 90 | 90 |
resolver := resolver.DefaultPool.GetResolver(p.RegistryHosts, p.Ref, "pull", p.SessionManager, g).WithImageStore(p.ImageStore, p.Mode) |
| 91 |
- p.Puller.Resolver = resolver |
|
| 91 |
+ p.Resolver = resolver |
|
| 92 | 92 |
getResolver = func(g session.Group) remotes.Resolver { return resolver.WithSession(g) }
|
| 93 | 93 |
case ResolverTypeOCILayout: |
| 94 | 94 |
resolver := getOCILayoutResolver(p.store, p.SessionManager, g) |
| 95 |
- p.Puller.Resolver = resolver |
|
| 95 |
+ p.Resolver = resolver |
|
| 96 | 96 |
// OCILayout has no need for session |
| 97 | 97 |
getResolver = func(g session.Group) remotes.Resolver { return resolver }
|
| 98 | 98 |
default: |
| ... | ... |
@@ -152,6 +153,7 @@ func (p *puller) CacheKey(ctx context.Context, g session.Group, index int) (cach |
| 152 | 152 |
labels = make(map[string]string) |
| 153 | 153 |
} |
| 154 | 154 |
maps.Copy(labels, estargz.SnapshotLabels(p.manifest.Ref, p.manifest.Descriptors, i)) |
| 155 |
+ labels[snapshotters.TargetRefLabel] = p.manifest.Ref |
|
| 155 | 156 |
|
| 156 | 157 |
p.descHandlers[desc.Digest] = &cache.DescHandler{
|
| 157 | 158 |
Provider: p.manifest.Provider, |
| ... | ... |
@@ -203,11 +205,11 @@ func (p *puller) Snapshot(ctx context.Context, g session.Group) (ir cache.Immuta |
| 203 | 203 |
switch p.ResolverType {
|
| 204 | 204 |
case ResolverTypeRegistry: |
| 205 | 205 |
resolver := resolver.DefaultPool.GetResolver(p.RegistryHosts, p.Ref, "pull", p.SessionManager, g).WithImageStore(p.ImageStore, p.Mode) |
| 206 |
- p.Puller.Resolver = resolver |
|
| 206 |
+ p.Resolver = resolver |
|
| 207 | 207 |
getResolver = func(g session.Group) remotes.Resolver { return resolver.WithSession(g) }
|
| 208 | 208 |
case ResolverTypeOCILayout: |
| 209 | 209 |
resolver := getOCILayoutResolver(p.store, p.SessionManager, g) |
| 210 |
- p.Puller.Resolver = resolver |
|
| 210 |
+ p.Resolver = resolver |
|
| 211 | 211 |
// OCILayout has no need for session |
| 212 | 212 |
getResolver = func(g session.Group) remotes.Resolver { return resolver }
|
| 213 | 213 |
default: |
| ... | ... |
@@ -4,6 +4,7 @@ package git |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 | 6 |
"context" |
| 7 |
+ "errors" |
|
| 7 | 8 |
"os" |
| 8 | 9 |
"os/exec" |
| 9 | 10 |
"os/signal" |
| ... | ... |
@@ -59,7 +60,8 @@ func gitMain() {
|
| 59 | 59 |
err := cmd.Run() |
| 60 | 60 |
close(done) |
| 61 | 61 |
if err != nil {
|
| 62 |
- if exiterr, ok := err.(*exec.ExitError); ok {
|
|
| 62 |
+ exiterr := &exec.ExitError{}
|
|
| 63 |
+ if errors.As(err, &exiterr) {
|
|
| 63 | 64 |
switch status := exiterr.Sys().(type) {
|
| 64 | 65 |
case unix.WaitStatus: |
| 65 | 66 |
os.Exit(status.ExitStatus()) |
| ... | ... |
@@ -398,7 +398,7 @@ func (hs *httpSourceHandler) save(ctx context.Context, resp *http.Response, s se |
| 398 | 398 |
uid := hs.src.UID |
| 399 | 399 |
gid := hs.src.GID |
| 400 | 400 |
if idmap := mount.IdentityMapping(); idmap != nil {
|
| 401 |
- uid, gid, err = idmap.ToHost(int(uid), int(gid)) |
|
| 401 |
+ uid, gid, err = idmap.ToHost(uid, gid) |
|
| 402 | 402 |
if err != nil {
|
| 403 | 403 |
return nil, "", err |
| 404 | 404 |
} |
| ... | ... |
@@ -496,7 +496,7 @@ func (hs *httpSourceHandler) Snapshot(ctx context.Context, g session.Group) (cac |
| 496 | 496 |
} |
| 497 | 497 |
|
| 498 | 498 |
func (hs *httpSourceHandler) newHTTPRequest(ctx context.Context, g session.Group) (*http.Request, error) {
|
| 499 |
- req, err := http.NewRequest("GET", hs.src.URL, nil)
|
|
| 499 |
+ req, err := http.NewRequest(http.MethodGet, hs.src.URL, nil) |
|
| 500 | 500 |
if err != nil {
|
| 501 | 501 |
return nil, err |
| 502 | 502 |
} |
| ... | ... |
@@ -25,7 +25,7 @@ func (h *sessionHandler) RoundTrip(req *http.Request) (*http.Response, error) {
|
| 25 | 25 |
return h.rt.RoundTrip(req) |
| 26 | 26 |
} |
| 27 | 27 |
|
| 28 |
- if req.Method != "GET" {
|
|
| 28 |
+ if req.Method != http.MethodGet {
|
|
| 29 | 29 |
return nil, errors.Errorf("invalid request")
|
| 30 | 30 |
} |
| 31 | 31 |
|
| ... | ... |
@@ -44,7 +44,7 @@ func (h *sessionHandler) RoundTrip(req *http.Request) (*http.Response, error) {
|
| 44 | 44 |
|
| 45 | 45 |
resp = &http.Response{
|
| 46 | 46 |
Status: "200 OK", |
| 47 |
- StatusCode: 200, |
|
| 47 |
+ StatusCode: http.StatusOK, |
|
| 48 | 48 |
Body: pr, |
| 49 | 49 |
ContentLength: -1, |
| 50 | 50 |
} |
| ... | ... |
@@ -164,7 +164,7 @@ func (ls *localSourceHandler) Snapshot(ctx context.Context, g session.Group) (ca |
| 164 | 164 |
} |
| 165 | 165 |
|
| 166 | 166 |
timeoutCtx, cancel := context.WithCancelCause(ctx) |
| 167 |
- timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 167 |
+ timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 168 | 168 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 169 | 169 |
|
| 170 | 170 |
caller, err := ls.sm.Get(timeoutCtx, sessionID, false) |
| ... | ... |
@@ -74,6 +74,7 @@ func (e *Engine) Evaluate(ctx context.Context, op *pb.SourceOp) (bool, error) {
|
| 74 | 74 |
return mutated, errors.Wrapf(ErrTooManyOps, "too many mutations on a single source") |
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 |
+ ctx := ctx |
|
| 77 | 78 |
if i == 0 {
|
| 78 | 79 |
ctx = bklog.WithLogger(ctx, bklog.G(ctx).WithField("orig", op))
|
| 79 | 80 |
} else {
|
| ... | ... |
@@ -1,8 +1,9 @@ |
| 1 | 1 |
package apicaps |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "cmp" |
|
| 4 | 5 |
"fmt" |
| 5 |
- "sort" |
|
| 6 |
+ "slices" |
|
| 6 | 7 |
"strings" |
| 7 | 8 |
|
| 8 | 9 |
pb "github.com/moby/buildkit/util/apicaps/pb" |
| ... | ... |
@@ -76,8 +77,8 @@ func (l *CapList) All() []*pb.APICap {
|
| 76 | 76 |
DisabledAlternative: c.DisabledAlternative, |
| 77 | 77 |
}) |
| 78 | 78 |
} |
| 79 |
- sort.Slice(out, func(i, j int) bool {
|
|
| 80 |
- return out[i].ID < out[j].ID |
|
| 79 |
+ slices.SortFunc(out, func(a, b *pb.APICap) int {
|
|
| 80 |
+ return cmp.Compare(a.ID, b.ID) |
|
| 81 | 81 |
}) |
| 82 | 82 |
return out |
| 83 | 83 |
} |
| ... | ... |
@@ -12,8 +12,9 @@ const ( |
| 12 | 12 |
var ( |
| 13 | 13 |
Root = filepath.Join(os.Getenv("ProgramData"), "buildkitd", ".buildstate")
|
| 14 | 14 |
ConfigDir = filepath.Join(os.Getenv("ProgramData"), "buildkitd")
|
| 15 |
- DefaultCNIBinDir = filepath.Join(ConfigDir, "bin") |
|
| 16 |
- DefaultCNIConfigPath = filepath.Join(ConfigDir, "cni.json") |
|
| 15 |
+ defaultContainerdDir = filepath.Join(os.Getenv("ProgramFiles"), "containerd")
|
|
| 16 |
+ DefaultCNIBinDir = filepath.Join(defaultContainerdDir, "cni", "bin") |
|
| 17 |
+ DefaultCNIConfigPath = filepath.Join(defaultContainerdDir, "cni", "conf", "0-containerd-nat.conf") |
|
| 17 | 18 |
) |
| 18 | 19 |
|
| 19 | 20 |
var ( |
| ... | ... |
@@ -57,7 +57,8 @@ func check(arch, bin string) (string, error) {
|
| 57 | 57 |
if err == nil {
|
| 58 | 58 |
return "", errors.Errorf("invalid zero exit code")
|
| 59 | 59 |
} |
| 60 |
- if exitError, ok := err.(*exec.ExitError); ok {
|
|
| 60 |
+ exitError := &exec.ExitError{}
|
|
| 61 |
+ if errors.As(err, &exitError) {
|
|
| 61 | 62 |
switch exitError.ExitCode() {
|
| 62 | 63 |
case 65: |
| 63 | 64 |
return "v1", nil |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
package archutil |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "sort" |
|
| 4 |
+ "slices" |
|
| 5 | 5 |
"strings" |
| 6 | 6 |
"sync" |
| 7 | 7 |
"time" |
| ... | ... |
@@ -192,7 +192,7 @@ func amd64vector(v string) (out []string) {
|
| 192 | 192 |
case "v2": |
| 193 | 193 |
out = append(out, "v2") |
| 194 | 194 |
} |
| 195 |
- sort.Strings(out) |
|
| 195 |
+ slices.Sort(out) |
|
| 196 | 196 |
return |
| 197 | 197 |
} |
| 198 | 198 |
|
| ... | ... |
@@ -191,7 +191,7 @@ func (c estargzType) Is(ctx context.Context, cs content.Store, dgst digest.Diges |
| 191 | 191 |
if h.Name != estargz.TOCTarName {
|
| 192 | 192 |
return false |
| 193 | 193 |
} |
| 194 |
- if _, err = tr.Next(); err != io.EOF { // must be EOF
|
|
| 194 |
+ if _, err = tr.Next(); !errors.Is(err, io.EOF) { // must be EOF
|
|
| 195 | 195 |
return false |
| 196 | 196 |
} |
| 197 | 197 |
|
| ... | ... |
@@ -27,7 +27,7 @@ type localFetcher struct {
|
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 | 29 |
func (f *localFetcher) Fetch(ctx context.Context, desc ocispecs.Descriptor) (io.ReadCloser, error) {
|
| 30 |
- r, err := f.Provider.ReaderAt(ctx, desc) |
|
| 30 |
+ r, err := f.ReaderAt(ctx, desc) |
|
| 31 | 31 |
if err != nil {
|
| 32 | 32 |
return nil, err |
| 33 | 33 |
} |
| ... | ... |
@@ -42,7 +42,7 @@ type rc struct {
|
| 42 | 42 |
func (r *rc) Read(b []byte) (int, error) {
|
| 43 | 43 |
n, err := r.ReadAt(b, r.offset) |
| 44 | 44 |
r.offset += int64(n) |
| 45 |
- if n > 0 && err == io.EOF {
|
|
| 45 |
+ if n > 0 && errors.Is(err, io.EOF) {
|
|
| 46 | 46 |
err = nil |
| 47 | 47 |
} |
| 48 | 48 |
return n, err |
| ... | ... |
@@ -54,8 +54,8 @@ func (r *readerAt) ReadAt(b []byte, off int64) (int, error) {
|
| 54 | 54 |
|
| 55 | 55 |
var totalN int |
| 56 | 56 |
for len(b) > 0 {
|
| 57 |
- n, err := r.Reader.Read(b) |
|
| 58 |
- if err == io.EOF && n == len(b) {
|
|
| 57 |
+ n, err := r.Read(b) |
|
| 58 |
+ if errors.Is(err, io.EOF) && n == len(b) {
|
|
| 59 | 59 |
err = nil |
| 60 | 60 |
} |
| 61 | 61 |
r.offset += int64(n) |
| ... | ... |
@@ -2,6 +2,7 @@ package tarconverter |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"archive/tar" |
| 5 |
+ "errors" |
|
| 5 | 6 |
"io" |
| 6 | 7 |
) |
| 7 | 8 |
|
| ... | ... |
@@ -19,7 +20,7 @@ func NewReader(srcContent io.Reader, headerConverter HeaderConverter) io.ReadClo |
| 19 | 19 |
|
| 20 | 20 |
for {
|
| 21 | 21 |
hdr, err := srcTar.Next() |
| 22 |
- if err == io.EOF {
|
|
| 22 |
+ if errors.Is(err, io.EOF) {
|
|
| 23 | 23 |
// Signals end of archive. |
| 24 | 24 |
rebasedTar.Close() |
| 25 | 25 |
// drain the reader into io.Discard, until hitting EOF |
| ... | ... |
@@ -17,6 +17,6 @@ func GetDiskStat(root string) (DiskStat, error) {
|
| 17 | 17 |
return DiskStat{
|
| 18 | 18 |
Total: int64(st.Bsize) * int64(st.Blocks), |
| 19 | 19 |
Free: int64(st.Bsize) * int64(st.Bfree), |
| 20 |
- Available: int64(st.Bsize) * int64(st.Bavail), |
|
| 20 |
+ Available: int64(st.Bsize) * st.Bavail, |
|
| 21 | 21 |
}, nil |
| 22 | 22 |
} |
| ... | ... |
@@ -120,7 +120,7 @@ func getFreeLoopID() (int, error) {
|
| 120 | 120 |
} |
| 121 | 121 |
defer fd.Close() |
| 122 | 122 |
|
| 123 |
- const _LOOP_CTL_GET_FREE = 0x4C82 //nolint:revive |
|
| 123 |
+ const _LOOP_CTL_GET_FREE = 0x4C82 //nolint:revive,staticcheck |
|
| 124 | 124 |
r1, _, uerr := unix.Syscall(unix.SYS_IOCTL, fd.Fd(), _LOOP_CTL_GET_FREE, 0) |
| 125 | 125 |
if uerr == 0 {
|
| 126 | 126 |
return int(r1), nil |
| ... | ... |
@@ -5,7 +5,6 @@ import ( |
| 5 | 5 |
"io" |
| 6 | 6 |
"math/rand" |
| 7 | 7 |
"slices" |
| 8 |
- "sort" |
|
| 9 | 8 |
"sync" |
| 10 | 9 |
"time" |
| 11 | 10 |
|
| ... | ... |
@@ -300,7 +299,7 @@ func (ps *progressState) run(pr progress.Reader) {
|
| 300 | 300 |
for {
|
| 301 | 301 |
p, err := pr.Read(context.TODO()) |
| 302 | 302 |
if err != nil {
|
| 303 |
- if err == io.EOF {
|
|
| 303 |
+ if errors.Is(err, io.EOF) {
|
|
| 304 | 304 |
ps.mu.Lock() |
| 305 | 305 |
ps.done = true |
| 306 | 306 |
ps.mu.Unlock() |
| ... | ... |
@@ -331,8 +330,8 @@ func (ps *progressState) add(pw progress.Writer) {
|
| 331 | 331 |
for _, p := range ps.items {
|
| 332 | 332 |
plist = append(plist, p) |
| 333 | 333 |
} |
| 334 |
- sort.Slice(plist, func(i, j int) bool {
|
|
| 335 |
- return plist[i].Timestamp.Before(plist[j].Timestamp) |
|
| 334 |
+ slices.SortFunc(plist, func(a, b *progress.Progress) int {
|
|
| 335 |
+ return a.Timestamp.Compare(b.Timestamp) |
|
| 336 | 336 |
}) |
| 337 | 337 |
for _, p := range plist {
|
| 338 | 338 |
rw.WriteRawProgress(p) |
| ... | ... |
@@ -45,7 +45,7 @@ func ToGRPC(ctx context.Context, err error) error {
|
| 45 | 45 |
|
| 46 | 46 |
// If the original error was wrapped with more context than the GRPCStatus error, |
| 47 | 47 |
// copy the original message to the GRPCStatus error |
| 48 |
- if err.Error() != st.Message() {
|
|
| 48 |
+ if errorHasMoreContext(err, st) {
|
|
| 49 | 49 |
pb := st.Proto() |
| 50 | 50 |
pb.Message = err.Error() |
| 51 | 51 |
st = status.FromProto(pb) |
| ... | ... |
@@ -72,6 +72,21 @@ func ToGRPC(ctx context.Context, err error) error {
|
| 72 | 72 |
return st.Err() |
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 |
+// errorHasMoreContext checks if the original error provides more context by having |
|
| 76 |
+// a different message or additional details than the Status. |
|
| 77 |
+func errorHasMoreContext(err error, st *status.Status) bool {
|
|
| 78 |
+ if errMessage := err.Error(); len(errMessage) > len(st.Message()) {
|
|
| 79 |
+ // check if the longer message in errMessage is only due to |
|
| 80 |
+ // prepending with the status code |
|
| 81 |
+ var grpcStatusError *grpcStatusError |
|
| 82 |
+ if errors.As(err, &grpcStatusError) {
|
|
| 83 |
+ return st.Code() != grpcStatusError.st.Code() || st.Message() != grpcStatusError.st.Message() |
|
| 84 |
+ } |
|
| 85 |
+ return true |
|
| 86 |
+ } |
|
| 87 |
+ return false |
|
| 88 |
+} |
|
| 89 |
+ |
|
| 75 | 90 |
func withDetails(ctx context.Context, s *status.Status, details ...proto.Message) (*status.Status, error) {
|
| 76 | 91 |
if s.Code() == codes.OK {
|
| 77 | 92 |
return nil, errors.New("no error details for status with code OK")
|
| ... | ... |
@@ -124,7 +139,7 @@ func Code(err error) codes.Code {
|
| 124 | 124 |
} |
| 125 | 125 |
|
| 126 | 126 |
func WrapCode(err error, code codes.Code) error {
|
| 127 |
- return &withCode{error: err, code: code}
|
|
| 127 |
+ return &withCodeError{error: err, code: code}
|
|
| 128 | 128 |
} |
| 129 | 129 |
|
| 130 | 130 |
func AsGRPCStatus(err error) (*status.Status, bool) {
|
| ... | ... |
@@ -172,6 +187,8 @@ func FromGRPC(err error) error {
|
| 172 | 172 |
for _, d := range pb.Details {
|
| 173 | 173 |
m, err := typeurl.UnmarshalAny(d) |
| 174 | 174 |
if err != nil {
|
| 175 |
+ bklog.L.Debugf("failed to unmarshal error detail with type %q: %v", d.GetTypeUrl(), err)
|
|
| 176 |
+ n.Details = append(n.Details, d) |
|
| 175 | 177 |
continue |
| 176 | 178 |
} |
| 177 | 179 |
|
| ... | ... |
@@ -181,6 +198,7 @@ func FromGRPC(err error) error {
|
| 181 | 181 |
case TypedErrorProto: |
| 182 | 182 |
details = append(details, v) |
| 183 | 183 |
default: |
| 184 |
+ bklog.L.Debugf("unknown detail with type %T", v)
|
|
| 184 | 185 |
n.Details = append(n.Details, d) |
| 185 | 186 |
} |
| 186 | 187 |
} |
| ... | ... |
@@ -219,16 +237,16 @@ func (e *grpcStatusError) GRPCStatus() *status.Status {
|
| 219 | 219 |
return e.st |
| 220 | 220 |
} |
| 221 | 221 |
|
| 222 |
-type withCode struct {
|
|
| 222 |
+type withCodeError struct {
|
|
| 223 | 223 |
code codes.Code |
| 224 | 224 |
error |
| 225 | 225 |
} |
| 226 | 226 |
|
| 227 |
-func (e *withCode) Code() codes.Code {
|
|
| 227 |
+func (e *withCodeError) Code() codes.Code {
|
|
| 228 | 228 |
return e.code |
| 229 | 229 |
} |
| 230 | 230 |
|
| 231 |
-func (e *withCode) Unwrap() error {
|
|
| 231 |
+func (e *withCodeError) Unwrap() error {
|
|
| 232 | 232 |
return e.error |
| 233 | 233 |
} |
| 234 | 234 |
|
| ... | ... |
@@ -282,10 +282,10 @@ func (c *cniProvider) newNS(ctx context.Context, hostname string) (*cniNS, error |
| 282 | 282 |
|
| 283 | 283 |
var cniRes *cni.Result |
| 284 | 284 |
if ctx.Value(contextKeyDetachedNetNS) == nil {
|
| 285 |
- cniRes, err = c.CNI.Setup(context.TODO(), id, nativeID, nsOpts...) |
|
| 285 |
+ cniRes, err = c.Setup(context.TODO(), id, nativeID, nsOpts...) |
|
| 286 | 286 |
} else {
|
| 287 | 287 |
// Parallel Setup cannot be used, apparently due to the goroutine issue with setns |
| 288 |
- cniRes, err = c.CNI.SetupSerially(context.TODO(), id, nativeID, nsOpts...) |
|
| 288 |
+ cniRes, err = c.SetupSerially(context.TODO(), id, nativeID, nsOpts...) |
|
| 289 | 289 |
} |
| 290 | 290 |
if err != nil {
|
| 291 | 291 |
deleteNetNS(nativeID) |
| ... | ... |
@@ -86,7 +86,7 @@ func withDetachedNetNSIfAny(ctx context.Context, fn func(context.Context) error) |
| 86 | 86 |
detachedNetNS := filepath.Join(stateDir, "netns") |
| 87 | 87 |
if _, err := os.Lstat(detachedNetNS); !errors.Is(err, os.ErrNotExist) {
|
| 88 | 88 |
return ns.WithNetNSPath(detachedNetNS, func(_ ns.NetNS) error {
|
| 89 |
- ctx = context.WithValue(ctx, contextKeyDetachedNetNS, detachedNetNS) |
|
| 89 |
+ ctx := context.WithValue(ctx, contextKeyDetachedNetNS, detachedNetNS) |
|
| 90 | 90 |
bklog.G(ctx).Debugf("Entering RootlessKit's detached netns %q", detachedNetNS)
|
| 91 | 91 |
err2 := fn(ctx) |
| 92 | 92 |
bklog.G(ctx).WithError(err2).Debugf("Leaving RootlessKit's detached netns %q", detachedNetNS)
|
| ... | ... |
@@ -94,7 +94,7 @@ func setNetNS(s *specs.Spec, nsPath string) error {
|
| 94 | 94 |
|
| 95 | 95 |
func unmountNetNS(nsPath string) error {
|
| 96 | 96 |
if err := unix.Unmount(nsPath, unix.MNT_DETACH); err != nil {
|
| 97 |
- if err != syscall.EINVAL && err != syscall.ENOENT {
|
|
| 97 |
+ if !errors.Is(err, syscall.EINVAL) && !errors.Is(err, syscall.ENOENT) {
|
|
| 98 | 98 |
return errors.Wrap(err, "error unmounting network namespace") |
| 99 | 99 |
} |
| 100 | 100 |
} |
| ... | ... |
@@ -86,10 +86,10 @@ func GetOverlayLayers(m mount.Mount) ([]string, error) {
|
| 86 | 86 |
var uFound bool |
| 87 | 87 |
var l []string // l[0] = bottommost |
| 88 | 88 |
for _, o := range m.Options {
|
| 89 |
- if strings.HasPrefix(o, "upperdir=") {
|
|
| 90 |
- u, uFound = strings.TrimPrefix(o, "upperdir="), true |
|
| 91 |
- } else if strings.HasPrefix(o, "lowerdir=") {
|
|
| 92 |
- l = strings.Split(strings.TrimPrefix(o, "lowerdir="), ":") |
|
| 89 |
+ if after, ok := strings.CutPrefix(o, "upperdir="); ok {
|
|
| 90 |
+ u, uFound = after, true |
|
| 91 |
+ } else if after, ok := strings.CutPrefix(o, "lowerdir="); ok {
|
|
| 92 |
+ l = strings.Split(after, ":") |
|
| 93 | 93 |
for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 {
|
| 94 | 94 |
l[i], l[j] = l[j], l[i] // make l[0] = bottommost |
| 95 | 95 |
} |
| ... | ... |
@@ -273,7 +273,7 @@ func checkOpaque(upperdir string, path string, base string, f os.FileInfo) (isOp |
| 273 | 273 |
if f.IsDir() {
|
| 274 | 274 |
for _, oKey := range []string{"trusted.overlay.opaque", "user.overlay.opaque"} {
|
| 275 | 275 |
opaque, err := sysx.LGetxattr(filepath.Join(upperdir, path), oKey) |
| 276 |
- if err != nil && err != unix.ENODATA {
|
|
| 276 |
+ if err != nil && !errors.Is(err, unix.ENODATA) {
|
|
| 277 | 277 |
return false, errors.Wrapf(err, "failed to retrieve %s attr", oKey) |
| 278 | 278 |
} else if len(opaque) == 1 && opaque[0] == 'y' {
|
| 279 | 279 |
// This is an opaque whiteout directory. |
| ... | ... |
@@ -296,7 +296,7 @@ func checkRedirect(upperdir string, path string, f os.FileInfo) (bool, error) {
|
| 296 | 296 |
if f.IsDir() {
|
| 297 | 297 |
rKey := "trusted.overlay.redirect" |
| 298 | 298 |
redirect, err := sysx.LGetxattr(filepath.Join(upperdir, path), rKey) |
| 299 |
- if err != nil && err != unix.ENODATA {
|
|
| 299 |
+ if err != nil && !errors.Is(err, unix.ENODATA) {
|
|
| 300 | 300 |
return false, errors.Wrapf(err, "failed to retrieve %s attr", rKey) |
| 301 | 301 |
} |
| 302 | 302 |
return len(redirect) > 0, nil |
| ... | ... |
@@ -379,11 +379,11 @@ func compareSysStat(s1, s2 any) (bool, error) {
|
| 379 | 379 |
// Copyright The containerd Authors. |
| 380 | 380 |
func compareCapabilities(p1, p2 string) (bool, error) {
|
| 381 | 381 |
c1, err := sysx.LGetxattr(p1, "security.capability") |
| 382 |
- if err != nil && err != sysx.ENODATA {
|
|
| 382 |
+ if err != nil && !errors.Is(err, sysx.ENODATA) {
|
|
| 383 | 383 |
return false, errors.Wrapf(err, "failed to get xattr for %s", p1) |
| 384 | 384 |
} |
| 385 | 385 |
c2, err := sysx.LGetxattr(p2, "security.capability") |
| 386 |
- if err != nil && err != sysx.ENODATA {
|
|
| 386 |
+ if err != nil && !errors.Is(err, sysx.ENODATA) {
|
|
| 387 | 387 |
return false, errors.Wrapf(err, "failed to get xattr for %s", p2) |
| 388 | 388 |
} |
| 389 | 389 |
return bytes.Equal(c1, c2), nil |
| ... | ... |
@@ -443,7 +443,7 @@ func compareFileContent(p1, p2 string) (bool, error) {
|
| 443 | 443 |
defer bufPool.Put(b2) |
| 444 | 444 |
for {
|
| 445 | 445 |
n1, err1 := io.ReadFull(f1, *b1) |
| 446 |
- if err1 == io.ErrUnexpectedEOF {
|
|
| 446 |
+ if errors.Is(err1, io.ErrUnexpectedEOF) {
|
|
| 447 | 447 |
// it's expected to get EOF when file size isn't a multiple of chunk size, consolidate these error types |
| 448 | 448 |
err1 = io.EOF |
| 449 | 449 |
} |
| ... | ... |
@@ -451,7 +451,7 @@ func compareFileContent(p1, p2 string) (bool, error) {
|
| 451 | 451 |
return false, err1 |
| 452 | 452 |
} |
| 453 | 453 |
n2, err2 := io.ReadFull(f2, *b2) |
| 454 |
- if err2 == io.ErrUnexpectedEOF {
|
|
| 454 |
+ if errors.Is(err2, io.ErrUnexpectedEOF) {
|
|
| 455 | 455 |
err2 = io.EOF |
| 456 | 456 |
} |
| 457 | 457 |
if err2 != nil && err2 != io.EOF {
|
| ... | ... |
@@ -2,6 +2,7 @@ package progress |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
+ "errors" |
|
| 5 | 6 |
"io" |
| 6 | 7 |
"sync" |
| 7 | 8 |
) |
| ... | ... |
@@ -110,7 +111,7 @@ func (mr *MultiReader) handle() error {
|
| 110 | 110 |
for {
|
| 111 | 111 |
p, err := mr.main.Read(context.TODO()) |
| 112 | 112 |
if err != nil {
|
| 113 |
- if err == io.EOF {
|
|
| 113 |
+ if errors.Is(err, io.EOF) {
|
|
| 114 | 114 |
mr.mu.Lock() |
| 115 | 115 |
cancelErr := context.Canceled |
| 116 | 116 |
for w, c := range mr.writers {
|
| ... | ... |
@@ -2,7 +2,7 @@ package progress |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"maps" |
| 5 |
- "sort" |
|
| 5 |
+ "slices" |
|
| 6 | 6 |
"sync" |
| 7 | 7 |
"time" |
| 8 | 8 |
) |
| ... | ... |
@@ -49,8 +49,8 @@ func (ps *MultiWriter) Add(pw Writer) {
|
| 49 | 49 |
ps.mu.Lock() |
| 50 | 50 |
plist := make([]*Progress, 0, len(ps.items)) |
| 51 | 51 |
plist = append(plist, ps.items...) |
| 52 |
- sort.Slice(plist, func(i, j int) bool {
|
|
| 53 |
- return plist[i].Timestamp.Before(plist[j].Timestamp) |
|
| 52 |
+ slices.SortFunc(plist, func(a, b *Progress) int {
|
|
| 53 |
+ return a.Timestamp.Compare(b.Timestamp) |
|
| 54 | 54 |
}) |
| 55 | 55 |
for _, p := range plist {
|
| 56 | 56 |
rw.WriteRawProgress(p) |
| ... | ... |
@@ -4,7 +4,7 @@ import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
"io" |
| 6 | 6 |
"maps" |
| 7 |
- "sort" |
|
| 7 |
+ "slices" |
|
| 8 | 8 |
"sync" |
| 9 | 9 |
"time" |
| 10 | 10 |
|
| ... | ... |
@@ -165,9 +165,8 @@ func (pr *progressReader) Read(ctx context.Context) ([]*Progress, error) {
|
| 165 | 165 |
for _, p := range dmap {
|
| 166 | 166 |
out = append(out, p) |
| 167 | 167 |
} |
| 168 |
- |
|
| 169 |
- sort.Slice(out, func(i, j int) bool {
|
|
| 170 |
- return out[i].Timestamp.Before(out[j].Timestamp) |
|
| 168 |
+ slices.SortFunc(out, func(a, b *Progress) int {
|
|
| 169 |
+ return a.Timestamp.Compare(b.Timestamp) |
|
| 171 | 170 |
}) |
| 172 | 171 |
|
| 173 | 172 |
return out, nil |
| ... | ... |
@@ -40,7 +40,7 @@ func setUserDefinedTermColors(colorsEnv string) {
|
| 40 | 40 |
for _, field := range fields {
|
| 41 | 41 |
k, v, ok := strings.Cut(field, "=") |
| 42 | 42 |
if !ok || strings.Contains(v, "=") {
|
| 43 |
- err := errors.New("A valid entry must have exactly two fields")
|
|
| 43 |
+ err := errors.New("valid entry must have exactly two fields")
|
|
| 44 | 44 |
bklog.L.WithError(err).Warnf("Could not parse BUILDKIT_COLORS component: %s", field)
|
| 45 | 45 |
continue |
| 46 | 46 |
} |
| ... | ... |
@@ -52,7 +52,7 @@ func setUserDefinedTermColors(colorsEnv string) {
|
| 52 | 52 |
parseKeys(k, c) |
| 53 | 53 |
} |
| 54 | 54 |
} else {
|
| 55 |
- err := errors.New("Colors must be a name from the pre-defined list or a valid 3-part RGB value")
|
|
| 55 |
+ err := errors.New("colors must be a name from the pre-defined list or a valid 3-part RGB value")
|
|
| 56 | 56 |
bklog.L.WithError(err).Warnf("Unknown color value found in BUILDKIT_COLORS: %s=%s", k, v)
|
| 57 | 57 |
} |
| 58 | 58 |
} |
| ... | ... |
@@ -63,7 +63,7 @@ func readBuildkitColorsEnv(colorsEnv string) []string {
|
| 63 | 63 |
csvReader.Comma = ':' |
| 64 | 64 |
fields, err := csvReader.Fields(colorsEnv, nil) |
| 65 | 65 |
if err != nil {
|
| 66 |
- bklog.L.WithError(err).Warnf("Could not parse BUILDKIT_COLORS. Falling back to defaults.")
|
|
| 66 |
+ bklog.L.WithError(err).Warnf("could not parse BUILDKIT_COLORS. Falling back to defaults.")
|
|
| 67 | 67 |
return nil |
| 68 | 68 |
} |
| 69 | 69 |
return fields |
| ... | ... |
@@ -76,7 +76,7 @@ func readRGB(v string) aec.ANSI {
|
| 76 | 76 |
return nil |
| 77 | 77 |
} |
| 78 | 78 |
if len(fields) != 3 {
|
| 79 |
- err = errors.New("A valid RGB color must have three fields")
|
|
| 79 |
+ err = errors.New("valid RGB color must have three fields")
|
|
| 80 | 80 |
bklog.L.WithError(err).Warnf("Could not parse value %s as valid RGB color. Ignoring.", v)
|
| 81 | 81 |
return nil |
| 82 | 82 |
} |
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
"fmt" |
| 9 | 9 |
"io" |
| 10 | 10 |
"os" |
| 11 |
+ "slices" |
|
| 11 | 12 |
"sort" |
| 12 | 13 |
"strconv" |
| 13 | 14 |
"strings" |
| ... | ... |
@@ -518,8 +519,8 @@ func mergeIntervals(intervals []interval) []interval {
|
| 518 | 518 |
} |
| 519 | 519 |
|
| 520 | 520 |
// sort intervals by start time |
| 521 |
- sort.Slice(intervals, func(i, j int) bool {
|
|
| 522 |
- return intervals[i].start.Before(*intervals[j].start) |
|
| 521 |
+ slices.SortFunc(intervals, func(a, b interval) int {
|
|
| 522 |
+ return a.start.Compare(*b.start) |
|
| 523 | 523 |
}) |
| 524 | 524 |
|
| 525 | 525 |
var merged []interval |
| ... | ... |
@@ -587,10 +588,8 @@ func (t *trace) triggerVertexEvent(v *client.Vertex) {
|
| 587 | 587 |
old = *v |
| 588 | 588 |
} |
| 589 | 589 |
|
| 590 |
- changed := false |
|
| 591 |
- if v.Digest != old.Digest {
|
|
| 592 |
- changed = true |
|
| 593 |
- } |
|
| 590 |
+ changed := v.Digest != old.Digest |
|
| 591 |
+ |
|
| 594 | 592 |
if v.Name != old.Name {
|
| 595 | 593 |
changed = true |
| 596 | 594 |
} |
| ... | ... |
@@ -641,7 +640,11 @@ func (t *trace) update(s *client.SolveStatus, termWidth int) {
|
| 641 | 641 |
subVtxs: make(map[digest.Digest]client.Vertex), |
| 642 | 642 |
} |
| 643 | 643 |
if t.modeConsole {
|
| 644 |
- group.term = vt100.NewVT100(termHeight, termWidth-termPad) |
|
| 644 |
+ w := termWidth - termPad |
|
| 645 |
+ if w <= 0 {
|
|
| 646 |
+ w = 1 |
|
| 647 |
+ } |
|
| 648 |
+ group.term = vt100.NewVT100(termHeight, w) |
|
| 645 | 649 |
} |
| 646 | 650 |
t.groups[v.ProgressGroup.Id] = group |
| 647 | 651 |
t.byDigest[group.Digest] = group.vertex |
| ... | ... |
@@ -662,7 +665,11 @@ func (t *trace) update(s *client.SolveStatus, termWidth int) {
|
| 662 | 662 |
intervals: make(map[int64]interval), |
| 663 | 663 |
} |
| 664 | 664 |
if t.modeConsole {
|
| 665 |
- t.byDigest[v.Digest].term = vt100.NewVT100(termHeight, termWidth-termPad) |
|
| 665 |
+ w := termWidth - termPad |
|
| 666 |
+ if w <= 0 {
|
|
| 667 |
+ w = 1 |
|
| 668 |
+ } |
|
| 669 |
+ t.byDigest[v.Digest].term = vt100.NewVT100(termHeight, w) |
|
| 666 | 670 |
} |
| 667 | 671 |
} |
| 668 | 672 |
t.triggerVertexEvent(v) |
| ... | ... |
@@ -673,7 +680,7 @@ func (t *trace) update(s *client.SolveStatus, termWidth int) {
|
| 673 | 673 |
t.vertexes = append(t.vertexes, t.byDigest[v.Digest]) |
| 674 | 674 |
} |
| 675 | 675 |
// allow a duplicate initial vertex that shouldn't reset state |
| 676 |
- if !(prev != nil && prev.isStarted() && v.Started == nil) {
|
|
| 676 |
+ if prev == nil || !prev.isStarted() || v.Started != nil {
|
|
| 677 | 677 |
t.byDigest[v.Digest].Vertex = v |
| 678 | 678 |
} |
| 679 | 679 |
if v.Started != nil {
|
| ... | ... |
@@ -1000,6 +1007,9 @@ func (disp *ttyDisplay) print(d displayInfo, width, height int, all bool) {
|
| 1000 | 1000 |
} else {
|
| 1001 | 1001 |
out = align(out, "", width) |
| 1002 | 1002 |
} |
| 1003 |
+ if len(out) > width {
|
|
| 1004 |
+ out = out[:width] |
|
| 1005 |
+ } |
|
| 1003 | 1006 |
fmt.Fprintln(disp.c, out) |
| 1004 | 1007 |
lineCount := 0 |
| 1005 | 1008 |
for _, j := range d.jobs {
|
| ... | ... |
@@ -147,7 +147,7 @@ func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
|
| 147 | 147 |
l = l[v.logsOffset:] |
| 148 | 148 |
fmt.Fprintf(p.w, "%s", l) |
| 149 | 149 |
} else {
|
| 150 |
- fmt.Fprintf(p.w, "#%d %s", v.index, []byte(l)) |
|
| 150 |
+ fmt.Fprintf(p.w, "#%d %s", v.index, l) |
|
| 151 | 151 |
} |
| 152 | 152 |
|
| 153 | 153 |
if i != len(v.logs)-1 || !v.logsPartial {
|
| ... | ... |
@@ -6,7 +6,7 @@ import ( |
| 6 | 6 |
"fmt" |
| 7 | 7 |
"maps" |
| 8 | 8 |
"net/http" |
| 9 |
- "sort" |
|
| 9 |
+ "slices" |
|
| 10 | 10 |
"strings" |
| 11 | 11 |
"sync" |
| 12 | 12 |
"time" |
| ... | ... |
@@ -153,7 +153,8 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R |
| 153 | 153 |
handler := a.handlers.get(ctx, host, a.sm, a.session) |
| 154 | 154 |
|
| 155 | 155 |
for _, c := range auth.ParseAuthHeader(last.Header) {
|
| 156 |
- if c.Scheme == auth.BearerAuth {
|
|
| 156 |
+ switch c.Scheme {
|
|
| 157 |
+ case auth.BearerAuth: |
|
| 157 | 158 |
var oldScopes []string |
| 158 | 159 |
if err := invalidAuthorization(c, responses); err != nil {
|
| 159 | 160 |
a.handlers.delete(handler) |
| ... | ... |
@@ -200,7 +201,7 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R |
| 200 | 200 |
a.handlers.set(host, sessionID, newAuthHandler(host, a.client, c.Scheme, pubKey, common)) |
| 201 | 201 |
|
| 202 | 202 |
return nil |
| 203 |
- } else if c.Scheme == auth.BasicAuth {
|
|
| 203 |
+ case auth.BasicAuth: |
|
| 204 | 204 |
sessionID, username, secret, err := a.getCredentials(host) |
| 205 | 205 |
if err != nil {
|
| 206 | 206 |
return err |
| ... | ... |
@@ -288,7 +289,7 @@ func (ah *authHandler) doBearerAuth(ctx context.Context, sm *session.Manager, g |
| 288 | 288 |
|
| 289 | 289 |
to.Scopes = parseScopes(docker.GetTokenScopes(ctx, to.Scopes)).normalize() |
| 290 | 290 |
|
| 291 |
- // Docs: https://docs.docker.com/registry/spec/auth/scope |
|
| 291 |
+ // Docs: https://distribution.github.io/distribution/spec/auth/scope |
|
| 292 | 292 |
scoped := strings.Join(to.Scopes, " ") |
| 293 | 293 |
|
| 294 | 294 |
res, err := ah.g.Do(ctx, scoped, func(ctx context.Context) (*authResult, error) {
|
| ... | ... |
@@ -377,7 +378,7 @@ func (ah *authHandler) fetchToken(ctx context.Context, sm *session.Manager, g se |
| 377 | 377 |
// retry with POST request |
| 378 | 378 |
// As of September 2017, GCR is known to return 404. |
| 379 | 379 |
// As of February 2018, JFrog Artifactory is known to return 401. |
| 380 |
- if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 {
|
|
| 380 |
+ if (errStatus.StatusCode == http.StatusMethodNotAllowed && to.Username != "") || errStatus.StatusCode == http.StatusNotFound || errStatus.StatusCode == http.StatusUnauthorized {
|
|
| 381 | 381 |
resp, err := auth.FetchTokenWithOAuth(ctx, ah.client, hdr, "buildkit-client", to) |
| 382 | 382 |
if err != nil {
|
| 383 | 383 |
return nil, err |
| ... | ... |
@@ -444,7 +445,7 @@ func sameRequest(r1, r2 *http.Request) bool {
|
| 444 | 444 |
type scopes map[string]map[string]struct{}
|
| 445 | 445 |
|
| 446 | 446 |
func parseScopes(s []string) scopes {
|
| 447 |
- // https://docs.docker.com/registry/spec/auth/scope/ |
|
| 447 |
+ // https://distribution.github.io/distribution/spec/auth/scope/ |
|
| 448 | 448 |
m := map[string]map[string]struct{}{}
|
| 449 | 449 |
for _, scopeStr := range s {
|
| 450 | 450 |
if scopeStr == "" {
|
| ... | ... |
@@ -481,7 +482,7 @@ func (s scopes) normalize() []string {
|
| 481 | 481 |
for n := range s {
|
| 482 | 482 |
names = append(names, n) |
| 483 | 483 |
} |
| 484 |
- sort.Strings(names) |
|
| 484 |
+ slices.Sort(names) |
|
| 485 | 485 |
|
| 486 | 486 |
out := make([]string, 0, len(s)) |
| 487 | 487 |
|
| ... | ... |
@@ -490,7 +491,7 @@ func (s scopes) normalize() []string {
|
| 490 | 490 |
for a := range s[n] {
|
| 491 | 491 |
actions = append(actions, a) |
| 492 | 492 |
} |
| 493 |
- sort.Strings(actions) |
|
| 493 |
+ slices.Sort(actions) |
|
| 494 | 494 |
|
| 495 | 495 |
out = append(out, n+":"+strings.Join(actions, ",")) |
| 496 | 496 |
} |
| ... | ... |
@@ -25,7 +25,7 @@ loop0: |
| 25 | 25 |
} |
| 26 | 26 |
// full match, potentially skip all |
| 27 | 27 |
if idx == len(st.Frames)-1 {
|
| 28 |
- if st.Pid == prev.Pid && st.Version == prev.Version && slices.Compare(st.Cmdline, st.Cmdline) == 0 {
|
|
| 28 |
+ if st.Pid == prev.Pid && st.Version == prev.Version && slices.Equal(st.Cmdline, prev.Cmdline) {
|
|
| 29 | 29 |
continue loop0 |
| 30 | 30 |
} |
| 31 | 31 |
} |
| ... | ... |
@@ -50,7 +50,7 @@ func Traces(err error) []*Stack {
|
| 50 | 50 |
func traces(err error) []*Stack {
|
| 51 | 51 |
var st []*Stack |
| 52 | 52 |
|
| 53 |
- switch e := err.(type) {
|
|
| 53 |
+ switch e := err.(type) { //nolint:errorlint
|
|
| 54 | 54 |
case interface{ Unwrap() error }:
|
| 55 | 55 |
st = Traces(e.Unwrap()) |
| 56 | 56 |
case interface{ Unwrap() []error }:
|
| ... | ... |
@@ -63,7 +63,7 @@ func traces(err error) []*Stack {
|
| 63 | 63 |
} |
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 |
- switch ste := err.(type) {
|
|
| 66 |
+ switch ste := err.(type) { //nolint:errorlint
|
|
| 67 | 67 |
case interface{ StackTrace() errors.StackTrace }:
|
| 68 | 68 |
st = append(st, convertStack(ste.StackTrace())) |
| 69 | 69 |
case interface{ StackTrace() *Stack }:
|
| ... | ... |
@@ -85,7 +85,7 @@ func Enable(err error) error {
|
| 85 | 85 |
} |
| 86 | 86 |
|
| 87 | 87 |
func Wrap(err error, s *Stack) error {
|
| 88 |
- return &withStack{stack: s, error: err}
|
|
| 88 |
+ return &withStackError{stack: s, error: err}
|
|
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 | 91 |
func hasLocalStackTrace(err error) bool {
|
| ... | ... |
@@ -173,15 +173,15 @@ func convertStack(s errors.StackTrace) *Stack {
|
| 173 | 173 |
return &out |
| 174 | 174 |
} |
| 175 | 175 |
|
| 176 |
-type withStack struct {
|
|
| 176 |
+type withStackError struct {
|
|
| 177 | 177 |
stack *Stack |
| 178 | 178 |
error |
| 179 | 179 |
} |
| 180 | 180 |
|
| 181 |
-func (e *withStack) Unwrap() error {
|
|
| 181 |
+func (e *withStackError) Unwrap() error {
|
|
| 182 | 182 |
return e.error |
| 183 | 183 |
} |
| 184 | 184 |
|
| 185 |
-func (e *withStack) StackTrace() *Stack {
|
|
| 185 |
+func (e *withStackError) StackTrace() *Stack {
|
|
| 186 | 186 |
return e.stack |
| 187 | 187 |
} |
| ... | ... |
@@ -69,10 +69,7 @@ func (mfs *MergeFS) Walk(ctx context.Context, target string, fn fs.WalkDirFunc) |
| 69 | 69 |
next2, ok2 := <-ch2 |
| 70 | 70 |
key2 := next2.key() |
| 71 | 71 |
|
| 72 |
- for {
|
|
| 73 |
- if !ok1 && !ok2 {
|
|
| 74 |
- break |
|
| 75 |
- } |
|
| 72 |
+ for ok1 || ok2 {
|
|
| 76 | 73 |
if !ok2 || ok1 && key1 < key2 {
|
| 77 | 74 |
if err := fn(next1.path, next1.entry, next1.err); err != nil {
|
| 78 | 75 |
return err |
| ... | ... |
@@ -6,7 +6,7 @@ import ( |
| 6 | 6 |
"io" |
| 7 | 7 |
"io/fs" |
| 8 | 8 |
"os" |
| 9 |
- "sort" |
|
| 9 |
+ "slices" |
|
| 10 | 10 |
"strings" |
| 11 | 11 |
|
| 12 | 12 |
"github.com/tonistiigi/fsutil" |
| ... | ... |
@@ -52,7 +52,7 @@ func (fs *FS) Walk(ctx context.Context, target string, fn fs.WalkDirFunc) error |
| 52 | 52 |
} |
| 53 | 53 |
keys = append(keys, convertPathToKey(k)) |
| 54 | 54 |
} |
| 55 |
- sort.Strings(keys) |
|
| 55 |
+ slices.Sort(keys) |
|
| 56 | 56 |
for _, k := range keys {
|
| 57 | 57 |
p := convertKeyToPath(k) |
| 58 | 58 |
st := fs.files[p].Stat |
| ... | ... |
@@ -3,7 +3,7 @@ package detect |
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
"os" |
| 6 |
- "sort" |
|
| 6 |
+ "slices" |
|
| 7 | 7 |
"strconv" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/pkg/errors" |
| ... | ... |
@@ -66,8 +66,8 @@ func detectExporter[T any](envVar string, fn func(d ExporterDetector) (T, bool, |
| 66 | 66 |
for _, d := range detectors {
|
| 67 | 67 |
arr = append(arr, d) |
| 68 | 68 |
} |
| 69 |
- sort.Slice(arr, func(i, j int) bool {
|
|
| 70 |
- return arr[i].priority < arr[j].priority |
|
| 69 |
+ slices.SortFunc(arr, func(a, b detector) int {
|
|
| 70 |
+ return a.priority - b.priority |
|
| 71 | 71 |
}) |
| 72 | 72 |
|
| 73 | 73 |
var ok bool |
| ... | ... |
@@ -72,7 +72,7 @@ func (c *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc |
| 72 | 72 |
ctx, cancel := c.connection.ContextWithStop(ctx) |
| 73 | 73 |
defer func() { cancel(errors.WithStack(context.Canceled)) }()
|
| 74 | 74 |
ctx, tCancel := context.WithCancelCause(ctx) |
| 75 |
- ctx, _ = context.WithTimeoutCause(ctx, 30*time.Second, errors.WithStack(context.DeadlineExceeded)) |
|
| 75 |
+ ctx, _ = context.WithTimeoutCause(ctx, 30*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet |
|
| 76 | 76 |
defer tCancel(errors.WithStack(context.Canceled)) |
| 77 | 77 |
|
| 78 | 78 |
ctx = c.connection.ContextWithMetadata(ctx) |
| ... | ... |
@@ -5,7 +5,6 @@ import ( |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"net/http" |
| 7 | 7 |
"net/http/httptrace" |
| 8 |
- "slices" |
|
| 9 | 8 |
|
| 10 | 9 |
"github.com/moby/buildkit/util/bklog" |
| 11 | 10 |
"github.com/moby/buildkit/util/stack" |
| ... | ... |
@@ -34,19 +33,9 @@ func StartSpan(ctx context.Context, operationName string, opts ...trace.SpanStar |
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 | 36 |
func hasStacktrace(err error) bool {
|
| 37 |
- switch e := err.(type) {
|
|
| 38 |
- case interface{ StackTrace() *stack.Stack }:
|
|
| 39 |
- return true |
|
| 40 |
- case interface{ StackTrace() errors.StackTrace }:
|
|
| 41 |
- return true |
|
| 42 |
- case interface{ Unwrap() error }:
|
|
| 43 |
- return hasStacktrace(e.Unwrap()) |
|
| 44 |
- case interface{ Unwrap() []error }:
|
|
| 45 |
- if slices.ContainsFunc(e.Unwrap(), hasStacktrace) {
|
|
| 46 |
- return true |
|
| 47 |
- } |
|
| 48 |
- } |
|
| 49 |
- return false |
|
| 37 |
+ var stack interface{ StackTrace() *stack.Stack }
|
|
| 38 |
+ var pkgStack interface{ StackTrace() errors.StackTrace }
|
|
| 39 |
+ return errors.As(err, &stack) || errors.As(err, &pkgStack) |
|
| 50 | 40 |
} |
| 51 | 41 |
|
| 52 | 42 |
// FinishWithError finalizes the span and sets the error if one is passed |
| ... | ... |
@@ -76,8 +76,8 @@ func (s *winApplier) Apply(ctx context.Context, desc ocispecs.Descriptor, mounts |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
rc2, discard := filter(rc, func(hdr *tar.Header) bool {
|
| 79 |
- if strings.HasPrefix(hdr.Name, "Files/") {
|
|
| 80 |
- hdr.Name = strings.TrimPrefix(hdr.Name, "Files/") |
|
| 79 |
+ if after, ok := strings.CutPrefix(hdr.Name, "Files/"); ok {
|
|
| 80 |
+ hdr.Name = after |
|
| 81 | 81 |
hdr.Linkname = strings.TrimPrefix(hdr.Linkname, "Files/") |
| 82 | 82 |
// TODO: could convert the windows PAX headers to xattr here to reuse |
| 83 | 83 |
// the original ones in diff for parent directories and file modifications |
| ... | ... |
@@ -495,7 +495,6 @@ func (w *Worker) FromRemote(ctx context.Context, remote *solver.Remote) (ref cac |
| 495 | 495 |
if len(remote.Descriptors) > 0 {
|
| 496 | 496 |
var eg errgroup.Group |
| 497 | 497 |
for _, desc := range remote.Descriptors {
|
| 498 |
- desc := desc |
|
| 499 | 498 |
eg.Go(func() error {
|
| 500 | 499 |
if _, err := remote.Provider.Info(ctx, desc.Digest); err != nil {
|
| 501 | 500 |
return err |
| ... | ... |
@@ -5,6 +5,7 @@ package fsutil |
| 5 | 5 |
|
| 6 | 6 |
import ( |
| 7 | 7 |
"os" |
| 8 |
+ "strings" |
|
| 8 | 9 |
"syscall" |
| 9 | 10 |
|
| 10 | 11 |
"github.com/containerd/continuity/sysx" |
| ... | ... |
@@ -12,6 +13,8 @@ import ( |
| 12 | 12 |
"github.com/tonistiigi/fsutil/types" |
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 |
+const xattrApplePrefix = "com.apple." |
|
| 16 |
+ |
|
| 15 | 17 |
func loadXattr(origpath string, stat *types.Stat) error {
|
| 16 | 18 |
xattrs, err := sysx.LListxattr(origpath) |
| 17 | 19 |
if err != nil {
|
| ... | ... |
@@ -23,16 +26,29 @@ func loadXattr(origpath string, stat *types.Stat) error {
|
| 23 | 23 |
if len(xattrs) > 0 {
|
| 24 | 24 |
m := make(map[string][]byte) |
| 25 | 25 |
for _, key := range xattrs {
|
| 26 |
- v, err := sysx.LGetxattr(origpath, key) |
|
| 27 |
- if err == nil {
|
|
| 26 |
+ if skipXattr(key) {
|
|
| 27 |
+ continue |
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ if v, err := sysx.LGetxattr(origpath, key); err == nil {
|
|
| 28 | 31 |
m[key] = v |
| 29 | 32 |
} |
| 30 | 33 |
} |
| 31 |
- stat.Xattrs = m |
|
| 34 |
+ |
|
| 35 |
+ if len(m) > 0 {
|
|
| 36 |
+ stat.Xattrs = m |
|
| 37 |
+ } |
|
| 32 | 38 |
} |
| 33 | 39 |
return nil |
| 34 | 40 |
} |
| 35 | 41 |
|
| 42 |
+func skipXattr(key string) bool {
|
|
| 43 |
+ if strings.HasPrefix(key, xattrApplePrefix) {
|
|
| 44 |
+ return true |
|
| 45 |
+ } |
|
| 46 |
+ return false |
|
| 47 |
+} |
|
| 48 |
+ |
|
| 36 | 49 |
func setUnixOpt(fi os.FileInfo, stat *types.Stat, path string, seenFiles map[uint64]string) {
|
| 37 | 50 |
s := fi.Sys().(*syscall.Stat_t) |
| 38 | 51 |
|
| ... | ... |
@@ -293,6 +293,11 @@ github.com/cloudflare/cfssl/signer/local |
| 293 | 293 |
# github.com/container-storage-interface/spec v1.5.0 |
| 294 | 294 |
## explicit; go 1.16 |
| 295 | 295 |
github.com/container-storage-interface/spec/lib/go/csi |
| 296 |
+# github.com/containerd/accelerated-container-image v1.2.3 |
|
| 297 |
+## explicit; go 1.22.0 |
|
| 298 |
+github.com/containerd/accelerated-container-image/pkg/label |
|
| 299 |
+github.com/containerd/accelerated-container-image/pkg/types |
|
| 300 |
+github.com/containerd/accelerated-container-image/pkg/utils |
|
| 296 | 301 |
# github.com/containerd/cgroups/v3 v3.0.5 |
| 297 | 302 |
## explicit; go 1.22.0 |
| 298 | 303 |
github.com/containerd/cgroups/v3 |
| ... | ... |
@@ -758,7 +763,7 @@ github.com/mitchellh/hashstructure/v2 |
| 758 | 758 |
# github.com/mitchellh/reflectwalk v1.0.2 |
| 759 | 759 |
## explicit |
| 760 | 760 |
github.com/mitchellh/reflectwalk |
| 761 |
-# github.com/moby/buildkit v0.21.1 |
|
| 761 |
+# github.com/moby/buildkit v0.22.0-rc1 |
|
| 762 | 762 |
## explicit; go 1.23.0 |
| 763 | 763 |
github.com/moby/buildkit/api/services/control |
| 764 | 764 |
github.com/moby/buildkit/api/types |
| ... | ... |
@@ -1183,7 +1188,7 @@ github.com/tinylib/msgp/msgp |
| 1183 | 1183 |
# github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 |
| 1184 | 1184 |
## explicit; go 1.21 |
| 1185 | 1185 |
github.com/tonistiigi/dchapes-mode |
| 1186 |
-# github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583 |
|
| 1186 |
+# github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144 |
|
| 1187 | 1187 |
## explicit; go 1.21 |
| 1188 | 1188 |
github.com/tonistiigi/fsutil |
| 1189 | 1189 |
github.com/tonistiigi/fsutil/copy |