Merge pull request #1680 from containers/renovate/github.com-docker-distribution-2.x
Update module github.com/docker/distribution to v2.8.3+incompatible
This commit is contained in:
		
						commit
						3276349d24
					
				|  | @ -15,7 +15,7 @@ require ( | |||
| 	github.com/cyphar/filepath-securejoin v0.2.4 | ||||
| 	github.com/davecgh/go-spew v1.1.1 | ||||
| 	github.com/disiqueira/gotree/v3 v3.0.2 | ||||
| 	github.com/docker/distribution v2.8.2+incompatible | ||||
| 	github.com/docker/distribution v2.8.3+incompatible | ||||
| 	github.com/docker/docker v24.0.6+incompatible | ||||
| 	github.com/docker/go-units v0.5.0 | ||||
| 	github.com/fsnotify/fsnotify v1.6.0 | ||||
|  | @ -61,6 +61,7 @@ require ( | |||
| 	github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect | ||||
| 	github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect | ||||
| 	github.com/cyberphone/json-canonicalization v0.0.0-20230710064741-aa7fe85c7dbd // indirect | ||||
| 	github.com/distribution/reference v0.5.0 // indirect | ||||
| 	github.com/docker/docker-credential-helpers v0.8.0 // indirect | ||||
| 	github.com/docker/go-connections v0.4.0 // indirect | ||||
| 	github.com/go-jose/go-jose/v3 v3.0.0 // indirect | ||||
|  |  | |||
|  | @ -69,8 +69,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c | |||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/disiqueira/gotree/v3 v3.0.2 h1:ik5iuLQQoufZBNPY518dXhiO5056hyNBIK9lWhkNRq8= | ||||
| github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8= | ||||
| github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= | ||||
| github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= | ||||
| github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= | ||||
| github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= | ||||
| github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= | ||||
| github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= | ||||
| github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= | ||||
| github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= | ||||
| github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| *.go text eol=lf | ||||
|  | @ -0,0 +1,2 @@ | |||
| # Cover profiles | ||||
| *.out | ||||
|  | @ -0,0 +1,18 @@ | |||
| linters: | ||||
|   enable: | ||||
|     - bodyclose | ||||
|     - dupword # Checks for duplicate words in the source code | ||||
|     - gofmt | ||||
|     - goimports | ||||
|     - ineffassign | ||||
|     - misspell | ||||
|     - revive | ||||
|     - staticcheck | ||||
|     - unconvert | ||||
|     - unused | ||||
|     - vet | ||||
|   disable: | ||||
|     - errcheck | ||||
| 
 | ||||
| run: | ||||
|   deadline: 2m | ||||
|  | @ -0,0 +1,5 @@ | |||
| # Code of Conduct | ||||
| 
 | ||||
| We follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). | ||||
| 
 | ||||
| Please contact the [CNCF Code of Conduct Committee](mailto:conduct@cncf.io) in order to report violations of the Code of Conduct. | ||||
|  | @ -0,0 +1,114 @@ | |||
| # Contributing to the reference library | ||||
| 
 | ||||
| ## Community help | ||||
| 
 | ||||
| If you need help, please ask in the [#distribution](https://cloud-native.slack.com/archives/C01GVR8SY4R) channel on CNCF community slack. | ||||
| [Click here for an invite to the CNCF community slack](https://slack.cncf.io/) | ||||
| 
 | ||||
| ## Reporting security issues | ||||
| 
 | ||||
| The maintainers take security seriously. If you discover a security | ||||
| issue, please bring it to their attention right away! | ||||
| 
 | ||||
| Please **DO NOT** file a public issue, instead send your report privately to | ||||
| [cncf-distribution-security@lists.cncf.io](mailto:cncf-distribution-security@lists.cncf.io). | ||||
| 
 | ||||
| ## Reporting an issue properly | ||||
| 
 | ||||
| By following these simple rules you will get better and faster feedback on your issue. | ||||
| 
 | ||||
|  - search the bugtracker for an already reported issue | ||||
| 
 | ||||
| ### If you found an issue that describes your problem: | ||||
| 
 | ||||
|  - please read other user comments first, and confirm this is the same issue: a given error condition might be indicative of different problems - you may also find a workaround in the comments | ||||
|  - please refrain from adding "same thing here" or "+1" comments | ||||
|  - you don't need to comment on an issue to get notified of updates: just hit the "subscribe" button | ||||
|  - comment if you have some new, technical and relevant information to add to the case | ||||
|  - __DO NOT__ comment on closed issues or merged PRs. If you think you have a related problem, open up a new issue and reference the PR or issue. | ||||
| 
 | ||||
| ### If you have not found an existing issue that describes your problem: | ||||
| 
 | ||||
|  1. create a new issue, with a succinct title that describes your issue: | ||||
|    - bad title: "It doesn't work with my docker" | ||||
|    - good title: "Private registry push fail: 400 error with E_INVALID_DIGEST" | ||||
|  2. copy the output of (or similar for other container tools): | ||||
|    - `docker version` | ||||
|    - `docker info` | ||||
|    - `docker exec <registry-container> registry --version` | ||||
|  3. copy the command line you used to launch your Registry | ||||
|  4. restart your docker daemon in debug mode (add `-D` to the daemon launch arguments) | ||||
|  5. reproduce your problem and get your docker daemon logs showing the error | ||||
|  6. if relevant, copy your registry logs that show the error | ||||
|  7. provide any relevant detail about your specific Registry configuration (e.g., storage backend used) | ||||
|  8. indicate if you are using an enterprise proxy, Nginx, or anything else between you and your Registry | ||||
| 
 | ||||
| ## Contributing Code | ||||
| 
 | ||||
| Contributions should be made via pull requests. Pull requests will be reviewed | ||||
| by one or more maintainers or reviewers and merged when acceptable. | ||||
| 
 | ||||
| You should follow the basic GitHub workflow: | ||||
| 
 | ||||
|  1. Use your own [fork](https://help.github.com/en/articles/about-forks) | ||||
|  2. Create your [change](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes) | ||||
|  3. Test your code | ||||
|  4. [Commit](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) your work, always [sign your commits](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) | ||||
|  5. Push your change to your fork and create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) | ||||
| 
 | ||||
| Refer to [containerd's contribution guide](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes) | ||||
| for tips on creating a successful contribution. | ||||
| 
 | ||||
| ## Sign your work | ||||
| 
 | ||||
| The sign-off is a simple line at the end of the explanation for the patch. Your | ||||
| signature certifies that you wrote the patch or otherwise have the right to pass | ||||
| it on as an open-source patch. The rules are pretty simple: if you can certify | ||||
| the below (from [developercertificate.org](http://developercertificate.org/)): | ||||
| 
 | ||||
| ``` | ||||
| Developer Certificate of Origin | ||||
| Version 1.1 | ||||
| 
 | ||||
| Copyright (C) 2004, 2006 The Linux Foundation and its contributors. | ||||
| 660 York Street, Suite 102, | ||||
| San Francisco, CA 94110 USA | ||||
| 
 | ||||
| Everyone is permitted to copy and distribute verbatim copies of this | ||||
| license document, but changing it is not allowed. | ||||
| 
 | ||||
| Developer's Certificate of Origin 1.1 | ||||
| 
 | ||||
| By making a contribution to this project, I certify that: | ||||
| 
 | ||||
| (a) The contribution was created in whole or in part by me and I | ||||
|     have the right to submit it under the open source license | ||||
|     indicated in the file; or | ||||
| 
 | ||||
| (b) The contribution is based upon previous work that, to the best | ||||
|     of my knowledge, is covered under an appropriate open source | ||||
|     license and I have the right under that license to submit that | ||||
|     work with modifications, whether created in whole or in part | ||||
|     by me, under the same open source license (unless I am | ||||
|     permitted to submit under a different license), as indicated | ||||
|     in the file; or | ||||
| 
 | ||||
| (c) The contribution was provided directly to me by some other | ||||
|     person who certified (a), (b) or (c) and I have not modified | ||||
|     it. | ||||
| 
 | ||||
| (d) I understand and agree that this project and the contribution | ||||
|     are public and that a record of the contribution (including all | ||||
|     personal information I submit with it, including my sign-off) is | ||||
|     maintained indefinitely and may be redistributed consistent with | ||||
|     this project or the open source license(s) involved. | ||||
| ``` | ||||
| 
 | ||||
| Then you just add a line to every git commit message: | ||||
| 
 | ||||
|     Signed-off-by: Joe Smith <joe.smith@email.com> | ||||
| 
 | ||||
| Use your real name (sorry, no pseudonyms or anonymous contributions.) | ||||
| 
 | ||||
| If you set your `user.name` and `user.email` git configs, you can sign your | ||||
| commit automatically with `git commit -s`. | ||||
|  | @ -0,0 +1,144 @@ | |||
| # distribution/reference Project Governance | ||||
| 
 | ||||
| Distribution [Code of Conduct](./CODE-OF-CONDUCT.md) can be found here. | ||||
| 
 | ||||
| For specific guidance on practical contribution steps please | ||||
| see our [CONTRIBUTING.md](./CONTRIBUTING.md) guide. | ||||
| 
 | ||||
| ## Maintainership | ||||
| 
 | ||||
| There are different types of maintainers, with different responsibilities, but | ||||
| all maintainers have 3 things in common: | ||||
| 
 | ||||
| 1) They share responsibility in the project's success. | ||||
| 2) They have made a long-term, recurring time investment to improve the project. | ||||
| 3) They spend that time doing whatever needs to be done, not necessarily what | ||||
| is the most interesting or fun. | ||||
| 
 | ||||
| Maintainers are often under-appreciated, because their work is harder to appreciate. | ||||
| It's easy to appreciate a really cool and technically advanced feature. It's harder | ||||
| to appreciate the absence of bugs, the slow but steady improvement in stability, | ||||
| or the reliability of a release process. But those things distinguish a good | ||||
| project from a great one. | ||||
| 
 | ||||
| ## Reviewers | ||||
| 
 | ||||
| A reviewer is a core role within the project. | ||||
| They share in reviewing issues and pull requests and their LGTM counts towards the | ||||
| required LGTM count to merge a code change into the project. | ||||
| 
 | ||||
| Reviewers are part of the organization but do not have write access. | ||||
| Becoming a reviewer is a core aspect in the journey to becoming a maintainer. | ||||
| 
 | ||||
| ## Adding maintainers | ||||
| 
 | ||||
| Maintainers are first and foremost contributors that have shown they are | ||||
| committed to the long term success of a project. Contributors wanting to become | ||||
| maintainers are expected to be deeply involved in contributing code, pull | ||||
| request review, and triage of issues in the project for more than three months. | ||||
| 
 | ||||
| Just contributing does not make you a maintainer, it is about building trust | ||||
| with the current maintainers of the project and being a person that they can | ||||
| depend on and trust to make decisions in the best interest of the project. | ||||
| 
 | ||||
| Periodically, the existing maintainers curate a list of contributors that have | ||||
| shown regular activity on the project over the prior months. From this list, | ||||
| maintainer candidates are selected and proposed in a pull request or a | ||||
| maintainers communication channel. | ||||
| 
 | ||||
| After a candidate has been announced to the maintainers, the existing | ||||
| maintainers are given five business days to discuss the candidate, raise | ||||
| objections and cast their vote. Votes may take place on the communication | ||||
| channel or via pull request comment. Candidates must be approved by at least 66% | ||||
| of the current maintainers by adding their vote on the mailing list. The | ||||
| reviewer role has the same process but only requires 33% of current maintainers. | ||||
| Only maintainers of the repository that the candidate is proposed for are | ||||
| allowed to vote. | ||||
| 
 | ||||
| If a candidate is approved, a maintainer will contact the candidate to invite | ||||
| the candidate to open a pull request that adds the contributor to the | ||||
| MAINTAINERS file. The voting process may take place inside a pull request if a | ||||
| maintainer has already discussed the candidacy with the candidate and a | ||||
| maintainer is willing to be a sponsor by opening the pull request. The candidate | ||||
| becomes a maintainer once the pull request is merged. | ||||
| 
 | ||||
| ## Stepping down policy | ||||
| 
 | ||||
| Life priorities, interests, and passions can change. If you're a maintainer but | ||||
| feel you must remove yourself from the list, inform other maintainers that you | ||||
| intend to step down, and if possible, help find someone to pick up your work. | ||||
| At the very least, ensure your work can be continued where you left off. | ||||
| 
 | ||||
| After you've informed other maintainers, create a pull request to remove | ||||
| yourself from the MAINTAINERS file. | ||||
| 
 | ||||
| ## Removal of inactive maintainers | ||||
| 
 | ||||
| Similar to the procedure for adding new maintainers, existing maintainers can | ||||
| be removed from the list if they do not show significant activity on the | ||||
| project. Periodically, the maintainers review the list of maintainers and their | ||||
| activity over the last three months. | ||||
| 
 | ||||
| If a maintainer has shown insufficient activity over this period, a neutral | ||||
| person will contact the maintainer to ask if they want to continue being | ||||
| a maintainer. If the maintainer decides to step down as a maintainer, they | ||||
| open a pull request to be removed from the MAINTAINERS file. | ||||
| 
 | ||||
| If the maintainer wants to remain a maintainer, but is unable to perform the | ||||
| required duties they can be removed with a vote of at least 66% of the current | ||||
| maintainers. In this case, maintainers should first propose the change to | ||||
| maintainers via the maintainers communication channel, then open a pull request | ||||
| for voting. The voting period is five business days. The voting pull request | ||||
| should not come as a surpise to any maintainer and any discussion related to | ||||
| performance must not be discussed on the pull request. | ||||
| 
 | ||||
| ## How are decisions made? | ||||
| 
 | ||||
| Docker distribution is an open-source project with an open design philosophy. | ||||
| This means that the repository is the source of truth for EVERY aspect of the | ||||
| project, including its philosophy, design, road map, and APIs. *If it's part of | ||||
| the project, it's in the repo. If it's in the repo, it's part of the project.* | ||||
| 
 | ||||
| As a result, all decisions can be expressed as changes to the repository. An | ||||
| implementation change is a change to the source code. An API change is a change | ||||
| to the API specification. A philosophy change is a change to the philosophy | ||||
| manifesto, and so on. | ||||
| 
 | ||||
| All decisions affecting distribution, big and small, follow the same 3 steps: | ||||
| 
 | ||||
| * Step 1: Open a pull request. Anyone can do this. | ||||
| 
 | ||||
| * Step 2: Discuss the pull request. Anyone can do this. | ||||
| 
 | ||||
| * Step 3: Merge or refuse the pull request. Who does this depends on the nature | ||||
| of the pull request and which areas of the project it affects. | ||||
| 
 | ||||
| ## Helping contributors with the DCO | ||||
| 
 | ||||
| The [DCO or `Sign your work`](./CONTRIBUTING.md#sign-your-work) | ||||
| requirement is not intended as a roadblock or speed bump. | ||||
| 
 | ||||
| Some contributors are not as familiar with `git`, or have used a web | ||||
| based editor, and thus asking them to `git commit --amend -s` is not the best | ||||
| way forward. | ||||
| 
 | ||||
| In this case, maintainers can update the commits based on clause (c) of the DCO. | ||||
| The most trivial way for a contributor to allow the maintainer to do this, is to | ||||
| add a DCO signature in a pull requests's comment, or a maintainer can simply | ||||
| note that the change is sufficiently trivial that it does not substantially | ||||
| change the existing contribution - i.e., a spelling change. | ||||
| 
 | ||||
| When you add someone's DCO, please also add your own to keep a log. | ||||
| 
 | ||||
| ## I'm a maintainer. Should I make pull requests too? | ||||
| 
 | ||||
| Yes. Nobody should ever push to master directly. All changes should be | ||||
| made through a pull request. | ||||
| 
 | ||||
| ## Conflict Resolution | ||||
| 
 | ||||
| If you have a technical dispute that you feel has reached an impasse with a | ||||
| subset of the community, any contributor may open an issue, specifically | ||||
| calling for a resolution vote of the current core maintainers to resolve the | ||||
| dispute. The same voting quorums required (2/3) for adding and removing | ||||
| maintainers will apply to conflict resolution. | ||||
|  | @ -0,0 +1,202 @@ | |||
| Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
| 
 | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
| 
 | ||||
|    1. Definitions. | ||||
| 
 | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
| 
 | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
| 
 | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
| 
 | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
| 
 | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
| 
 | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
| 
 | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
| 
 | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
| 
 | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
| 
 | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
| 
 | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
| 
 | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
| 
 | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
| 
 | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
| 
 | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
| 
 | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
| 
 | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
| 
 | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
| 
 | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
| 
 | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
| 
 | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
| 
 | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
| 
 | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
| 
 | ||||
|    END OF TERMS AND CONDITIONS | ||||
| 
 | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
| 
 | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "{}" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
| 
 | ||||
|    Copyright {yyyy} {name of copyright owner} | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
| 
 | ||||
|        http://www.apache.org/licenses/LICENSE-2.0 | ||||
| 
 | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
| 
 | ||||
|  | @ -0,0 +1,26 @@ | |||
| # Distribution project maintainers & reviewers | ||||
| # | ||||
| # See GOVERNANCE.md for maintainer versus reviewer roles | ||||
| # | ||||
| # MAINTAINERS (cncf-distribution-maintainers@lists.cncf.io) | ||||
| # GitHub ID, Name, Email address | ||||
| "chrispat","Chris Patterson","chrispat@github.com" | ||||
| "clarkbw","Bryan Clark","clarkbw@github.com" | ||||
| "corhere","Cory Snider","csnider@mirantis.com" | ||||
| "deleteriousEffect","Hayley Swimelar","hswimelar@gitlab.com" | ||||
| "heww","He Weiwei","hweiwei@vmware.com" | ||||
| "joaodrp","João Pereira","jpereira@gitlab.com" | ||||
| "justincormack","Justin Cormack","justin.cormack@docker.com" | ||||
| "squizzi","Kyle Squizzato","ksquizzato@mirantis.com" | ||||
| "milosgajdos","Milos Gajdos","milosthegajdos@gmail.com" | ||||
| "sargun","Sargun Dhillon","sargun@sargun.me" | ||||
| "wy65701436","Wang Yan","wangyan@vmware.com" | ||||
| "stevelasker","Steve Lasker","steve.lasker@microsoft.com" | ||||
| # | ||||
| # REVIEWERS | ||||
| # GitHub ID, Name, Email address | ||||
| "dmcgowan","Derek McGowan","derek@mcgstyle.net" | ||||
| "stevvooe","Stephen Day","stevvooe@gmail.com" | ||||
| "thajeztah","Sebastiaan van Stijn","github@gone.nl" | ||||
| "DavidSpek", "David van der Spek", "vanderspek.david@gmail.com" | ||||
| "Jamstah", "James Hewitt", "james.hewitt@gmail.com" | ||||
|  | @ -0,0 +1,25 @@ | |||
| # Project packages.
 | ||||
| PACKAGES=$(shell go list ./...) | ||||
| 
 | ||||
| # Flags passed to `go test`
 | ||||
| BUILDFLAGS ?=  | ||||
| TESTFLAGS ?=  | ||||
| 
 | ||||
| .PHONY: all build test coverage | ||||
| .DEFAULT: all | ||||
| 
 | ||||
| all: build | ||||
| 
 | ||||
| build: ## no binaries to build, so just check compilation suceeds
 | ||||
| 	go build ${BUILDFLAGS} ./... | ||||
| 
 | ||||
| test: ## run tests
 | ||||
| 	go test ${TESTFLAGS} ./... | ||||
| 
 | ||||
| coverage: ## generate coverprofiles from the unit tests
 | ||||
| 	rm -f coverage.txt | ||||
| 	go test ${TESTFLAGS} -cover -coverprofile=cover.out ./... | ||||
| 
 | ||||
| .PHONY: help | ||||
| help: | ||||
| 	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n"} /^[a-zA-Z_\/%-]+:.*?##/ { printf "  \033[36m%-27s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) | ||||
|  | @ -0,0 +1,30 @@ | |||
| # Distribution reference | ||||
| 
 | ||||
| Go library to handle references to container images. | ||||
| 
 | ||||
| <img src="/distribution-logo.svg" width="200px" /> | ||||
| 
 | ||||
| [](https://github.com/distribution/reference/actions?query=workflow%3ACI) | ||||
| [](https://pkg.go.dev/github.com/distribution/reference) | ||||
| [](LICENSE) | ||||
| [](https://codecov.io/gh/distribution/reference) | ||||
| [](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield) | ||||
| 
 | ||||
| This repository contains a library for handling refrences to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details. | ||||
| 
 | ||||
| ## Contribution | ||||
| 
 | ||||
| Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute | ||||
| issues, fixes, and patches to this project. | ||||
| 
 | ||||
| ## Communication | ||||
| 
 | ||||
| For async communication and long running discussions please use issues and pull requests on the github repo. | ||||
| This will be the best place to discuss design and implementation. | ||||
| 
 | ||||
| For sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/) | ||||
| that everyone is welcome to join and chat about development. | ||||
| 
 | ||||
| ## Licenses | ||||
| 
 | ||||
| The distribution codebase is released under the [Apache 2.0 license](LICENSE). | ||||
|  | @ -0,0 +1,7 @@ | |||
| # Security Policy | ||||
| 
 | ||||
| ## Reporting a Vulnerability | ||||
| 
 | ||||
| The maintainers take security seriously. If you discover a security issue, please bring it to their attention right away! | ||||
| 
 | ||||
| Please DO NOT file a public issue, instead send your report privately to cncf-distribution-security@lists.cncf.io. | ||||
							
								
								
									
										1
									
								
								common/vendor/github.com/distribution/reference/distribution-logo.svg
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										1
									
								
								common/vendor/github.com/distribution/reference/distribution-logo.svg
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 8.6 KiB | 
|  | @ -32,7 +32,7 @@ func FamiliarString(ref Reference) string { | |||
| } | ||||
| 
 | ||||
| // FamiliarMatch reports whether ref matches the specified pattern.
 | ||||
| // See https://godoc.org/path#Match for supported patterns.
 | ||||
| // See [path.Match] for supported patterns.
 | ||||
| func FamiliarMatch(pattern string, ref Reference) (bool, error) { | ||||
| 	matched, err := path.Match(pattern, FamiliarString(ref)) | ||||
| 	if namedRef, isNamed := ref.(Named); isNamed && !matched { | ||||
|  | @ -1,19 +1,42 @@ | |||
| package reference | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/docker/distribution/digestset" | ||||
| 	"github.com/opencontainers/go-digest" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| const ( | ||||
| 	// legacyDefaultDomain is the legacy domain for Docker Hub (which was
 | ||||
| 	// originally named "the Docker Index"). This domain is still used for
 | ||||
| 	// authentication and image search, which were part of the "v1" Docker
 | ||||
| 	// registry specification.
 | ||||
| 	//
 | ||||
| 	// This domain will continue to be supported, but there are plans to consolidate
 | ||||
| 	// legacy domains to new "canonical" domains. Once those domains are decided
 | ||||
| 	// on, we must update the normalization functions, but preserve compatibility
 | ||||
| 	// with existing installs, clients, and user configuration.
 | ||||
| 	legacyDefaultDomain = "index.docker.io" | ||||
| 	defaultDomain       = "docker.io" | ||||
| 	officialRepoName    = "library" | ||||
| 	defaultTag          = "latest" | ||||
| 
 | ||||
| 	// defaultDomain is the default domain used for images on Docker Hub.
 | ||||
| 	// It is used to normalize "familiar" names to canonical names, for example,
 | ||||
| 	// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
 | ||||
| 	//
 | ||||
| 	// Note that actual domain of Docker Hub's registry is registry-1.docker.io.
 | ||||
| 	// This domain will continue to be supported, but there are plans to consolidate
 | ||||
| 	// legacy domains to new "canonical" domains. Once those domains are decided
 | ||||
| 	// on, we must update the normalization functions, but preserve compatibility
 | ||||
| 	// with existing installs, clients, and user configuration.
 | ||||
| 	defaultDomain = "docker.io" | ||||
| 
 | ||||
| 	// officialRepoPrefix is the namespace used for official images on Docker Hub.
 | ||||
| 	// It is used to normalize "familiar" names to canonical names, for example,
 | ||||
| 	// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
 | ||||
| 	officialRepoPrefix = "library/" | ||||
| 
 | ||||
| 	// defaultTag is the default tag if no tag is provided.
 | ||||
| 	defaultTag = "latest" | ||||
| ) | ||||
| 
 | ||||
| // normalizedNamed represents a name which has been
 | ||||
|  | @ -35,14 +58,14 @@ func ParseNormalizedNamed(s string) (Named, error) { | |||
| 		return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s) | ||||
| 	} | ||||
| 	domain, remainder := splitDockerDomain(s) | ||||
| 	var remoteName string | ||||
| 	var remote string | ||||
| 	if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 { | ||||
| 		remoteName = remainder[:tagSep] | ||||
| 		remote = remainder[:tagSep] | ||||
| 	} else { | ||||
| 		remoteName = remainder | ||||
| 		remote = remainder | ||||
| 	} | ||||
| 	if strings.ToLower(remoteName) != remoteName { | ||||
| 		return nil, errors.New("invalid reference format: repository name must be lowercase") | ||||
| 	if strings.ToLower(remote) != remote { | ||||
| 		return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remote) | ||||
| 	} | ||||
| 
 | ||||
| 	ref, err := Parse(domain + "/" + remainder) | ||||
|  | @ -56,41 +79,53 @@ func ParseNormalizedNamed(s string) (Named, error) { | |||
| 	return named, nil | ||||
| } | ||||
| 
 | ||||
| // ParseDockerRef normalizes the image reference following the docker convention. This is added
 | ||||
| // mainly for backward compatibility.
 | ||||
| // The reference returned can only be either tagged or digested. For reference contains both tag
 | ||||
| // and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@
 | ||||
| // sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as
 | ||||
| // docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa.
 | ||||
| // namedTaggedDigested is a reference that has both a tag and a digest.
 | ||||
| type namedTaggedDigested interface { | ||||
| 	NamedTagged | ||||
| 	Digested | ||||
| } | ||||
| 
 | ||||
| // ParseDockerRef normalizes the image reference following the docker convention,
 | ||||
| // which allows for references to contain both a tag and a digest. It returns a
 | ||||
| // reference that is either tagged or digested. For references containing both
 | ||||
| // a tag and a digest, it returns a digested reference. For example, the following
 | ||||
| // reference:
 | ||||
| //
 | ||||
| //	docker.io/library/busybox:latest@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
 | ||||
| //
 | ||||
| // Is returned as a digested reference (with the ":latest" tag removed):
 | ||||
| //
 | ||||
| //	docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
 | ||||
| //
 | ||||
| // References that are already "tagged" or "digested" are returned unmodified:
 | ||||
| //
 | ||||
| //	// Already a digested reference
 | ||||
| //	docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
 | ||||
| //
 | ||||
| //	// Already a named reference
 | ||||
| //	docker.io/library/busybox:latest
 | ||||
| func ParseDockerRef(ref string) (Named, error) { | ||||
| 	named, err := ParseNormalizedNamed(ref) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if _, ok := named.(NamedTagged); ok { | ||||
| 		if canonical, ok := named.(Canonical); ok { | ||||
| 			// The reference is both tagged and digested, only
 | ||||
| 			// return digested.
 | ||||
| 			newNamed, err := WithName(canonical.Name()) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			newCanonical, err := WithDigest(newNamed, canonical.Digest()) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			return newCanonical, nil | ||||
| 	if canonical, ok := named.(namedTaggedDigested); ok { | ||||
| 		// The reference is both tagged and digested; only return digested.
 | ||||
| 		newNamed, err := WithName(canonical.Name()) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return WithDigest(newNamed, canonical.Digest()) | ||||
| 	} | ||||
| 	return TagNameOnly(named), nil | ||||
| } | ||||
| 
 | ||||
| // splitDockerDomain splits a repository name to domain and remotename string.
 | ||||
| // splitDockerDomain splits a repository name to domain and remote-name.
 | ||||
| // If no valid domain is found, the default domain is used. Repository name
 | ||||
| // needs to be already validated before.
 | ||||
| func splitDockerDomain(name string) (domain, remainder string) { | ||||
| 	i := strings.IndexRune(name, '/') | ||||
| 	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") { | ||||
| 	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != localhost && strings.ToLower(name[:i]) == name[:i]) { | ||||
| 		domain, remainder = defaultDomain, name | ||||
| 	} else { | ||||
| 		domain, remainder = name[:i], name[i+1:] | ||||
|  | @ -99,13 +134,13 @@ func splitDockerDomain(name string) (domain, remainder string) { | |||
| 		domain = defaultDomain | ||||
| 	} | ||||
| 	if domain == defaultDomain && !strings.ContainsRune(remainder, '/') { | ||||
| 		remainder = officialRepoName + "/" + remainder | ||||
| 		remainder = officialRepoPrefix + remainder | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // familiarizeName returns a shortened version of the name familiar
 | ||||
| // to to the Docker UI. Familiar names have the default domain
 | ||||
| // to the Docker UI. Familiar names have the default domain
 | ||||
| // "docker.io" and "library/" repository prefix removed.
 | ||||
| // For example, "docker.io/library/redis" will have the familiar
 | ||||
| // name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp".
 | ||||
|  | @ -119,8 +154,15 @@ func familiarizeName(named namedRepository) repository { | |||
| 	if repo.domain == defaultDomain { | ||||
| 		repo.domain = "" | ||||
| 		// Handle official repositories which have the pattern "library/<official repo name>"
 | ||||
| 		if split := strings.Split(repo.path, "/"); len(split) == 2 && split[0] == officialRepoName { | ||||
| 			repo.path = split[1] | ||||
| 		if strings.HasPrefix(repo.path, officialRepoPrefix) { | ||||
| 			// TODO(thaJeztah): this check may be too strict, as it assumes the
 | ||||
| 			//  "library/" namespace does not have nested namespaces. While this
 | ||||
| 			//  is true (currently), technically it would be possible for Docker
 | ||||
| 			//  Hub to use those (e.g. "library/distros/ubuntu:latest").
 | ||||
| 			//  See https://github.com/distribution/distribution/pull/3769#issuecomment-1302031785.
 | ||||
| 			if remainder := strings.TrimPrefix(repo.path, officialRepoPrefix); !strings.ContainsRune(remainder, '/') { | ||||
| 				repo.path = remainder | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return repo | ||||
|  | @ -180,20 +222,3 @@ func ParseAnyReference(ref string) (Reference, error) { | |||
| 
 | ||||
| 	return ParseNormalizedNamed(ref) | ||||
| } | ||||
| 
 | ||||
| // ParseAnyReferenceWithSet parses a reference string as a possible short
 | ||||
| // identifier to be matched in a digest set, a full digest, or familiar name.
 | ||||
| func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) { | ||||
| 	if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok { | ||||
| 		dgst, err := ds.Lookup(ref) | ||||
| 		if err == nil { | ||||
| 			return digestReference(dgst), nil | ||||
| 		} | ||||
| 	} else { | ||||
| 		if dgst, err := digest.Parse(ref); err == nil { | ||||
| 			return digestReference(dgst), nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return ParseNormalizedNamed(ref) | ||||
| } | ||||
|  | @ -4,11 +4,14 @@ | |||
| // Grammar
 | ||||
| //
 | ||||
| //	reference                       := name [ ":" tag ] [ "@" digest ]
 | ||||
| //	name                            := [domain '/'] path-component ['/' path-component]*
 | ||||
| //	domain                          := domain-component ['.' domain-component]* [':' port-number]
 | ||||
| //	name                            := [domain '/'] remote-name
 | ||||
| //	domain                          := host [':' port-number]
 | ||||
| //	host                            := domain-name | IPv4address | \[ IPv6address \]	; rfc3986 appendix-A
 | ||||
| //	domain-name                     := domain-component ['.' domain-component]*
 | ||||
| //	domain-component                := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
 | ||||
| //	port-number                     := /[0-9]+/
 | ||||
| //	path-component                  := alpha-numeric [separator alpha-numeric]*
 | ||||
| //	path (or "remote-name")         := path-component ['/' path-component]*
 | ||||
| //	alpha-numeric                   := /[a-z0-9]+/
 | ||||
| //	separator                       := /[_.]|__|[-]*/
 | ||||
| //
 | ||||
|  | @ -21,7 +24,6 @@ | |||
| //	digest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
 | ||||
| //
 | ||||
| //	identifier                      := /[a-f0-9]{64}/
 | ||||
| //	short-identifier                := /[a-f0-9]{6,64}/
 | ||||
| package reference | ||||
| 
 | ||||
| import ( | ||||
|  | @ -145,7 +147,7 @@ type namedRepository interface { | |||
| 	Path() string | ||||
| } | ||||
| 
 | ||||
| // Domain returns the domain part of the Named reference
 | ||||
| // Domain returns the domain part of the [Named] reference.
 | ||||
| func Domain(named Named) string { | ||||
| 	if r, ok := named.(namedRepository); ok { | ||||
| 		return r.Domain() | ||||
|  | @ -154,7 +156,7 @@ func Domain(named Named) string { | |||
| 	return domain | ||||
| } | ||||
| 
 | ||||
| // Path returns the name without the domain part of the Named reference
 | ||||
| // Path returns the name without the domain part of the [Named] reference.
 | ||||
| func Path(named Named) (name string) { | ||||
| 	if r, ok := named.(namedRepository); ok { | ||||
| 		return r.Path() | ||||
|  | @ -175,7 +177,8 @@ func splitDomain(name string) (string, string) { | |||
| // hostname and name string. If no valid hostname is
 | ||||
| // found, the hostname is empty and the full value
 | ||||
| // is returned as name
 | ||||
| // DEPRECATED: Use Domain or Path
 | ||||
| //
 | ||||
| // Deprecated: Use [Domain] or [Path].
 | ||||
| func SplitHostname(named Named) (string, string) { | ||||
| 	if r, ok := named.(namedRepository); ok { | ||||
| 		return r.Domain(), r.Path() | ||||
|  | @ -185,7 +188,6 @@ func SplitHostname(named Named) (string, string) { | |||
| 
 | ||||
| // Parse parses s and returns a syntactically valid Reference.
 | ||||
| // If an error was encountered it is returned, along with a nil Reference.
 | ||||
| // NOTE: Parse will not handle short digests.
 | ||||
| func Parse(s string) (Reference, error) { | ||||
| 	matches := ReferenceRegexp.FindStringSubmatch(s) | ||||
| 	if matches == nil { | ||||
|  | @ -237,7 +239,6 @@ func Parse(s string) (Reference, error) { | |||
| // the Named interface. The reference must have a name and be in the canonical
 | ||||
| // form, otherwise an error is returned.
 | ||||
| // If an error was encountered it is returned, along with a nil Reference.
 | ||||
| // NOTE: ParseNamed will not handle short digests.
 | ||||
| func ParseNamed(s string) (Named, error) { | ||||
| 	named, err := ParseNormalizedNamed(s) | ||||
| 	if err != nil { | ||||
|  | @ -320,11 +321,13 @@ func WithDigest(name Named, digest digest.Digest) (Canonical, error) { | |||
| 
 | ||||
| // TrimNamed removes any tag or digest from the named reference.
 | ||||
| func TrimNamed(ref Named) Named { | ||||
| 	domain, path := SplitHostname(ref) | ||||
| 	return repository{ | ||||
| 		domain: domain, | ||||
| 		path:   path, | ||||
| 	repo := repository{} | ||||
| 	if r, ok := ref.(namedRepository); ok { | ||||
| 		repo.domain, repo.path = r.Domain(), r.Path() | ||||
| 	} else { | ||||
| 		repo.domain, repo.path = splitDomain(ref.Name()) | ||||
| 	} | ||||
| 	return repo | ||||
| } | ||||
| 
 | ||||
| func getBestReferenceType(ref reference) Reference { | ||||
|  | @ -0,0 +1,163 @@ | |||
| package reference | ||||
| 
 | ||||
| import ( | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
 | ||||
| var DigestRegexp = regexp.MustCompile(digestPat) | ||||
| 
 | ||||
| // DomainRegexp matches hostname or IP-addresses, optionally including a port
 | ||||
| // number. It defines the structure of potential domain components that may be
 | ||||
| // part of image names. This is purposely a subset of what is allowed by DNS to
 | ||||
| // ensure backwards compatibility with Docker image names. It may be a subset of
 | ||||
| // DNS domain name, an IPv4 address in decimal format, or an IPv6 address between
 | ||||
| // square brackets (excluding zone identifiers as defined by [RFC 6874] or special
 | ||||
| // addresses such as IPv4-Mapped).
 | ||||
| //
 | ||||
| // [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.
 | ||||
| var DomainRegexp = regexp.MustCompile(domainAndPort) | ||||
| 
 | ||||
| // IdentifierRegexp is the format for string identifier used as a
 | ||||
| // content addressable identifier using sha256. These identifiers
 | ||||
| // are like digests without the algorithm, since sha256 is used.
 | ||||
| var IdentifierRegexp = regexp.MustCompile(identifier) | ||||
| 
 | ||||
| // NameRegexp is the format for the name component of references, including
 | ||||
| // an optional domain and port, but without tag or digest suffix.
 | ||||
| var NameRegexp = regexp.MustCompile(namePat) | ||||
| 
 | ||||
| // ReferenceRegexp is the full supported format of a reference. The regexp
 | ||||
| // is anchored and has capturing groups for name, tag, and digest
 | ||||
| // components.
 | ||||
| var ReferenceRegexp = regexp.MustCompile(referencePat) | ||||
| 
 | ||||
| // TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].
 | ||||
| //
 | ||||
| // [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28
 | ||||
| var TagRegexp = regexp.MustCompile(tag) | ||||
| 
 | ||||
| const ( | ||||
| 	// alphanumeric defines the alphanumeric atom, typically a
 | ||||
| 	// component of names. This only allows lower case characters and digits.
 | ||||
| 	alphanumeric = `[a-z0-9]+` | ||||
| 
 | ||||
| 	// separator defines the separators allowed to be embedded in name
 | ||||
| 	// components. This allows one period, one or two underscore and multiple
 | ||||
| 	// dashes. Repeated dashes and underscores are intentionally treated
 | ||||
| 	// differently. In order to support valid hostnames as name components,
 | ||||
| 	// supporting repeated dash was added. Additionally double underscore is
 | ||||
| 	// now allowed as a separator to loosen the restriction for previously
 | ||||
| 	// supported names.
 | ||||
| 	separator = `(?:[._]|__|[-]+)` | ||||
| 
 | ||||
| 	// localhost is treated as a special value for domain-name. Any other
 | ||||
| 	// domain-name without a "." or a ":port" are considered a path component.
 | ||||
| 	localhost = `localhost` | ||||
| 
 | ||||
| 	// domainNameComponent restricts the registry domain component of a
 | ||||
| 	// repository name to start with a component as defined by DomainRegexp.
 | ||||
| 	domainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])` | ||||
| 
 | ||||
| 	// optionalPort matches an optional port-number including the port separator
 | ||||
| 	// (e.g. ":80").
 | ||||
| 	optionalPort = `(?::[0-9]+)?` | ||||
| 
 | ||||
| 	// tag matches valid tag names. From docker/docker:graph/tags.go.
 | ||||
| 	tag = `[\w][\w.-]{0,127}` | ||||
| 
 | ||||
| 	// digestPat matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
 | ||||
| 	//
 | ||||
| 	// TODO(thaJeztah): this should follow the same rules as https://pkg.go.dev/github.com/opencontainers/go-digest@v1.0.0#DigestRegexp
 | ||||
| 	// so that go-digest defines the canonical format. Note that the go-digest is
 | ||||
| 	// more relaxed:
 | ||||
| 	//   - it allows multiple algorithms (e.g. "sha256+b64:<encoded>") to allow
 | ||||
| 	//     future expansion of supported algorithms.
 | ||||
| 	//   - it allows the "<encoded>" value to use urlsafe base64 encoding as defined
 | ||||
| 	//     in [rfc4648, section 5].
 | ||||
| 	//
 | ||||
| 	// [rfc4648, section 5]: https://www.rfc-editor.org/rfc/rfc4648#section-5.
 | ||||
| 	digestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}` | ||||
| 
 | ||||
| 	// identifier is the format for a content addressable identifier using sha256.
 | ||||
| 	// These identifiers are like digests without the algorithm, since sha256 is used.
 | ||||
| 	identifier = `([a-f0-9]{64})` | ||||
| 
 | ||||
| 	// ipv6address are enclosed between square brackets and may be represented
 | ||||
| 	// in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format
 | ||||
| 	// are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as
 | ||||
| 	// IPv4-Mapped are deliberately excluded.
 | ||||
| 	ipv6address = `\[(?:[a-fA-F0-9:]+)\]` | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// domainName defines the structure of potential domain components
 | ||||
| 	// that may be part of image names. This is purposely a subset of what is
 | ||||
| 	// allowed by DNS to ensure backwards compatibility with Docker image
 | ||||
| 	// names. This includes IPv4 addresses on decimal format.
 | ||||
| 	domainName = domainNameComponent + anyTimes(`\.`+domainNameComponent) | ||||
| 
 | ||||
| 	// host defines the structure of potential domains based on the URI
 | ||||
| 	// Host subcomponent on rfc3986. It may be a subset of DNS domain name,
 | ||||
| 	// or an IPv4 address in decimal format, or an IPv6 address between square
 | ||||
| 	// brackets (excluding zone identifiers as defined by rfc6874 or special
 | ||||
| 	// addresses such as IPv4-Mapped).
 | ||||
| 	host = `(?:` + domainName + `|` + ipv6address + `)` | ||||
| 
 | ||||
| 	// allowed by the URI Host subcomponent on rfc3986 to ensure backwards
 | ||||
| 	// compatibility with Docker image names.
 | ||||
| 	domainAndPort = host + optionalPort | ||||
| 
 | ||||
| 	// anchoredTagRegexp matches valid tag names, anchored at the start and
 | ||||
| 	// end of the matched string.
 | ||||
| 	anchoredTagRegexp = regexp.MustCompile(anchored(tag)) | ||||
| 
 | ||||
| 	// anchoredDigestRegexp matches valid digests, anchored at the start and
 | ||||
| 	// end of the matched string.
 | ||||
| 	anchoredDigestRegexp = regexp.MustCompile(anchored(digestPat)) | ||||
| 
 | ||||
| 	// pathComponent restricts path-components to start with an alphanumeric
 | ||||
| 	// character, with following parts able to be separated by a separator
 | ||||
| 	// (one period, one or two underscore and multiple dashes).
 | ||||
| 	pathComponent = alphanumeric + anyTimes(separator+alphanumeric) | ||||
| 
 | ||||
| 	// remoteName matches the remote-name of a repository. It consists of one
 | ||||
| 	// or more forward slash (/) delimited path-components:
 | ||||
| 	//
 | ||||
| 	//	pathComponent[[/pathComponent] ...] // e.g., "library/ubuntu"
 | ||||
| 	remoteName = pathComponent + anyTimes(`/`+pathComponent) | ||||
| 	namePat    = optional(domainAndPort+`/`) + remoteName | ||||
| 
 | ||||
| 	// anchoredNameRegexp is used to parse a name value, capturing the
 | ||||
| 	// domain and trailing components.
 | ||||
| 	anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName))) | ||||
| 
 | ||||
| 	referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat))) | ||||
| 
 | ||||
| 	// anchoredIdentifierRegexp is used to check or match an
 | ||||
| 	// identifier value, anchored at start and end of string.
 | ||||
| 	anchoredIdentifierRegexp = regexp.MustCompile(anchored(identifier)) | ||||
| ) | ||||
| 
 | ||||
| // optional wraps the expression in a non-capturing group and makes the
 | ||||
| // production optional.
 | ||||
| func optional(res ...string) string { | ||||
| 	return `(?:` + strings.Join(res, "") + `)?` | ||||
| } | ||||
| 
 | ||||
| // anyTimes wraps the expression in a non-capturing group that can occur
 | ||||
| // any number of times.
 | ||||
| func anyTimes(res ...string) string { | ||||
| 	return `(?:` + strings.Join(res, "") + `)*` | ||||
| } | ||||
| 
 | ||||
| // capture wraps the expression in a capturing group.
 | ||||
| func capture(res ...string) string { | ||||
| 	return `(` + strings.Join(res, "") + `)` | ||||
| } | ||||
| 
 | ||||
| // anchored anchors the regular expression by adding start and end delimiters.
 | ||||
| func anchored(res ...string) string { | ||||
| 	return `^` + strings.Join(res, "") + `$` | ||||
| } | ||||
|  | @ -0,0 +1,75 @@ | |||
| /* | ||||
|    Copyright The containerd Authors. | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
| 
 | ||||
|        http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| 
 | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| package reference | ||||
| 
 | ||||
| import ( | ||||
| 	"sort" | ||||
| ) | ||||
| 
 | ||||
| // Sort sorts string references preferring higher information references.
 | ||||
| //
 | ||||
| // The precedence is as follows:
 | ||||
| //
 | ||||
| //  1. [Named] + [Tagged] + [Digested] (e.g., "docker.io/library/busybox:latest@sha256:<digest>")
 | ||||
| //  2. [Named] + [Tagged]              (e.g., "docker.io/library/busybox:latest")
 | ||||
| //  3. [Named] + [Digested]            (e.g., "docker.io/library/busybo@sha256:<digest>")
 | ||||
| //  4. [Named]                         (e.g., "docker.io/library/busybox")
 | ||||
| //  5. [Digested]                      (e.g., "docker.io@sha256:<digest>")
 | ||||
| //  6. Parse error
 | ||||
| func Sort(references []string) []string { | ||||
| 	var prefs []Reference | ||||
| 	var bad []string | ||||
| 
 | ||||
| 	for _, ref := range references { | ||||
| 		pref, err := ParseAnyReference(ref) | ||||
| 		if err != nil { | ||||
| 			bad = append(bad, ref) | ||||
| 		} else { | ||||
| 			prefs = append(prefs, pref) | ||||
| 		} | ||||
| 	} | ||||
| 	sort.Slice(prefs, func(a, b int) bool { | ||||
| 		ar := refRank(prefs[a]) | ||||
| 		br := refRank(prefs[b]) | ||||
| 		if ar == br { | ||||
| 			return prefs[a].String() < prefs[b].String() | ||||
| 		} | ||||
| 		return ar < br | ||||
| 	}) | ||||
| 	sort.Strings(bad) | ||||
| 	var refs []string | ||||
| 	for _, pref := range prefs { | ||||
| 		refs = append(refs, pref.String()) | ||||
| 	} | ||||
| 	return append(refs, bad...) | ||||
| } | ||||
| 
 | ||||
| func refRank(ref Reference) uint8 { | ||||
| 	if _, ok := ref.(Named); ok { | ||||
| 		if _, ok = ref.(Tagged); ok { | ||||
| 			if _, ok = ref.(Digested); ok { | ||||
| 				return 1 | ||||
| 			} | ||||
| 			return 2 | ||||
| 		} | ||||
| 		if _, ok = ref.(Digested); ok { | ||||
| 			return 3 | ||||
| 		} | ||||
| 		return 4 | ||||
| 	} | ||||
| 	return 5 | ||||
| } | ||||
							
								
								
									
										34
									
								
								common/vendor/github.com/docker/distribution/reference/helpers_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										34
									
								
								common/vendor/github.com/docker/distribution/reference/helpers_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,34 @@ | |||
| package reference | ||||
| 
 | ||||
| import "github.com/distribution/reference" | ||||
| 
 | ||||
| // IsNameOnly returns true if reference only contains a repo name.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.IsNameOnly].
 | ||||
| func IsNameOnly(ref reference.Named) bool { | ||||
| 	return reference.IsNameOnly(ref) | ||||
| } | ||||
| 
 | ||||
| // FamiliarName returns the familiar name string
 | ||||
| // for the given named, familiarizing if needed.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.FamiliarName].
 | ||||
| func FamiliarName(ref reference.Named) string { | ||||
| 	return reference.FamiliarName(ref) | ||||
| } | ||||
| 
 | ||||
| // FamiliarString returns the familiar string representation
 | ||||
| // for the given reference, familiarizing if needed.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.FamiliarString].
 | ||||
| func FamiliarString(ref reference.Reference) string { | ||||
| 	return reference.FamiliarString(ref) | ||||
| } | ||||
| 
 | ||||
| // FamiliarMatch reports whether ref matches the specified pattern.
 | ||||
| // See [path.Match] for supported patterns.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.FamiliarMatch].
 | ||||
| func FamiliarMatch(pattern string, ref reference.Reference) (bool, error) { | ||||
| 	return reference.FamiliarMatch(pattern, ref) | ||||
| } | ||||
							
								
								
									
										92
									
								
								common/vendor/github.com/docker/distribution/reference/normalize_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										92
									
								
								common/vendor/github.com/docker/distribution/reference/normalize_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,92 @@ | |||
| package reference | ||||
| 
 | ||||
| import ( | ||||
| 	"regexp" | ||||
| 
 | ||||
| 	"github.com/distribution/reference" | ||||
| 	"github.com/opencontainers/go-digest" | ||||
| 	"github.com/opencontainers/go-digest/digestset" | ||||
| ) | ||||
| 
 | ||||
| // ParseNormalizedNamed parses a string into a named reference
 | ||||
| // transforming a familiar name from Docker UI to a fully
 | ||||
| // qualified reference. If the value may be an identifier
 | ||||
| // use ParseAnyReference.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.ParseNormalizedNamed].
 | ||||
| func ParseNormalizedNamed(s string) (reference.Named, error) { | ||||
| 	return reference.ParseNormalizedNamed(s) | ||||
| } | ||||
| 
 | ||||
| // ParseDockerRef normalizes the image reference following the docker convention,
 | ||||
| // which allows for references to contain both a tag and a digest.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.ParseDockerRef].
 | ||||
| func ParseDockerRef(ref string) (reference.Named, error) { | ||||
| 	return reference.ParseDockerRef(ref) | ||||
| } | ||||
| 
 | ||||
| // TagNameOnly adds the default tag "latest" to a reference if it only has
 | ||||
| // a repo name.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.TagNameOnly].
 | ||||
| func TagNameOnly(ref reference.Named) reference.Named { | ||||
| 	return reference.TagNameOnly(ref) | ||||
| } | ||||
| 
 | ||||
| // ParseAnyReference parses a reference string as a possible identifier,
 | ||||
| // full digest, or familiar name.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.ParseAnyReference].
 | ||||
| func ParseAnyReference(ref string) (reference.Reference, error) { | ||||
| 	return reference.ParseAnyReference(ref) | ||||
| } | ||||
| 
 | ||||
| // Functions and types below have been removed in distribution v3 and
 | ||||
| // have not been ported to github.com/distribution/reference. See
 | ||||
| // https://github.com/distribution/distribution/pull/3774
 | ||||
| 
 | ||||
| var ( | ||||
| 	// ShortIdentifierRegexp is the format used to represent a prefix
 | ||||
| 	// of an identifier. A prefix may be used to match a sha256 identifier
 | ||||
| 	// within a list of trusted identifiers.
 | ||||
| 	//
 | ||||
| 	// Deprecated: support for short-identifiers is deprecated, and will be removed in v3.
 | ||||
| 	ShortIdentifierRegexp = regexp.MustCompile(shortIdentifier) | ||||
| 
 | ||||
| 	shortIdentifier = `([a-f0-9]{6,64})` | ||||
| 
 | ||||
| 	// anchoredShortIdentifierRegexp is used to check if a value
 | ||||
| 	// is a possible identifier prefix, anchored at start and end
 | ||||
| 	// of string.
 | ||||
| 	anchoredShortIdentifierRegexp = regexp.MustCompile(`^` + shortIdentifier + `$`) | ||||
| ) | ||||
| 
 | ||||
| type digestReference digest.Digest | ||||
| 
 | ||||
| func (d digestReference) String() string { | ||||
| 	return digest.Digest(d).String() | ||||
| } | ||||
| 
 | ||||
| func (d digestReference) Digest() digest.Digest { | ||||
| 	return digest.Digest(d) | ||||
| } | ||||
| 
 | ||||
| // ParseAnyReferenceWithSet parses a reference string as a possible short
 | ||||
| // identifier to be matched in a digest set, a full digest, or familiar name.
 | ||||
| //
 | ||||
| // Deprecated: support for short-identifiers is deprecated, and will be removed in v3.
 | ||||
| func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) { | ||||
| 	if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok { | ||||
| 		dgst, err := ds.Lookup(ref) | ||||
| 		if err == nil { | ||||
| 			return digestReference(dgst), nil | ||||
| 		} | ||||
| 	} else { | ||||
| 		if dgst, err := digest.Parse(ref); err == nil { | ||||
| 			return digestReference(dgst), nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return reference.ParseNormalizedNamed(ref) | ||||
| } | ||||
							
								
								
									
										172
									
								
								common/vendor/github.com/docker/distribution/reference/reference_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										172
									
								
								common/vendor/github.com/docker/distribution/reference/reference_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,172 @@ | |||
| // Package reference is deprecated, and has moved to github.com/distribution/reference.
 | ||||
| //
 | ||||
| // Deprecated: use github.com/distribution/reference instead.
 | ||||
| package reference | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/distribution/reference" | ||||
| 	"github.com/opencontainers/go-digest" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// NameTotalLengthMax is the maximum total number of characters in a repository name.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.NameTotalLengthMax].
 | ||||
| 	NameTotalLengthMax = reference.NameTotalLengthMax | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.ErrReferenceInvalidFormat].
 | ||||
| 	ErrReferenceInvalidFormat = reference.ErrReferenceInvalidFormat | ||||
| 
 | ||||
| 	// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.ErrTagInvalidFormat].
 | ||||
| 	ErrTagInvalidFormat = reference.ErrTagInvalidFormat | ||||
| 
 | ||||
| 	// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.ErrDigestInvalidFormat].
 | ||||
| 	ErrDigestInvalidFormat = reference.ErrDigestInvalidFormat | ||||
| 
 | ||||
| 	// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.ErrNameContainsUppercase].
 | ||||
| 	ErrNameContainsUppercase = reference.ErrNameContainsUppercase | ||||
| 
 | ||||
| 	// ErrNameEmpty is returned for empty, invalid repository names.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.ErrNameEmpty].
 | ||||
| 	ErrNameEmpty = reference.ErrNameEmpty | ||||
| 
 | ||||
| 	// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.ErrNameTooLong].
 | ||||
| 	ErrNameTooLong = reference.ErrNameTooLong | ||||
| 
 | ||||
| 	// ErrNameNotCanonical is returned when a name is not canonical.
 | ||||
| 	//
 | ||||
| 	// Deprecated: use [reference.ErrNameNotCanonical].
 | ||||
| 	ErrNameNotCanonical = reference.ErrNameNotCanonical | ||||
| ) | ||||
| 
 | ||||
| // Reference is an opaque object reference identifier that may include
 | ||||
| // modifiers such as a hostname, name, tag, and digest.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Reference].
 | ||||
| type Reference = reference.Reference | ||||
| 
 | ||||
| // Field provides a wrapper type for resolving correct reference types when
 | ||||
| // working with encoding.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Field].
 | ||||
| type Field = reference.Field | ||||
| 
 | ||||
| // AsField wraps a reference in a Field for encoding.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.AsField].
 | ||||
| func AsField(ref reference.Reference) reference.Field { | ||||
| 	return reference.AsField(ref) | ||||
| } | ||||
| 
 | ||||
| // Named is an object with a full name
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Named].
 | ||||
| type Named = reference.Named | ||||
| 
 | ||||
| // Tagged is an object which has a tag
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Tagged].
 | ||||
| type Tagged = reference.Tagged | ||||
| 
 | ||||
| // NamedTagged is an object including a name and tag.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.NamedTagged].
 | ||||
| type NamedTagged reference.NamedTagged | ||||
| 
 | ||||
| // Digested is an object which has a digest
 | ||||
| // in which it can be referenced by
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Digested].
 | ||||
| type Digested reference.Digested | ||||
| 
 | ||||
| // Canonical reference is an object with a fully unique
 | ||||
| // name including a name with domain and digest
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Canonical].
 | ||||
| type Canonical reference.Canonical | ||||
| 
 | ||||
| // Domain returns the domain part of the [Named] reference.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Domain].
 | ||||
| func Domain(named reference.Named) string { | ||||
| 	return reference.Domain(named) | ||||
| } | ||||
| 
 | ||||
| // Path returns the name without the domain part of the [Named] reference.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Path].
 | ||||
| func Path(named reference.Named) (name string) { | ||||
| 	return reference.Path(named) | ||||
| } | ||||
| 
 | ||||
| // SplitHostname splits a named reference into a
 | ||||
| // hostname and name string. If no valid hostname is
 | ||||
| // found, the hostname is empty and the full value
 | ||||
| // is returned as name
 | ||||
| //
 | ||||
| // Deprecated: Use [reference.Domain] or [reference.Path].
 | ||||
| func SplitHostname(named reference.Named) (string, string) { | ||||
| 	return reference.SplitHostname(named) | ||||
| } | ||||
| 
 | ||||
| // Parse parses s and returns a syntactically valid Reference.
 | ||||
| // If an error was encountered it is returned, along with a nil Reference.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Parse].
 | ||||
| func Parse(s string) (reference.Reference, error) { | ||||
| 	return reference.Parse(s) | ||||
| } | ||||
| 
 | ||||
| // ParseNamed parses s and returns a syntactically valid reference implementing
 | ||||
| // the Named interface. The reference must have a name and be in the canonical
 | ||||
| // form, otherwise an error is returned.
 | ||||
| // If an error was encountered it is returned, along with a nil Reference.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.ParseNamed].
 | ||||
| func ParseNamed(s string) (reference.Named, error) { | ||||
| 	return reference.ParseNamed(s) | ||||
| } | ||||
| 
 | ||||
| // WithName returns a named object representing the given string. If the input
 | ||||
| // is invalid ErrReferenceInvalidFormat will be returned.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.WithName].
 | ||||
| func WithName(name string) (reference.Named, error) { | ||||
| 	return reference.WithName(name) | ||||
| } | ||||
| 
 | ||||
| // WithTag combines the name from "name" and the tag from "tag" to form a
 | ||||
| // reference incorporating both the name and the tag.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.WithTag].
 | ||||
| func WithTag(name reference.Named, tag string) (reference.NamedTagged, error) { | ||||
| 	return reference.WithTag(name, tag) | ||||
| } | ||||
| 
 | ||||
| // WithDigest combines the name from "name" and the digest from "digest" to form
 | ||||
| // a reference incorporating both the name and the digest.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.WithDigest].
 | ||||
| func WithDigest(name reference.Named, digest digest.Digest) (reference.Canonical, error) { | ||||
| 	return reference.WithDigest(name, digest) | ||||
| } | ||||
| 
 | ||||
| // TrimNamed removes any tag or digest from the named reference.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.TrimNamed].
 | ||||
| func TrimNamed(ref reference.Named) reference.Named { | ||||
| 	return reference.TrimNamed(ref) | ||||
| } | ||||
|  | @ -1,143 +0,0 @@ | |||
| package reference | ||||
| 
 | ||||
| import "regexp" | ||||
| 
 | ||||
| var ( | ||||
| 	// alphaNumericRegexp defines the alpha numeric atom, typically a
 | ||||
| 	// component of names. This only allows lower case characters and digits.
 | ||||
| 	alphaNumericRegexp = match(`[a-z0-9]+`) | ||||
| 
 | ||||
| 	// separatorRegexp defines the separators allowed to be embedded in name
 | ||||
| 	// components. This allow one period, one or two underscore and multiple
 | ||||
| 	// dashes.
 | ||||
| 	separatorRegexp = match(`(?:[._]|__|[-]*)`) | ||||
| 
 | ||||
| 	// nameComponentRegexp restricts registry path component names to start
 | ||||
| 	// with at least one letter or number, with following parts able to be
 | ||||
| 	// separated by one period, one or two underscore and multiple dashes.
 | ||||
| 	nameComponentRegexp = expression( | ||||
| 		alphaNumericRegexp, | ||||
| 		optional(repeated(separatorRegexp, alphaNumericRegexp))) | ||||
| 
 | ||||
| 	// domainComponentRegexp restricts the registry domain component of a
 | ||||
| 	// repository name to start with a component as defined by DomainRegexp
 | ||||
| 	// and followed by an optional port.
 | ||||
| 	domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`) | ||||
| 
 | ||||
| 	// DomainRegexp defines the structure of potential domain components
 | ||||
| 	// that may be part of image names. This is purposely a subset of what is
 | ||||
| 	// allowed by DNS to ensure backwards compatibility with Docker image
 | ||||
| 	// names.
 | ||||
| 	DomainRegexp = expression( | ||||
| 		domainComponentRegexp, | ||||
| 		optional(repeated(literal(`.`), domainComponentRegexp)), | ||||
| 		optional(literal(`:`), match(`[0-9]+`))) | ||||
| 
 | ||||
| 	// TagRegexp matches valid tag names. From docker/docker:graph/tags.go.
 | ||||
| 	TagRegexp = match(`[\w][\w.-]{0,127}`) | ||||
| 
 | ||||
| 	// anchoredTagRegexp matches valid tag names, anchored at the start and
 | ||||
| 	// end of the matched string.
 | ||||
| 	anchoredTagRegexp = anchored(TagRegexp) | ||||
| 
 | ||||
| 	// DigestRegexp matches valid digests.
 | ||||
| 	DigestRegexp = match(`[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`) | ||||
| 
 | ||||
| 	// anchoredDigestRegexp matches valid digests, anchored at the start and
 | ||||
| 	// end of the matched string.
 | ||||
| 	anchoredDigestRegexp = anchored(DigestRegexp) | ||||
| 
 | ||||
| 	// NameRegexp is the format for the name component of references. The
 | ||||
| 	// regexp has capturing groups for the domain and name part omitting
 | ||||
| 	// the separating forward slash from either.
 | ||||
| 	NameRegexp = expression( | ||||
| 		optional(DomainRegexp, literal(`/`)), | ||||
| 		nameComponentRegexp, | ||||
| 		optional(repeated(literal(`/`), nameComponentRegexp))) | ||||
| 
 | ||||
| 	// anchoredNameRegexp is used to parse a name value, capturing the
 | ||||
| 	// domain and trailing components.
 | ||||
| 	anchoredNameRegexp = anchored( | ||||
| 		optional(capture(DomainRegexp), literal(`/`)), | ||||
| 		capture(nameComponentRegexp, | ||||
| 			optional(repeated(literal(`/`), nameComponentRegexp)))) | ||||
| 
 | ||||
| 	// ReferenceRegexp is the full supported format of a reference. The regexp
 | ||||
| 	// is anchored and has capturing groups for name, tag, and digest
 | ||||
| 	// components.
 | ||||
| 	ReferenceRegexp = anchored(capture(NameRegexp), | ||||
| 		optional(literal(":"), capture(TagRegexp)), | ||||
| 		optional(literal("@"), capture(DigestRegexp))) | ||||
| 
 | ||||
| 	// IdentifierRegexp is the format for string identifier used as a
 | ||||
| 	// content addressable identifier using sha256. These identifiers
 | ||||
| 	// are like digests without the algorithm, since sha256 is used.
 | ||||
| 	IdentifierRegexp = match(`([a-f0-9]{64})`) | ||||
| 
 | ||||
| 	// ShortIdentifierRegexp is the format used to represent a prefix
 | ||||
| 	// of an identifier. A prefix may be used to match a sha256 identifier
 | ||||
| 	// within a list of trusted identifiers.
 | ||||
| 	ShortIdentifierRegexp = match(`([a-f0-9]{6,64})`) | ||||
| 
 | ||||
| 	// anchoredIdentifierRegexp is used to check or match an
 | ||||
| 	// identifier value, anchored at start and end of string.
 | ||||
| 	anchoredIdentifierRegexp = anchored(IdentifierRegexp) | ||||
| 
 | ||||
| 	// anchoredShortIdentifierRegexp is used to check if a value
 | ||||
| 	// is a possible identifier prefix, anchored at start and end
 | ||||
| 	// of string.
 | ||||
| 	anchoredShortIdentifierRegexp = anchored(ShortIdentifierRegexp) | ||||
| ) | ||||
| 
 | ||||
| // match compiles the string to a regular expression.
 | ||||
| var match = regexp.MustCompile | ||||
| 
 | ||||
| // literal compiles s into a literal regular expression, escaping any regexp
 | ||||
| // reserved characters.
 | ||||
| func literal(s string) *regexp.Regexp { | ||||
| 	re := match(regexp.QuoteMeta(s)) | ||||
| 
 | ||||
| 	if _, complete := re.LiteralPrefix(); !complete { | ||||
| 		panic("must be a literal") | ||||
| 	} | ||||
| 
 | ||||
| 	return re | ||||
| } | ||||
| 
 | ||||
| // expression defines a full expression, where each regular expression must
 | ||||
| // follow the previous.
 | ||||
| func expression(res ...*regexp.Regexp) *regexp.Regexp { | ||||
| 	var s string | ||||
| 	for _, re := range res { | ||||
| 		s += re.String() | ||||
| 	} | ||||
| 
 | ||||
| 	return match(s) | ||||
| } | ||||
| 
 | ||||
| // optional wraps the expression in a non-capturing group and makes the
 | ||||
| // production optional.
 | ||||
| func optional(res ...*regexp.Regexp) *regexp.Regexp { | ||||
| 	return match(group(expression(res...)).String() + `?`) | ||||
| } | ||||
| 
 | ||||
| // repeated wraps the regexp in a non-capturing group to get one or more
 | ||||
| // matches.
 | ||||
| func repeated(res ...*regexp.Regexp) *regexp.Regexp { | ||||
| 	return match(group(expression(res...)).String() + `+`) | ||||
| } | ||||
| 
 | ||||
| // group wraps the regexp in a non-capturing group.
 | ||||
| func group(res ...*regexp.Regexp) *regexp.Regexp { | ||||
| 	return match(`(?:` + expression(res...).String() + `)`) | ||||
| } | ||||
| 
 | ||||
| // capture wraps the expression in a capturing group.
 | ||||
| func capture(res ...*regexp.Regexp) *regexp.Regexp { | ||||
| 	return match(`(` + expression(res...).String() + `)`) | ||||
| } | ||||
| 
 | ||||
| // anchored anchors the regular expression by adding start and end delimiters.
 | ||||
| func anchored(res ...*regexp.Regexp) *regexp.Regexp { | ||||
| 	return match(`^` + expression(res...).String() + `$`) | ||||
| } | ||||
							
								
								
									
										50
									
								
								common/vendor/github.com/docker/distribution/reference/regexp_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										50
									
								
								common/vendor/github.com/docker/distribution/reference/regexp_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,50 @@ | |||
| package reference | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/distribution/reference" | ||||
| ) | ||||
| 
 | ||||
| // DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
 | ||||
| //
 | ||||
| // Deprecated: use [reference.DigestRegexp].
 | ||||
| var DigestRegexp = reference.DigestRegexp | ||||
| 
 | ||||
| // DomainRegexp matches hostname or IP-addresses, optionally including a port
 | ||||
| // number. It defines the structure of potential domain components that may be
 | ||||
| // part of image names. This is purposely a subset of what is allowed by DNS to
 | ||||
| // ensure backwards compatibility with Docker image names. It may be a subset of
 | ||||
| // DNS domain name, an IPv4 address in decimal format, or an IPv6 address between
 | ||||
| // square brackets (excluding zone identifiers as defined by [RFC 6874] or special
 | ||||
| // addresses such as IPv4-Mapped).
 | ||||
| //
 | ||||
| // Deprecated: use [reference.DomainRegexp].
 | ||||
| //
 | ||||
| // [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.
 | ||||
| var DomainRegexp = reference.DigestRegexp | ||||
| 
 | ||||
| // IdentifierRegexp is the format for string identifier used as a
 | ||||
| // content addressable identifier using sha256. These identifiers
 | ||||
| // are like digests without the algorithm, since sha256 is used.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.IdentifierRegexp].
 | ||||
| var IdentifierRegexp = reference.IdentifierRegexp | ||||
| 
 | ||||
| // NameRegexp is the format for the name component of references, including
 | ||||
| // an optional domain and port, but without tag or digest suffix.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.NameRegexp].
 | ||||
| var NameRegexp = reference.NameRegexp | ||||
| 
 | ||||
| // ReferenceRegexp is the full supported format of a reference. The regexp
 | ||||
| // is anchored and has capturing groups for name, tag, and digest
 | ||||
| // components.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.ReferenceRegexp].
 | ||||
| var ReferenceRegexp = reference.ReferenceRegexp | ||||
| 
 | ||||
| // TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].
 | ||||
| //
 | ||||
| // Deprecated: use [reference.TagRegexp].
 | ||||
| //
 | ||||
| // [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28
 | ||||
| var TagRegexp = reference.TagRegexp | ||||
							
								
								
									
										10
									
								
								common/vendor/github.com/docker/distribution/reference/sort_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										10
									
								
								common/vendor/github.com/docker/distribution/reference/sort_deprecated.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,10 @@ | |||
| package reference | ||||
| 
 | ||||
| import "github.com/distribution/reference" | ||||
| 
 | ||||
| // Sort sorts string references preferring higher information references.
 | ||||
| //
 | ||||
| // Deprecated: use [reference.Sort].
 | ||||
| func Sort(references []string) []string { | ||||
| 	return reference.Sort(references) | ||||
| } | ||||
|  | @ -4,7 +4,7 @@ import ( | |||
| 	"net/http" | ||||
| 	"regexp" | ||||
| 
 | ||||
| 	"github.com/docker/distribution/reference" | ||||
| 	"github.com/distribution/reference" | ||||
| 	"github.com/docker/distribution/registry/api/errcode" | ||||
| 	"github.com/opencontainers/go-digest" | ||||
| ) | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ import ( | |||
| 	"net/url" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/docker/distribution/reference" | ||||
| 	"github.com/distribution/reference" | ||||
| 	"github.com/gorilla/mux" | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,18 @@ | |||
| // Copyright 2020, 2020 OCI Contributors
 | ||||
| // Copyright 2017 Docker, Inc.
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     https://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| package digestset | ||||
| 
 | ||||
| import ( | ||||
|  | @ -233,9 +233,11 @@ github.com/davecgh/go-spew/spew | |||
| # github.com/disiqueira/gotree/v3 v3.0.2 | ||||
| ## explicit; go 1.13 | ||||
| github.com/disiqueira/gotree/v3 | ||||
| # github.com/docker/distribution v2.8.2+incompatible | ||||
| # github.com/distribution/reference v0.5.0 | ||||
| ## explicit; go 1.20 | ||||
| github.com/distribution/reference | ||||
| # github.com/docker/distribution v2.8.3+incompatible | ||||
| ## explicit | ||||
| github.com/docker/distribution/digestset | ||||
| github.com/docker/distribution/reference | ||||
| github.com/docker/distribution/registry/api/errcode | ||||
| github.com/docker/distribution/registry/api/v2 | ||||
|  | @ -485,6 +487,7 @@ github.com/onsi/gomega/types | |||
| # github.com/opencontainers/go-digest v1.0.0 | ||||
| ## explicit; go 1.13 | ||||
| github.com/opencontainers/go-digest | ||||
| github.com/opencontainers/go-digest/digestset | ||||
| # github.com/opencontainers/image-spec v1.1.0-rc5 | ||||
| ## explicit; go 1.18 | ||||
| github.com/opencontainers/image-spec/specs-go | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue