forked from mirrors/docker-distribution
Compare commits
18 Commits
master
...
release/2.
Author | SHA1 | Date |
---|---|---|
Richard Scothern | 03efb43768 | |
Arthur Baars | 431e46a7f9 | |
Richard Scothern | 1e0f3b7b64 | |
Arthur Baars | 93e3aa9b21 | |
Aaron Lehmann | 93d76247f2 | |
Richard Scothern | ba672e8b69 | |
Richard Scothern | 96230decb9 | |
Richard Scothern | c0d3813f86 | |
Tony Holdstock-Brown | 011b7e493b | |
Serge Dubrouski | 0a1fcf9712 | |
Anis Elleuch | ed02e88075 | |
Serge Dubrouski | fd5a404996 | |
jhaohai | 3f538cac90 | |
Stefan Majewsky | 3330cc567e | |
Aaron Lehmann | 775d0968cc | |
Arien Holthuizen | 64a9727f11 | |
Tony Holdstock-Brown | dafb59f4ab | |
Richard Scothern | 3f7fa41272 |
|
@ -1,3 +0,0 @@
|
|||
## Docker Distribution Community Code of Conduct
|
||||
|
||||
Docker Distribution follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
|
@ -35,4 +35,3 @@ bin/*
|
|||
# Editor/IDE specific files.
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
.idea/*
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
linters:
|
||||
enable:
|
||||
- structcheck
|
||||
- varcheck
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- ineffassign
|
||||
- vet
|
||||
- unused
|
||||
- misspell
|
||||
disable:
|
||||
- errcheck
|
||||
|
||||
run:
|
||||
deadline: 2m
|
||||
skip-dirs:
|
||||
- vendor
|
28
.mailmap
28
.mailmap
|
@ -1,9 +1,9 @@
|
|||
Stephen J Day <stephen.day@docker.com> Stephen Day <stevvooe@users.noreply.github.com>
|
||||
Stephen J Day <stephen.day@docker.com> Stephen Day <stevvooe@gmail.com>
|
||||
Olivier Gambier <olivier@docker.com> Olivier Gambier <dmp42@users.noreply.github.com>
|
||||
Brian Bland <brian.bland@docker.com> Brian Bland <r4nd0m1n4t0r@gmail.com>
|
||||
Stephen J Day <stephen.day@docker.com> Stephen Day <stevvooe@users.noreply.github.com>
|
||||
Stephen J Day <stephen.day@docker.com> Stephen Day <stevvooe@gmail.com>
|
||||
Olivier Gambier <olivier@docker.com> Olivier Gambier <dmp42@users.noreply.github.com>
|
||||
Brian Bland <brian.bland@docker.com> Brian Bland <r4nd0m1n4t0r@gmail.com>
|
||||
Brian Bland <brian.bland@docker.com> Brian Bland <brian.t.bland@gmail.com>
|
||||
Josh Hawn <josh.hawn@docker.com> Josh Hawn <jlhawn@berkeley.edu>
|
||||
Josh Hawn <josh.hawn@docker.com> Josh Hawn <jlhawn@berkeley.edu>
|
||||
Richard Scothern <richard.scothern@docker.com> Richard <richard.scothern@gmail.com>
|
||||
Richard Scothern <richard.scothern@docker.com> Richard Scothern <richard.scothern@gmail.com>
|
||||
Andrew Meredith <andymeredith@gmail.com> Andrew Meredith <kendru@users.noreply.github.com>
|
||||
|
@ -13,20 +13,4 @@ Sharif Nassar <sharif@mrwacky.com> Sharif Nassar <mrwacky42@users.noreply.github
|
|||
Sven Dowideit <SvenDowideit@home.org.au> Sven Dowideit <SvenDowideit@users.noreply.github.com>
|
||||
Vincent Giersch <vincent.giersch@ovh.net> Vincent Giersch <vincent@giersch.fr>
|
||||
davidli <wenquan.li@hp.com> davidli <wenquan.li@hpe.com>
|
||||
Omer Cohen <git@omer.io> Omer Cohen <git@omerc.net>
|
||||
Eric Yang <windfarer@gmail.com> Eric Yang <Windfarer@users.noreply.github.com>
|
||||
Nikita Tarasov <nikita@mygento.ru> Nikita <luckyraul@users.noreply.github.com>
|
||||
Yu Wang <yuwa@microsoft.com> yuwaMSFT2 <yuwa@microsoft.com>
|
||||
Yu Wang <yuwa@microsoft.com> Yu Wang (UC) <yuwa@microsoft.com>
|
||||
Olivier Gambier <olivier@docker.com> dmp <dmp@loaner.local>
|
||||
Olivier Gambier <olivier@docker.com> Olivier <o+github@gambier.email>
|
||||
Olivier Gambier <olivier@docker.com> Olivier <dmp42@users.noreply.github.com>
|
||||
Elsan Li 李楠 <elsanli@tencent.com> elsanli(李楠) <elsanli@tencent.com>
|
||||
Rui Cao <ruicao@alauda.io> ruicao <ruicao@alauda.io>
|
||||
Gwendolynne Barr <gwendolynne.barr@docker.com> gbarr01 <gwendolynne.barr@docker.com>
|
||||
Haibing Zhou 周海兵 <zhouhaibing089@gmail.com> zhouhaibing089 <zhouhaibing089@gmail.com>
|
||||
Feng Honglin <tifayuki@gmail.com> tifayuki <tifayuki@gmail.com>
|
||||
Helen Xie <xieyulin821@harmonycloud.cn> Helen-xie <xieyulin821@harmonycloud.cn>
|
||||
Mike Brown <brownwm@us.ibm.com> Mike Brown <mikebrow@users.noreply.github.com>
|
||||
Manish Tomar <manish.tomar@docker.com> Manish Tomar <manishtomar@users.noreply.github.com>
|
||||
Sakeven Jiang <jc5930@sina.cn> sakeven <jc5930@sina.cn>
|
||||
Omer Cohen <git@omer.io> Omer Cohen <git@omerc.net>
|
56
.travis.yml
56
.travis.yml
|
@ -1,56 +0,0 @@
|
|||
dist: bionic
|
||||
sudo: required
|
||||
# setup travis so that we can run containers for integration tests
|
||||
services:
|
||||
- docker
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- arch: amd64
|
||||
- arch: s390x
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- "1.14.x"
|
||||
|
||||
go_import_path: github.com/docker/distribution
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- python-minimal
|
||||
|
||||
|
||||
env:
|
||||
- TRAVIS_GOOS=linux DOCKER_BUILDTAGS="include_oss include_gcs" TRAVIS_CGO_ENABLED=1
|
||||
|
||||
before_install:
|
||||
- uname -r
|
||||
- sudo apt-get -q update
|
||||
|
||||
install:
|
||||
- cd /tmp && go get -u github.com/vbatts/git-validation
|
||||
# TODO: Add enforcement of license
|
||||
# - go get -u github.com/kunalkushwaha/ltag
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
|
||||
script:
|
||||
- export GOOS=$TRAVIS_GOOS
|
||||
- export CGO_ENABLED=$TRAVIS_CGO_ENABLED
|
||||
- DCO_VERBOSITY=-q script/validate/dco
|
||||
- GOOS=linux GO111MODULE=on script/setup/install-dev-tools
|
||||
- script/validate/vendor
|
||||
- go build -i .
|
||||
- make check
|
||||
- make build
|
||||
- make binaries
|
||||
# Currently takes too long
|
||||
#- if [ "$GOOS" = "linux" ]; then make test-race ; fi
|
||||
- if [ "$GOOS" = "linux" ]; then make coverage ; fi
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash) -F linux
|
||||
|
||||
before_deploy:
|
||||
# Run tests with storage driver configurations
|
|
@ -0,0 +1,133 @@
|
|||
Aaron Lehmann <aaron.lehmann@docker.com>
|
||||
Aaron Schlesinger <aschlesinger@deis.com>
|
||||
Aaron Vinson <avinson.public@gmail.com>
|
||||
Adam Enger <adamenger@gmail.com>
|
||||
Adrian Mouat <adrian.mouat@gmail.com>
|
||||
Ahmet Alp Balkan <ahmetalpbalkan@gmail.com>
|
||||
Alex Chan <alex.chan@metaswitch.com>
|
||||
Alex Elman <aelman@indeed.com>
|
||||
amitshukla <ashukla73@hotmail.com>
|
||||
Amy Lindburg <amy.lindburg@docker.com>
|
||||
Andrew Meredith <andymeredith@gmail.com>
|
||||
Andrew T Nguyen <andrew.nguyen@docker.com>
|
||||
Andrey Kostov <kostov.andrey@gmail.com>
|
||||
Andy Goldstein <agoldste@redhat.com>
|
||||
Anton Tiurin <noxiouz@yandex.ru>
|
||||
Antonio Mercado <amercado@thinknode.com>
|
||||
Antonio Murdaca <runcom@redhat.com>
|
||||
Arnaud Porterie <arnaud.porterie@docker.com>
|
||||
Arthur Baars <arthur@semmle.com>
|
||||
Asuka Suzuki <hello@tanksuzuki.com>
|
||||
Avi Miller <avi.miller@oracle.com>
|
||||
Ayose Cazorla <ayosec@gmail.com>
|
||||
BadZen <dave.trombley@gmail.com>
|
||||
Ben Firshman <ben@firshman.co.uk>
|
||||
bin liu <liubin0329@gmail.com>
|
||||
Brian Bland <brian.bland@docker.com>
|
||||
burnettk <burnettk@gmail.com>
|
||||
Carson A <ca@carsonoid.net>
|
||||
Chris Dillon <squarism@gmail.com>
|
||||
Daisuke Fujita <dtanshi45@gmail.com>
|
||||
Daniel Huhn <daniel@danielhuhn.de>
|
||||
Darren Shepherd <darren@rancher.com>
|
||||
Dave Trombley <dave.trombley@gmail.com>
|
||||
Dave Tucker <dt@docker.com>
|
||||
David Lawrence <david.lawrence@docker.com>
|
||||
David Verhasselt <david@crowdway.com>
|
||||
David Xia <dxia@spotify.com>
|
||||
davidli <wenquan.li@hp.com>
|
||||
Dejan Golja <dejan@golja.org>
|
||||
Derek McGowan <derek@mcgstyle.net>
|
||||
Diogo Mónica <diogo.monica@gmail.com>
|
||||
DJ Enriquez <dj.enriquez@infospace.com>
|
||||
Donald Huang <don.hcd@gmail.com>
|
||||
Doug Davis <dug@us.ibm.com>
|
||||
Eric Yang <windfarer@gmail.com>
|
||||
farmerworking <farmerworking@gmail.com>
|
||||
Felix Yan <felixonmars@archlinux.org>
|
||||
Florentin Raud <florentin.raud@gmail.com>
|
||||
Frederick F. Kautz IV <fkautz@alumni.cmu.edu>
|
||||
gabriell nascimento <gabriell@bluesoft.com.br>
|
||||
harche <p.harshal@gmail.com>
|
||||
Henri Gomez <henri.gomez@gmail.com>
|
||||
Hu Keping <hukeping@huawei.com>
|
||||
Hua Wang <wanghua.humble@gmail.com>
|
||||
HuKeping <hukeping@huawei.com>
|
||||
Ian Babrou <ibobrik@gmail.com>
|
||||
igayoso <igayoso@gmail.com>
|
||||
Jack Griffin <jackpg14@gmail.com>
|
||||
Jason Freidman <jason.freidman@gmail.com>
|
||||
Jeff Nickoloff <jeff@allingeek.com>
|
||||
Jessie Frazelle <jessie@docker.com>
|
||||
Jianqing Wang <tsing@jianqing.org>
|
||||
John Starks <jostarks@microsoft.com>
|
||||
Jon Johnson <jonjohnson@google.com>
|
||||
Jon Poler <jonathan.poler@apcera.com>
|
||||
Jonathan Boulle <jonathanboulle@gmail.com>
|
||||
Jordan Liggitt <jliggitt@redhat.com>
|
||||
Josh Hawn <josh.hawn@docker.com>
|
||||
Julien Fernandez <julien.fernandez@gmail.com>
|
||||
Keerthan Mala <kmala@engineyard.com>
|
||||
Kelsey Hightower <kelsey.hightower@gmail.com>
|
||||
Kenneth Lim <kennethlimcp@gmail.com>
|
||||
Kenny Leung <kleung@google.com>
|
||||
Li Yi <denverdino@gmail.com>
|
||||
Liu Hua <sdu.liu@huawei.com>
|
||||
liuchang0812 <liuchang0812@gmail.com>
|
||||
Louis Kottmann <louis.kottmann@gmail.com>
|
||||
Luke Carpenter <x@rubynerd.net>
|
||||
Mary Anthony <mary@docker.com>
|
||||
Matt Bentley <mbentley@mbentley.net>
|
||||
Matt Duch <matt@learnmetrics.com>
|
||||
Matt Moore <mattmoor@google.com>
|
||||
Matt Robenolt <matt@ydekproductions.com>
|
||||
Michael Prokop <mika@grml.org>
|
||||
Michal Minar <miminar@redhat.com>
|
||||
Miquel Sabaté <msabate@suse.com>
|
||||
Morgan Bauer <mbauer@us.ibm.com>
|
||||
moxiegirl <mary@docker.com>
|
||||
Nathan Sullivan <nathan@nightsys.net>
|
||||
nevermosby <robolwq@qq.com>
|
||||
Nghia Tran <tcnghia@gmail.com>
|
||||
Nuutti Kotivuori <nuutti.kotivuori@poplatek.fi>
|
||||
Oilbeater <liumengxinfly@gmail.com>
|
||||
Olivier Gambier <olivier@docker.com>
|
||||
Olivier Jacques <olivier.jacques@hp.com>
|
||||
Omer Cohen <git@omer.io>
|
||||
Patrick Devine <patrick.devine@docker.com>
|
||||
Philip Misiowiec <philip@atlashealth.com>
|
||||
Richard Scothern <richard.scothern@docker.com>
|
||||
Rodolfo Carvalho <rhcarvalho@gmail.com>
|
||||
Rusty Conover <rusty@luckydinosaur.com>
|
||||
Sean Boran <Boran@users.noreply.github.com>
|
||||
Sebastiaan van Stijn <github@gone.nl>
|
||||
Sharif Nassar <sharif@mrwacky.com>
|
||||
Shawn Falkner-Horine <dreadpirateshawn@gmail.com>
|
||||
Shreyas Karnik <karnik.shreyas@gmail.com>
|
||||
Simon Thulbourn <simon+github@thulbourn.com>
|
||||
Spencer Rinehart <anubis@overthemonkey.com>
|
||||
Stefan Majewsky <stefan.majewsky@sap.com>
|
||||
Stefan Weil <sw@weilnetz.de>
|
||||
Stephen J Day <stephen.day@docker.com>
|
||||
Sungho Moon <sungho.moon@navercorp.com>
|
||||
Sven Dowideit <SvenDowideit@home.org.au>
|
||||
Sylvain Baubeau <sbaubeau@redhat.com>
|
||||
Ted Reed <ted.reed@gmail.com>
|
||||
tgic <farmer1992@gmail.com>
|
||||
Thomas Sjögren <konstruktoid@users.noreply.github.com>
|
||||
Tianon Gravi <admwiggin@gmail.com>
|
||||
Tibor Vass <teabee89@gmail.com>
|
||||
Tonis Tiigi <tonistiigi@gmail.com>
|
||||
Tony Holdstock-Brown <tony@docker.com>
|
||||
Trevor Pounds <trevor.pounds@gmail.com>
|
||||
Troels Thomsen <troels@thomsen.io>
|
||||
Vincent Batts <vbatts@redhat.com>
|
||||
Vincent Demeester <vincent@sbr.pm>
|
||||
Vincent Giersch <vincent.giersch@ovh.net>
|
||||
W. Trevor King <wking@tremily.us>
|
||||
weiyuan.yl <weiyuan.yl@alibaba-inc.com>
|
||||
xg.song <xg.song@venusource.com>
|
||||
xiekeyang <xiekeyang@huawei.com>
|
||||
Yann ROBERT <yann.robert@anantaplex.fr>
|
||||
yuzou <zouyu7@huawei.com>
|
||||
姜继忠 <jizhong.jiangjz@alibaba-inc.com>
|
147
CONTRIBUTING.md
147
CONTRIBUTING.md
|
@ -1,15 +1,14 @@
|
|||
# Contributing to the registry
|
||||
|
||||
## Before reporting an issue...
|
||||
## Before reporting an issue...
|
||||
|
||||
### If your problem is with...
|
||||
|
||||
- automated builds or your [Docker Hub](https://hub.docker.com/) account
|
||||
- Report it to [Hub Support](https://hub.docker.com/support/)
|
||||
- Distributions of Docker for desktop or Linux
|
||||
- Report [Mac Desktop issues](https://github.com/docker/for-mac)
|
||||
- Report [Windows Desktop issues](https://github.com/docker/for-win)
|
||||
- Report [Linux issues](https://github.com/docker/for-linux)
|
||||
- automated builds
|
||||
- your account on the [Docker Hub](https://hub.docker.com/)
|
||||
- any other [Docker Hub](https://hub.docker.com/) issue
|
||||
|
||||
Then please do not report your issue here - you should instead report it to [https://support.docker.com](https://support.docker.com)
|
||||
|
||||
### If you...
|
||||
|
||||
|
@ -17,16 +16,10 @@
|
|||
- can't figure out something
|
||||
- are not sure what's going on or what your problem is
|
||||
|
||||
Please ask first in the #distribution channel on Docker community slack.
|
||||
[Click here for an invite to Docker community slack](https://dockr.ly/slack)
|
||||
Then please do not open an issue here yet - you should first try one of the following support forums:
|
||||
|
||||
### Reporting security issues
|
||||
|
||||
The Docker 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
|
||||
[security@docker.com](mailto:security@docker.com).
|
||||
- irc: #docker-distribution on freenode
|
||||
- mailing-list: <distribution@dockerproject.org> or https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution
|
||||
|
||||
## Reporting an issue properly
|
||||
|
||||
|
@ -34,7 +27,7 @@ By following these simple rules you will get better and faster feedback on your
|
|||
|
||||
- search the bugtracker for an already reported issue
|
||||
|
||||
### If you found an issue that describes your problem:
|
||||
### 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
|
||||
|
@ -50,7 +43,7 @@ By following these simple rules you will get better and faster feedback on your
|
|||
2. copy the output of:
|
||||
- `docker version`
|
||||
- `docker info`
|
||||
- `docker exec <registry-container> registry --version`
|
||||
- `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
|
||||
|
@ -58,72 +51,90 @@ By following these simple rules you will get better and faster feedback on your
|
|||
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.
|
||||
## Contributing a patch for a known bug, or a small correction
|
||||
|
||||
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)
|
||||
1. fork
|
||||
2. commit a change
|
||||
3. make sure the tests pass
|
||||
4. PR
|
||||
|
||||
Refer to [containerd's contribution guide](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)
|
||||
for tips on creating a successful contribution.
|
||||
Additionally, you must [sign your commits](https://github.com/docker/docker/blob/master/CONTRIBUTING.md#sign-your-work). It's very simple:
|
||||
|
||||
## Sign your work
|
||||
- configure your name with git: `git config user.name "Real Name" && git config user.email mail@example.com`
|
||||
- sign your commits using `-s`: `git commit -s -m "My commit"`
|
||||
|
||||
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/)):
|
||||
Some simple rules to ensure quick merge:
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
- clearly point to the issue(s) you want to fix in your PR comment (e.g., `closes #12345`)
|
||||
- prefer multiple (smaller) PRs addressing individual issues over a big one trying to address multiple issues at once
|
||||
- if you need to amend your PR following comments, please squash instead of adding more commits
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
## Contributing new features
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
You are heavily encouraged to first discuss what you want to do. You can do so on the irc channel, or by opening an issue that clearly describes the use case you want to fulfill, or the problem you are trying to solve.
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
If this is a major new feature, you should then submit a proposal that describes your technical solution and reasoning.
|
||||
If you did discuss it first, this will likely be greenlighted very fast. It's advisable to address all feedback on this proposal before starting actual work.
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
Then you should submit your implementation, clearly linking to the issue (and possible proposal).
|
||||
|
||||
(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
|
||||
Your PR will be reviewed by the community, then ultimately by the project maintainers, before being merged.
|
||||
|
||||
(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
|
||||
It's mandatory to:
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
- interact respectfully with other community members and maintainers - more generally, you are expected to abide by the [Docker community rules](https://github.com/docker/docker/blob/master/CONTRIBUTING.md#docker-community-guidelines)
|
||||
- address maintainers' comments and modify your submission accordingly
|
||||
- write tests for any new code
|
||||
|
||||
(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.
|
||||
```
|
||||
Complying to these simple rules will greatly accelerate the review process, and will ensure you have a pleasant experience in contributing code to the Registry.
|
||||
|
||||
Then you just add a line to every git commit message:
|
||||
Have a look at a great, successful contribution: the [Swift driver PR](https://github.com/docker/distribution/pull/493)
|
||||
|
||||
Signed-off-by: Joe Smith <joe.smith@email.com>
|
||||
## Coding Style
|
||||
|
||||
Use your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
Unless explicitly stated, we follow all coding guidelines from the Go
|
||||
community. While some of these standards may seem arbitrary, they somehow seem
|
||||
to result in a solid, consistent codebase.
|
||||
|
||||
If you set your `user.name` and `user.email` git configs, you can sign your
|
||||
commit automatically with `git commit -s`.
|
||||
It is possible that the code base does not currently comply with these
|
||||
guidelines. We are not looking for a massive PR that fixes this, since that
|
||||
goes against the spirit of the guidelines. All new contributions should make a
|
||||
best effort to clean up and make the code base better than they left it.
|
||||
Obviously, apply your best judgement. Remember, the goal here is to make the
|
||||
code base easier for humans to navigate and understand. Always keep that in
|
||||
mind when nudging others to comply.
|
||||
|
||||
The rules:
|
||||
|
||||
1. All code should be formatted with `gofmt -s`.
|
||||
2. All code should pass the default levels of
|
||||
[`golint`](https://github.com/golang/lint).
|
||||
3. All code should follow the guidelines covered in [Effective
|
||||
Go](http://golang.org/doc/effective_go.html) and [Go Code Review
|
||||
Comments](https://github.com/golang/go/wiki/CodeReviewComments).
|
||||
4. Comment the code. Tell us the why, the history and the context.
|
||||
5. Document _all_ declarations and methods, even private ones. Declare
|
||||
expectations, caveats and anything else that may be important. If a type
|
||||
gets exported, having the comments already there will ensure it's ready.
|
||||
6. Variable name length should be proportional to its context and no longer.
|
||||
`noCommaALongVariableNameLikeThisIsNotMoreClearWhenASimpleCommentWouldDo`.
|
||||
In practice, short methods will have short variable names and globals will
|
||||
have longer names.
|
||||
7. No underscores in package names. If you need a compound name, step back,
|
||||
and re-examine why you need a compound name. If you still think you need a
|
||||
compound name, lose the underscore.
|
||||
8. No utils or helpers packages. If a function is not general enough to
|
||||
warrant its own package, it has not been written generally enough to be a
|
||||
part of a util package. Just leave it unexported and well-documented.
|
||||
9. All tests should run with `go test` and outside tooling should not be
|
||||
required. No, we don't need another unit testing framework. Assertion
|
||||
packages are acceptable if they provide _real_ incremental value.
|
||||
10. Even though we call these "rules" above, they are actually just
|
||||
guidelines. Since you've read all the rules, you now know that.
|
||||
|
||||
If you are having trouble getting into the mood of idiomatic Go, we recommend
|
||||
reading through [Effective Go](http://golang.org/doc/effective_go.html). The
|
||||
[Go Blog](http://blog.golang.org/) is also a great resource. Drinking the
|
||||
kool-aid is a lot easier than going thirsty.
|
||||
|
|
27
Dockerfile
27
Dockerfile
|
@ -1,30 +1,17 @@
|
|||
ARG GO_VERSION=1.13.8
|
||||
FROM golang:1.6
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine3.11 AS build
|
||||
RUN apt-get update && \
|
||||
apt-get install -y apache2-utils && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV DISTRIBUTION_DIR /go/src/github.com/docker/distribution
|
||||
ENV BUILDTAGS include_oss include_gcs
|
||||
|
||||
ARG GOOS=linux
|
||||
ARG GOARCH=amd64
|
||||
ARG GOARM=6
|
||||
ARG VERSION
|
||||
ARG REVISION
|
||||
|
||||
RUN set -ex \
|
||||
&& apk add --no-cache make git file
|
||||
ENV DOCKER_BUILDTAGS include_oss include_gcs
|
||||
|
||||
WORKDIR $DISTRIBUTION_DIR
|
||||
COPY . $DISTRIBUTION_DIR
|
||||
RUN CGO_ENABLED=0 make PREFIX=/go clean binaries && file ./bin/registry | grep "statically linked"
|
||||
|
||||
FROM alpine:3.11
|
||||
|
||||
RUN set -ex \
|
||||
&& apk add --no-cache ca-certificates apache2-utils
|
||||
|
||||
COPY cmd/registry/config-dev.yml /etc/docker/registry/config.yml
|
||||
COPY --from=build /go/src/github.com/docker/distribution/bin/registry /bin/registry
|
||||
RUN make PREFIX=/go clean binaries
|
||||
|
||||
VOLUME ["/var/lib/registry"]
|
||||
EXPOSE 5000
|
||||
ENTRYPOINT ["registry"]
|
||||
|
|
144
GOVERNANCE.md
144
GOVERNANCE.md
|
@ -1,144 +0,0 @@
|
|||
# docker/distribution Project Governance
|
||||
|
||||
Docker distribution abides by the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
||||
|
||||
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,430 @@
|
|||
{
|
||||
"ImportPath": "github.com/docker/distribution",
|
||||
"GoVersion": "go1.6",
|
||||
"GodepVersion": "v60",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/Azure/azure-sdk-for-go/storage",
|
||||
"Comment": "v1.2-334-g95361a2",
|
||||
"Rev": "95361a2573b1fa92a00c5fc2707a80308483c6f9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Sirupsen/logrus",
|
||||
"Comment": "v0.7.3",
|
||||
"Rev": "55eb11d21d2a31a3cc93838241d04800f52e823d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Sirupsen/logrus/formatters/logstash",
|
||||
"Comment": "v0.7.3",
|
||||
"Rev": "55eb11d21d2a31a3cc93838241d04800f52e823d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/request",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/session",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/endpoints",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/restxml",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/signer/v4",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/waiter",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/cloudfront/sign",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/s3",
|
||||
"Comment": "v1.1.0-14-g49c3892",
|
||||
"Rev": "49c3892b61af1d4996292a3025f36e4dfa25eaee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bugsnag/bugsnag-go",
|
||||
"Comment": "v1.0.2-5-gb1d1530",
|
||||
"Rev": "b1d153021fcd90ca3f080db36bec96dc690fb274"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bugsnag/bugsnag-go/errors",
|
||||
"Comment": "v1.0.2-5-gb1d1530",
|
||||
"Rev": "b1d153021fcd90ca3f080db36bec96dc690fb274"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bugsnag/osext",
|
||||
"Rev": "0dd3f918b21bec95ace9dc86c7e70266cfc5c702"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bugsnag/panicwrap",
|
||||
"Comment": "1.0.0-2-ge2c2850",
|
||||
"Rev": "e2c28503fcd0675329da73bf48b33404db873782"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/denverdino/aliyungo/common",
|
||||
"Rev": "6ffb587da9da6d029d0ce517b85fecc82172d502"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/denverdino/aliyungo/oss",
|
||||
"Rev": "6ffb587da9da6d029d0ce517b85fecc82172d502"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/denverdino/aliyungo/util",
|
||||
"Rev": "6ffb587da9da6d029d0ce517b85fecc82172d502"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/goamz/aws",
|
||||
"Rev": "f0a21f5b2e12f83a505ecf79b633bb2035cf6f85"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/goamz/s3",
|
||||
"Rev": "f0a21f5b2e12f83a505ecf79b633bb2035cf6f85"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/libtrust",
|
||||
"Rev": "fa567046d9b14f6aa788882a950d69651d230b21"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/garyburd/redigo/internal",
|
||||
"Rev": "535138d7bcd717d6531c701ef5933d98b1866257"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/garyburd/redigo/redis",
|
||||
"Rev": "535138d7bcd717d6531c701ef5933d98b1866257"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-ini/ini",
|
||||
"Comment": "v1.8.6",
|
||||
"Rev": "afbd495e5aaea13597b5e14fe514ddeaa4d76fc3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/proto",
|
||||
"Rev": "8d92cf5fc15a4382f8964b08e1f42a75c0591aa3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/context",
|
||||
"Rev": "14f550f51af52180c2eefed15e5fd18d63c0a64a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/handlers",
|
||||
"Rev": "60c7bfde3e33c201519a200a4507a158cc03a17b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/mux",
|
||||
"Rev": "e444e69cbd2e2e3e0749a2f3c717cec491552bbf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/inconshreveable/mousetrap",
|
||||
"Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jmespath/go-jmespath",
|
||||
"Comment": "0.2.2-12-g0b12d6b",
|
||||
"Rev": "0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/mapstructure",
|
||||
"Rev": "482a9fd5fa83e8c4e7817413b80f3eb8feec03ef"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ncw/swift",
|
||||
"Rev": "c54732e87b0b283d1baf0a18db689d0aea460ba3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ncw/swift/swifttest",
|
||||
"Rev": "c54732e87b0b283d1baf0a18db689d0aea460ba3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/cobra",
|
||||
"Rev": "312092086bed4968099259622145a0c9ae280064"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/pflag",
|
||||
"Rev": "5644820622454e71517561946e3d94b9f9db6842"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stevvooe/resumable",
|
||||
"Rev": "51ad44105773cafcbe91927f70ac68e1bf78f8b4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stevvooe/resumable/sha256",
|
||||
"Rev": "51ad44105773cafcbe91927f70ac68e1bf78f8b4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stevvooe/resumable/sha512",
|
||||
"Rev": "51ad44105773cafcbe91927f70ac68e1bf78f8b4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/yvasiyarov/go-metrics",
|
||||
"Rev": "57bccd1ccd43f94bb17fdd8bf3007059b802f85e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/yvasiyarov/gorelic",
|
||||
"Comment": "v0.0.6-8-ga9bba5b",
|
||||
"Rev": "a9bba5b9ab508a086f9a12b8c51fab68478e2128"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/yvasiyarov/newrelic_platform_go",
|
||||
"Rev": "b21fdbd4370f3717f3bbd2bf41c223bc273068e6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/bcrypt",
|
||||
"Rev": "c10c31b5e94b6f7a0283272dc2bb27163dcea24b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/blowfish",
|
||||
"Rev": "c10c31b5e94b6f7a0283272dc2bb27163dcea24b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context",
|
||||
"Rev": "4876518f9e71663000c348837735820161a42df7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context/ctxhttp",
|
||||
"Rev": "4876518f9e71663000c348837735820161a42df7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/http2",
|
||||
"Rev": "4876518f9e71663000c348837735820161a42df7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/http2/hpack",
|
||||
"Rev": "4876518f9e71663000c348837735820161a42df7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/internal/timeseries",
|
||||
"Rev": "4876518f9e71663000c348837735820161a42df7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/trace",
|
||||
"Rev": "4876518f9e71663000c348837735820161a42df7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2",
|
||||
"Rev": "045497edb6234273d67dbc25da3f2ddbc4c4cacf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/google",
|
||||
"Rev": "045497edb6234273d67dbc25da3f2ddbc4c4cacf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/internal",
|
||||
"Rev": "045497edb6234273d67dbc25da3f2ddbc4c4cacf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/jws",
|
||||
"Rev": "045497edb6234273d67dbc25da3f2ddbc4c4cacf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/jwt",
|
||||
"Rev": "045497edb6234273d67dbc25da3f2ddbc4c4cacf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/gensupport",
|
||||
"Rev": "9bf6e6e569ff057f75d9604a46c52928f17d2b54"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/googleapi",
|
||||
"Rev": "9bf6e6e569ff057f75d9604a46c52928f17d2b54"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/googleapi/internal/uritemplates",
|
||||
"Rev": "9bf6e6e569ff057f75d9604a46c52928f17d2b54"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/storage/v1",
|
||||
"Rev": "9bf6e6e569ff057f75d9604a46c52928f17d2b54"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/app_identity",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/base",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/datastore",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/log",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/modules",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/remote_api",
|
||||
"Rev": "12d5545dc1cfa6047a286d5e853841b6471f4c19"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/cloud",
|
||||
"Rev": "975617b05ea8a58727e6c1a06b6161ff4185a9f2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/cloud/compute/metadata",
|
||||
"Rev": "975617b05ea8a58727e6c1a06b6161ff4185a9f2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/cloud/internal",
|
||||
"Rev": "975617b05ea8a58727e6c1a06b6161ff4185a9f2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/cloud/internal/opts",
|
||||
"Rev": "975617b05ea8a58727e6c1a06b6161ff4185a9f2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/cloud/storage",
|
||||
"Rev": "975617b05ea8a58727e6c1a06b6161ff4185a9f2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/codes",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/credentials",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/grpclog",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/internal",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/metadata",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/naming",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/peer",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc/transport",
|
||||
"Rev": "d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/check.v1",
|
||||
"Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/yaml.v2",
|
||||
"Rev": "bef53efd0c76e49e6de55ead051f886bea7e9420"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
This directory tree is generated automatically by godep.
|
||||
|
||||
Please do not edit.
|
||||
|
||||
See https://github.com/tools/godep for more information.
|
73
MAINTAINERS
73
MAINTAINERS
|
@ -1,16 +1,63 @@
|
|||
# Docker distribution project maintainers & reviewers
|
||||
# Distribution maintainers file
|
||||
#
|
||||
# See GOVERNANCE.md for maintainer versus reviewer roles
|
||||
# This file describes who runs the docker/distribution project and how.
|
||||
# This is a living document - if you see something out of date or missing, speak up!
|
||||
#
|
||||
# MAINTAINERS
|
||||
# GitHub ID, Name, Email address
|
||||
"dmcgowan","Derek McGowan","derek@mcgstyle.net"
|
||||
"manishtomar","Manish Tomar","manish.tomar@docker.com"
|
||||
"stevvooe","Stephen Day","stevvooe@gmail.com"
|
||||
# It is structured to be consumable by both humans and programs.
|
||||
# To extract its contents programmatically, use any TOML-compliant parser.
|
||||
#
|
||||
# REVIEWERS
|
||||
# GitHub ID, Name, Email address
|
||||
"caervs","Ryan Abrams","rdabrams@gmail.com"
|
||||
"davidswu","David Wu","dwu7401@gmail.com"
|
||||
"RobbKistler","Robb Kistler","robb.kistler@docker.com"
|
||||
"thajeztah","Sebastiaan van Stijn","github@gone.nl"
|
||||
# This file is compiled into the MAINTAINERS file in docker/opensource.
|
||||
#
|
||||
[Org]
|
||||
[Org."Core maintainers"]
|
||||
people = [
|
||||
"aaronlehmann",
|
||||
"dmcgowan",
|
||||
"dmp42",
|
||||
"richardscothern",
|
||||
"shykes",
|
||||
"stevvooe",
|
||||
]
|
||||
|
||||
[people]
|
||||
|
||||
# A reference list of all people associated with the project.
|
||||
# All other sections should refer to people by their canonical key
|
||||
# in the people section.
|
||||
|
||||
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
|
||||
|
||||
[people.aaronlehmann]
|
||||
Name = "Aaron Lehmann"
|
||||
Email = "aaron.lehmann@docker.com"
|
||||
GitHub = "aaronlehmann"
|
||||
|
||||
[people.brianbland]
|
||||
Name = "Brian Bland"
|
||||
Email = "brian.bland@docker.com"
|
||||
GitHub = "BrianBland"
|
||||
|
||||
[people.dmcgowan]
|
||||
Name = "Derek McGowan"
|
||||
Email = "derek@mcgstyle.net"
|
||||
GitHub = "dmcgowan"
|
||||
|
||||
[people.dmp42]
|
||||
Name = "Olivier Gambier"
|
||||
Email = "olivier@docker.com"
|
||||
GitHub = "dmp42"
|
||||
|
||||
[people.richardscothern]
|
||||
Name = "Richard Scothern"
|
||||
Email = "richard.scothern@gmail.com"
|
||||
GitHub = "richardscothern"
|
||||
|
||||
[people.shykes]
|
||||
Name = "Solomon Hykes"
|
||||
Email = "solomon@docker.com"
|
||||
GitHub = "shykes"
|
||||
|
||||
[people.stevvooe]
|
||||
Name = "Stephen Day"
|
||||
Email = "stephen.day@docker.com"
|
||||
GitHub = "stevvooe"
|
||||
|
|
155
Makefile
155
Makefile
|
@ -1,21 +1,9 @@
|
|||
# Root directory of the project (absolute path).
|
||||
ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
# Set an output prefix, which is the local directory if not specified
|
||||
PREFIX?=$(shell pwd)
|
||||
|
||||
|
||||
# Used to populate version variable in main package.
|
||||
VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.m' --always)
|
||||
REVISION ?= $(shell git rev-parse HEAD)$(shell if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi)
|
||||
|
||||
|
||||
PKG=github.com/docker/distribution
|
||||
|
||||
# Project packages.
|
||||
PACKAGES=$(shell go list -tags "${BUILDTAGS}" ./... | grep -v /vendor/)
|
||||
INTEGRATION_PACKAGE=${PKG}
|
||||
COVERAGE_PACKAGES=$(filter-out ${PKG}/registry/storage/driver/%,${PACKAGES})
|
||||
|
||||
|
||||
# Project binaries.
|
||||
COMMANDS=registry digest registry-api-descriptor-template
|
||||
VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always)
|
||||
|
||||
# Allow turning off function inlining and variable registerization
|
||||
ifeq (${DISABLE_OPTIMIZATION},true)
|
||||
|
@ -23,80 +11,99 @@ ifeq (${DISABLE_OPTIMIZATION},true)
|
|||
VERSION:="$(VERSION)-noopt"
|
||||
endif
|
||||
|
||||
WHALE = "+"
|
||||
GO_LDFLAGS=-ldflags "-X `go list ./version`.Version=$(VERSION)"
|
||||
|
||||
# Go files
|
||||
#
|
||||
TESTFLAGS_RACE=
|
||||
GOFILES=$(shell find . -type f -name '*.go')
|
||||
GO_TAGS=$(if $(BUILDTAGS),-tags "$(BUILDTAGS)",)
|
||||
GO_LDFLAGS=-ldflags '-s -w -X $(PKG)/version.Version=$(VERSION) -X $(PKG)/version.Revision=$(REVISION) -X $(PKG)/version.Package=$(PKG) $(EXTRA_LDFLAGS)'
|
||||
|
||||
BINARIES=$(addprefix bin/,$(COMMANDS))
|
||||
|
||||
# Flags passed to `go test`
|
||||
TESTFLAGS ?= -v $(TESTFLAGS_RACE)
|
||||
TESTFLAGS_PARALLEL ?= 8
|
||||
|
||||
.PHONY: all build binaries check clean test test-race test-full integration coverage
|
||||
.PHONY: clean all fmt vet lint build test binaries
|
||||
.DEFAULT: all
|
||||
all: fmt vet lint build test binaries
|
||||
|
||||
all: binaries
|
||||
AUTHORS: .mailmap .git/HEAD
|
||||
git log --format='%aN <%aE>' | sort -fu > $@
|
||||
|
||||
# This only needs to be generated by hand when cutting full releases.
|
||||
version/version.go:
|
||||
@echo "$(WHALE) $@"
|
||||
./version/version.sh > $@
|
||||
|
||||
check: ## run all linters (TODO: enable "unused", "varcheck", "ineffassign", "unconvert", "staticheck", "goimports", "structcheck")
|
||||
@echo "$(WHALE) $@"
|
||||
@GO111MODULE=off golangci-lint run
|
||||
# Required for go 1.5 to build
|
||||
GO15VENDOREXPERIMENT := 1
|
||||
|
||||
test: ## run tests, except integration test with test.short
|
||||
@echo "$(WHALE) $@"
|
||||
@go test ${GO_TAGS} -test.short ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${PACKAGES})
|
||||
# Package list
|
||||
PKGS := $(shell go list -tags "${DOCKER_BUILDTAGS}" ./... | grep -v ^github.com/docker/distribution/vendor/)
|
||||
|
||||
test-race: ## run tests, except integration test with test.short and race
|
||||
@echo "$(WHALE) $@"
|
||||
@go test ${GO_TAGS} -race -test.short ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${PACKAGES})
|
||||
# Resolving binary dependencies for specific targets
|
||||
GOLINT_BIN := $(GOPATH)/bin/golint
|
||||
GOLINT := $(shell [ -x $(GOLINT_BIN) ] && echo $(GOLINT_BIN) || echo '')
|
||||
|
||||
test-full: ## run tests, except integration tests
|
||||
@echo "$(WHALE) $@"
|
||||
@go test ${GO_TAGS} ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${PACKAGES})
|
||||
GODEP_BIN := $(GOPATH)/bin/godep
|
||||
GODEP := $(shell [ -x $(GODEP_BIN) ] && echo $(GODEP_BIN) || echo '')
|
||||
|
||||
integration: ## run integration tests
|
||||
@echo "$(WHALE) $@"
|
||||
@go test ${TESTFLAGS} -parallel ${TESTFLAGS_PARALLEL} ${INTEGRATION_PACKAGE}
|
||||
${PREFIX}/bin/registry: $(wildcard **/*.go)
|
||||
@echo "+ $@"
|
||||
@go build -tags "${DOCKER_BUILDTAGS}" -o $@ ${GO_LDFLAGS} ${GO_GCFLAGS} ./cmd/registry
|
||||
|
||||
coverage: ## generate coverprofiles from the unit tests
|
||||
@echo "$(WHALE) $@"
|
||||
@rm -f coverage.txt
|
||||
@go test ${GO_TAGS} -i ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${COVERAGE_PACKAGES}) 2> /dev/null
|
||||
@( for pkg in $(filter-out ${INTEGRATION_PACKAGE},${COVERAGE_PACKAGES}); do \
|
||||
go test ${GO_TAGS} ${TESTFLAGS} \
|
||||
-cover \
|
||||
-coverprofile=profile.out \
|
||||
-covermode=atomic $$pkg || exit; \
|
||||
if [ -f profile.out ]; then \
|
||||
cat profile.out >> coverage.txt; \
|
||||
rm profile.out; \
|
||||
fi; \
|
||||
done )
|
||||
${PREFIX}/bin/digest: $(wildcard **/*.go)
|
||||
@echo "+ $@"
|
||||
@go build -tags "${DOCKER_BUILDTAGS}" -o $@ ${GO_LDFLAGS} ${GO_GCFLAGS} ./cmd/digest
|
||||
|
||||
FORCE:
|
||||
${PREFIX}/bin/registry-api-descriptor-template: $(wildcard **/*.go)
|
||||
@echo "+ $@"
|
||||
@go build -o $@ ${GO_LDFLAGS} ${GO_GCFLAGS} ./cmd/registry-api-descriptor-template
|
||||
|
||||
# Build a binary from a cmd.
|
||||
bin/%: cmd/% FORCE
|
||||
@echo "$(WHALE) $@${BINARY_SUFFIX}"
|
||||
@go build ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o $@${BINARY_SUFFIX} ${GO_LDFLAGS} ${GO_TAGS} ./$<
|
||||
docs/spec/api.md: docs/spec/api.md.tmpl ${PREFIX}/bin/registry-api-descriptor-template
|
||||
./bin/registry-api-descriptor-template $< > $@
|
||||
|
||||
binaries: $(BINARIES) ## build binaries
|
||||
@echo "$(WHALE) $@"
|
||||
vet:
|
||||
@echo "+ $@"
|
||||
@go vet -tags "${DOCKER_BUILDTAGS}" $(PKGS)
|
||||
|
||||
fmt:
|
||||
@echo "+ $@"
|
||||
@test -z "$$(gofmt -s -l . 2>&1 | grep -v ^vendor/ | tee /dev/stderr)" || \
|
||||
(echo >&2 "+ please format Go code with 'gofmt -s'" && false)
|
||||
|
||||
lint:
|
||||
@echo "+ $@"
|
||||
$(if $(GOLINT), , \
|
||||
$(error Please install golint: `go get -u github.com/golang/lint/golint`))
|
||||
@test -z "$$($(GOLINT) ./... 2>&1 | grep -v ^vendor/ | tee /dev/stderr)"
|
||||
|
||||
build:
|
||||
@echo "$(WHALE) $@"
|
||||
@go build ${GO_GCFLAGS} ${GO_BUILD_FLAGS} ${GO_LDFLAGS} ${GO_TAGS} $(PACKAGES)
|
||||
@echo "+ $@"
|
||||
@go build -tags "${DOCKER_BUILDTAGS}" -v ${GO_LDFLAGS} $(PKGS)
|
||||
|
||||
clean: ## clean up binaries
|
||||
@echo "$(WHALE) $@"
|
||||
@rm -f $(BINARIES)
|
||||
test:
|
||||
@echo "+ $@"
|
||||
@go test -test.short -tags "${DOCKER_BUILDTAGS}" $(PKGS)
|
||||
|
||||
test-full:
|
||||
@echo "+ $@"
|
||||
@go test -tags "${DOCKER_BUILDTAGS}" $(PKGS)
|
||||
|
||||
binaries: ${PREFIX}/bin/registry ${PREFIX}/bin/digest ${PREFIX}/bin/registry-api-descriptor-template
|
||||
@echo "+ $@"
|
||||
|
||||
clean:
|
||||
@echo "+ $@"
|
||||
@rm -rf "${PREFIX}/bin/registry" "${PREFIX}/bin/digest" "${PREFIX}/bin/registry-api-descriptor-template"
|
||||
|
||||
dep-save:
|
||||
@echo "+ $@"
|
||||
$(if $(GODEP), , \
|
||||
$(error Please install godep: go get github.com/tools/godep))
|
||||
@$(GODEP) save $(PKGS)
|
||||
|
||||
dep-restore:
|
||||
@echo "+ $@"
|
||||
$(if $(GODEP), , \
|
||||
$(error Please install godep: go get github.com/tools/godep))
|
||||
@$(GODEP) restore -v
|
||||
|
||||
dep-validate: dep-restore
|
||||
@echo "+ $@"
|
||||
@rm -Rf .vendor.bak
|
||||
@mv vendor .vendor.bak
|
||||
@rm -Rf Godeps
|
||||
@$(GODEP) save ./...
|
||||
@test -z "$$(diff -r vendor .vendor.bak 2>&1 | tee /dev/stderr)" || \
|
||||
(echo >&2 "+ borked dependencies! what you have in Godeps/Godeps.json does not match with what you have in vendor" && false)
|
||||
@rm -Rf .vendor.bak
|
||||
|
|
104
README.md
104
README.md
|
@ -2,32 +2,31 @@
|
|||
|
||||
The Docker toolset to pack, ship, store, and deliver content.
|
||||
|
||||
This repository's main product is the Open Source Docker Registry implementation
|
||||
for storing and distributing Docker and OCI images using the
|
||||
[OCI Distribution Specification](https://github.com/opencontainers/distribution-spec).
|
||||
The goal of this project is to provide a simple, secure, and scalable base
|
||||
for building a registry solution or running a simple private registry.
|
||||
This repository's main product is the Docker Registry 2.0 implementation
|
||||
for storing and distributing Docker images. It supersedes the
|
||||
[docker/docker-registry](https://github.com/docker/docker-registry)
|
||||
project with a new API design, focused around security and performance.
|
||||
|
||||
<img src="https://www.docker.com/sites/default/files/oyster-registry-3.png" width=200px/>
|
||||
|
||||
[![Build Status](https://travis-ci.org/docker/distribution.svg?branch=master)](https://travis-ci.org/docker/distribution)
|
||||
[![Circle CI](https://circleci.com/gh/docker/distribution/tree/master.svg?style=svg)](https://circleci.com/gh/docker/distribution/tree/master)
|
||||
[![GoDoc](https://godoc.org/github.com/docker/distribution?status.svg)](https://godoc.org/github.com/docker/distribution)
|
||||
|
||||
This repository contains the following components:
|
||||
|
||||
|**Component** |Description |
|
||||
|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **registry** | An implementation of the [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec). |
|
||||
| **libraries** | A rich set of libraries for interacting with distribution components. Please see [godoc](https://godoc.org/github.com/docker/distribution) for details. **Note**: The interfaces for these libraries are **unstable**. |
|
||||
| **documentation** | Docker's full documentation set is available at [docs.docker.com](https://docs.docker.com). This repository [contains the subset](docs/) related just to the registry. |
|
||||
| **registry** | An implementation of the [Docker Registry HTTP API V2](docs/spec/api.md) for use with docker 1.6+. |
|
||||
| **libraries** | A rich set of libraries for interacting with distribution components. Please see [godoc](https://godoc.org/github.com/docker/distribution) for details. **Note**: These libraries are **unstable**. |
|
||||
| **specifications** | _Distribution_ related specifications are available in [docs/spec](docs/spec) |
|
||||
| **documentation** | Docker's full documentation set is available at [docs.docker.com](https://docs.docker.com). This repository [contains the subset](docs/index.md) related just to the registry. |
|
||||
|
||||
### How does this integrate with Docker, containerd, and other OCI client?
|
||||
### How does this integrate with Docker engine?
|
||||
|
||||
Clients implement against the OCI specification and communicate with the
|
||||
registry using HTTP. This project contains an client implementation which
|
||||
is currently in use by Docker, however, it is deprecated for the
|
||||
[implementation in containerd](https://github.com/containerd/containerd/tree/master/remotes/docker)
|
||||
and will not support new features.
|
||||
This project should provide an implementation to a V2 API for use in the [Docker
|
||||
core project](https://github.com/docker/docker). The API should be embeddable
|
||||
and simplify the process of securely pulling and pushing content from `docker`
|
||||
daemons.
|
||||
|
||||
### What are the long term goals of the Distribution project?
|
||||
|
||||
|
@ -44,20 +43,32 @@ system that allow users to:
|
|||
* Implement their own home made solution through good specs, and solid
|
||||
extensions mechanism.
|
||||
|
||||
## More about Registry 2.0
|
||||
|
||||
The new registry implementation provides the following benefits:
|
||||
|
||||
- faster push and pull
|
||||
- new, more efficient implementation
|
||||
- simplified deployment
|
||||
- pluggable storage backend
|
||||
- webhook notifications
|
||||
|
||||
For information on upcoming functionality, please see [ROADMAP.md](ROADMAP.md).
|
||||
|
||||
### Who needs to deploy a registry?
|
||||
|
||||
By default, Docker users pull images from Docker's public registry instance.
|
||||
[Installing Docker](https://docs.docker.com/engine/installation/) gives users this
|
||||
ability. Users can also push images to a repository on Docker's public registry,
|
||||
if they have a [Docker Hub](https://hub.docker.com/) account.
|
||||
if they have a [Docker Hub](https://hub.docker.com/) account.
|
||||
|
||||
For some users and even companies, this default behavior is sufficient. For
|
||||
others, it is not.
|
||||
others, it is not.
|
||||
|
||||
For example, users with their own software products may want to maintain a
|
||||
registry for private, company images. Also, you may wish to deploy your own
|
||||
image repository for images used to test or in continuous integration. For these
|
||||
use cases and others, [deploying your own registry instance](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md)
|
||||
use cases and others, [deploying your own registry instance](docs/deploying.md)
|
||||
may be the better choice.
|
||||
|
||||
### Migration to Registry 2.0
|
||||
|
@ -65,27 +76,56 @@ may be the better choice.
|
|||
For those who have previously deployed their own registry based on the Registry
|
||||
1.0 implementation and wish to deploy a Registry 2.0 while retaining images,
|
||||
data migration is required. A tool to assist with migration efforts has been
|
||||
created. For more information see [docker/migrator](https://github.com/docker/migrator).
|
||||
created. For more information see [docker/migrator]
|
||||
(https://github.com/docker/migrator).
|
||||
|
||||
## Contribution
|
||||
## Contribute
|
||||
|
||||
Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute
|
||||
issues, fixes, and patches to this project. If you are contributing code, see
|
||||
the instructions for [building a development environment](BUILDING.md).
|
||||
the instructions for [building a development environment](docs/building.md).
|
||||
|
||||
## Communication
|
||||
## Support
|
||||
|
||||
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.
|
||||
If any issues are encountered while using the _Distribution_ project, several
|
||||
avenues are available for support:
|
||||
|
||||
For sync communication we have a community slack with a #distribution channel that everyone is welcome to join and chat about development.
|
||||
<table>
|
||||
<tr>
|
||||
<th align="left">
|
||||
IRC
|
||||
</th>
|
||||
<td>
|
||||
#docker-distribution on FreeNode
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left">
|
||||
Issue Tracker
|
||||
</th>
|
||||
<td>
|
||||
github.com/docker/distribution/issues
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left">
|
||||
Google Groups
|
||||
</th>
|
||||
<td>
|
||||
https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left">
|
||||
Mailing List
|
||||
</th>
|
||||
<td>
|
||||
docker@dockerproject.org
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Slack:** Catch us in the #distribution channels on dockercommunity.slack.com.
|
||||
[Click here for an invite to Docker community slack.](https://dockr.ly/slack)
|
||||
|
||||
## Licenses
|
||||
## License
|
||||
|
||||
The distribution codebase is released under the [Apache 2.0 license](LICENSE).
|
||||
The README.md file, and files in the "docs" folder are licensed under the
|
||||
Creative Commons Attribution 4.0 International License. You may obtain a
|
||||
copy of the license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/.
|
||||
This project is distributed under [Apache License, Version 2.0](LICENSE).
|
||||
|
|
|
@ -156,7 +156,7 @@ full and understand the problems behind deletes.
|
|||
While, at first glance, implementing deleting seems simple, there are a number
|
||||
mitigating factors that make many solutions not ideal or even pathological in
|
||||
the context of a registry. The following paragraph discuss the background and
|
||||
approaches that could be applied to arrive at a solution.
|
||||
approaches that could be applied to a arrive at a solution.
|
||||
|
||||
The goal of deletes in any system is to remove unused or unneeded data. Only
|
||||
data requested for deletion should be removed and no other data. Removing
|
||||
|
|
36
blobs.go
36
blobs.go
|
@ -1,16 +1,15 @@
|
|||
package distribution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -67,19 +66,9 @@ type Descriptor struct {
|
|||
Size int64 `json:"size,omitempty"`
|
||||
|
||||
// Digest uniquely identifies the content. A byte stream can be verified
|
||||
// against this digest.
|
||||
// against against this digest.
|
||||
Digest digest.Digest `json:"digest,omitempty"`
|
||||
|
||||
// URLs contains the source URLs of this content.
|
||||
URLs []string `json:"urls,omitempty"`
|
||||
|
||||
// Annotations contains arbitrary metadata relating to the targeted content.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// Platform describes the platform which the image in the manifest runs on.
|
||||
// This should only be used when referring to a manifest.
|
||||
Platform *v1.Platform `json:"platform,omitempty"`
|
||||
|
||||
// NOTE: Before adding a field here, please ensure that all
|
||||
// other options have been exhausted. Much of the type relationships
|
||||
// depend on the simplicity of this type.
|
||||
|
@ -135,11 +124,6 @@ type BlobDescriptorService interface {
|
|||
Clear(ctx context.Context, dgst digest.Digest) error
|
||||
}
|
||||
|
||||
// BlobDescriptorServiceFactory creates middleware for BlobDescriptorService.
|
||||
type BlobDescriptorServiceFactory interface {
|
||||
BlobAccessController(svc BlobDescriptorService) BlobDescriptorService
|
||||
}
|
||||
|
||||
// ReadSeekCloser is the primary reader type for blob data, combining
|
||||
// io.ReadSeeker with io.Closer.
|
||||
type ReadSeekCloser interface {
|
||||
|
@ -160,7 +144,7 @@ type BlobProvider interface {
|
|||
|
||||
// BlobServer can serve blobs via http.
|
||||
type BlobServer interface {
|
||||
// ServeBlob attempts to serve the blob, identified by dgst, via http. The
|
||||
// ServeBlob attempts to serve the blob, identifed by dgst, via http. The
|
||||
// service may decide to redirect the client elsewhere or serve the data
|
||||
// directly.
|
||||
//
|
||||
|
@ -200,18 +184,6 @@ type BlobCreateOption interface {
|
|||
Apply(interface{}) error
|
||||
}
|
||||
|
||||
// CreateOptions is a collection of blob creation modifiers relevant to general
|
||||
// blob storage intended to be configured by the BlobCreateOption.Apply method.
|
||||
type CreateOptions struct {
|
||||
Mount struct {
|
||||
ShouldMount bool
|
||||
From reference.Canonical
|
||||
// Stat allows to pass precalculated descriptor to link and return.
|
||||
// Blob access check will be skipped if set.
|
||||
Stat *Descriptor
|
||||
}
|
||||
}
|
||||
|
||||
// BlobWriter provides a handle for inserting data into a blob store.
|
||||
// Instances should be obtained from BlobWriteService.Writer and
|
||||
// BlobWriteService.Resume. If supported by the store, a writer can be
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
# Pony-up!
|
||||
machine:
|
||||
pre:
|
||||
# Install gvm
|
||||
- bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/1.0.22/binscripts/gvm-installer)
|
||||
# Install codecov for coverage
|
||||
- pip install --user codecov
|
||||
|
||||
post:
|
||||
# go
|
||||
- gvm install go1.6 --prefer-binary --name=stable
|
||||
|
||||
environment:
|
||||
# Convenient shortcuts to "common" locations
|
||||
CHECKOUT: /home/ubuntu/$CIRCLE_PROJECT_REPONAME
|
||||
BASE_DIR: src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
|
||||
# Trick circle brainflat "no absolute path" behavior
|
||||
BASE_STABLE: ../../../$HOME/.gvm/pkgsets/stable/global/$BASE_DIR
|
||||
DOCKER_BUILDTAGS: "include_oss include_gcs"
|
||||
# Workaround Circle parsing dumb bugs and/or YAML wonkyness
|
||||
CIRCLE_PAIN: "mode: set"
|
||||
|
||||
hosts:
|
||||
# Not used yet
|
||||
fancy: 127.0.0.1
|
||||
|
||||
dependencies:
|
||||
pre:
|
||||
# Copy the code to the gopath of all go versions
|
||||
- >
|
||||
gvm use stable &&
|
||||
mkdir -p "$(dirname $BASE_STABLE)" &&
|
||||
cp -R "$CHECKOUT" "$BASE_STABLE"
|
||||
|
||||
override:
|
||||
# Install dependencies for every copied clone/go version
|
||||
- gvm use stable && go get github.com/tools/godep:
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
post:
|
||||
# For the stable go version, additionally install linting tools
|
||||
- >
|
||||
gvm use stable &&
|
||||
go get github.com/axw/gocov/gocov github.com/golang/lint/golint
|
||||
|
||||
test:
|
||||
pre:
|
||||
# Output the go versions we are going to test
|
||||
# - gvm use old && go version
|
||||
- gvm use stable && go version
|
||||
|
||||
# Ensure validation of dependencies
|
||||
- gvm use stable && if test -n "`git diff --stat=1000 master | grep -Ei \"vendor|godeps\"`"; then make dep-validate; fi:
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
# First thing: build everything. This will catch compile errors, and it's
|
||||
# also necessary for go vet to work properly (see #807).
|
||||
- gvm use stable && godep go install $(go list ./... | grep -v "/vendor/"):
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
# FMT
|
||||
- gvm use stable && make fmt:
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
# VET
|
||||
- gvm use stable && make vet:
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
# LINT
|
||||
- gvm use stable && make lint:
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
override:
|
||||
# Test stable, and report
|
||||
- gvm use stable; export ROOT_PACKAGE=$(go list .); go list -tags "$DOCKER_BUILDTAGS" ./... | grep -v "/vendor/" | xargs -L 1 -I{} bash -c 'export PACKAGE={}; godep go test -tags "$DOCKER_BUILDTAGS" -test.short -coverprofile=$GOPATH/src/$PACKAGE/coverage.out -coverpkg=$(./coverpkg.sh $PACKAGE $ROOT_PACKAGE) $PACKAGE':
|
||||
timeout: 600
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
post:
|
||||
# Report to codecov
|
||||
- bash <(curl -s https://codecov.io/bash):
|
||||
pwd: $BASE_STABLE
|
||||
|
||||
## Notes
|
||||
# Disabled the -race detector due to massive memory usage.
|
||||
# Do we want these as well?
|
||||
# - go get code.google.com/p/go.tools/cmd/goimports
|
||||
# - test -z "$(goimports -l -w ./... | tee /dev/stderr)"
|
||||
# http://labix.org/gocheck
|
|
@ -7,11 +7,8 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/distribution/version"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
||||
_ "crypto/sha256"
|
||||
_ "crypto/sha512"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -35,7 +32,7 @@ func init() {
|
|||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: %s [files...]\n", os.Args[0])
|
||||
fmt.Fprint(os.Stderr, `
|
||||
fmt.Fprintf(os.Stderr, `
|
||||
Calculate the digest of one or more input files, emitting the result
|
||||
to standard out. If no files are provided, the digest of stdin will
|
||||
be calculated.
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/docker/distribution/registry/api/errcode"
|
||||
v2 "github.com/docker/distribution/registry/api/v2"
|
||||
"github.com/docker/distribution/registry/api/v2"
|
||||
)
|
||||
|
||||
var spaceRegex = regexp.MustCompile(`\n\s*`)
|
||||
|
|
|
@ -29,8 +29,6 @@ redis:
|
|||
readtimeout: 10ms
|
||||
writetimeout: 10ms
|
||||
notifications:
|
||||
events:
|
||||
includereferences: true
|
||||
endpoints:
|
||||
- name: local-8082
|
||||
url: http://localhost:5003/callback
|
||||
|
|
|
@ -31,10 +31,7 @@ storage:
|
|||
http:
|
||||
addr: :5000
|
||||
debug:
|
||||
addr: :5001
|
||||
prometheus:
|
||||
enabled: true
|
||||
path: /metrics
|
||||
addr: localhost:5001
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
redis:
|
||||
|
@ -47,8 +44,6 @@ redis:
|
|||
readtimeout: 10ms
|
||||
writetimeout: 10ms
|
||||
notifications:
|
||||
events:
|
||||
includereferences: true
|
||||
endpoints:
|
||||
- name: local-5003
|
||||
url: http://localhost:5003/callback
|
||||
|
|
|
@ -11,10 +11,6 @@ http:
|
|||
addr: :5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
auth:
|
||||
htpasswd:
|
||||
realm: basic-realm
|
||||
path: /etc/registry
|
||||
health:
|
||||
storagedriver:
|
||||
enabled: true
|
||||
|
|
|
@ -12,11 +12,10 @@ import (
|
|||
_ "github.com/docker/distribution/registry/storage/driver/filesystem"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/gcs"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/inmemory"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/middleware/alicdn"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/middleware/cloudfront"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/middleware/redirect"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/oss"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/s3-aws"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/s3-goamz"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/swift"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package configuration
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -23,14 +22,8 @@ type Configuration struct {
|
|||
// Log supports setting various parameters related to the logging
|
||||
// subsystem.
|
||||
Log struct {
|
||||
// AccessLog configures access logging.
|
||||
AccessLog struct {
|
||||
// Disabled disables access logging.
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
} `yaml:"accesslog,omitempty"`
|
||||
|
||||
// Level is the granularity at which registry operations are logged.
|
||||
Level Loglevel `yaml:"level,omitempty"`
|
||||
Level Loglevel `yaml:"level"`
|
||||
|
||||
// Formatter overrides the default formatter with another. Options
|
||||
// include "text", "json" and "logstash".
|
||||
|
@ -40,14 +33,13 @@ type Configuration struct {
|
|||
// the logger context.
|
||||
Fields map[string]interface{} `yaml:"fields,omitempty"`
|
||||
|
||||
// Hooks allows users to configure the log hooks, to enabling the
|
||||
// Hooks allows users to configurate the log hooks, to enabling the
|
||||
// sequent handling behavior, when defined levels of log message emit.
|
||||
Hooks []LogHook `yaml:"hooks,omitempty"`
|
||||
}
|
||||
|
||||
// Loglevel is the level at which registry operations are logged.
|
||||
//
|
||||
// Deprecated: Use Log.Level instead.
|
||||
// Loglevel is the level at which registry operations are logged. This is
|
||||
// deprecated. Please use Log.Level in the future.
|
||||
Loglevel Loglevel `yaml:"loglevel,omitempty"`
|
||||
|
||||
// Storage is the configuration for the registry's storage driver
|
||||
|
@ -85,10 +77,6 @@ type Configuration struct {
|
|||
// Location headers
|
||||
RelativeURLs bool `yaml:"relativeurls,omitempty"`
|
||||
|
||||
// Amount of time to wait for connection to drain before shutting down when registry
|
||||
// receives a stop signal
|
||||
DrainTimeout time.Duration `yaml:"draintimeout,omitempty"`
|
||||
|
||||
// TLS instructs the http server to listen with a TLS configuration.
|
||||
// This only support simple tls configuration with a cert and key.
|
||||
// Mostly, this is useful for testing situations or simple deployments
|
||||
|
@ -107,26 +95,6 @@ type Configuration struct {
|
|||
// Specifies the CA certs for client authentication
|
||||
// A file may contain multiple CA certificates encoded as PEM
|
||||
ClientCAs []string `yaml:"clientcas,omitempty"`
|
||||
|
||||
// Specifies the lowest TLS version allowed
|
||||
MinimumTLS string `yaml:"minimumtls,omitempty"`
|
||||
|
||||
// LetsEncrypt is used to configuration setting up TLS through
|
||||
// Let's Encrypt instead of manually specifying certificate and
|
||||
// key. If a TLS certificate is specified, the Let's Encrypt
|
||||
// section will not be used.
|
||||
LetsEncrypt struct {
|
||||
// CacheFile specifies cache file to use for lets encrypt
|
||||
// certificates and keys.
|
||||
CacheFile string `yaml:"cachefile,omitempty"`
|
||||
|
||||
// Email is the email to use during Let's Encrypt registration
|
||||
Email string `yaml:"email,omitempty"`
|
||||
|
||||
// Hosts specifies the hosts which are allowed to obtain Let's
|
||||
// Encrypt certificates.
|
||||
Hosts []string `yaml:"hosts,omitempty"`
|
||||
} `yaml:"letsencrypt,omitempty"`
|
||||
} `yaml:"tls,omitempty"`
|
||||
|
||||
// Headers is a set of headers to include in HTTP responses. A common
|
||||
|
@ -141,19 +109,7 @@ type Configuration struct {
|
|||
Debug struct {
|
||||
// Addr specifies the bind address for the debug server.
|
||||
Addr string `yaml:"addr,omitempty"`
|
||||
// Prometheus configures the Prometheus telemetry endpoint.
|
||||
Prometheus struct {
|
||||
Enabled bool `yaml:"enabled,omitempty"`
|
||||
Path string `yaml:"path,omitempty"`
|
||||
} `yaml:"prometheus,omitempty"`
|
||||
} `yaml:"debug,omitempty"`
|
||||
|
||||
// HTTP2 configuration options
|
||||
HTTP2 struct {
|
||||
// Specifies whether the registry should disallow clients attempting
|
||||
// to connect via http2. If set to true, only http/1.1 is supported.
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
} `yaml:"http2,omitempty"`
|
||||
} `yaml:"http,omitempty"`
|
||||
|
||||
// Notifications specifies configuration about various endpoint to which
|
||||
|
@ -201,44 +157,13 @@ type Configuration struct {
|
|||
// TrustKey is the signing key to use for adding the signature to
|
||||
// schema1 manifests.
|
||||
TrustKey string `yaml:"signingkeyfile,omitempty"`
|
||||
// Enabled determines if schema1 manifests should be pullable
|
||||
Enabled bool `yaml:"enabled,omitempty"`
|
||||
|
||||
// DisableSignatureStore will cause all signatures attached to schema1 manifests
|
||||
// to be ignored. Signatures will be generated on all schema1 manifest requests
|
||||
// rather than only requests which converted schema2 to schema1.
|
||||
DisableSignatureStore bool `yaml:"disablesignaturestore,omitempty"`
|
||||
} `yaml:"schema1,omitempty"`
|
||||
} `yaml:"compatibility,omitempty"`
|
||||
|
||||
// Validation configures validation options for the registry.
|
||||
Validation struct {
|
||||
// Enabled enables the other options in this section. This field is
|
||||
// deprecated in favor of Disabled.
|
||||
Enabled bool `yaml:"enabled,omitempty"`
|
||||
// Disabled disables the other options in this section.
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
// Manifests configures manifest validation.
|
||||
Manifests struct {
|
||||
// URLs configures validation for URLs in pushed manifests.
|
||||
URLs struct {
|
||||
// Allow specifies regular expressions (https://godoc.org/regexp/syntax)
|
||||
// that URLs in pushed manifests must match.
|
||||
Allow []string `yaml:"allow,omitempty"`
|
||||
// Deny specifies regular expressions (https://godoc.org/regexp/syntax)
|
||||
// that URLs in pushed manifests must not match.
|
||||
Deny []string `yaml:"deny,omitempty"`
|
||||
} `yaml:"urls,omitempty"`
|
||||
} `yaml:"manifests,omitempty"`
|
||||
} `yaml:"validation,omitempty"`
|
||||
|
||||
// Policy configures registry policy options.
|
||||
Policy struct {
|
||||
// Repository configures policies for repositories
|
||||
Repository struct {
|
||||
// Classes is a list of repository classes which the
|
||||
// registry allows content for. This class is matched
|
||||
// against the configuration media type inside uploaded
|
||||
// manifests. When non-empty, the registry will enforce
|
||||
// the class in authorized resources.
|
||||
Classes []string `yaml:"classes"`
|
||||
} `yaml:"repository,omitempty"`
|
||||
} `yaml:"policy,omitempty"`
|
||||
}
|
||||
|
||||
// LogHook is composed of hook Level and Type.
|
||||
|
@ -255,7 +180,7 @@ type LogHook struct {
|
|||
// Levels set which levels of log message will let hook executed.
|
||||
Levels []string `yaml:"levels,omitempty"`
|
||||
|
||||
// MailOptions allows user to configure email parameters.
|
||||
// MailOptions allows user to configurate email parameters.
|
||||
MailOptions MailOptions `yaml:"options,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -271,7 +196,7 @@ type MailOptions struct {
|
|||
// Password defines password of login user
|
||||
Password string `yaml:"password,omitempty"`
|
||||
|
||||
// Insecure defines if smtp login skips the secure certification.
|
||||
// Insecure defines if smtp login skips the secure cerification.
|
||||
Insecure bool `yaml:"insecure,omitempty"`
|
||||
} `yaml:"smtp,omitempty"`
|
||||
|
||||
|
@ -296,7 +221,7 @@ type FileChecker struct {
|
|||
// HTTPChecker is a type of entry in the health section for checking HTTP URIs.
|
||||
type HTTPChecker struct {
|
||||
// Timeout is the duration to wait before timing out the HTTP request
|
||||
Timeout time.Duration `yaml:"timeout,omitempty"`
|
||||
Timeout time.Duration `yaml:"interval,omitempty"`
|
||||
// StatusCode is the expected status code
|
||||
StatusCode int
|
||||
// Interval is the duration in between checks
|
||||
|
@ -313,7 +238,7 @@ type HTTPChecker struct {
|
|||
// TCPChecker is a type of entry in the health section for checking TCP servers.
|
||||
type TCPChecker struct {
|
||||
// Timeout is the duration to wait before timing out the TCP connection
|
||||
Timeout time.Duration `yaml:"timeout,omitempty"`
|
||||
Timeout time.Duration `yaml:"interval,omitempty"`
|
||||
// Interval is the duration in between checks
|
||||
Interval time.Duration `yaml:"interval,omitempty"`
|
||||
// Addr is the TCP address to check
|
||||
|
@ -349,7 +274,7 @@ type Health struct {
|
|||
type v0_1Configuration Configuration
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface
|
||||
// Unmarshals a string of the form X.Y into a Version, validating that X and Y can represent unsigned integers
|
||||
// Unmarshals a string of the form X.Y into a Version, validating that X and Y can represent uints
|
||||
func (version *Version) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var versionString string
|
||||
err := unmarshal(&versionString)
|
||||
|
@ -391,7 +316,7 @@ func (loglevel *Loglevel) UnmarshalYAML(unmarshal func(interface{}) error) error
|
|||
switch loglevelString {
|
||||
case "error", "warn", "info", "debug":
|
||||
default:
|
||||
return fmt.Errorf("invalid loglevel %s Must be one of [error, warn, info, debug]", loglevelString)
|
||||
return fmt.Errorf("Invalid loglevel %s Must be one of [error, warn, info, debug]", loglevelString)
|
||||
}
|
||||
|
||||
*loglevel = Loglevel(loglevelString)
|
||||
|
@ -466,7 +391,7 @@ func (storage *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
}
|
||||
|
||||
if len(types) > 1 {
|
||||
return fmt.Errorf("must provide exactly one storage type. Provided: %v", types)
|
||||
return fmt.Errorf("Must provide exactly one storage type. Provided: %v", types)
|
||||
}
|
||||
}
|
||||
*storage = storageMap
|
||||
|
@ -494,7 +419,7 @@ func (storage Storage) MarshalYAML() (interface{}, error) {
|
|||
// Auth defines the configuration for registry authorization.
|
||||
type Auth map[string]Parameters
|
||||
|
||||
// Type returns the auth type, such as htpasswd or token
|
||||
// Type returns the storage driver type, such as filesystem or s3
|
||||
func (auth Auth) Type() string {
|
||||
// Return only key in this map
|
||||
for k := range auth {
|
||||
|
@ -554,8 +479,6 @@ func (auth Auth) MarshalYAML() (interface{}, error) {
|
|||
|
||||
// Notifications configures multiple http endpoints.
|
||||
type Notifications struct {
|
||||
// EventConfig is the configuration for the event format that is sent to each Endpoint.
|
||||
EventConfig Events `yaml:"events,omitempty"`
|
||||
// Endpoints is a list of http configurations for endpoints that
|
||||
// respond to webhook notifications. In the future, we may allow other
|
||||
// kinds of endpoints, such as external queues.
|
||||
|
@ -565,26 +488,13 @@ type Notifications struct {
|
|||
// Endpoint describes the configuration of an http webhook notification
|
||||
// endpoint.
|
||||
type Endpoint struct {
|
||||
Name string `yaml:"name"` // identifies the endpoint in the registry instance.
|
||||
Disabled bool `yaml:"disabled"` // disables the endpoint
|
||||
URL string `yaml:"url"` // post url for the endpoint.
|
||||
Headers http.Header `yaml:"headers"` // static headers that should be added to all requests
|
||||
Timeout time.Duration `yaml:"timeout"` // HTTP timeout
|
||||
Threshold int `yaml:"threshold"` // circuit breaker threshold before backing off on failure
|
||||
Backoff time.Duration `yaml:"backoff"` // backoff duration
|
||||
IgnoredMediaTypes []string `yaml:"ignoredmediatypes"` // target media types to ignore
|
||||
Ignore Ignore `yaml:"ignore"` // ignore event types
|
||||
}
|
||||
|
||||
// Events configures notification events.
|
||||
type Events struct {
|
||||
IncludeReferences bool `yaml:"includereferences"` // include reference data in manifest events
|
||||
}
|
||||
|
||||
//Ignore configures mediaTypes and actions of the event, that it won't be propagated
|
||||
type Ignore struct {
|
||||
MediaTypes []string `yaml:"mediatypes"` // target media types to ignore
|
||||
Actions []string `yaml:"actions"` // ignore action types
|
||||
Name string `yaml:"name"` // identifies the endpoint in the registry instance.
|
||||
Disabled bool `yaml:"disabled"` // disables the endpoint
|
||||
URL string `yaml:"url"` // post url for the endpoint.
|
||||
Headers http.Header `yaml:"headers"` // static headers that should be added to all requests
|
||||
Timeout time.Duration `yaml:"timeout"` // HTTP timeout
|
||||
Threshold int `yaml:"threshold"` // circuit breaker threshold before backing off on failure
|
||||
Backoff time.Duration `yaml:"backoff"` // backoff duration
|
||||
}
|
||||
|
||||
// Reporting defines error reporting methods.
|
||||
|
@ -657,22 +567,15 @@ func Parse(rd io.Reader) (*Configuration, error) {
|
|||
ParseAs: reflect.TypeOf(v0_1Configuration{}),
|
||||
ConversionFunc: func(c interface{}) (interface{}, error) {
|
||||
if v0_1, ok := c.(*v0_1Configuration); ok {
|
||||
if v0_1.Log.Level == Loglevel("") {
|
||||
if v0_1.Loglevel != Loglevel("") {
|
||||
v0_1.Log.Level = v0_1.Loglevel
|
||||
} else {
|
||||
v0_1.Log.Level = Loglevel("info")
|
||||
}
|
||||
}
|
||||
if v0_1.Loglevel != Loglevel("") {
|
||||
v0_1.Loglevel = Loglevel("")
|
||||
if v0_1.Loglevel == Loglevel("") {
|
||||
v0_1.Loglevel = Loglevel("info")
|
||||
}
|
||||
if v0_1.Storage.Type() == "" {
|
||||
return nil, errors.New("no storage configuration provided")
|
||||
return nil, fmt.Errorf("No storage configuration provided")
|
||||
}
|
||||
return (*Configuration)(v0_1), nil
|
||||
}
|
||||
return nil, fmt.Errorf("expected *v0_1Configuration, received %#v", c)
|
||||
return nil, fmt.Errorf("Expected *v0_1Configuration, received %#v", c)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
@ -20,17 +19,14 @@ func Test(t *testing.T) { TestingT(t) }
|
|||
var configStruct = Configuration{
|
||||
Version: "0.1",
|
||||
Log: struct {
|
||||
AccessLog struct {
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
} `yaml:"accesslog,omitempty"`
|
||||
Level Loglevel `yaml:"level,omitempty"`
|
||||
Level Loglevel `yaml:"level"`
|
||||
Formatter string `yaml:"formatter,omitempty"`
|
||||
Fields map[string]interface{} `yaml:"fields,omitempty"`
|
||||
Hooks []LogHook `yaml:"hooks,omitempty"`
|
||||
}{
|
||||
Level: "info",
|
||||
Fields: map[string]interface{}{"environment": "test"},
|
||||
},
|
||||
Loglevel: "info",
|
||||
Storage: Storage{
|
||||
"s3": Parameters{
|
||||
"region": "us-east-1",
|
||||
|
@ -63,66 +59,36 @@ var configStruct = Configuration{
|
|||
Headers: http.Header{
|
||||
"Authorization": []string{"Bearer <example>"},
|
||||
},
|
||||
IgnoredMediaTypes: []string{"application/octet-stream"},
|
||||
Ignore: Ignore{
|
||||
MediaTypes: []string{"application/octet-stream"},
|
||||
Actions: []string{"pull"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
HTTP: struct {
|
||||
Addr string `yaml:"addr,omitempty"`
|
||||
Net string `yaml:"net,omitempty"`
|
||||
Host string `yaml:"host,omitempty"`
|
||||
Prefix string `yaml:"prefix,omitempty"`
|
||||
Secret string `yaml:"secret,omitempty"`
|
||||
RelativeURLs bool `yaml:"relativeurls,omitempty"`
|
||||
DrainTimeout time.Duration `yaml:"draintimeout,omitempty"`
|
||||
Addr string `yaml:"addr,omitempty"`
|
||||
Net string `yaml:"net,omitempty"`
|
||||
Host string `yaml:"host,omitempty"`
|
||||
Prefix string `yaml:"prefix,omitempty"`
|
||||
Secret string `yaml:"secret,omitempty"`
|
||||
RelativeURLs bool `yaml:"relativeurls,omitempty"`
|
||||
TLS struct {
|
||||
Certificate string `yaml:"certificate,omitempty"`
|
||||
Key string `yaml:"key,omitempty"`
|
||||
ClientCAs []string `yaml:"clientcas,omitempty"`
|
||||
MinimumTLS string `yaml:"minimumtls,omitempty"`
|
||||
LetsEncrypt struct {
|
||||
CacheFile string `yaml:"cachefile,omitempty"`
|
||||
Email string `yaml:"email,omitempty"`
|
||||
Hosts []string `yaml:"hosts,omitempty"`
|
||||
} `yaml:"letsencrypt,omitempty"`
|
||||
} `yaml:"tls,omitempty"`
|
||||
Headers http.Header `yaml:"headers,omitempty"`
|
||||
Debug struct {
|
||||
Addr string `yaml:"addr,omitempty"`
|
||||
Prometheus struct {
|
||||
Enabled bool `yaml:"enabled,omitempty"`
|
||||
Path string `yaml:"path,omitempty"`
|
||||
} `yaml:"prometheus,omitempty"`
|
||||
Addr string `yaml:"addr,omitempty"`
|
||||
} `yaml:"debug,omitempty"`
|
||||
HTTP2 struct {
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
} `yaml:"http2,omitempty"`
|
||||
}{
|
||||
TLS: struct {
|
||||
Certificate string `yaml:"certificate,omitempty"`
|
||||
Key string `yaml:"key,omitempty"`
|
||||
ClientCAs []string `yaml:"clientcas,omitempty"`
|
||||
MinimumTLS string `yaml:"minimumtls,omitempty"`
|
||||
LetsEncrypt struct {
|
||||
CacheFile string `yaml:"cachefile,omitempty"`
|
||||
Email string `yaml:"email,omitempty"`
|
||||
Hosts []string `yaml:"hosts,omitempty"`
|
||||
} `yaml:"letsencrypt,omitempty"`
|
||||
}{
|
||||
ClientCAs: []string{"/path/to/ca.pem"},
|
||||
},
|
||||
Headers: http.Header{
|
||||
"X-Content-Type-Options": []string{"nosniff"},
|
||||
},
|
||||
HTTP2: struct {
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
}{
|
||||
Disabled: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -130,9 +96,9 @@ var configStruct = Configuration{
|
|||
var configYamlV0_1 = `
|
||||
version: 0.1
|
||||
log:
|
||||
level: info
|
||||
fields:
|
||||
environment: test
|
||||
loglevel: info
|
||||
storage:
|
||||
s3:
|
||||
region: us-east-1
|
||||
|
@ -154,13 +120,6 @@ notifications:
|
|||
url: http://example.com
|
||||
headers:
|
||||
Authorization: [Bearer <example>]
|
||||
ignoredmediatypes:
|
||||
- application/octet-stream
|
||||
ignore:
|
||||
mediatypes:
|
||||
- application/octet-stream
|
||||
actions:
|
||||
- pull
|
||||
reporting:
|
||||
bugsnag:
|
||||
apikey: BugsnagApiKey
|
||||
|
@ -175,8 +134,7 @@ http:
|
|||
// storage driver with no parameters
|
||||
var inmemoryConfigYamlV0_1 = `
|
||||
version: 0.1
|
||||
log:
|
||||
level: info
|
||||
loglevel: info
|
||||
storage: inmemory
|
||||
auth:
|
||||
silly:
|
||||
|
@ -188,13 +146,6 @@ notifications:
|
|||
url: http://example.com
|
||||
headers:
|
||||
Authorization: [Bearer <example>]
|
||||
ignoredmediatypes:
|
||||
- application/octet-stream
|
||||
ignore:
|
||||
mediatypes:
|
||||
- application/octet-stream
|
||||
actions:
|
||||
- pull
|
||||
http:
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
|
@ -217,7 +168,6 @@ func (suite *ConfigSuite) TestMarshalRoundtrip(c *C) {
|
|||
configBytes, err := yaml.Marshal(suite.expectedConfig)
|
||||
c.Assert(err, IsNil)
|
||||
config, err := Parse(bytes.NewReader(configBytes))
|
||||
c.Log(string(configBytes))
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(config, DeepEquals, suite.expectedConfig)
|
||||
}
|
||||
|
@ -340,9 +290,9 @@ func (suite *ConfigSuite) TestParseWithSameEnvLoglevel(c *C) {
|
|||
// TestParseWithDifferentEnvLoglevel validates that providing an environment variable defining the
|
||||
// log level will override the value provided in the yaml document
|
||||
func (suite *ConfigSuite) TestParseWithDifferentEnvLoglevel(c *C) {
|
||||
suite.expectedConfig.Log.Level = "error"
|
||||
suite.expectedConfig.Loglevel = "error"
|
||||
|
||||
os.Setenv("REGISTRY_LOG_LEVEL", "error")
|
||||
os.Setenv("REGISTRY_LOGLEVEL", "error")
|
||||
|
||||
config, err := Parse(bytes.NewReader([]byte(configYamlV0_1)))
|
||||
c.Assert(err, IsNil)
|
||||
|
@ -542,7 +492,9 @@ func copyConfig(config Configuration) *Configuration {
|
|||
}
|
||||
|
||||
configCopy.Notifications = Notifications{Endpoints: []Endpoint{}}
|
||||
configCopy.Notifications.Endpoints = append(configCopy.Notifications.Endpoints, config.Notifications.Endpoints...)
|
||||
for _, v := range config.Notifications.Endpoints {
|
||||
configCopy.Notifications.Endpoints = append(configCopy.Notifications.Endpoints, v)
|
||||
}
|
||||
|
||||
configCopy.HTTP.Headers = make(http.Header)
|
||||
for k, v := range config.HTTP.Headers {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
|
@ -122,7 +122,7 @@ func (p *Parser) Parse(in []byte, v interface{}) error {
|
|||
|
||||
parseInfo, ok := p.mapping[versionedStruct.Version]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported version: %q", versionedStruct.Version)
|
||||
return fmt.Errorf("Unsupported version: %q", versionedStruct.Version)
|
||||
}
|
||||
|
||||
parseAs := reflect.New(parseInfo.ParseAs)
|
||||
|
@ -220,7 +220,7 @@ func (p *Parser) overwriteStruct(v reflect.Value, fullpath string, path []string
|
|||
}
|
||||
case reflect.Ptr:
|
||||
if field.IsNil() {
|
||||
field.Set(reflect.New(field.Type().Elem()))
|
||||
field.Set(reflect.New(sf.Type))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
package configuration
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
type localConfiguration struct {
|
||||
Version Version `yaml:"version"`
|
||||
Log *Log `yaml:"log"`
|
||||
}
|
||||
|
||||
type Log struct {
|
||||
Formatter string `yaml:"formatter,omitempty"`
|
||||
}
|
||||
|
||||
var expectedConfig = localConfiguration{
|
||||
Version: "0.1",
|
||||
Log: &Log{
|
||||
Formatter: "json",
|
||||
},
|
||||
}
|
||||
|
||||
type ParserSuite struct{}
|
||||
|
||||
var _ = Suite(new(ParserSuite))
|
||||
|
||||
func (suite *ParserSuite) TestParserOverwriteIninitializedPoiner(c *C) {
|
||||
config := localConfiguration{}
|
||||
|
||||
os.Setenv("REGISTRY_LOG_FORMATTER", "json")
|
||||
defer os.Unsetenv("REGISTRY_LOG_FORMATTER")
|
||||
|
||||
p := NewParser("registry", []VersionedParseInfo{
|
||||
{
|
||||
Version: "0.1",
|
||||
ParseAs: reflect.TypeOf(config),
|
||||
ConversionFunc: func(c interface{}) (interface{}, error) {
|
||||
return c, nil
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
err := p.Parse([]byte(`{version: "0.1", log: {formatter: "text"}}`), &config)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(config, DeepEquals, expectedConfig)
|
||||
}
|
||||
|
||||
func (suite *ParserSuite) TestParseOverwriteUnininitializedPoiner(c *C) {
|
||||
config := localConfiguration{}
|
||||
|
||||
os.Setenv("REGISTRY_LOG_FORMATTER", "json")
|
||||
defer os.Unsetenv("REGISTRY_LOG_FORMATTER")
|
||||
|
||||
p := NewParser("registry", []VersionedParseInfo{
|
||||
{
|
||||
Version: "0.1",
|
||||
ParseAs: reflect.TypeOf(config),
|
||||
ConversionFunc: func(c interface{}) (interface{}, error) {
|
||||
return c, nil
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
err := p.Parse([]byte(`{version: "0.1"}`), &config)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(config, DeepEquals, expectedConfig)
|
||||
}
|
|
@ -1,16 +1,21 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/distribution/uuid"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Context is a copy of Context from the golang.org/x/net/context package.
|
||||
type Context interface {
|
||||
context.Context
|
||||
}
|
||||
|
||||
// instanceContext is a context that provides only an instance id. It is
|
||||
// provided as the main background context.
|
||||
type instanceContext struct {
|
||||
context.Context
|
||||
Context
|
||||
id string // id of context, logged as "instance.id"
|
||||
once sync.Once // once protect generation of the id
|
||||
}
|
||||
|
@ -37,10 +42,17 @@ var background = &instanceContext{
|
|||
// Background returns a non-nil, empty Context. The background context
|
||||
// provides a single key, "instance.id" that is globally unique to the
|
||||
// process.
|
||||
func Background() context.Context {
|
||||
func Background() Context {
|
||||
return background
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is
|
||||
// val. Use context Values only for request-scoped data that transits processes
|
||||
// and APIs, not for passing optional parameters to functions.
|
||||
func WithValue(parent Context, key, val interface{}) Context {
|
||||
return context.WithValue(parent, key, val)
|
||||
}
|
||||
|
||||
// stringMapContext is a simple context implementation that checks a map for a
|
||||
// key, falling back to a parent if not present.
|
||||
type stringMapContext struct {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Package context provides several utilities for working with
|
||||
// Go's context in http requests. Primarily, the focus is on logging relevant
|
||||
// request information but this package is not limited to that purpose.
|
||||
// golang.org/x/net/context in http requests. Primarily, the focus is on
|
||||
// logging relevant request information but this package is not limited to
|
||||
// that purpose.
|
||||
//
|
||||
// The easiest way to get started is to get the background context:
|
||||
//
|
||||
|
@ -63,7 +64,7 @@
|
|||
// Note that this only affects the new context, the previous context, with the
|
||||
// version field, can be used independently. Put another way, the new logger,
|
||||
// added to the request context, is unique to that context and can have
|
||||
// request scoped variables.
|
||||
// request scoped varaibles.
|
||||
//
|
||||
// HTTP Requests
|
||||
//
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
|
@ -9,9 +8,9 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/distribution/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Common errors used with this package.
|
||||
|
@ -69,7 +68,7 @@ func RemoteIP(r *http.Request) string {
|
|||
// is available at "http.request". Other common attributes are available under
|
||||
// the prefix "http.request.". If a request is already present on the context,
|
||||
// this method will panic.
|
||||
func WithRequest(ctx context.Context, r *http.Request) context.Context {
|
||||
func WithRequest(ctx Context, r *http.Request) Context {
|
||||
if ctx.Value("http.request") != nil {
|
||||
// NOTE(stevvooe): This needs to be considered a programming error. It
|
||||
// is unlikely that we'd want to have more than one request in
|
||||
|
@ -88,7 +87,7 @@ func WithRequest(ctx context.Context, r *http.Request) context.Context {
|
|||
// GetRequest returns the http request in the given context. Returns
|
||||
// ErrNoRequestContext if the context does not have an http request associated
|
||||
// with it.
|
||||
func GetRequest(ctx context.Context) (*http.Request, error) {
|
||||
func GetRequest(ctx Context) (*http.Request, error) {
|
||||
if r, ok := ctx.Value("http.request").(*http.Request); r != nil && ok {
|
||||
return r, nil
|
||||
}
|
||||
|
@ -97,24 +96,34 @@ func GetRequest(ctx context.Context) (*http.Request, error) {
|
|||
|
||||
// GetRequestID attempts to resolve the current request id, if possible. An
|
||||
// error is return if it is not available on the context.
|
||||
func GetRequestID(ctx context.Context) string {
|
||||
func GetRequestID(ctx Context) string {
|
||||
return GetStringValue(ctx, "http.request.id")
|
||||
}
|
||||
|
||||
// WithResponseWriter returns a new context and response writer that makes
|
||||
// interesting response statistics available within the context.
|
||||
func WithResponseWriter(ctx context.Context, w http.ResponseWriter) (context.Context, http.ResponseWriter) {
|
||||
func WithResponseWriter(ctx Context, w http.ResponseWriter) (Context, http.ResponseWriter) {
|
||||
irw := instrumentedResponseWriter{
|
||||
ResponseWriter: w,
|
||||
Context: ctx,
|
||||
}
|
||||
|
||||
if closeNotifier, ok := w.(http.CloseNotifier); ok {
|
||||
irwCN := &instrumentedResponseWriterCN{
|
||||
instrumentedResponseWriter: irw,
|
||||
CloseNotifier: closeNotifier,
|
||||
}
|
||||
|
||||
return irwCN, irwCN
|
||||
}
|
||||
|
||||
return &irw, &irw
|
||||
}
|
||||
|
||||
// GetResponseWriter returns the http.ResponseWriter from the provided
|
||||
// context. If not present, ErrNoResponseWriterContext is returned. The
|
||||
// returned instance provides instrumentation in the context.
|
||||
func GetResponseWriter(ctx context.Context) (http.ResponseWriter, error) {
|
||||
func GetResponseWriter(ctx Context) (http.ResponseWriter, error) {
|
||||
v := ctx.Value("http.response")
|
||||
|
||||
rw, ok := v.(http.ResponseWriter)
|
||||
|
@ -134,7 +143,7 @@ var getVarsFromRequest = mux.Vars
|
|||
// example, if looking for the variable "name", it can be accessed as
|
||||
// "vars.name". Implementations that are accessing values need not know that
|
||||
// the underlying context is implemented with gorilla/mux vars.
|
||||
func WithVars(ctx context.Context, r *http.Request) context.Context {
|
||||
func WithVars(ctx Context, r *http.Request) Context {
|
||||
return &muxVarsContext{
|
||||
Context: ctx,
|
||||
vars: getVarsFromRequest(r),
|
||||
|
@ -144,7 +153,7 @@ func WithVars(ctx context.Context, r *http.Request) context.Context {
|
|||
// GetRequestLogger returns a logger that contains fields from the request in
|
||||
// the current context. If the request is not available in the context, no
|
||||
// fields will display. Request loggers can safely be pushed onto the context.
|
||||
func GetRequestLogger(ctx context.Context) Logger {
|
||||
func GetRequestLogger(ctx Context) Logger {
|
||||
return GetLogger(ctx,
|
||||
"http.request.id",
|
||||
"http.request.method",
|
||||
|
@ -160,7 +169,7 @@ func GetRequestLogger(ctx context.Context) Logger {
|
|||
// Because the values are read at call time, pushing a logger returned from
|
||||
// this function on the context will lead to missing or invalid data. Only
|
||||
// call this at the end of a request, after the response has been written.
|
||||
func GetResponseLogger(ctx context.Context) Logger {
|
||||
func GetResponseLogger(ctx Context) Logger {
|
||||
l := getLogrusLogger(ctx,
|
||||
"http.response.written",
|
||||
"http.response.status",
|
||||
|
@ -177,7 +186,7 @@ func GetResponseLogger(ctx context.Context) Logger {
|
|||
|
||||
// httpRequestContext makes information about a request available to context.
|
||||
type httpRequestContext struct {
|
||||
context.Context
|
||||
Context
|
||||
|
||||
startedAt time.Time
|
||||
id string
|
||||
|
@ -236,7 +245,7 @@ fallback:
|
|||
}
|
||||
|
||||
type muxVarsContext struct {
|
||||
context.Context
|
||||
Context
|
||||
vars map[string]string
|
||||
}
|
||||
|
||||
|
@ -258,12 +267,20 @@ func (ctx *muxVarsContext) Value(key interface{}) interface{} {
|
|||
return ctx.Context.Value(key)
|
||||
}
|
||||
|
||||
// instrumentedResponseWriterCN provides response writer information in a
|
||||
// context. It implements http.CloseNotifier so that users can detect
|
||||
// early disconnects.
|
||||
type instrumentedResponseWriterCN struct {
|
||||
instrumentedResponseWriter
|
||||
http.CloseNotifier
|
||||
}
|
||||
|
||||
// instrumentedResponseWriter provides response writer information in a
|
||||
// context. This variant is only used in the case where CloseNotifier is not
|
||||
// implemented by the parent ResponseWriter.
|
||||
type instrumentedResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
context.Context
|
||||
Context
|
||||
|
||||
mu sync.Mutex
|
||||
status int
|
||||
|
@ -335,3 +352,13 @@ func (irw *instrumentedResponseWriter) Value(key interface{}) interface{} {
|
|||
fallback:
|
||||
return irw.Context.Value(key)
|
||||
}
|
||||
|
||||
func (irw *instrumentedResponseWriterCN) Value(key interface{}) interface{} {
|
||||
if keyStr, ok := key.(string); ok {
|
||||
if keyStr == "http.response" {
|
||||
return irw
|
||||
}
|
||||
}
|
||||
|
||||
return irw.instrumentedResponseWriter.Value(key)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Logger provides a leveled-logging interface.
|
||||
|
@ -39,28 +38,24 @@ type Logger interface {
|
|||
Warn(args ...interface{})
|
||||
Warnf(format string, args ...interface{})
|
||||
Warnln(args ...interface{})
|
||||
|
||||
WithError(err error) *logrus.Entry
|
||||
}
|
||||
|
||||
type loggerKey struct{}
|
||||
|
||||
// WithLogger creates a new context with provided logger.
|
||||
func WithLogger(ctx context.Context, logger Logger) context.Context {
|
||||
return context.WithValue(ctx, loggerKey{}, logger)
|
||||
func WithLogger(ctx Context, logger Logger) Context {
|
||||
return WithValue(ctx, "logger", logger)
|
||||
}
|
||||
|
||||
// GetLoggerWithField returns a logger instance with the specified field key
|
||||
// and value without affecting the context. Extra specified keys will be
|
||||
// resolved from the context.
|
||||
func GetLoggerWithField(ctx context.Context, key, value interface{}, keys ...interface{}) Logger {
|
||||
func GetLoggerWithField(ctx Context, key, value interface{}, keys ...interface{}) Logger {
|
||||
return getLogrusLogger(ctx, keys...).WithField(fmt.Sprint(key), value)
|
||||
}
|
||||
|
||||
// GetLoggerWithFields returns a logger instance with the specified fields
|
||||
// without affecting the context. Extra specified keys will be resolved from
|
||||
// the context.
|
||||
func GetLoggerWithFields(ctx context.Context, fields map[interface{}]interface{}, keys ...interface{}) Logger {
|
||||
func GetLoggerWithFields(ctx Context, fields map[interface{}]interface{}, keys ...interface{}) Logger {
|
||||
// must convert from interface{} -> interface{} to string -> interface{} for logrus.
|
||||
lfields := make(logrus.Fields, len(fields))
|
||||
for key, value := range fields {
|
||||
|
@ -76,7 +71,7 @@ func GetLoggerWithFields(ctx context.Context, fields map[interface{}]interface{}
|
|||
// argument passed to GetLogger will be passed to fmt.Sprint when expanded as
|
||||
// a logging key field. If context keys are integer constants, for example,
|
||||
// its recommended that a String method is implemented.
|
||||
func GetLogger(ctx context.Context, keys ...interface{}) Logger {
|
||||
func GetLogger(ctx Context, keys ...interface{}) Logger {
|
||||
return getLogrusLogger(ctx, keys...)
|
||||
}
|
||||
|
||||
|
@ -84,11 +79,11 @@ func GetLogger(ctx context.Context, keys ...interface{}) Logger {
|
|||
// are provided, they will be resolved on the context and included in the
|
||||
// logger. Only use this function if specific logrus functionality is
|
||||
// required.
|
||||
func getLogrusLogger(ctx context.Context, keys ...interface{}) *logrus.Entry {
|
||||
func getLogrusLogger(ctx Context, keys ...interface{}) *logrus.Entry {
|
||||
var logger *logrus.Entry
|
||||
|
||||
// Get a logger, if it is present.
|
||||
loggerInterface := ctx.Value(loggerKey{})
|
||||
loggerInterface := ctx.Value("logger")
|
||||
if loggerInterface != nil {
|
||||
if lgr, ok := loggerInterface.(*logrus.Entry); ok {
|
||||
logger = lgr
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
|
@ -37,7 +36,7 @@ import (
|
|||
//
|
||||
// Notice that the function name is automatically resolved, along with the
|
||||
// package and a trace id is emitted that can be linked with parent ids.
|
||||
func WithTrace(ctx context.Context) (context.Context, func(format string, a ...interface{})) {
|
||||
func WithTrace(ctx Context) (Context, func(format string, a ...interface{})) {
|
||||
if ctx == nil {
|
||||
ctx = Background()
|
||||
}
|
||||
|
@ -70,7 +69,7 @@ func WithTrace(ctx context.Context) (context.Context, func(format string, a ...i
|
|||
// also provides fast lookup for the various attributes that are available on
|
||||
// the trace.
|
||||
type traced struct {
|
||||
context.Context
|
||||
Context
|
||||
id string
|
||||
parent string
|
||||
start time.Time
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -36,7 +35,7 @@ func TestWithTrace(t *testing.T) {
|
|||
ctx, done := WithTrace(Background())
|
||||
defer done("this will be emitted at end of test")
|
||||
|
||||
checkContextForValues(ctx, t, append(base, valueTestCase{
|
||||
checkContextForValues(t, ctx, append(base, valueTestCase{
|
||||
key: "trace.func",
|
||||
expected: f.Name(),
|
||||
}))
|
||||
|
@ -49,7 +48,7 @@ func TestWithTrace(t *testing.T) {
|
|||
ctx, done := WithTrace(ctx)
|
||||
defer done("this should be subordinate to the other trace")
|
||||
time.Sleep(time.Second)
|
||||
checkContextForValues(ctx, t, append(base, valueTestCase{
|
||||
checkContextForValues(t, ctx, append(base, valueTestCase{
|
||||
key: "trace.func",
|
||||
expected: f.Name(),
|
||||
}, valueTestCase{
|
||||
|
@ -68,7 +67,8 @@ type valueTestCase struct {
|
|||
notnilorempty bool // just check not empty/not nil
|
||||
}
|
||||
|
||||
func checkContextForValues(ctx context.Context, t *testing.T, values []valueTestCase) {
|
||||
func checkContextForValues(t *testing.T, ctx Context, values []valueTestCase) {
|
||||
|
||||
for _, testcase := range values {
|
||||
v := ctx.Value(testcase.key)
|
||||
if testcase.notnilorempty {
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Since looks up key, which should be a time.Time, and returns the duration
|
||||
// since that time. If the key is not found, the value returned will be zero.
|
||||
// This is helpful when inferring metrics related to context execution times.
|
||||
func Since(ctx context.Context, key interface{}) time.Duration {
|
||||
func Since(ctx Context, key interface{}) time.Duration {
|
||||
if startedAt, ok := ctx.Value(key).(time.Time); ok {
|
||||
return time.Since(startedAt)
|
||||
}
|
||||
|
@ -17,7 +16,7 @@ func Since(ctx context.Context, key interface{}) time.Duration {
|
|||
|
||||
// GetStringValue returns a string value from the context. The empty string
|
||||
// will be returned if not found.
|
||||
func GetStringValue(ctx context.Context, key interface{}) (value string) {
|
||||
func GetStringValue(ctx Context, key interface{}) (value string) {
|
||||
if valuev, ok := ctx.Value(key).(string); ok {
|
||||
value = valuev
|
||||
}
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
package context
|
||||
|
||||
import "context"
|
||||
|
||||
type versionKey struct{}
|
||||
|
||||
func (versionKey) String() string { return "version" }
|
||||
|
||||
// WithVersion stores the application version in the context. The new context
|
||||
// gets a logger to ensure log messages are marked with the application
|
||||
// version.
|
||||
func WithVersion(ctx context.Context, version string) context.Context {
|
||||
ctx = context.WithValue(ctx, versionKey{}, version)
|
||||
func WithVersion(ctx Context, version string) Context {
|
||||
ctx = WithValue(ctx, "version", version)
|
||||
// push a new logger onto the stack
|
||||
return WithLogger(ctx, GetLogger(ctx, versionKey{}))
|
||||
return WithLogger(ctx, GetLogger(ctx, "version"))
|
||||
}
|
||||
|
||||
// GetVersion returns the application version from the context. An empty
|
||||
// string may returned if the version was not set on the context.
|
||||
func GetVersion(ctx context.Context) string {
|
||||
return GetStringValue(ctx, versionKey{})
|
||||
func GetVersion(ctx Context) string {
|
||||
return GetStringValue(ctx, "version")
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ to the 1.0 registry. Requests from newer clients will route to the 2.0 registry.
|
|||
Removing intermediate container edb84c2b40cb
|
||||
Successfully built 74acc70fa106
|
||||
|
||||
The command outputs its progress until it completes.
|
||||
The commmand outputs its progress until it completes.
|
||||
|
||||
4. Start your configuration with compose.
|
||||
|
||||
|
@ -123,22 +123,22 @@ to the 1.0 registry. Requests from newer clients will route to the 2.0 registry.
|
|||
|
||||
4. Use `curl` to list the image in the registry.
|
||||
|
||||
$ curl -v -X GET http://localhost:5000/v2/registry_one/tags/list
|
||||
$ curl -v -X GET http://localhost:32777/v2/registry1/tags/list
|
||||
* Hostname was NOT found in DNS cache
|
||||
* Trying 127.0.0.1...
|
||||
* Connected to localhost (127.0.0.1) port 32777 (#0)
|
||||
> GET /v2/registry1/tags/list HTTP/1.1
|
||||
> User-Agent: curl/7.36.0
|
||||
> Host: localhost:5000
|
||||
> Host: localhost:32777
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Content-Type: application/json
|
||||
< Content-Type: application/json; charset=utf-8
|
||||
< Docker-Distribution-Api-Version: registry/2.0
|
||||
< Date: Tue, 14 Apr 2015 22:34:13 GMT
|
||||
< Content-Length: 39
|
||||
<
|
||||
{"name":"registry_one","tags":["latest"]}
|
||||
{"name":"registry1","tags":["latest"]}
|
||||
* Connection #0 to host localhost left intact
|
||||
|
||||
This example refers to the specific port assigned to the 2.0 registry. You saw
|
||||
|
|
|
@ -4,6 +4,3 @@ proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
|
|||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 900;
|
||||
proxy_send_timeout 300;
|
||||
proxy_request_buffering off; (see issue #2292 - https://github.com/moby/moby/issues/2292)
|
||||
proxy_http_version 1.1;
|
||||
|
|
|
@ -1,9 +1,46 @@
|
|||
FROM distribution/golem:0.1
|
||||
FROM debian:jessie
|
||||
|
||||
MAINTAINER Docker Distribution Team <distribution@docker.com>
|
||||
|
||||
RUN apk add --no-cache git
|
||||
# compile and runtime deps
|
||||
# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#runtime-dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
# For DIND
|
||||
ca-certificates \
|
||||
curl \
|
||||
iptables \
|
||||
procps \
|
||||
e2fsprogs \
|
||||
xz-utils \
|
||||
# For build
|
||||
build-essential \
|
||||
file \
|
||||
git \
|
||||
net-tools \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV TMPDIR /var/lib/docker/tmp
|
||||
# Install Docker
|
||||
ENV VERSION 1.7.1
|
||||
RUN curl -L -o /usr/local/bin/docker https://test.docker.com/builds/Linux/x86_64/docker-${VERSION} \
|
||||
&& chmod +x /usr/local/bin/docker
|
||||
|
||||
# Install DIND
|
||||
RUN curl -L -o /dind https://raw.githubusercontent.com/docker/docker/v1.8.1/hack/dind \
|
||||
&& chmod +x /dind
|
||||
|
||||
# Install bats
|
||||
RUN cd /usr/local/src/ \
|
||||
&& git clone https://github.com/sstephenson/bats.git \
|
||||
&& cd bats \
|
||||
&& ./install.sh /usr/local
|
||||
|
||||
# Install docker-compose
|
||||
RUN curl -L https://github.com/docker/compose/releases/download/1.3.3/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
RUN mkdir -p /go/src/github.com/docker/distribution
|
||||
WORKDIR /go/src/github.com/docker/distribution/contrib/docker-integration
|
||||
|
||||
VOLUME /var/lib/docker
|
||||
|
||||
ENTRYPOINT ["/dind"]
|
||||
|
|
|
@ -1,63 +1,138 @@
|
|||
# Docker Registry Integration Testing
|
||||
|
||||
These integration tests cover interactions between registry clients such as
|
||||
the docker daemon and the registry server. All tests can be run using the
|
||||
[golem integration test runner](https://github.com/docker/golem)
|
||||
These integration tests cover interactions between the Docker daemon and the
|
||||
registry server. All tests are run using the docker cli.
|
||||
|
||||
The integration tests configure components using docker compose
|
||||
(see docker-compose.yaml) and the runner can be using the golem
|
||||
configuration file (see golem.conf).
|
||||
The compose configuration is intended to setup a testing environment for Docker
|
||||
using multiple registry configurations. These configurations include different
|
||||
combinations of a v1 and v2 registry as well as TLS configurations.
|
||||
|
||||
## Running integration tests
|
||||
## Running inside of Docker
|
||||
### Get integration container
|
||||
The container image to run the integation tests will need to be pulled or built
|
||||
locally.
|
||||
|
||||
### Run using multiversion script
|
||||
*Building locally*
|
||||
```
|
||||
$ docker build -t distribution/docker-integration .
|
||||
```
|
||||
|
||||
The integration tests in the `contrib/docker-integration` directory can be simply
|
||||
run by executing the run script `./run_multiversion.sh`. If there is no running
|
||||
daemon to connect to, run as `./run_multiversion.sh -d`.
|
||||
### Run script
|
||||
|
||||
This command will build the distribution image from the locally checked out
|
||||
version and run against multiple versions of docker defined in the script. To
|
||||
run a specific version of the registry or docker, Golem will need to be
|
||||
executed manually.
|
||||
Invoke the tests within Docker through the `run.sh` script.
|
||||
|
||||
### Run manually using Golem
|
||||
```
|
||||
$ ./run.sh
|
||||
```
|
||||
|
||||
Using the golem tool directly allows running against multiple versions of
|
||||
the registry and docker. Running against multiple versions of the registry
|
||||
can be useful for testing changes in the docker daemon which are not
|
||||
covered by the default run script.
|
||||
Run with aufs driver and tmp volume
|
||||
**NOTE: Using a volume will prevent multiple runs from needing to
|
||||
re-pull images**
|
||||
```
|
||||
$ DOCKER_GRAPHDRIVER=aufs DOCKER_VOLUME=/tmp/volume ./run.sh
|
||||
```
|
||||
|
||||
#### Installing Golem
|
||||
### Example developer flow
|
||||
|
||||
Golem is distributed as an executable binary which can be installed from
|
||||
the [release page](https://github.com/docker/golem/releases/tag/v0.1).
|
||||
These tests are useful for developing both as a registry and docker
|
||||
core developer. The following setup may be used to do integration
|
||||
testing between development versions
|
||||
|
||||
#### Running golem with docker
|
||||
Insert into your `.zshrc` or `.bashrc`
|
||||
|
||||
Additionally golem can be run as a docker image requiring no additional
|
||||
installation.
|
||||
```
|
||||
# /usr/lib/docker for Docker-in-Docker
|
||||
# Set this directory to make each invocation run much faster, without
|
||||
# the need to repull images.
|
||||
export DOCKER_VOLUME=$HOME/.docker-test-volume
|
||||
|
||||
`docker run --privileged -v "$GOPATH/src/github.com/docker/distribution/contrib/docker-integration:/test" -w /test distribution/golem golem -rundaemon .`
|
||||
# Use overlay for all Docker testing, try aufs if overlay not supported
|
||||
export DOCKER_GRAPHDRIVER=overlay
|
||||
|
||||
#### Golem custom images
|
||||
# Name this according to personal preference
|
||||
function rdtest() {
|
||||
if [ "$1" != "" ]; then
|
||||
DOCKER_BINARY=$GOPATH/src/github.com/docker/docker/bundles/$1/binary/docker
|
||||
if [ ! -f $DOCKER_BINARY ]; then
|
||||
current_version=`cat $GOPATH/src/github.com/docker/docker/VERSION`
|
||||
echo "$DOCKER_BINARY does not exist"
|
||||
echo "Current checked out docker version: $current_version"
|
||||
echo "Checkout desired version and run 'make binary' from $GOPATH/src/github.com/docker/docker"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
Golem tests version of software by defining the docker image to test.
|
||||
$GOPATH/src/github.com/docker/distribution/contrib/docker-integration/run.sh
|
||||
}
|
||||
```
|
||||
|
||||
Run with registry 2.2.1 and docker 1.10.3
|
||||
Run with Docker release version
|
||||
```
|
||||
$ rdtest
|
||||
```
|
||||
|
||||
`golem -i golem-dind:latest,docker:1.10.3-dind,1.10.3 -i golem-distribution:latest,registry:2.2.1 .`
|
||||
Run using local development version of docker
|
||||
```
|
||||
$ cd $GOPATH/src/github.com/docker/docker
|
||||
$ make binary
|
||||
$ rdtest `cat VERSION`
|
||||
```
|
||||
|
||||
## Running manually outside of Docker
|
||||
|
||||
#### Use golem caching for developing tests
|
||||
### Install Docker Compose
|
||||
|
||||
Golem allows caching image configuration to reduce test start up time.
|
||||
Using this cache will allow tests with the same set of images to start
|
||||
up quickly. This can be useful when developing tests and needing the
|
||||
test to run quickly. If there are changes which effect the image (such as
|
||||
building a new registry image), then startup time will be slower.
|
||||
[Docker Compose Installation Guide](https://docs.docker.com/compose/install/)
|
||||
|
||||
Run this command multiple times and after the first time test runs
|
||||
should start much quicker.
|
||||
`golem -cache ~/.cache/docker/golem -i golem-dind:latest,docker:1.10.3-dind,1.10.3 -i golem-distribution:latest,registry:2.2.1 .`
|
||||
### Start compose setup
|
||||
```
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
### Install Certificates
|
||||
The certificates must be installed in /etc/docker/cert.d in order to use TLS
|
||||
client auth and use the CA certificate.
|
||||
```
|
||||
sudo sh ./install_certs.sh
|
||||
```
|
||||
|
||||
### Test with Docker
|
||||
Tag an image as with any other private registry. Attempt to push the image.
|
||||
|
||||
```
|
||||
docker pull hello-world
|
||||
docker tag hello-world localhost:5440/hello-world
|
||||
docker push localhost:5440/hello-world
|
||||
|
||||
docker tag hello-world localhost:5441/hello-world
|
||||
docker push localhost:5441/hello-world
|
||||
# Perform login using user `testuser` and password `passpassword`
|
||||
```
|
||||
|
||||
### Set /etc/hosts entry
|
||||
Find the non-localhost ip address of local machine
|
||||
|
||||
### Run bats
|
||||
Run the bats tests after updating /etc/hosts, installing the certificates, and
|
||||
running the `docker-compose` script.
|
||||
```
|
||||
bats -p .
|
||||
```
|
||||
|
||||
## Configurations
|
||||
|
||||
Port | V2 | V1 | TLS | Authentication
|
||||
--- | --- | --- | --- | ---
|
||||
5000 | yes | yes | no | none
|
||||
5001 | no | yes | no | none
|
||||
5002 | yes | no | no | none
|
||||
5011 | no | yes | yes | none
|
||||
5440 | yes | yes | yes | none
|
||||
5441 | yes | yes | yes | basic (testuser/passpassword)
|
||||
5442 | yes | yes | yes | TLS client
|
||||
5443 | yes | yes | yes | TLS client (no CA)
|
||||
5444 | yes | yes | yes | TLS client + basic (testuser/passpassword)
|
||||
5445 | yes | yes | yes (no CA) | none
|
||||
5446 | yes | yes | yes (no CA) | basic (testuser/passpassword)
|
||||
5447 | yes | yes | yes (no CA) | TLS client
|
||||
5448 | yes | yes | yes (SSLv3) | none
|
||||
|
|
|
@ -2,7 +2,9 @@ nginx:
|
|||
build: "nginx"
|
||||
ports:
|
||||
- "5000:5000"
|
||||
- "5001:5001"
|
||||
- "5002:5002"
|
||||
- "5011:5011"
|
||||
- "5440:5440"
|
||||
- "5441:5441"
|
||||
- "5442:5442"
|
||||
|
@ -12,80 +14,14 @@ nginx:
|
|||
- "5446:5446"
|
||||
- "5447:5447"
|
||||
- "5448:5448"
|
||||
- "5554:5554"
|
||||
- "5555:5555"
|
||||
- "5556:5556"
|
||||
- "5557:5557"
|
||||
- "5558:5558"
|
||||
- "5559:5559"
|
||||
- "5600:5600"
|
||||
- "6666:6666"
|
||||
links:
|
||||
- registryv1:registryv1
|
||||
- registryv2:registryv2
|
||||
- malevolent:malevolent
|
||||
- registryv2token:registryv2token
|
||||
- tokenserver:tokenserver
|
||||
- registryv2tokenoauth:registryv2tokenoauth
|
||||
- registryv2tokenoauthnotls:registryv2tokenoauthnotls
|
||||
- tokenserveroauth:tokenserveroauth
|
||||
registryv1:
|
||||
image: registry:0.9.1
|
||||
ports:
|
||||
- "5000"
|
||||
registryv2:
|
||||
image: golem-distribution:latest
|
||||
build: "../../"
|
||||
ports:
|
||||
- "5000"
|
||||
registryv2token:
|
||||
image: golem-distribution:latest
|
||||
ports:
|
||||
- "5000"
|
||||
volumes:
|
||||
- ./tokenserver/registry-config.yml:/etc/docker/registry/config.yml
|
||||
- ./tokenserver/certs/localregistry.cert:/etc/docker/registry/localregistry.cert
|
||||
- ./tokenserver/certs/localregistry.key:/etc/docker/registry/localregistry.key
|
||||
- ./tokenserver/certs/signing.cert:/etc/docker/registry/tokenbundle.pem
|
||||
tokenserver:
|
||||
build: "tokenserver"
|
||||
command: "--debug -addr 0.0.0.0:5556 -issuer registry-test -passwd .htpasswd -tlscert tls.cert -tlskey tls.key -key sign.key -realm http://auth.localregistry:5556"
|
||||
ports:
|
||||
- "5556"
|
||||
registryv2tokenoauth:
|
||||
image: golem-distribution:latest
|
||||
ports:
|
||||
- "5000"
|
||||
volumes:
|
||||
- ./tokenserver-oauth/registry-config.yml:/etc/docker/registry/config.yml
|
||||
- ./tokenserver-oauth/certs/localregistry.cert:/etc/docker/registry/localregistry.cert
|
||||
- ./tokenserver-oauth/certs/localregistry.key:/etc/docker/registry/localregistry.key
|
||||
- ./tokenserver-oauth/certs/signing.cert:/etc/docker/registry/tokenbundle.pem
|
||||
registryv2tokenoauthnotls:
|
||||
image: golem-distribution:latest
|
||||
ports:
|
||||
- "5000"
|
||||
volumes:
|
||||
- ./tokenserver-oauth/registry-config-notls.yml:/etc/docker/registry/config.yml
|
||||
- ./tokenserver-oauth/certs/signing.cert:/etc/docker/registry/tokenbundle.pem
|
||||
tokenserveroauth:
|
||||
build: "tokenserver-oauth"
|
||||
command: "--debug -addr 0.0.0.0:5559 -issuer registry-test -passwd .htpasswd -tlscert tls.cert -tlskey tls.key -key sign.key -realm http://auth.localregistry:5559 -enforce-class"
|
||||
ports:
|
||||
- "5559"
|
||||
malevolent:
|
||||
image: "dmcgowan/malevolent:0.1.0"
|
||||
command: "-l 0.0.0.0:6666 -r http://registryv2:5000 -c /certs/localregistry.cert -k /certs/localregistry.key"
|
||||
links:
|
||||
- registryv2:registryv2
|
||||
volumes:
|
||||
- ./malevolent-certs:/certs:ro
|
||||
ports:
|
||||
- "6666"
|
||||
docker:
|
||||
image: golem-dind:latest
|
||||
container_name: dockerdaemon
|
||||
command: "docker daemon --debug -s $DOCKER_GRAPHDRIVER"
|
||||
privileged: true
|
||||
environment:
|
||||
DOCKER_GRAPHDRIVER:
|
||||
volumes:
|
||||
- /etc/generated_certs.d:/etc/docker/certs.d
|
||||
- /var/lib/docker
|
||||
links:
|
||||
- nginx:localregistry
|
||||
- nginx:auth.localregistry
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
[[suite]]
|
||||
dind=true
|
||||
images=[ "nginx:1.9", "dmcgowan/token-server:simple", "dmcgowan/token-server:oauth", "dmcgowan/malevolent:0.1.0", "dmcgowan/ncat:latest" ]
|
||||
|
||||
[[suite.pretest]]
|
||||
command="sh ./install_certs.sh /etc/generated_certs.d"
|
||||
[[suite.testrunner]]
|
||||
command="bats -t ."
|
||||
format="tap"
|
||||
env=["TEST_REPO=hello-world", "TEST_TAG=latest", "TEST_USER=testuser", "TEST_PASSWORD=passpassword", "TEST_REGISTRY=localregistry", "TEST_SKIP_PULL=true"]
|
||||
[[suite.customimage]]
|
||||
tag="golem-distribution:latest"
|
||||
default="registry:2.2.1"
|
||||
[[suite.customimage]]
|
||||
tag="golem-dind:latest"
|
||||
default="docker:1.10.1-dind"
|
||||
version="1.10.1"
|
||||
|
|
@ -1,127 +1,21 @@
|
|||
# has_digest enforces the last output line is "Digest: sha256:..."
|
||||
# the input is the output from a docker push cli command
|
||||
function has_digest() {
|
||||
filtered=$(echo "$1" |sed -rn '/[dD]igest\: sha(256|384|512)/ p')
|
||||
[ "$filtered" != "" ]
|
||||
# See http://wiki.alpinelinux.org/wiki/Regex#BREs before making changes to regex
|
||||
digest=$(expr "$filtered" : ".*\(sha[0-9]\{3,3\}:[a-z0-9]*\)")
|
||||
}
|
||||
|
||||
# tempImage creates a new image using the provided name
|
||||
# requires bats
|
||||
function tempImage() {
|
||||
dir=$(mktemp -d)
|
||||
run dd if=/dev/urandom of="$dir/f" bs=1024 count=512
|
||||
cat <<DockerFileContent > "$dir/Dockerfile"
|
||||
FROM scratch
|
||||
COPY f /f
|
||||
|
||||
CMD []
|
||||
DockerFileContent
|
||||
|
||||
cp_t $dir "/tmpbuild/"
|
||||
exec_t "cd /tmpbuild/; docker build --no-cache -t $1 .; rm -rf /tmpbuild/"
|
||||
}
|
||||
|
||||
# skip basic auth tests with Docker 1.6, where they don't pass due to
|
||||
# certificate issues, requires bats
|
||||
function basic_auth_version_check() {
|
||||
run sh -c 'docker version | fgrep -q "Client version: 1.6."'
|
||||
if [ "$status" -eq 0 ]; then
|
||||
skip "Basic auth tests don't support 1.6.x"
|
||||
fi
|
||||
}
|
||||
|
||||
email="a@nowhere.com"
|
||||
|
||||
# docker_t_login calls login with email depending on version
|
||||
function docker_t_login() {
|
||||
# Only pass email field pre 1.11, no deprecation warning
|
||||
parse_version "$GOLEM_DIND_VERSION"
|
||||
v=$version
|
||||
parse_version "1.11.0"
|
||||
if [ "$v" -lt "$version" ]; then
|
||||
run docker_t login -e $email $@
|
||||
else
|
||||
run docker_t login $@
|
||||
fi
|
||||
}
|
||||
|
||||
# login issues a login to docker to the provided server
|
||||
# uses user, password, and email variables set outside of function
|
||||
# requies bats
|
||||
function login() {
|
||||
rm -f /root/.docker/config.json
|
||||
|
||||
docker_t_login -u $user -p $password $1
|
||||
if [ "$status" -ne 0 ]; then
|
||||
echo $output
|
||||
fi
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Handle different deprecation warnings
|
||||
parse_version "$GOLEM_DIND_VERSION"
|
||||
v=$version
|
||||
parse_version "1.11.0"
|
||||
if [ "$v" -lt "$version" ]; then
|
||||
# First line is WARNING about credential save or email deprecation (maybe both)
|
||||
[ "${lines[2]}" = "Login Succeeded" -o "${lines[1]}" = "Login Succeeded" ]
|
||||
else
|
||||
[ "${lines[0]}" = "Login Succeeded" ]
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function login_oauth() {
|
||||
login $@
|
||||
|
||||
tmpFile=$(mktemp)
|
||||
get_file_t /root/.docker/config.json $tmpFile
|
||||
run awk -v RS="" "/\"$1\": \\{[[:space:]]+\"auth\": \"[[:alnum:]]+\",[[:space:]]+\"identitytoken\"/ {exit 3}" $tmpFile
|
||||
[ "$status" -eq 3 ]
|
||||
}
|
||||
|
||||
function parse_version() {
|
||||
version=$(echo "$1" | cut -d '-' -f1) # Strip anything after '-'
|
||||
major=$(echo "$version" | cut -d . -f1)
|
||||
minor=$(echo "$version" | cut -d . -f2)
|
||||
rev=$(echo "$version" | cut -d . -f3)
|
||||
|
||||
version=$((major * 1000 * 1000 + minor * 1000 + rev))
|
||||
}
|
||||
|
||||
function version_check() {
|
||||
name=$1
|
||||
checkv=$2
|
||||
minv=$3
|
||||
parse_version "$checkv"
|
||||
v=$version
|
||||
parse_version "$minv"
|
||||
if [ "$v" -lt "$version" ]; then
|
||||
skip "$name version \"$checkv\" does not meet required version \"$minv\""
|
||||
fi
|
||||
}
|
||||
|
||||
function get_file_t() {
|
||||
docker cp dockerdaemon:$1 $2
|
||||
}
|
||||
|
||||
function cp_t() {
|
||||
docker cp $1 dockerdaemon:$2
|
||||
}
|
||||
|
||||
function exec_t() {
|
||||
docker exec dockerdaemon sh -c "$@"
|
||||
}
|
||||
|
||||
function docker_t() {
|
||||
docker exec dockerdaemon docker $@
|
||||
}
|
||||
|
||||
# build creates a new docker image id from another image
|
||||
function build() {
|
||||
docker exec -i dockerdaemon docker build --no-cache -t $1 - <<DOCKERFILE
|
||||
FROM $2
|
||||
MAINTAINER distribution@docker.com
|
||||
DOCKERFILE
|
||||
# Start docker daemon
|
||||
function start_daemon() {
|
||||
# Drivers to use for Docker engines the tests are going to create.
|
||||
STORAGE_DRIVER=${STORAGE_DRIVER:-overlay}
|
||||
EXEC_DRIVER=${EXEC_DRIVER:-native}
|
||||
|
||||
docker --daemon --log-level=panic \
|
||||
--storage-driver="$STORAGE_DRIVER" --exec-driver="$EXEC_DRIVER" &
|
||||
DOCKER_PID=$!
|
||||
|
||||
# Wait for it to become reachable.
|
||||
tries=10
|
||||
until docker version &> /dev/null; do
|
||||
(( tries-- ))
|
||||
if [ $tries -le 0 ]; then
|
||||
echo >&2 "error: daemon failed to start"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
|
|
@ -1,50 +1,38 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
hostname="localregistry"
|
||||
installdir="$1"
|
||||
hostname=$1
|
||||
if [ "$hostname" = "" ]; then
|
||||
hostname="localhost"
|
||||
fi
|
||||
|
||||
install_ca() {
|
||||
mkdir -p $1/$hostname:$2
|
||||
cp ./nginx/ssl/registry-ca+ca.pem $1/$hostname:$2/ca.crt
|
||||
if [ "$3" != "" ]; then
|
||||
cp ./nginx/ssl/registry-$3+client-cert.pem $1/$hostname:$2/client.cert
|
||||
cp ./nginx/ssl/registry-$3+client-key.pem $1/$hostname:$2/client.key
|
||||
fi
|
||||
}
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5011
|
||||
cp ./nginx/ssl/registry-ca+ca.pem /etc/docker/certs.d/$hostname:5011/ca.crt
|
||||
|
||||
install_test_certs() {
|
||||
install_ca $1 5440
|
||||
install_ca $1 5441
|
||||
install_ca $1 5442 ca
|
||||
install_ca $1 5443 noca
|
||||
install_ca $1 5444 ca
|
||||
install_ca $1 5447 ca
|
||||
# For test remove CA
|
||||
rm $1/${hostname}:5447/ca.crt
|
||||
install_ca $1 5448
|
||||
install_ca $1 5600
|
||||
}
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5440
|
||||
cp ./nginx/ssl/registry-ca+ca.pem /etc/docker/certs.d/$hostname:5440/ca.crt
|
||||
|
||||
install_ca_file() {
|
||||
mkdir -p $2
|
||||
cp $1 $2/ca.crt
|
||||
}
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5441
|
||||
cp ./nginx/ssl/registry-ca+ca.pem /etc/docker/certs.d/$hostname:5441/ca.crt
|
||||
|
||||
append_ca_file() {
|
||||
mkdir -p $2
|
||||
cat $1 >> $2/ca.crt
|
||||
}
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5442
|
||||
cp ./nginx/ssl/registry-ca+ca.pem /etc/docker/certs.d/$hostname:5442/ca.crt
|
||||
cp ./nginx/ssl/registry-ca+client-cert.pem /etc/docker/certs.d/$hostname:5442/client.cert
|
||||
cp ./nginx/ssl/registry-ca+client-key.pem /etc/docker/certs.d/$hostname:5442/client.key
|
||||
|
||||
install_test_certs $installdir
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5443
|
||||
cp ./nginx/ssl/registry-ca+ca.pem /etc/docker/certs.d/$hostname:5443/ca.crt
|
||||
cp ./nginx/ssl/registry-noca+client-cert.pem /etc/docker/certs.d/$hostname:5443/client.cert
|
||||
cp ./nginx/ssl/registry-noca+client-key.pem /etc/docker/certs.d/$hostname:5443/client.key
|
||||
|
||||
# Malevolent server
|
||||
install_ca_file ./malevolent-certs/ca.pem $installdir/$hostname:6666
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5444
|
||||
cp ./nginx/ssl/registry-ca+ca.pem /etc/docker/certs.d/$hostname:5444/ca.crt
|
||||
cp ./nginx/ssl/registry-ca+client-cert.pem /etc/docker/certs.d/$hostname:5444/client.cert
|
||||
cp ./nginx/ssl/registry-ca+client-key.pem /etc/docker/certs.d/$hostname:5444/client.key
|
||||
|
||||
# Token server
|
||||
install_ca_file ./tokenserver/certs/ca.pem $installdir/$hostname:5554
|
||||
install_ca_file ./tokenserver/certs/ca.pem $installdir/$hostname:5555
|
||||
install_ca_file ./tokenserver/certs/ca.pem $installdir/$hostname:5557
|
||||
install_ca_file ./tokenserver/certs/ca.pem $installdir/$hostname:5558
|
||||
append_ca_file ./tokenserver/certs/ca.pem $installdir/$hostname:5600
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5447
|
||||
cp ./nginx/ssl/registry-ca+client-cert.pem /etc/docker/certs.d/$hostname:5447/client.cert
|
||||
cp ./nginx/ssl/registry-ca+client-key.pem /etc/docker/certs.d/$hostname:5447/client.key
|
||||
|
||||
mkdir -p /etc/docker/certs.d/$hostname:5448
|
||||
cp ./nginx/ssl/registry-ca+ca.pem /etc/docker/certs.d/$hostname:5448/ca.crt
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+TCCAeGgAwIBAgIQJMzVQNYVNTbh36kZUytWiDANBgkqhkiG9w0BAQsFADAm
|
||||
MREwDwYDVQQKEwhRdWlja1RMUzERMA8GA1UEAxMIUXVpY2tUTFMwHhcNMTgwNTIx
|
||||
MjI1OTA2WhcNMjgwODI2MjI1OTA2WjAmMREwDwYDVQQKEwhRdWlja1RMUzERMA8G
|
||||
A1UEAxMIUXVpY2tUTFMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCe
|
||||
8rEU8xHh6BMYVRz/KhFftKSxS4dxJi2LoNN4fxzY6EgHNfBACt2MhIWaUSHf2YkF
|
||||
NsS/T7qZWq23NEuIJYUUwbJRAh/iQsEhCI56eV+aJX+DGd2SQQNKdx1Pt528LNws
|
||||
n8Ci8rEHTe6i2/U7n/DLqa32BWF3aShsVrchRgpizXezS7GLyFmhv0hi0zRKJgDG
|
||||
JebLeqe/BUtEOsS/Oa65NQTEO/5EZBzM74+4eRo5zyp9Uvw4edmOrXRXK1fK9gP3
|
||||
Fq/jz9+8b5eUd9vl0e9z/xTqMdicYZOUHuUtxM3hXAkkxcaVJqqqDe6URbJHpbaN
|
||||
8Vt/p/csFXMWj3oSokvDAgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMB
|
||||
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCC3NiX+2Qk3WB+TRNDPCtQ7Pw+
|
||||
o31SSqfF8m3fevT4mdrJqFAF4qUpDwgV9/9EkU4UBoIq03S91Dk/No0jR3VAzzRA
|
||||
h3+ul/7u08JriS/ZgVediodi7H8xeCz3nvZfAwCP2ZmHzDGp39Uhc3L3WFZImZuV
|
||||
fCDeSWF3c5CjJbdUuCYYFy6LwSFLPoBXZaNBL19XP9btJtjbNTm77PZJ4cELTQ+U
|
||||
r5Ofw9D9mCCYrapmprw7Fw9wdE+iLL9EJCHAj7L8UYshF4+7O7Jv3ZatySMWPbjS
|
||||
nIa2+eKl/sfvRvLZWV9dUSObVsm/bpv8bsHIKp4bYl+IDb2aoSWnw4eZQHDJ
|
||||
-----END CERTIFICATE-----
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFTCCAf2gAwIBAgIQfv/raCIVnmpXY74aUyohmDANBgkqhkiG9w0BAQsFADAm
|
||||
MREwDwYDVQQKEwhRdWlja1RMUzERMA8GA1UEAxMIUXVpY2tUTFMwHhcNMTgwNTIx
|
||||
MjI1OTA2WhcNMjgwODI2MjI1OTA2WjArMREwDwYDVQQKEwhRdWlja1RMUzEWMBQG
|
||||
A1UEAxMNbG9jYWxyZWdpc3RyeTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBALedGn6gB0Km693mvJ8yz89wtfDs+SGjJi+XmJv0PYe6j5uToXQH2naXXIOZ
|
||||
lT9lmXd/RciZwn50aK4T6alu96D8yeLE13P+75rdrI9DWTNHsfx0jwRxUEXNazPI
|
||||
5Knwbf2MgGJfvHE6LjQ3FStJJ9f8JzryspIAYy5PJETuzoF7GsrUhgmcgQNqQcIx
|
||||
d81QwOnW3EHastTPIbUxQ3cbEKZMVmvsYSY60pQuw/syN7vGcR/uJQ6HsCUWTEpk
|
||||
LWFNJYudYnRIJ/mb6bGJ0tJhdlXKQ9+89oiEWZp9p1KMfyXesp8HeW8Jyoa06+Ri
|
||||
5U82r0oQgC0MI5AueueoNOmQyGsCAwEAAaM6MDgwDgYDVR0PAQH/BAQDAgWgMAwG
|
||||
A1UdEwEB/wQCMAAwGAYDVR0RBBEwD4INbG9jYWxyZWdpc3RyeTANBgkqhkiG9w0B
|
||||
AQsFAAOCAQEAGgUESvQoD/QGZQlY2NA4sauad/yMHVo7vs5TLiKxnAfJrnP1ycD6
|
||||
sqcbwCu6B1GU7fqGjKKgzXWXHTi4MiLi5bnh5Y2JBTABksGmzNAU1LbQJJkwsPnE
|
||||
GBF0RgUmcw7a+4qu3TqPJABOsl+RiUQ4VDzP3DFRbyigs2li+SjLTJepahDhAke9
|
||||
11lU/r3pm1cov9m0AsKSHrU777Hv5B7gmyJ1FO1Os7/KnkdHKUwiIZx0VW6Ho5H+
|
||||
IiCH7iKJ1tTxe3nkwjlkSXnx7xiLOG7QK1LtTNHzBumF4COSF1kvWvIqNhJeg482
|
||||
e38+Kzctl5iVbrB+JWY6roTQ26VLIdlS7A==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAt50afqAHQqbr3ea8nzLPz3C18Oz5IaMmL5eYm/Q9h7qPm5Oh
|
||||
dAfadpdcg5mVP2WZd39FyJnCfnRorhPpqW73oPzJ4sTXc/7vmt2sj0NZM0ex/HSP
|
||||
BHFQRc1rM8jkqfBt/YyAYl+8cTouNDcVK0kn1/wnOvKykgBjLk8kRO7OgXsaytSG
|
||||
CZyBA2pBwjF3zVDA6dbcQdqy1M8htTFDdxsQpkxWa+xhJjrSlC7D+zI3u8ZxH+4l
|
||||
DoewJRZMSmQtYU0li51idEgn+ZvpsYnS0mF2VcpD37z2iIRZmn2nUox/Jd6ynwd5
|
||||
bwnKhrTr5GLlTzavShCALQwjkC5656g06ZDIawIDAQABAoIBAQCw7oKJYkucvpyq
|
||||
x50bCyuVCVdJQhEPiNdTJRG5tjFUiUG4+RmrZaXugQx1A5n97TllHQ9xrjjtAd+d
|
||||
XzLaQkP8rZsdGfFDpXXeFZ4irxNVhtDMJMVr0oU3vip/TCaMW1Kh8LIGGZrMwPOk
|
||||
/S849tWeGyzycMwCRL1N8pVQl44G1aexTmlt/tjpGyQAUcGt3MtKaUhhr8mLttfL
|
||||
2r6wfZgvSqReURBMdn/bf+sMKnJrYnZLRv/iPz+YWhdk4v1OXPO3D4OlYwR8HwSo
|
||||
a9mOpPuC6lWBqzq8eCBU474aQw4FXaFwN08YkJKa4DqUrmadnd4o+ajvOIA4MdF5
|
||||
7OOsHQaBAoGBANcVQIM6vndN2MFwODGnF8RfeLhEf46VlANkZadOOa0/igyra865
|
||||
7IR4dREFFkSdte8bj6/iEAPeDzXgS4TRsZfr2gkhdXuc2NW4jTVeiYfWW3cgKfW+
|
||||
7BQiHXsXCDeoZ1gXq/F5RmD8ue0TkP+IclWR52AM5e1MzfAuZzaIFNJFAoGBANqL
|
||||
Q925GxuDamcbuloxQUBarXPJgBDfTWUAXAJVISy80N3av45Y0gyoNjPaU7wHNtU9
|
||||
ppnYvM47o1W4qe9AkTtuU79T1WwXFr5T+4Ehm5I8WDHQwkzWGd+WlWkDidLWuvlx
|
||||
ZkzwQGp3KOTJhO20lpOtCbnOa627Op/zLhCBQzLvAoGAFF4A0+x2KNoIUpkL2TfX
|
||||
elMIHXrvEVN8xq11KtivgYZozjZVaSgWC51UiJ4Qs8KzfccAXklr9tHKYvGwdQ1e
|
||||
YeKFrSOr+l6p8eMeDBW9tE1KMAetsYW42Vc5r3RI5OxfjOoA8EbpsTl9acPWkTwc
|
||||
h5nfbSsLguMpBTt/rpxITHkCgYEAnKwwSBj25P+OXULUkuoytDcNmC+Bnxbm/hyG
|
||||
2ak78j2eox26LAti8m35Ba1kUCz/01myQSLPIC5DByYutXWdaHTMlyI7o5Td2i6M
|
||||
5GM6i1i1hWj6kmj+/XqPvEwsFzmXq1HvnAK0u16Xs4UAxgSr2ky35zujmFXcTmTg
|
||||
xjZU/YMCgYEAqF93h8WfckZxSUUMBgxTkNfu4MJlbsVBzIHv6TJY95VA49RcRYEK
|
||||
b7Xg+RiNQ42QGd8JBXZ50zQrIDhdd/yJ0KcytvW7WdiEEaF3ANO2QesygmI50611
|
||||
R76F8Bj0xnoQUCbyPuMOLRfTwEaS1jBG7TKWQXTaN0fm4DxUU0KazxU=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,192 +0,0 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
# This tests various expected error scenarios when pulling bad content
|
||||
|
||||
load helpers
|
||||
|
||||
host="localregistry:6666"
|
||||
base="malevolent-test"
|
||||
|
||||
function setup() {
|
||||
tempImage $base:latest
|
||||
}
|
||||
|
||||
@test "Test malevolent proxy pass through" {
|
||||
docker_t tag $base:latest $host/$base/nochange:latest
|
||||
run docker_t push $host/$base/nochange:latest
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
run docker_t pull $host/$base/nochange:latest
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "Test malevolent image name change" {
|
||||
imagename="$host/$base/rename"
|
||||
image="$imagename:lastest"
|
||||
docker_t tag $base:latest $image
|
||||
run docker_t push $image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
# Pull attempt should fail to verify manifest digest
|
||||
run docker_t pull "$imagename@$digest"
|
||||
echo "$output"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test malevolent altered layer" {
|
||||
image="$host/$base/addfile:latest"
|
||||
tempImage $image
|
||||
run docker_t push $image
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
# Remove image to ensure layer is pulled and digest verified
|
||||
docker_t rmi -f $image
|
||||
|
||||
run docker_t pull $image
|
||||
echo "$output"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test malevolent altered layer (by digest)" {
|
||||
imagename="$host/$base/addfile"
|
||||
image="$imagename:latest"
|
||||
tempImage $image
|
||||
run docker_t push $image
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
# Remove image to ensure layer is pulled and digest verified
|
||||
docker_t rmi -f $image
|
||||
|
||||
run docker_t pull "$imagename@$digest"
|
||||
echo "$output"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test malevolent poisoned images" {
|
||||
truncid="777cf9284131"
|
||||
poison="${truncid}d77ca0863fb7f054c0a276d7e227b5e9a5d62b497979a481fa32"
|
||||
image1="$host/$base/image1/poison:$poison"
|
||||
tempImage $image1
|
||||
run docker_t push $image1
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
image2="$host/$base/image2/poison:$poison"
|
||||
tempImage $image2
|
||||
run docker_t push $image2
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
|
||||
# Remove image to ensure layer is pulled and digest verified
|
||||
docker_t rmi -f $image1
|
||||
docker_t rmi -f $image2
|
||||
|
||||
run docker_t pull $image1
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run docker_t pull $image2
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Test if there are multiple images
|
||||
run docker_t images
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Test images have same ID and not the poison
|
||||
id1=$(docker_t inspect --format="{{.Id}}" $image1)
|
||||
id2=$(docker_t inspect --format="{{.Id}}" $image2)
|
||||
|
||||
# Remove old images
|
||||
docker_t rmi -f $image1
|
||||
docker_t rmi -f $image2
|
||||
|
||||
[ "$id1" != "$id2" ]
|
||||
|
||||
[ "$id1" != "$truncid" ]
|
||||
|
||||
[ "$id2" != "$truncid" ]
|
||||
}
|
||||
|
||||
@test "Test malevolent altered identical images" {
|
||||
truncid1="777cf9284131"
|
||||
poison1="${truncid1}d77ca0863fb7f054c0a276d7e227b5e9a5d62b497979a481fa32"
|
||||
truncid2="888cf9284131"
|
||||
poison2="${truncid2}d77ca0863fb7f054c0a276d7e227b5e9a5d62b497979a481fa64"
|
||||
|
||||
image1="$host/$base/image1/alteredid:$poison1"
|
||||
tempImage $image1
|
||||
run docker_t push $image1
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
image2="$host/$base/image2/alteredid:$poison2"
|
||||
docker_t tag $image1 $image2
|
||||
run docker_t push $image2
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
|
||||
# Remove image to ensure layer is pulled and digest verified
|
||||
docker_t rmi -f $image1
|
||||
docker_t rmi -f $image2
|
||||
|
||||
run docker_t pull $image1
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run docker_t pull $image2
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Test if there are multiple images
|
||||
run docker_t images
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Test images have same ID and not the poison
|
||||
id1=$(docker_t inspect --format="{{.Id}}" $image1)
|
||||
id2=$(docker_t inspect --format="{{.Id}}" $image2)
|
||||
|
||||
# Remove old images
|
||||
docker_t rmi -f $image1
|
||||
docker_t rmi -f $image2
|
||||
|
||||
[ "$id1" == "$id2" ]
|
||||
|
||||
[ "$id1" != "$truncid1" ]
|
||||
|
||||
[ "$id2" != "$truncid2" ]
|
||||
}
|
||||
|
||||
@test "Test malevolent resumeable pull" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.11.0"
|
||||
version_check registry "$GOLEM_DISTRIBUTION_VERSION" "2.3.0"
|
||||
|
||||
imagename="$host/$base/resumeable"
|
||||
image="$imagename:latest"
|
||||
tempImage $image
|
||||
run docker_t push $image
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
# Remove image to ensure layer is pulled and digest verified
|
||||
docker_t rmi -f $image
|
||||
|
||||
run docker_t pull "$imagename@$digest"
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
|
@ -2,9 +2,9 @@ FROM nginx:1.9
|
|||
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
COPY registry.conf /etc/nginx/conf.d/registry.conf
|
||||
COPY docker-registry.conf /etc/nginx/docker-registry.conf
|
||||
COPY docker-registry-v2.conf /etc/nginx/docker-registry-v2.conf
|
||||
COPY registry-noauth.conf /etc/nginx/registry-noauth.conf
|
||||
COPY registry-basic.conf /etc/nginx/registry-basic.conf
|
||||
COPY test.passwd /etc/nginx/test.passwd
|
||||
COPY ssl /etc/nginx/ssl
|
||||
COPY v1 /var/www/html/v1
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
proxy_pass http://docker-registry;
|
||||
proxy_set_header Host $http_host; # required for docker client's sake
|
||||
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Authorization ""; # see https://github.com/docker/docker-registry/issues/170
|
||||
proxy_read_timeout 900;
|
|
@ -25,37 +25,3 @@ http {
|
|||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
|
||||
# Setup TCP proxies
|
||||
stream {
|
||||
# Malevolent proxy
|
||||
server {
|
||||
listen 6666;
|
||||
proxy_pass malevolent:6666;
|
||||
}
|
||||
|
||||
# Registry configured for token server
|
||||
server {
|
||||
listen 5554;
|
||||
listen 5555;
|
||||
proxy_pass registryv2token:5000;
|
||||
}
|
||||
|
||||
# Token server
|
||||
server {
|
||||
listen 5556;
|
||||
proxy_pass tokenserver:5556;
|
||||
}
|
||||
|
||||
# Registry configured for token server with oauth
|
||||
server {
|
||||
listen 5557;
|
||||
listen 5558;
|
||||
proxy_pass registryv2tokenoauth:5000;
|
||||
}
|
||||
|
||||
# Token server with oauth
|
||||
server {
|
||||
listen 5559;
|
||||
proxy_pass tokenserveroauth:5559;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,3 +6,8 @@ location /v2/ {
|
|||
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
|
||||
include docker-registry-v2.conf;
|
||||
}
|
||||
location / {
|
||||
auth_basic "registry.localhost";
|
||||
auth_basic_user_file test.passwd;
|
||||
include docker-registry.conf;
|
||||
}
|
||||
|
|
|
@ -3,3 +3,6 @@ chunked_transfer_encoding on;
|
|||
location /v2/ {
|
||||
include docker-registry-v2.conf;
|
||||
}
|
||||
location / {
|
||||
include docker-registry.conf;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# Docker registry proxy for api version 2
|
||||
# Docker registry proxy for api versions 1 and 2
|
||||
|
||||
upstream docker-registry {
|
||||
server registryv1:5000;
|
||||
}
|
||||
|
||||
upstream docker-registry-v2 {
|
||||
server registryv2:5000;
|
||||
|
@ -24,6 +28,26 @@ server {
|
|||
|
||||
include docker-registry-v2.conf;
|
||||
}
|
||||
|
||||
location / {
|
||||
include docker-registry.conf;
|
||||
}
|
||||
}
|
||||
|
||||
# No client auth or TLS (V1 Only)
|
||||
server {
|
||||
listen 5001;
|
||||
server_name localhost;
|
||||
|
||||
# disable any limits to avoid HTTP 413 for large image uploads
|
||||
client_max_body_size 0;
|
||||
|
||||
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
|
||||
chunked_transfer_encoding on;
|
||||
|
||||
location / {
|
||||
include docker-registry.conf;
|
||||
}
|
||||
}
|
||||
|
||||
# No client auth or TLS (V2 Only)
|
||||
|
@ -42,6 +66,38 @@ server {
|
|||
}
|
||||
}
|
||||
|
||||
# TLS localhost (V1 Only)
|
||||
server {
|
||||
listen 5011;
|
||||
server_name localhost;
|
||||
ssl on;
|
||||
ssl_certificate /etc/nginx/ssl/registry-ca+localhost-cert.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/registry-ca+localhost-key.pem;
|
||||
|
||||
client_max_body_size 0;
|
||||
chunked_transfer_encoding on;
|
||||
location / {
|
||||
include docker-registry.conf;
|
||||
}
|
||||
}
|
||||
|
||||
# TLS localregistry (V1 Only)
|
||||
server {
|
||||
listen 5011;
|
||||
server_name localregistry;
|
||||
ssl on;
|
||||
ssl_certificate /etc/nginx/ssl/registry-ca+localregistry-cert.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/registry-ca+localregistry-key.pem;
|
||||
|
||||
client_max_body_size 0;
|
||||
chunked_transfer_encoding on;
|
||||
location / {
|
||||
include docker-registry.conf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
# TLS Configuration chart
|
||||
# Username/Password: testuser/passpassword
|
||||
# | ca | client | basic | notes
|
||||
|
@ -219,42 +275,3 @@ server {
|
|||
include registry-noauth.conf;
|
||||
}
|
||||
|
||||
|
||||
# V1 search test
|
||||
# Registry configured with token auth and no tls
|
||||
# TLS termination done by nginx, search results
|
||||
# served by nginx
|
||||
|
||||
upstream docker-registry-v2-oauth {
|
||||
server registryv2tokenoauthnotls:5000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 5600;
|
||||
server_name localregistry;
|
||||
ssl on;
|
||||
ssl_certificate /etc/nginx/ssl/registry-ca+localregistry-cert.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/registry-ca+localregistry-key.pem;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
client_max_body_size 0;
|
||||
chunked_transfer_encoding on;
|
||||
location /v2/ {
|
||||
proxy_buffering off;
|
||||
proxy_pass http://docker-registry-v2-oauth;
|
||||
proxy_set_header Host $http_host; # required for docker client's sake
|
||||
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 900;
|
||||
}
|
||||
|
||||
location /v1/search {
|
||||
if ($http_authorization !~ "Bearer [a-zA-Z0-9\._-]+") {
|
||||
return 401;
|
||||
}
|
||||
try_files /v1/search.json =404;
|
||||
add_header Content-Type application/json;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
KauB3KY1NiL+Ng5DCzNdkwDkWH78ZguI2w==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,18 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
SpS/cacZYUsSLgB4cWbxElcc/p7CW1PbOA==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,51 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDDTCCAfWgAwIBAgIQfzdVwVz4igfdJPd6SW/ENTANBgkqhkiG9w0BAQsFADAm
|
||||
MREwDwYDVQQKEwhRdWlja1RMUzERMA8GA1UEAxMIUXVpY2tUTFMwHhcNMTgwNTIx
|
||||
MjI1MjMwWhcNMjgwODI2MjI1MjMwWjAnMREwDwYDVQQKEwhRdWlja1RMUzESMBAG
|
||||
A1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
||||
v+H3BTOGLRYjyPx+JQQcP5r8HHBmjknflE6VcrbRD5VGx8192hwsjAdlL0kz1CEq
|
||||
FW2KQidJieDi8iIh9BWB8lsTQ51xZGnry6CbVXxTbv1Ss8ci9r8Cm3GPjWy5gqTi
|
||||
DTUUQez8xq29gUod4ZvRoJ8jl/eI7gF7MBFakv7tZQ40SHcogjQoG7nKMXG1VOhX
|
||||
D4kM120E+hW9x0U3j0SaCIYl6bG2RHIvUMlrVnj4es6JBVzqItkhAwugE6ytneOh
|
||||
VxWQ/7e8qKW2+lVsPnH/zjNES0j/9XYgVCjwkgirxjs2eZRIS5Mg14DdYqfQ9MRQ
|
||||
EoyQxl3xcDxjqPocMgGYHwIDAQABozYwNDAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0T
|
||||
AQH/BAIwADAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEB
|
||||
ACU0E2BAdqjVvO06ZyHplxxQ4TQxK9voBCTheC2G7oFaM4VLFf48GgoMkvbsMGyd
|
||||
1JqIACCDuSJ5UVjmWm6VIDZrnRsf/BbQCTZXKQd4ONLL5DU/OPjAFKGeCpAK51yj
|
||||
OMHdw3cQmMCEpMH9HHJ+iB3XWLcDKPAxTkcsBytC9VLUgU7Q4+3eYIT/j/ug+y4G
|
||||
W4A0cmdDDuozwBAPXj7ZLKdVlkUFka8WjQAJesHTIifS1bfahGiSNVJbYjXbGoML
|
||||
d0IeGMd1lXlc2M+ygqZsSM2ErzndNdvDs7S6u/FIICm7uW6P2naPeMtedb2orO6Q
|
||||
5O3gRtj/UQjegI0XV4YO2TQ=
|
||||
MIIFCTCCAvOgAwIBAgIQdcXDOHrLsd2ENSfj5h8ZmjALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE1MDUyNjIw
|
||||
NTQwM1oXDTE4MDUxMDIwNTQwM1owJzERMA8GA1UEChMIUXVpY2tUTFMxEjAQBgNV
|
||||
BAMTCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2K
|
||||
saEVcHq0eldu5kABbWtZsf9keK7lz8beVIowzOqp5IHpGlggtH7xDVeigA/sLdds
|
||||
WTgKEOq3zsJzdgfEti5TNAjjmPqjMKkolqv3LXDJG0dZ2GZ8W/eBB6X1wB0LKr3i
|
||||
ye3/5jb/wCZYVGGMQXj0VQxY8Qq+OHEp0effeheJqA0OYOj+RaZwi20OR/KmJRgY
|
||||
wXU33bZyapuyT4krhFlFbtzXeKsKQPrT2ePWxPAceqUGUTIqyJySYIw6vb72YxjX
|
||||
FNRw6Jg7B7RqVJaVCfBrVxtAv+rCLOhUOVYmWhgWEIODPXiqOGwB0VUApAVAYqfi
|
||||
TYnJIZ7QYLlQx5VPNlzZuSJTUzKmHQLtLcTqdO5HmLxfxc0WuS/ftK916wy/jpSc
|
||||
m2DiHjIy6aAEaHKGQrNgT+no68kp30xkYAVsIs0BFpl6Q2iNr5e0uKta82A0xU1Q
|
||||
we7swSHOHCevuDZfFA/CqnBptOjvNUuVytcroCeCrV/ftp75w/Fd9zOcb6LGLxM2
|
||||
2UzhkSXl3II250xj74Q3q8T9TDxCLty7oiawhaYKI+8SDYc510EQ7MH46WMO+3Uq
|
||||
JkpmmELd9POgnnZ1JrCFmf0flUKTi2CqU3wrBPpPMwFBxoFipp5iL87npACHc3DY
|
||||
6uaoF4Pf9Et1Fd7HRon8RMsKkrSF92NFiBx5UvhZAgMBAAGjNjA0MA4GA1UdDwEB
|
||||
/wQEAwIAoDAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDALBgkq
|
||||
hkiG9w0BAQsDggIBAC0F4ci1nqZ9KUhEEAmWmy8g89DovNNIGSC51r2WJ/COmYUX
|
||||
X70TONscsBL/kx5MK4xoAmb+EN6Yy8i+z9NkNJd0B+2MjXPMFBpgGb0UiPv2wEmZ
|
||||
5PAKyjwTxNIm6L/nFhkmVqfsQHfjHukXES4C0ff6fj6fuDpBfl5nTlVmc9LpP+hT
|
||||
5RAwW10qumucGxAWGNBWW+K66cf8O7n/0nQykxJxYjBx16ZB80H2uvqFDKDVFqze
|
||||
co5M4euXQq9KiXPRlcC9rab2a7FGLHd0TyPkq6TvfsqpxcryyKS4rIAz3sQh/tl/
|
||||
/qm1tBcZW2bce3UlF2Wb2dW9HqvIu1O84f6ptLqwgKcIdTbwgQZ0kbFoWE2kWJSV
|
||||
w+eAFb7tz1LDTpF3NRlz+1K27pBQWRQgcqoIRoQXpC0LfQY9Mp70QIfUQdUh6tnO
|
||||
8hmq5y623tfxiDwCxb/EOpwCmwK1Cp9cloZTDefVE1r6NkEJWeeHG79VljUGF1KT
|
||||
NKzXWrrsFtge/hU9Pj+frcZO9qExxPCcsrdZcoK7Ll8s+pjulRvbnCnJkNpeOI3P
|
||||
iz6+sdGmzKSKg2daRM67Zmy5tmlBEX/eV7kFqt+b3HsdUiLo3Ng2lyPLNNDfwUtB
|
||||
EukgYGjVJoyqLjLXgsCxLJlk7X/ogVwf8SlAnQ7p6KuxGWm02vlUpEmJp+Hq
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,51 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAv+H3BTOGLRYjyPx+JQQcP5r8HHBmjknflE6VcrbRD5VGx819
|
||||
2hwsjAdlL0kz1CEqFW2KQidJieDi8iIh9BWB8lsTQ51xZGnry6CbVXxTbv1Ss8ci
|
||||
9r8Cm3GPjWy5gqTiDTUUQez8xq29gUod4ZvRoJ8jl/eI7gF7MBFakv7tZQ40SHco
|
||||
gjQoG7nKMXG1VOhXD4kM120E+hW9x0U3j0SaCIYl6bG2RHIvUMlrVnj4es6JBVzq
|
||||
ItkhAwugE6ytneOhVxWQ/7e8qKW2+lVsPnH/zjNES0j/9XYgVCjwkgirxjs2eZRI
|
||||
S5Mg14DdYqfQ9MRQEoyQxl3xcDxjqPocMgGYHwIDAQABAoIBABbp0ueqGXG03R0Z
|
||||
Ga8t6Hmn9kcnHPgM1kgNgkcqkZh8yPD/FvI+vwsRrwGQikHgm/fnFsWDj4KJelBT
|
||||
xx4wm03nlktSt8G37FJqoWH58LSmR4P0WbaBZLxPOUc4Hob9TYkqN3sP47eN871G
|
||||
rn7MbqHxnvx8sLtLLfy1dc1r58lTTZB7YL1OPV7B/VYhYFDtpkUBvadV+WJ7SJ5G
|
||||
UHrBsshOUJbUI4ahmc8izi40yDw+A0LRhtj3i7aFr2Og+vCq9M8NXDjhdOu9VBkI
|
||||
fvniC6worJk/GnQDJ/KT5Uqfejdd3Pq7eHp11riqwua8+/wi726zRz9perFh/3gJ
|
||||
pYjaY+ECgYEA+ssW+vJRZNHEzdf8zzIJxHqq9tOjbQK9yyIPQP5O4q9zKvDJIpnX
|
||||
T31aZTLGy0op+XA9GJ7X0/d1tqo3G2wNBsFYWPn3gmVVth/7iHxRznorNfmsuea7
|
||||
1gFm19StL2+q8PaZ4fx9vUcWwDHlALYTYlTaazms6z9FWD/KbB8kiWkCgYEAw93H
|
||||
Pp12ND3f6p2rYbXPfHJ0aAUbrQR4wRG3ipVWXGjvn2h/CbrLAt5W1wB3iwnWwatX
|
||||
opdbfzjxgb0wRQHSPNVj3/SOHr8E5zH/mw+eV7mOea4xlCLTSIAJNzW1320hwsbw
|
||||
FrEC5qe41PrbMUu+4LvXPkHCKVxRXaV4QX4YHEcCgYEAurjegTRM+X1cw81dwn4E
|
||||
265g/6iO8qip2kWficpNvWTXoE7p0cMslVhFJzdo3w52teqk8mHBW2XQ1JFiuh32
|
||||
jOMC/iwN5Z3A9PpW8kVtOwemiGc9/KMXkrw0b9k+oCTJ5uITrDeq/nOhMrNzRtZJ
|
||||
FFsMy+yDHBtda9kCwwFk2JECgYBQUpbu+qwK6IT3NgmeXGzmYBmUvuOGpJrQsm9O
|
||||
iceMxgvel3/hgZTXbE64hRyBDFvhuF6L8v42widoSSmOYxzQjcITibruqO9d0Ic+
|
||||
E72fxBzFkcYLNezngnpFBeW75ok900+KPrUt2gJWdTmGkcWJa/7tLRJu28kSWlVi
|
||||
pk9E6QKBgDH2Uh61ToeNq8Gbnue3pnhUddHELRFQfwHHaa4tFrXBHuPLKqkVefKT
|
||||
A58awVoPpKTECROeyqe2DJXg9EdSVzKyhg217N/07NRaunfCJ9/TSpFy+5Xls7Rl
|
||||
U7zK25S1/13KZ6rGVHpmP6Q82VSnsHkPtUfDo3A29llqIQ8je43Y
|
||||
MIIJJwIBAAKCAgEArYqxoRVwerR6V27mQAFta1mx/2R4ruXPxt5UijDM6qnkgeka
|
||||
WCC0fvENV6KAD+wt12xZOAoQ6rfOwnN2B8S2LlM0COOY+qMwqSiWq/ctcMkbR1nY
|
||||
Znxb94EHpfXAHQsqveLJ7f/mNv/AJlhUYYxBePRVDFjxCr44cSnR5996F4moDQ5g
|
||||
6P5FpnCLbQ5H8qYlGBjBdTfdtnJqm7JPiSuEWUVu3Nd4qwpA+tPZ49bE8Bx6pQZR
|
||||
MirInJJgjDq9vvZjGNcU1HDomDsHtGpUlpUJ8GtXG0C/6sIs6FQ5ViZaGBYQg4M9
|
||||
eKo4bAHRVQCkBUBip+JNickhntBguVDHlU82XNm5IlNTMqYdAu0txOp07keYvF/F
|
||||
zRa5L9+0r3XrDL+OlJybYOIeMjLpoARocoZCs2BP6ejrySnfTGRgBWwizQEWmXpD
|
||||
aI2vl7S4q1rzYDTFTVDB7uzBIc4cJ6+4Nl8UD8KqcGm06O81S5XK1yugJ4KtX9+2
|
||||
nvnD8V33M5xvosYvEzbZTOGRJeXcgjbnTGPvhDerxP1MPEIu3LuiJrCFpgoj7xIN
|
||||
hznXQRDswfjpYw77dSomSmaYQt3086CednUmsIWZ/R+VQpOLYKpTfCsE+k8zAUHG
|
||||
gWKmnmIvzuekAIdzcNjq5qgXg9/0S3UV3sdGifxEywqStIX3Y0WIHHlS+FkCAwEA
|
||||
AQKCAgAtZw3V8P/+el1PpqoCsNzpqwvQn36bc3CKvPwtM1tJQa2Q92V3DQdr9rDg
|
||||
7pjGkankpGorKScH4ZLseLy2h5aKRCZm9PS/DhbbCs1wrDhtO5AxeKYPGhYNiOpx
|
||||
VvwuHQ/Pohfmdn7KgNrKrW1WIBW5CWN+2X4mq2Gk6aYLHgKZSeB3mf1st6mNRACW
|
||||
RZg5OZKW3VMv0a/l3cVaeqooXwQ/PtUkXhMp3ILnnKly3Gulzi2gIyj3EQ5vODSe
|
||||
O3gND/UZOJwwgGG6Aief4fnDc7an+c1OSgBr8OVC21Ys3dfQWWV0os9gVFhymX8k
|
||||
2AgRf6jP93sFw2NSY34KvcGZpKG59oMDxWF1vPo8sOt17Ey0+qp3eUtB3FfE7Wtf
|
||||
BaLaD/x4U91izIqOEMzQ6QiZAyvmUoBkUSo125CYuIkt8C8Q1lA1KjihETWF37QR
|
||||
mr8LUk0A0x3SErtm4wVfeDEqVSfI9gKpk6i6rlUzuCjv58Rc0yyqoghXwBWM4CKj
|
||||
5ZHYpBKAxj4bM6IrKnodAOcsyVk2c2zVTaMxPhoUj0fF7IE5Hy6YAQ/yBheZEM1v
|
||||
fhsdBFyS6OqSCnN6UinhH268QPam82lfKTFjW5lOgsSDQZ9rhiWoyamhonJTq65I
|
||||
nb08f4mzT6OGMwV13zq8dXio6WnUIQAhXdEYWrMBmxp5b6CxAQKCAQEA4kmwV3Nb
|
||||
n3ZIzVAp2l+yGZwdg4YWzN2kcfdNkL8I+Pn8pWrOwv/uGQYmM0786ys9kB5lu4FR
|
||||
TMcoEo3AaK/z8N49ro2Kl6HcTmxZgTMr+cl6iwetzqYdkRK7klxyCv5uVloDQDtc
|
||||
AulDH6RkW9BfRERpi6XtlgiFdJj5jMvXMpwGHX69JVsXb83ZSQESjI2JfO9Y8+4M
|
||||
a7hNKWW/W0ZBrGCcQQPbgpysfJ+PFKUF/yF1h8SSCdetW2Kv2ix16wL5uHKINYmZ
|
||||
Y/Om+/AFnUOQlANycgThtgBI5mvg9Khq6W2i/RNcIL7bvwAzq1p+o6cGnImXo4bY
|
||||
hC4fs2/aeX17UQKCAQEAxFQHSLBYDLal5CQYbHbNZ2sLjwRUraEd/+BA8XoERVVQ
|
||||
JPihgEvTPEaHnWrFTw0qaGKgMZ5SZCZSWUIfXjYvQIUcEMhNUOHweXhJJhifO5sd
|
||||
sTuvU7bWg76F69bRKfp8KM266m7qMYv+tNlQ6Kbz/1ImsW00xb86vCK2hPfhldtN
|
||||
d/iBb4HVDu1uoATHUNuqsSGj/UvttKudQdg7MapzM4N+D4m6rPZUjQmtoMWOXt7R
|
||||
LYrqEOHWfkxXKlVHw1cL9uzUpArvnR0VcYvGfXiYJFbXWsEB07VxIoLMPEtPbpH9
|
||||
YLY37KugrthEVnsbySmZIWCRDEqQuuAaa5o8S1naiQKCAQAiU/dybMebe0A0FVMk
|
||||
E5xbEjnP+AmBbqZBu7iCmthrnNDc70UKg/TEyxAEfJkVu+uM72+TcFy6/wNvPR3R
|
||||
Q9AH3E8TKdm6gw1+wCUb2n1zWUND0Bhn3v9hQKw/2dJbJJnsc59GoTqmHmjWZgPr
|
||||
gcLSAmbYjoVqW0STmZlR6KJuxQiQdOeQwS7fASVTU9xSgi43S7/80UIFHWJnQ04y
|
||||
NIhF9CoAGuuz9ryb80CraxVrzNGdlQ5qe9OKp3/x4wjIbB0iBA3xwTwJ066jTZgs
|
||||
cVF/gr5b2a28BHMKsZbgxqPhYYZ2SfeR6CJB6W/tML9BaFcybBUa85vpAW5BtFg6
|
||||
UfThAoIBAAp1/71byBVFVimF0tdUrTUpewAv1uM5hoOvy0YSnk+jcBXIObLAV40K
|
||||
pQc6PTEtHmlZd/es2+8CK7kd0NYQRQxHC2vJgHUi1NFkG2GwRivC5B4hdAId5+g1
|
||||
KqWaWKLH+f2imKcNKeVh9Dxmp+z9mFquYelqTDmNKvADWX5URuzZNpOB5kOuw098
|
||||
TzyvhH9GdR3jEP3aIdxSmJp9jwnibyj7hKgHSq8UoQSy01GRtThQ3wxyLm6f2fH4
|
||||
11wmFyDNbpHFpL7o5kOU3SOjsvvUhSbKiccIKbTCIjkYhxFfYegeV0Xj767opjMq
|
||||
ytlgzeY2FTa2EoR5JKUQc9fv6+6H5yECggEAVVfnywPm8QXn+ByFDdUndZg3uEje
|
||||
DGyvt1M3mIz5geyRZO8ECzgsZVzKgZC8jDB4lPKz3AGgNlUl/vyGHk6CtW6V6ePA
|
||||
EXcmOkkMKJQMdopY2/cE6YlSpBGMCcnfothgL0HXxYoop4xVjb74k7tFcNrIDoRx
|
||||
zp9dSalgxx9aMeaURRbMWf8AhWLZUAjJ/359M1SmcNW619SL3p8Q95Nptvdiltww
|
||||
lWOCkBdgkjW0mel+Mi2+gY8UPmgNBMPrJ1z9b7b7529YCv5Oci8ABn/N202nhjCp
|
||||
LupADooNknOMLDyqwRorEv4g6wRjuPIYTIhI9fO5ranu089x+mmGU2tCBw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFTCCAf2gAwIBAgIQM3khHYh+82EC0qR1Pelk2DANBgkqhkiG9w0BAQsFADAm
|
||||
MREwDwYDVQQKEwhRdWlja1RMUzERMA8GA1UEAxMIUXVpY2tUTFMwHhcNMTgwNTIx
|
||||
MjI1MjMxWhcNMjgwODI2MjI1MjMxWjArMREwDwYDVQQKEwhRdWlja1RMUzEWMBQG
|
||||
A1UEAxMNbG9jYWxyZWdpc3RyeTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBAKA8e9cUSyasRtEHw3yGW5lFCnnZIN+SSvykAOynt9LLKzU5G5ge3ekBtzsl
|
||||
HE1ndeYjy/dK7XkECQBQ0csF+KSacU5QiZek8g6btH94HDwltCq1I8f1E8LQFP6k
|
||||
483MKZUDeNNnHzbuK9xsMjYOCrJWGysLHnKjzK/+yfVPwTm9tmUVRqd4xjw1oYY6
|
||||
C7iCffIWn7+dQKDjHrn+KyheIy244v5y63AaxgPfjHrtvJtz1vPqxi+FyzDM7RfZ
|
||||
GIjklC6KaKHmxvUsB0hO4WNb9kt8FBvnxOxuDKf+rUYKTg6JK72O3TaUauiEvE2X
|
||||
SKT0vYpLoep5hc9ns/yh3BuuznECAwEAAaM6MDgwDgYDVR0PAQH/BAQDAgWgMAwG
|
||||
A1UdEwEB/wQCMAAwGAYDVR0RBBEwD4INbG9jYWxyZWdpc3RyeTANBgkqhkiG9w0B
|
||||
AQsFAAOCAQEAMt/lnR3Wy99X/knvjtg7wsPz5T9sZ5hGy/9sIm8sFdsqt5NZi9IY
|
||||
vS+eyij1yHvOU+pqOxsYQ2NG26CS0CKM3JWLJTo/w8GyiSwxL8a1/UxHmTxDnSMH
|
||||
cYZRsuPtdkTiAuZhoT5I1ZTsOa7MQF25HiFBL6Ei88FFhcQQjJ7+xYDNhSoddMtz
|
||||
U8mUY6NOENmvE86QMjWjaj1PXPLO8PxPIqw482Ln/95pHzuaxAYMvxhs2aQlBS1/
|
||||
9+vi6VOkbQna9+crmzniXjZDx5QdvMN2QwzFL4hCgqbebVg0zwjhByOwQIjtNEXE
|
||||
gqxjLkTNOdSva6Fkk/z8BD2XSZ4L+nM3Mw==
|
||||
MIIFETCCAvugAwIBAgIQJ+iLgsp9gA0DmROqW+tHFzALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE1MDUyNjIw
|
||||
NTQxNloXDTE4MDUxMDIwNTQxNlowKzERMA8GA1UEChMIUXVpY2tUTFMxFjAUBgNV
|
||||
BAMTDWxvY2FscmVnaXN0cnkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
|
||||
AQDHR/A6uiQ9X/Xh5ivmdjRr5XVr1D7+fU9Qu6ohArqtBuJsLr6t2RBTS9w6PIAf
|
||||
xjQSMSFlrm/CY+hbfBMSgm9NeH23o3kYCgoEPhP/634A45W5xwUFno388U8/NHK7
|
||||
qwzSP1ezKXfXNvzuo1mZhT08aVdGMOrZUcZZZl8R3RPcIRw9XDSfXKVkMluH6egk
|
||||
8iLdOxdIdRS58DeSI09FskWe3cIZ5kJmMqnKoIbYSJCVVeYPO0RFlIBi+zpdVyI/
|
||||
r9LG0r0plRdz/HJevbOitU2y93S1s9NWMNEkOFU1PFJmsF3ZzNqJFCySj00y/Hcs
|
||||
jPULYwIxYdqcv16cTNmd3P6FegvuzLJLjNuGaLJGc1antv+p62P7ZdE3DyprFuxs
|
||||
MJgDL9+NjDaIzoamFf0Uv7K3F7hxrrAHfvm1CMUOyQLg9J6Wl4mLsOy2ZhCbdNFs
|
||||
T6dobAUGvz4Muj9V8V5pR+nFehjmsPENSsTcs5j0e8zTWtvMFISdS+NZAkpiz0s4
|
||||
PV8DLgk5Rp1ZG2V5OnRPLMOTgK0nngc5GVaxf7OYCrFHbBJ8tL93MXNQptNFeBpV
|
||||
FhjUGqVFcz+6nbFX2NsFLZnghQRs9lej4TTG33NSAYusKqhVwpYFf8CsXCcvYuU6
|
||||
RlkCYjr3PB+nX1UDa0eUGm0zOabf9O3D1VzHQBpDuzSHQwIDAQABozowODAOBgNV
|
||||
HQ8BAf8EBAMCAKAwDAYDVR0TAQH/BAIwADAYBgNVHREEETAPgg1sb2NhbHJlZ2lz
|
||||
dHJ5MAsGCSqGSIb3DQEBCwOCAgEAaPfAs6saij4FZIPbzAb5M6ZVvfXBg+AfH52t
|
||||
p3tFsnWUJCiOh9ywsc2NcmJdleKDc4/spElFMUarHqcE1ua6EH15O5GEnHWKj8EY
|
||||
PVQFrPvf30UkRGNPl8eC7afZtCNk9MLllIATAzBr5Z1i+psV7MmgBKpbZ4B0TnhR
|
||||
GXNT60QaCJ9RfUuc2z7RHJNo9XTn3Q44X7TFj+P3jHOWzTf8y6Mz6saTy2bugIUy
|
||||
AfRgRgq/bB8hRjrazg55FIlrMv7dr3J0cIuqmaHfsw7Q2ECMCXW8oQXMBzfuIT0n
|
||||
sG4u0oVxdNx4OdHsAubGjjwNDhxJvN5j8+YFqZMu03i8LbyamTwsrZg2C3QrRUq8
|
||||
SujQEEB+AmO0lpuJ24FsOOYVSYCpLy2ugrKOr2NUqbiBKZs8uBh6RGACfunMZlEw
|
||||
4BntohiO7oZ5gjvhGZNUEqzMChw7knvVjZ+DkhFk9yE4qIL7VsJSUNI2ZJym/Xeq
|
||||
jr/oT8CpP8/mFZspa6DFciPfhGLQqKcaZZohL7461pOYWY5C2vsJNR2ucBZzTFvD
|
||||
BiN/rMnIGFrxUscCCje6RLmrsZ3Lb7bfhB3W6kwzLRfr/XEygAzx6S2mlOM34kqF
|
||||
HFpKrg9TtLIpYLAKAIfuNbrLaNP1UKh7iLarhDz/qDcvRka/qJTzLD3eLeGXefAP
|
||||
KjJ1S7s=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,51 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1,18 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
RfbdpOr8p/Ks34ZqQPukFwpM1s/6aicF
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,51 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDDjCCAfagAwIBAgIRAI0Dt8LVd8cJPc0dv5aW+wcwDQYJKoZIhvcNAQELBQAw
|
||||
JjERMA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE4MDUy
|
||||
MTIyNTcyN1oXDTI4MDgyNjIyNTcyN1owJzERMA8GA1UEChMIUXVpY2tUTFMxEjAQ
|
||||
BgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
ANr32CUXFUCW1c2oPoHjq76T8jUTH/cxPiR5NabJ1y4gMCBko2rIe+TblW9UclxH
|
||||
911gjfpSAxFtNf+lX5kwmAMHhU8pcCc+Mjp3Ax9acFXSXvzzTDg+xj0NGig6OBk3
|
||||
jyPuO92lM8A4qs0mBZ/T04iLkawLmdRXViRoGK/T7Df8HN+hm7UsG0VO3GxFgSST
|
||||
YhhKTu6JMTADszbIFPOvBxGCUNhffXiLNyviO4AiBdcAv2v0SUadEPmSGm5Jb1DK
|
||||
tfKY0jWi1k1zNSqzit/bhML/EHbVkYJ00QmH50MBTunpz60gIgHjt48nzJarLDML
|
||||
oRFMppG9XIBQlUn3lo0gVwcCAwEAAaM2MDQwDgYDVR0PAQH/BAQDAgWgMAwGA1Ud
|
||||
EwEB/wQCMAAwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IB
|
||||
AQAb388owui+O9vUle+A99FXwcMDEb0OILc0lBXVWx8q5ZE73vcanxyAcfOsZYRY
|
||||
Lh7G6VtJwC9xVjAdNwJ1gd+ak1l0/Rhs1V0JZ12/wOvAOQ7+9g2lRc1IedOh3EIh
|
||||
d3BMI4RdDB/BnnK3XjkggYQZK3yiAOavmmsZxAOl/apzjF+5u8XjuydMmotE2NYw
|
||||
IpM93zE5wWXqzYs/Kmyy7zAcHKfvq9xej/gMCFEvO6lopmwyslBLPpPNHwyfIVtA
|
||||
mspm2OZhdmpRJYGzkR4wK5NjoRl2O11uzlMRDckp0GSZ0x6TGxmb7ot5HK27p3ep
|
||||
6LPZM1wJIwuYHIP74eH0ctQP
|
||||
MIIFCTCCAvOgAwIBAgIQPjclBRGzhznCybQzYRQTyjALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE1MDUyNjIw
|
||||
NTQ1NloXDTE4MDUxMDIwNTQ1NlowJzERMA8GA1UEChMIUXVpY2tUTFMxEjAQBgNV
|
||||
BAMTCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALBe
|
||||
C9O6es+mStDowUd1kiM59VkinzzdHgE24LvKmGxQ6fDnnT8S9L7iyzoxcJWlvSHu
|
||||
pfyZWvij0ZIyRZ288XemTEFYq25RK0IBGGdvYz9OqT2R3lblBQrXDjSi9WG16sGx
|
||||
60MGhM2egGMqFQ5DBfT16IKw00+RjFgCVzJ8T64Lzw82E0e7d6hl39SPybY+uvrt
|
||||
SID60hYGmXoOdaiC9qquivks67BZprGNfORrvyJNrCFI6oKUFWHrQ1PpGd2tOwJN
|
||||
1P3gkkS8pVlAif6ZQkAf+zuKu+l4j5tKxGlJAkJsafVJDLOxBKutUj5msha0g6uJ
|
||||
gFXUe0+G8hkNcEjd8XqUUCwIOY3pdv4WsydKBk3uH9zMnYolw53k1q0ObvoY1NXf
|
||||
beMxHQAtDi7nfQGlae9cuuOSymy95WuvzfhZFKdPWUe8lKN9QXFIWVoCFnOm8T3P
|
||||
+FNCUE+p8DIWkal6Ul9THi/Kz4p7twyrUp1LwT5EtSaJ3iGAmB9I+8/1vmZT3lPi
|
||||
nX8P+iVGM5yOUnptrsFm0bUcJWRD6iaTK1KxpH+Is4h2kiUiSz1tC/9bKaJYN2o9
|
||||
oy7q7+ZVfHSmIxLo8ZFYsaZBcXi96cKuuPMR3X4ISPwKDqP5irxU/QbI+YQBMshg
|
||||
G4b0BNoMZ50g30r3Hcsifw4pzPQF0RDMOBeCiOi3AgMBAAGjNjA0MA4GA1UdDwEB
|
||||
/wQEAwIAoDAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDALBgkq
|
||||
hkiG9w0BAQsDggIBAFuS/VrMNUwEMyUIktDyna5ExYh/FDOE+YEYf8tsX7dSMhRK
|
||||
wE560/AcVZcbKKAZOnZ/262a++8tparsQt+bXBJ2so6YUqsFDNdOLCI2aShjWDRe
|
||||
TNhqmLIO3FNsLRKp96WHVz+jFoiECsoYfKn0jgqTqxx+7nWFqgBaNSlF5cbCgLCH
|
||||
jQV1uQhzsw/Mh/32hXAidkv/nLeLf7FbKq08hgthtoP+XstlzZ5BxkPodjb8XWXG
|
||||
DSS49SWX971GHa1apwMKfxVGSppxn18ZwEmW1BUfQBNxtMytqA9DK3+xuoUdXkB0
|
||||
iJbm3Jc10JSRju8iyL121Xt6f8O33paVz/ndDJIWztUOjnItc89rxHsINPt5+cUt
|
||||
jix8ohwmHGDrK7ZooXBvotvmGT/xhPr2eHUAG8JuSJ/Cr09UUOwUEigz4CfgJOHm
|
||||
XukdzjOkb4r7lhNmVeGqrjRol1W0Wsc1NGH++J6xdkIeQ+i23kHwFHfQWV/J69tm
|
||||
rOn2N+qijtmbIy9YfVcrFDtUtEAzXylZ2StCVQNofd0M7tXNdrUL8yAFwlrhWGJV
|
||||
wsSP++1xH2Ie6Diupy8z6rbP383HmnmVPU/UecgLrlX2lEpt/UZkkX1Xm+6PhrrT
|
||||
HDeeULvqtUP3PD8wS0C873Pl9GXOKISqf0HKEIDUAVZhQOsGFqiZH0388M4L
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,51 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFTCCAf2gAwIBAgIQTyBNJlm7fS0yutwdLbhG9zANBgkqhkiG9w0BAQsFADAm
|
||||
MREwDwYDVQQKEwhRdWlja1RMUzERMA8GA1UEAxMIUXVpY2tUTFMwHhcNMTgwNTIx
|
||||
MjI1NzI4WhcNMjgwODI2MjI1NzI4WjArMREwDwYDVQQKEwhRdWlja1RMUzEWMBQG
|
||||
A1UEAxMNbG9jYWxyZWdpc3RyeTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBANSMT7auGdwF63fFdQM9O/EqrX++gnuBQgFa4cZzC7GqsvS90uKTOLuWIA2U
|
||||
ehgF548EDkZu1z6nRAvoFh5L6B5f1VjiVknzLEPlR+5uPD22kbcxgCrMCRZn+5mK
|
||||
vJhTUpx18yeBXMhxtPhkGnKaKwGcgeW8O69KM7Mo4HBQqg5656pa+4wkUo7GX2v0
|
||||
R4ZqmrS1tlwOgpld8KZKVJ1FNyGEeKQkIYGJKHqgC2/JrXsbzuSZ/4pqf8BHc6Mb
|
||||
AHU85RlBFVDHFPMtQ7Rg1vrhYzgInKeqXtc2kEAe63nqyYyHxPOUd3vIQX/N4tdB
|
||||
aH41ffs68Pdtp9GeocTiYyj7KuUCAwEAAaM6MDgwDgYDVR0PAQH/BAQDAgWgMAwG
|
||||
A1UdEwEB/wQCMAAwGAYDVR0RBBEwD4INbG9jYWxyZWdpc3RyeTANBgkqhkiG9w0B
|
||||
AQsFAAOCAQEAkjfZvcd5WysbfqGfhPErG7ADWAFJ1bsIDlHVUaEn2/Asr68iJpfF
|
||||
fqb0fhBkBExPhiLDS+jmL1L86QRNIgyM+7zGCCagKJkl9uNBGXPdS6KxZtY8W8rV
|
||||
bF/GIYnYUL5pnyrhX4pH2ZnDJpKIAJl8CAZ1VHwErQ5VqnJAX/gGO/eKgiyCciZv
|
||||
WmmQkhcOo60FwLW+Wi9sLOYD+YAT+VnFrGfak/SDfT78wrmmfg5v05tvFXgJaZLh
|
||||
JSxRET9D5iT3DIxb+m5GyQAqIH1djh02ybrPJ9j6/+qRQDojIe5qJUL90qIvhwO+
|
||||
aSbIL/p+I6//AUMWJvcR7GbXy3xywgmaYw==
|
||||
MIIFETCCAvugAwIBAgIQCnqSQalw9ytL5bHLgHZe+jALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE1MDUyNjIw
|
||||
NTQ1OFoXDTE4MDUxMDIwNTQ1OFowKzERMA8GA1UEChMIUXVpY2tUTFMxFjAUBgNV
|
||||
BAMTDWxvY2FscmVnaXN0cnkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
|
||||
AQC9gvT3cwz0Ih9+7Ilv5lc15HsEiSmEMh4nOMZrSaamKgf/ydCiGo3DQapr/XDK
|
||||
FHMLKq68AxwfOlzmEFQ4d9umpPMQ2+4GBr0VG23ppGtQApIPHgD06S0/CeHmDIXN
|
||||
FXcKybPX/9KbgNkXBWbbJkJy0EcsdP8VJD50Q2WH89nvgEYJNFuKEELD3iGY6bBF
|
||||
jeDTle5jYA7CgBKvD2avn31g24Qhxn8n8/BdYO/U0kw0qmoy1veLOjCAW0os0jkM
|
||||
NlKrFpyHEWNj5B3X6UgSn8EGQaVbDq17PrQwlHJYU4nih0TnD1OwvBnFnd27pXjr
|
||||
68eGA6Zc2BbUnhNGhppWHZ46LpPxpIbafSOH3ES3N/MZAfcUKIUntLlWE2xCQgFV
|
||||
TW95WeVtP/r1aWgIHu0E2Jb2eHCE+qXYqJxSU7S4DcknmmcTS69hzyHs+92Ec+7Q
|
||||
m0aQFZ0dyPoYPwXMgZpTAIuXEGg/FKC1fiS/deTW37DyvB2jppehKW3RJY3uso7R
|
||||
o9vs6DJx1OdU5XEq9R3n7op61N7PK8Wxmn7TVYHEZHkITVvtucZZd1FNTOrOJaNJ
|
||||
UnE+FuPK1Mrff+jz666Ru4zQL0CondOamX3QR5tuNK6MTqFs87wKY25qsqz7cS27
|
||||
kHW+r7UNWbJY3/UQhaPZM78zCZa2IL1nBFUjsFvEA4rtYwIDAQABozowODAOBgNV
|
||||
HQ8BAf8EBAMCAKAwDAYDVR0TAQH/BAIwADAYBgNVHREEETAPgg1sb2NhbHJlZ2lz
|
||||
dHJ5MAsGCSqGSIb3DQEBCwOCAgEAHVGMyoyX4lRzWCDkUjrXkrDZzuv03M2ojW2Q
|
||||
UL61ejMkTWQW8R4gKrcPHAOJAPKVfGEVOrQH3ZMyxV2HnWrJ7egrn65zOzmLbWSh
|
||||
O7gdpL6YYjBr218fqJn/8HadXZa4k70JyympYOLojeWSLy3KP03U+y7AMcdE1uG6
|
||||
6HJI54ZjBoW/nEyWmMh/mfMz8EN+Mgek48Z9AVaOswbtHtDIXN7XO0jbB3DbY5Yh
|
||||
prVqVLYAz4sCchGTadj+aEChF5sJkKREDvAew/njC0WGS2TmMJ+V1uVhXV6354mr
|
||||
edk79YvdwzwDgeYArkprahMtn9eu1aSTfUXsmM5OP5tR4gyFV1kUmTPY1yUd/yO+
|
||||
638wV0mWtGbbf6j8dUKeUBCyt2qGg8J80OUeFdvdHMswtaUq951NApX44BinPkbK
|
||||
moBVQByZ5OEcmMidFC9SqYSUwTQ7uNyWeguhCXav+l3x900YlKnUQgRUZntPwXjs
|
||||
yc7MXv0j0E86Gme6G1O02zamwkRgr3qOTHu2oQOow/a24fM4HASayLR0Kegt0sh3
|
||||
rzk0HRF1mGonf1Ecyyj/3LpHVsgYSckwtJoZLOqtDMn+CKtOCEByssQfD+E9Qe07
|
||||
qMyvcwpXUpfqe3ZERbJ10m98Z88VeK/XGt9ptq7HY47n1KL6lx3oyXwZIw8pq928
|
||||
89dcqL0=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,51 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
{"num_pages":1,"num_results":2,"page":1,"page_size": 25,"query":"testsearch","results":[{"description":"","is_automated":false,"is_official":false,"is_trusted":false, "name":"dmcgowan/testsearch-1","star_count":1000},{"description":"Some automated build","is_automated":true,"is_official":false,"is_trusted":false,"name":"dmcgowan/testsearch-2","star_count":10}]}
|
|
@ -1,103 +0,0 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
# This tests pushing and pulling plugins
|
||||
|
||||
load helpers
|
||||
|
||||
user="testuser"
|
||||
password="testpassword"
|
||||
base="hello-world"
|
||||
|
||||
#TODO: Create plugin image
|
||||
function create_plugin() {
|
||||
plugindir=$(mktemp -d)
|
||||
|
||||
cat - > $plugindir/config.json <<CONFIGJSON
|
||||
{
|
||||
"manifestVersion": "v0",
|
||||
"description": "A test plugin for integration tests",
|
||||
"entrypoint": ["/usr/bin/ncat", "-l", "-U", "//run/docker/plugins/plugin.sock"],
|
||||
"interface" : {
|
||||
"types": ["docker.volumedriver/1.0"],
|
||||
"socket": "plugin.sock"
|
||||
}
|
||||
}
|
||||
CONFIGJSON
|
||||
|
||||
cid=$(docker create dmcgowan/ncat:latest /bin/sh)
|
||||
|
||||
mkdir $plugindir/rootfs
|
||||
|
||||
docker export $cid | tar -x -C $plugindir/rootfs
|
||||
|
||||
docker rm $cid
|
||||
|
||||
daemontmp=$(docker exec dockerdaemon mktemp -d)
|
||||
|
||||
tar -c -C $plugindir . | docker exec -i dockerdaemon tar -x -C $daemontmp
|
||||
|
||||
docker exec dockerdaemon docker plugin create $1 $daemontmp
|
||||
|
||||
docker exec dockerdaemon rm -rf $daemontmp
|
||||
|
||||
rm -rf $plugindir
|
||||
}
|
||||
|
||||
@test "Test plugin push and pull" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.13.0-rc3"
|
||||
version_check docker "$GOLEM_DISTRIBUTION_VERSION" "2.6.0"
|
||||
|
||||
login_oauth localregistry:5558
|
||||
image="localregistry:5558/testuser/plugin1"
|
||||
|
||||
create_plugin $image
|
||||
|
||||
run docker_t plugin push $image
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
docker_t plugin rm $image
|
||||
|
||||
docker_t plugin install --grant-all-permissions $image
|
||||
}
|
||||
|
||||
@test "Test plugin push and failed image pull" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.13.0-rc3"
|
||||
version_check docker "$GOLEM_DISTRIBUTION_VERSION" "2.6.0"
|
||||
|
||||
|
||||
login_oauth localregistry:5558
|
||||
image="localregistry:5558/testuser/plugin-not-image"
|
||||
|
||||
create_plugin $image
|
||||
|
||||
run docker_t plugin push $image
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
docker_t plugin rm $image
|
||||
|
||||
run docker_t pull $image
|
||||
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test image push and failed plugin pull" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.13.0-rc3"
|
||||
version_check docker "$GOLEM_DISTRIBUTION_VERSION" "2.6.0"
|
||||
|
||||
login_oauth localregistry:5558
|
||||
image="localregistry:5558/testuser/image-not-plugin"
|
||||
|
||||
build $image "$base:latest"
|
||||
|
||||
run docker_t push $image
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
docker_t rmi $image
|
||||
|
||||
run docker_t plugin install --grant-all-permissions $image
|
||||
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
|
||||
|
||||
source helpers.bash
|
||||
|
||||
# Root directory of Distribution
|
||||
DISTRIBUTION_ROOT=$(cd ../..; pwd -P)
|
||||
|
||||
volumeMount=""
|
||||
if [ "$DOCKER_VOLUME" != "" ]; then
|
||||
volumeMount="-v ${DOCKER_VOLUME}:/var/lib/docker"
|
||||
fi
|
||||
|
||||
dockerMount=""
|
||||
if [ "$DOCKER_BINARY" != "" ]; then
|
||||
dockerMount="-v ${DOCKER_BINARY}:/usr/local/bin/docker"
|
||||
else
|
||||
DOCKER_BINARY=docker
|
||||
fi
|
||||
|
||||
# Image containing the integration tests environment.
|
||||
INTEGRATION_IMAGE=${INTEGRATION_IMAGE:-distribution/docker-integration}
|
||||
|
||||
if [ "$1" == "-d" ]; then
|
||||
start_daemon
|
||||
shift
|
||||
fi
|
||||
|
||||
TESTS=${@:-.}
|
||||
|
||||
# Make sure we upgrade the integration environment.
|
||||
docker pull $INTEGRATION_IMAGE
|
||||
|
||||
# Start a Docker engine inside a docker container
|
||||
ID=$(docker run -d -it --privileged $volumeMount $dockerMount \
|
||||
-v ${DISTRIBUTION_ROOT}:/go/src/github.com/docker/distribution \
|
||||
-e "DOCKER_GRAPHDRIVER=$DOCKER_GRAPHDRIVER" \
|
||||
${INTEGRATION_IMAGE} \
|
||||
./run_engine.sh)
|
||||
|
||||
# Stop container on exit
|
||||
trap "docker rm -f -v $ID" EXIT
|
||||
|
||||
|
||||
# Wait for it to become reachable.
|
||||
tries=10
|
||||
until docker exec "$ID" docker version &> /dev/null; do
|
||||
(( tries-- ))
|
||||
if [ $tries -le 0 ]; then
|
||||
echo >&2 "error: daemon failed to start"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# If no volume is specified, transfer images into the container from
|
||||
# the outer docker instance
|
||||
if [ "$DOCKER_VOLUME" == "" ]; then
|
||||
# Make sure we have images outside the container, to transfer to the container.
|
||||
# Not much will happen here if the images are already present.
|
||||
docker-compose pull
|
||||
docker-compose build
|
||||
|
||||
# Transfer images to the inner container.
|
||||
for image in "$INTEGRATION_IMAGE" registry:0.9.1 dockerintegration_nginx dockerintegration_registryv2; do
|
||||
docker save "$image" | docker exec -i "$ID" docker load
|
||||
done
|
||||
fi
|
||||
|
||||
# Run the tests.
|
||||
docker exec -it "$ID" sh -c "./test_runner.sh $TESTS"
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
DOCKER_GRAPHDRIVER=${DOCKER_GRAPHDRIVER:-overlay}
|
||||
EXEC_DRIVER=${EXEC_DRIVER:-native}
|
||||
|
||||
# Set IP address in /etc/hosts for localregistry
|
||||
IP=$(ifconfig eth0|grep "inet addr:"| cut -d: -f2 | awk '{ print $1}')
|
||||
echo "$IP localregistry" >> /etc/hosts
|
||||
|
||||
sh install_certs.sh localregistry
|
||||
|
||||
DOCKER_VERSION=$(docker --version | cut -d ' ' -f3 | cut -d ',' -f1)
|
||||
major=$(echo "$DOCKER_VERSION"| cut -d '.' -f1)
|
||||
minor=$(echo "$DOCKER_VERSION"| cut -d '.' -f2)
|
||||
|
||||
daemonOpts="daemon"
|
||||
if [ $major -le 1 ] && [ $minor -lt 9 ]; then
|
||||
daemonOpts="--daemon"
|
||||
fi
|
||||
|
||||
docker $daemonOpts --log-level=debug --storage-driver="$DOCKER_GRAPHDRIVER"
|
|
@ -5,63 +5,49 @@
|
|||
set -e
|
||||
set -x
|
||||
|
||||
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
source helpers.bash
|
||||
|
||||
|
||||
if [ "$TMPDIR" != "" ] && [ ! -d "$TMPDIR" ]; then
|
||||
mkdir -p $TMPDIR
|
||||
if [ `uname` = "Linux" ]; then
|
||||
tmpdir_template="$TMPDIR/docker-versions.XXXXX"
|
||||
else
|
||||
# /tmp isn't available for mounting in boot2docker
|
||||
tmpdir_template="`pwd`/../../../docker-versions.XXXXX"
|
||||
fi
|
||||
|
||||
cachedir=`mktemp -t -d golem-cache.XXXXXX`
|
||||
trap "rm -rf $cachedir" EXIT
|
||||
tmpdir=`mktemp -d "$tmpdir_template"`
|
||||
trap "rm -rf $tmpdir" EXIT
|
||||
|
||||
if [ "$1" == "-d" ]; then
|
||||
# Drivers to use for Docker engines the tests are going to create.
|
||||
STORAGE_DRIVER=${STORAGE_DRIVER:-overlay}
|
||||
|
||||
docker daemon --log-level=panic --storage-driver="$STORAGE_DRIVER" &
|
||||
DOCKER_PID=$!
|
||||
|
||||
# Wait for it to become reachable.
|
||||
tries=10
|
||||
until docker version &> /dev/null; do
|
||||
(( tries-- ))
|
||||
if [ $tries -le 0 ]; then
|
||||
echo >&2 "error: daemon failed to start"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
trap "kill $DOCKER_PID" EXIT
|
||||
start_daemon
|
||||
fi
|
||||
|
||||
distimage=$(docker build -q $DIR/../..)
|
||||
fullversion=$(git describe --match 'v[0-9]*' --dirty='.m' --always)
|
||||
distversion=${fullversion:1}
|
||||
# Released versions
|
||||
|
||||
echo "Testing image $distimage with distribution version $distversion"
|
||||
versions="1.6.1 1.7.1 1.8.3 1.9.1"
|
||||
|
||||
# Pull needed images before invoking golem to get pull time
|
||||
# These images are defined in golem.conf
|
||||
time docker pull nginx:1.9
|
||||
time docker pull golang:1.6
|
||||
time docker pull dmcgowan/token-server:simple
|
||||
time docker pull dmcgowan/token-server:oauth
|
||||
time docker pull distribution/golem-runner:0.1-bats
|
||||
for v in $versions; do
|
||||
echo "Extracting Docker $v from dind image"
|
||||
binpath="$tmpdir/docker-$v/docker"
|
||||
ID=$(docker create dockerswarm/dind:$v)
|
||||
docker cp "$ID:/usr/local/bin/docker" "$tmpdir/docker-$v"
|
||||
|
||||
time docker pull docker:1.9.1-dind
|
||||
time docker pull docker:1.10.3-dind
|
||||
time docker pull docker:1.11.1-dind
|
||||
time docker pull docker:1.12.3-dind
|
||||
time docker pull docker:1.13.0-rc5-dind
|
||||
echo "Running tests with Docker $v"
|
||||
DOCKER_BINARY="$binpath" DOCKER_VOLUME="$DOCKER_VOLUME" DOCKER_GRAPHDRIVER="$DOCKER_GRAPHDRIVER" ./run.sh
|
||||
|
||||
golem -cache $cachedir \
|
||||
-i "golem-distribution:latest,$distimage,$distversion" \
|
||||
-i "golem-dind:latest,docker:1.9.1-dind,1.9.1" \
|
||||
-i "golem-dind:latest,docker:1.10.3-dind,1.10.3" \
|
||||
-i "golem-dind:latest,docker:1.11.1-dind,1.11.1" \
|
||||
-i "golem-dind:latest,docker:1.12.3-dind,1.12.3" \
|
||||
-i "golem-dind:latest,docker:1.13.0-rc5-dind,1.13.0" \
|
||||
$DIR
|
||||
# Cleanup.
|
||||
docker rm -f "$ID"
|
||||
done
|
||||
|
||||
# Latest experimental version
|
||||
|
||||
echo "Extracting Docker master from dind image"
|
||||
binpath="$tmpdir/docker-master/docker"
|
||||
docker pull dockerswarm/dind-master
|
||||
ID=$(docker create dockerswarm/dind-master)
|
||||
docker cp "$ID:/usr/local/bin/docker" "$tmpdir/docker-master"
|
||||
|
||||
echo "Running tests with Docker master"
|
||||
DOCKER_BINARY="$binpath" DOCKER_VOLUME="$DOCKER_VOLUME" ./run.sh
|
||||
|
||||
# Cleanup.
|
||||
docker rm -f "$ID"
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
|
||||
|
||||
TESTS=${@:-.}
|
||||
|
||||
function execute() {
|
||||
>&2 echo "++ $@"
|
||||
eval "$@"
|
||||
}
|
||||
|
||||
execute time docker-compose build
|
||||
|
||||
execute docker-compose up -d
|
||||
|
||||
# Run the tests.
|
||||
execute time bats -p $TESTS
|
|
@ -1,25 +1,44 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
# Registry host name, should be set to non-localhost address and match
|
||||
# DNS name in nginx/ssl certificates and what is installed in /etc/docker/cert.d
|
||||
|
||||
load helpers
|
||||
|
||||
hostname="localregistry"
|
||||
base="hello-world"
|
||||
image="${base}:latest"
|
||||
|
||||
image="hello-world:latest"
|
||||
|
||||
# Login information, should match values in nginx/test.passwd
|
||||
user=${TEST_USER:-"testuser"}
|
||||
password=${TEST_PASSWORD:-"passpassword"}
|
||||
user="testuser"
|
||||
password="passpassword"
|
||||
email="distribution@docker.com"
|
||||
|
||||
function setup() {
|
||||
tempImage $image
|
||||
docker pull $image
|
||||
}
|
||||
|
||||
# skip basic auth tests with Docker 1.6, where they don't pass due to
|
||||
# certificate issues
|
||||
function basic_auth_version_check() {
|
||||
run sh -c 'docker version | fgrep -q "Client version: 1.6."'
|
||||
if [ "$status" -eq 0 ]; then
|
||||
skip "Basic auth tests don't support 1.6.x"
|
||||
fi
|
||||
}
|
||||
|
||||
# has_digest enforces the last output line is "Digest: sha256:..."
|
||||
# the input is the name of the array containing the output lines
|
||||
function has_digest() {
|
||||
filtered=$(echo "$1" |sed -rn '/[dD]igest\: sha(256|384|512)/ p')
|
||||
[ "$filtered" != "" ]
|
||||
}
|
||||
|
||||
function login() {
|
||||
run docker login -u $user -p $password -e $email $1
|
||||
[ "$status" -eq 0 ]
|
||||
# First line is WARNING about credential save
|
||||
[ "${lines[1]}" = "Login Succeeded" ]
|
||||
}
|
||||
|
||||
@test "Test valid certificates" {
|
||||
docker_t tag $image $hostname:5440/$image
|
||||
run docker_t push $hostname:5440/$image
|
||||
docker tag -f $image $hostname:5440/$image
|
||||
run docker push $hostname:5440/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
}
|
||||
|
@ -27,82 +46,57 @@ function setup() {
|
|||
@test "Test basic auth" {
|
||||
basic_auth_version_check
|
||||
login $hostname:5441
|
||||
docker_t tag $image $hostname:5441/$image
|
||||
run docker_t push $hostname:5441/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
}
|
||||
|
||||
@test "Test basic auth with build" {
|
||||
basic_auth_version_check
|
||||
login $hostname:5441
|
||||
|
||||
image1=$hostname:5441/$image-build
|
||||
image2=$hostname:5441/$image-build-2
|
||||
|
||||
tempImage $image1
|
||||
|
||||
run docker_t push $image1
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
docker_t rmi $image1
|
||||
|
||||
run build $image2 $image1
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run docker_t push $image2
|
||||
echo $output
|
||||
docker tag -f $image $hostname:5441/$image
|
||||
run docker push $hostname:5441/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
}
|
||||
|
||||
@test "Test TLS client auth" {
|
||||
docker_t tag $image $hostname:5442/$image
|
||||
run docker_t push $hostname:5442/$image
|
||||
docker tag -f $image $hostname:5442/$image
|
||||
run docker push $hostname:5442/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
}
|
||||
|
||||
@test "Test TLS client with invalid certificate authority fails" {
|
||||
docker_t tag $image $hostname:5443/$image
|
||||
run docker_t push $hostname:5443/$image
|
||||
docker tag -f $image $hostname:5443/$image
|
||||
run docker push $hostname:5443/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test basic auth with TLS client auth" {
|
||||
basic_auth_version_check
|
||||
login $hostname:5444
|
||||
docker_t tag $image $hostname:5444/$image
|
||||
run docker_t push $hostname:5444/$image
|
||||
docker tag -f $image $hostname:5444/$image
|
||||
run docker push $hostname:5444/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
}
|
||||
|
||||
@test "Test unknown certificate authority fails" {
|
||||
docker_t tag $image $hostname:5445/$image
|
||||
run docker_t push $hostname:5445/$image
|
||||
docker tag -f $image $hostname:5445/$image
|
||||
run docker push $hostname:5445/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test basic auth with unknown certificate authority fails" {
|
||||
run login $hostname:5446
|
||||
[ "$status" -ne 0 ]
|
||||
docker_t tag $image $hostname:5446/$image
|
||||
run docker_t push $hostname:5446/$image
|
||||
docker tag -f $image $hostname:5446/$image
|
||||
run docker push $hostname:5446/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test TLS client auth to server with unknown certificate authority fails" {
|
||||
docker_t tag $image $hostname:5447/$image
|
||||
run docker_t push $hostname:5447/$image
|
||||
docker tag -f $image $hostname:5447/$image
|
||||
run docker push $hostname:5447/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test failure to connect to server fails to fallback to SSLv3" {
|
||||
docker_t tag $image $hostname:5448/$image
|
||||
run docker_t push $hostname:5448/$image
|
||||
docker tag -f $image $hostname:5448/$image
|
||||
run docker push $hostname:5448/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
# This tests contacting a registry using a token server
|
||||
|
||||
load helpers
|
||||
|
||||
user="testuser"
|
||||
password="testpassword"
|
||||
base="hello-world"
|
||||
|
||||
@test "Test token server login" {
|
||||
login localregistry:5554
|
||||
}
|
||||
|
||||
@test "Test token server bad login" {
|
||||
docker_t_login -u "testuser" -p "badpassword" localregistry:5554
|
||||
[ "$status" -ne 0 ]
|
||||
|
||||
docker_t_login -u "baduser" -p "testpassword" localregistry:5554
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test push and pull with token auth" {
|
||||
login localregistry:5555
|
||||
image="localregistry:5555/testuser/token"
|
||||
build $image "$base:latest"
|
||||
|
||||
run docker_t push $image
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
docker_t rmi $image
|
||||
|
||||
docker_t pull $image
|
||||
}
|
||||
|
||||
@test "Test push and pull with token auth wrong namespace" {
|
||||
login localregistry:5555
|
||||
image="localregistry:5555/notuser/token"
|
||||
build $image "$base:latest"
|
||||
|
||||
run docker_t push $image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test oauth token server login" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.11.0"
|
||||
|
||||
login_oauth localregistry:5557
|
||||
}
|
||||
|
||||
@test "Test oauth token server bad login" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.11.0"
|
||||
|
||||
docker_t_login -u "testuser" -p "badpassword" -e $email localregistry:5557
|
||||
[ "$status" -ne 0 ]
|
||||
|
||||
docker_t_login -u "baduser" -p "testpassword" -e $email localregistry:5557
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test oauth push and pull with token auth" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.11.0"
|
||||
|
||||
login_oauth localregistry:5558
|
||||
image="localregistry:5558/testuser/token"
|
||||
build $image "$base:latest"
|
||||
|
||||
run docker_t push $image
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
docker_t rmi $image
|
||||
|
||||
docker_t pull $image
|
||||
}
|
||||
|
||||
@test "Test oauth push and build with token auth" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.11.0"
|
||||
|
||||
login_oauth localregistry:5558
|
||||
image="localregistry:5558/testuser/token-build"
|
||||
tempImage $image
|
||||
|
||||
run docker_t push $image
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
docker_t rmi $image
|
||||
|
||||
image2="localregistry:5558/testuser/token-build-2"
|
||||
run build $image2 $image
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run docker_t push $image2
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest "$output"
|
||||
|
||||
}
|
||||
|
||||
@test "Test oauth push and pull with token auth wrong namespace" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.11.0"
|
||||
|
||||
login_oauth localregistry:5558
|
||||
image="localregistry:5558/notuser/token"
|
||||
build $image "$base:latest"
|
||||
|
||||
run docker_t push $image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test oauth with v1 search" {
|
||||
version_check docker "$GOLEM_DIND_VERSION" "1.12.0"
|
||||
|
||||
run docker_t search localregistry:5600/testsearch
|
||||
[ "$status" -ne 0 ]
|
||||
|
||||
login_oauth localregistry:5600
|
||||
|
||||
run docker_t search localregistry:5600/testsearch
|
||||
echo $output
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
echo $output | grep "testsearch-1"
|
||||
echo $output | grep "testsearch-2"
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
testuser:$2y$05$T2MlBvkN1R/yICNnLuf1leOlOfAY0DvybctbbWUFKlojfkShVgn4m
|
|
@ -1,8 +0,0 @@
|
|||
FROM dmcgowan/token-server@sha256:5a6f76d3086cdf63249c77b521108387b49d85a30c5e1c4fe82fdf5ae3b76ba7
|
||||
|
||||
WORKDIR /
|
||||
|
||||
COPY ./.htpasswd /.htpasswd
|
||||
COPY ./certs/auth.localregistry.cert /tls.cert
|
||||
COPY ./certs/auth.localregistry.key /tls.key
|
||||
COPY ./certs/signing.key /sign.key
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDHDCCAgagAwIBAgIRAKhhQMnqZx+hkOmoUYgPb+kwCwYJKoZIhvcNAQELMCYx
|
||||
ETAPBgNVBAoTCFF1aWNrVExTMREwDwYDVQQDEwhRdWlja1RMUzAeFw0xNjAxMjgw
|
||||
MDQyMzFaFw0xOTAxMTIwMDQyMzFaMDAxETAPBgNVBAoTCFF1aWNrVExTMRswGQYD
|
||||
VQQDExJhdXRoLmxvY2FscmVnaXN0cnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQD1tUf1EghBlIRrE83yF4zDgRu7vH2Jo0kygKJUWtQQe+DfXyjjE/fg
|
||||
FdKnnoEjsIeF9hxNbTt0ldDz7/n97pbMhoiXULi9iq4jlgSzVL2XEAgrON0YSY/c
|
||||
Lmmd1KSa/pOUZr2WMAYPZ+FdQfE1W7SMNbErPefBqYdFzpZ+esAtvbajYwIjl8Vy
|
||||
9c4bidx4vgnNrR9GcFYibjC5sj8syh/OtbzzqiVGT8YcPpmMG6KNRkausa4gqpon
|
||||
NKYG8C3WDaiPCLYKcvFrFfdEWF/m2oj14eXACXT9iwp8r4bsLgXrZwqcpKOWfVRu
|
||||
qHC8aV476EYgxWCAOANExUdUaRt5wL/jAgMBAAGjPzA9MA4GA1UdDwEB/wQEAwIA
|
||||
oDAMBgNVHRMBAf8EAjAAMB0GA1UdEQQWMBSCEmF1dGgubG9jYWxyZWdpc3RyeTAL
|
||||
BgkqhkiG9w0BAQsDggEBABxPGK9FdGDxcLowNsExKnnZvmQT3H0u+Dux1gkp0AhH
|
||||
KOrmx3LUENUKLSgotzx133tgOgR5lzAWVFy7bhLwlPhOslxf2oEfztsAMd/tY8rW
|
||||
PrG2ZqYqlzEQQ9INbAc3woo5A3slN07uhP3F16jNqoMM4zRmw6Ba70CluGKT7x5+
|
||||
xVjKoWITLjWDXT5m35PnsN8CpBaFzXYcod/5p9XwCFp0s+aNxfpZECCV/3yqIr+J
|
||||
ALzroPh43FAlG96o4NyYZ2Msp63newN19R2+TgpV4nXuw2mLVDpvetP7RRqnpvj/
|
||||
qwRgt5j4hFjJWb61M0ELL7A9fA71h1ImdGCvnArdBQs=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA9bVH9RIIQZSEaxPN8heMw4Ebu7x9iaNJMoCiVFrUEHvg318o
|
||||
4xP34BXSp56BI7CHhfYcTW07dJXQ8+/5/e6WzIaIl1C4vYquI5YEs1S9lxAIKzjd
|
||||
GEmP3C5pndSkmv6TlGa9ljAGD2fhXUHxNVu0jDWxKz3nwamHRc6WfnrALb22o2MC
|
||||
I5fFcvXOG4nceL4Jza0fRnBWIm4wubI/LMofzrW886olRk/GHD6ZjBuijUZGrrGu
|
||||
IKqaJzSmBvAt1g2ojwi2CnLxaxX3RFhf5tqI9eHlwAl0/YsKfK+G7C4F62cKnKSj
|
||||
ln1UbqhwvGleO+hGIMVggDgDRMVHVGkbecC/4wIDAQABAoIBAQCrsjXKRwOF8CZo
|
||||
PLqZBWPT6hBbK+f9miC4LbNBhwbRTf9hl7mWlImOCTHe95/+NIk/Ty+P21jEqzwM
|
||||
ehETJPoziX9BXaL6sEHnlBlMx1aEjStoKKA3LJBeqAAdzk4IEQVHmlO4824IreqJ
|
||||
pF7Njnunzo0zTlr4tWJVoXsAfv5z9tNtdkxYBbIa0fjfGtlqXU3gLq58FCON3mB/
|
||||
NGc0AyA1UFGp0FzpdEcwTGD4InsXbcmsl2l/VPBJuZbryITRqWs6BbK++80DRhNt
|
||||
afMhP+IzKrWSCp0rBYrqqz6AevtlKdEfQK1yXPEjN/63QLMevt8mF/1JCp//TQnf
|
||||
Z6bIQbAhAoGBAP7vFA0PcvoXt9MXvvAwrKY1s6pNw4nWPG27qY1/m+DkBwP8IQms
|
||||
4AWGv1wscZzXJYTvaLO5/qjmGUj50ohcVEvyZJioh1pKXA8Chxvd6rBA/O/Lj5E0
|
||||
3MOSA5Q0gxJ0Mhv0zGbbyN5fY8D8zhxoqQP4LoW+UdZG2Oi6JxsQ9c9dAoGBAPa8
|
||||
U3bGuM5OGA9EWP7mkB/VnjDTL1aEIN3cOHbHIKwH/loxdYcNMBE7vwxV1CzgIzXT
|
||||
wsL0iE15fQdK938u0+um8aH5QtbWNI8tdk1XVjEC/i3C7N6WVUutneCKUDb4QxiB
|
||||
9OvWCbNNiN+xTKBBM93YlwO3GYfrW9Pmm9q1+hg/AoGBALJlUS22gun50PxaIJZq
|
||||
KVcCO2DQnCYHki/j48mN4+HjD/m85M2lePrFCYIR48syTyIQer9SR5+frVAA6k/b
|
||||
9G1VCQo+3MDVSkiCp1Nb3tBKGfYgB65ARMBinDiI6rPuNeaUTrkn0g+yxtaU0hLV
|
||||
Nnj9omia/x+oYj+xjI4HN0xNAoGARy92dSJIV104m88ATip/EnAzP6ruUWu1f8z1
|
||||
jW9OAdQckjEK03f+kjpGmGx61qekAPejjVO3r4KJi/0ZAtyjz61OsYiUvB748wYO
|
||||
x6mW+HUAmHtQk7eTzE2+6vV8xx9BXGTCIPiTu+N2xfMFRIcLS8odZ7j/6LMCv1Qd
|
||||
SzCNg0kCgYBaNlEs4pK1VxZZpEWwVmFpgIxfEfxLIaGrek6wBTcCn/VA2M0oHuez
|
||||
mlMio8VY0yWPBJz30JflDiTmYIvteLPMHT0N0J6isiXLhzJSFI4+cAMLE2Q5v8rz
|
||||
W+W5/L8YZeierW0qJat1BrgStaf5ZLpiOc9pKBSwycydPH5BfVdK/A==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC9TCCAd+gAwIBAgIQNS9SaFSFBN7Zvwjalrf2DDALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE2MDEyODAw
|
||||
NDIzMFoXDTE5MDExMjAwNDIzMFowJjERMA8GA1UEChMIUXVpY2tUTFMxETAPBgNV
|
||||
BAMTCFF1aWNrVExTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu/Pf
|
||||
fQ7VUTSXs12PRyrLDVDz7kPDbGNTt0vF7FYDmTTGOU3i62xZNOGuxBezAiVSV5A3
|
||||
lopwsv4OH7DRtSaPn+XCt1JDALna2WrjT0MshypMd5o2c3jmGUfAKf5gjizgIoEl
|
||||
d4e5aqEBuOQP+QCEde+8p8N1buQW+zMy9srM2O/7BFMIaQ07CWLlj3hIiF+L5rKD
|
||||
L6dWtKT7INRmRwpuZZnThEWnBSNgayrWek6G0i3y8QYTfVA1SwA+H3grJxy5NrLp
|
||||
GYXSmu2509mu0QAHhx05t1rJhwhFz/4sG7j8AggYeDXEqfQ/VIb/bvnW9bD+vrQ2
|
||||
ZnICvxnzNMYBx23BkQIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAKQwDwYDVR0TAQH/
|
||||
BAUwAwEB/zALBgkqhkiG9w0BAQsDggEBALvTi6E44Fltu83dFLVEj0kLtusI/TTH
|
||||
Tw6upoB5pRG+7A75w0Ii8bvvd2tNpBOg+L+80xyIFqaNkXhLKTN4lgtd7WiCuyb/
|
||||
w1BEuF/+RjCXhu6wQ/63ab46d6ctaQ1zjxlU2rQLQXQFALI8ntyn/TELc01HYkr2
|
||||
x3NHlbnBNlgI2CKXPeUBzvBylTCcdYGwoa+2ZPdIsFjle2aCIBoZ+WNZlIbFwgLh
|
||||
XCHwcbviC+thjqOneJpJZmRW9AxQ638ki6iGItdrJewCN/1dcL2KKjxnC5VHbpne
|
||||
SOjEPNXihY08Brl8myhFNtRRKZ55MJIYzDtVQSkCaT91Q3XX9tSZadY=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDETCCAfugAwIBAgIQN7rT95eAy75c4n6/AsDJODALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE2MDEyODAw
|
||||
NDIzMloXDTE5MDExMjAwNDIzMlowKzERMA8GA1UEChMIUXVpY2tUTFMxFjAUBgNV
|
||||
BAMTDWxvY2FscmVnaXN0cnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQDLi75QEkl/qekcoOJlNv9y1IXvrbU2ssl4ViJiZRjWx+/CkyCCOyf9YUpAgRLr
|
||||
Pskqde2mwhuNP8yBlOBb17Sapz7N3+hJi5j9vLBAFcamPeF3PqxjFv7j5TKkRmSI
|
||||
dFYQclREwMUd3qEH322KkqOnsEEfdmCgFqWORe+QR5AxzxQP3Pnd4OYH1yZCh0MQ
|
||||
P2pJgrxxf2I5I/m1AUgoHV1cdBbCv9LGohJPpMtwPC0dJpgMFcnf6hT37At236AY
|
||||
V437HiRruY7iPWkYFrSPWpwdslJ32MZvRN5RS163jZXjiZ7qWnQOiiDJfXe4evB/
|
||||
yQLN4m0qVQxsMz7rkY7OsqaXAgMBAAGjOjA4MA4GA1UdDwEB/wQEAwIAoDAMBgNV
|
||||
HRMBAf8EAjAAMBgGA1UdEQQRMA+CDWxvY2FscmVnaXN0cnkwCwYJKoZIhvcNAQEL
|
||||
A4IBAQAyUb3EuMaOylBeV8+4KeBiE4lxykDOwLLSk3jXRsVVtfJpX3v8l5vwo/Jf
|
||||
iG8tzzz+7uiskI96u3TsekUtVkUxujfKevMP+369K/59s7NRmwwlFMyB2fvL14B2
|
||||
oweVjWvM/8fZl6irtFdbJFXXRm7paKso5cmfImxhojAwohgcd4XTVLE/7juYa582
|
||||
AaBdRuIiyL71MU9qa1mC5+57AaSLPYaPKpahemgYYkV1Z403Kd6rXchxdQ8JIAL8
|
||||
+0oYTSC+svnz1tUU/V5E5id9LQaTmDN5iIVFhNpqAaZmR45UI86woWvnkMb8Ants
|
||||
4aknwTwY3300PuTqBdQufvOFDRN5
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAy4u+UBJJf6npHKDiZTb/ctSF7621NrLJeFYiYmUY1sfvwpMg
|
||||
gjsn/WFKQIES6z7JKnXtpsIbjT/MgZTgW9e0mqc+zd/oSYuY/bywQBXGpj3hdz6s
|
||||
Yxb+4+UypEZkiHRWEHJURMDFHd6hB99tipKjp7BBH3ZgoBaljkXvkEeQMc8UD9z5
|
||||
3eDmB9cmQodDED9qSYK8cX9iOSP5tQFIKB1dXHQWwr/SxqIST6TLcDwtHSaYDBXJ
|
||||
3+oU9+wLdt+gGFeN+x4ka7mO4j1pGBa0j1qcHbJSd9jGb0TeUUtet42V44me6lp0
|
||||
DoogyX13uHrwf8kCzeJtKlUMbDM+65GOzrKmlwIDAQABAoIBAF6vFMp+lz4RteSh
|
||||
Wm8m1FGAVwWVUpStOlcGClynFpTi0L88XYT3K7UMStQSttBDlqRv0ysdZF+ia+lj
|
||||
bbKLdvHyFp8CJzX/AB4YZgyJlKzEYFtuBhbaHZu5hIMyU5W+OELSTCznV0p7w4C8
|
||||
CGLLr+FTdhfCo1QU9NJn6fa9s2/XRdSClBBalAHYs0ZS7ZckaF/sPiC/VapfBMet
|
||||
qjJXNYiO6pXYriGWKF9zdAMfk2CM0BVWbnwQZkMSEQirrTcJwm3ezyloXCv2nywK
|
||||
/VzbUT1HJVyzo5oAwTd0MwDc2oEMiFzlfO028zY4LDltpia+SyWvFi5NaIqzFESc
|
||||
yLgJacECgYEA3jvH+ZQHQf42Md8TCciokaYvwWIKJdk4WRjbvE5cBZekyXAm7/3b
|
||||
/1VFDKsy2RPlfmfHP3wy9rlnjzsRveB5qaclgS8aI67AYsWd/yRgfRatl7Ve9bHl
|
||||
LY6VM5L/DZTxykcqivwjc77XoDuBfUKs6tyuSLQku+FOTbLtNYlUCHECgYEA6nkR
|
||||
lkXufyLmDhNb3093RsYvPcs1kGaIIGTnz3cxWNh485DgsyLBuYQ5ugupQkzM8YSt
|
||||
ohDTmVpggqjlXQxCg0Zw8gkEV0v8KsLGjn1CuTJg/mBArXlelq1FEeRAYC9/YfOz
|
||||
ocXegHV7wDKKtcraNZFsEc7Z0LwbC9wtzSFG44cCgYASkMX1CLPOhJE8e1lY0OWc
|
||||
PVjx++HDJbF6aAQ7aARyBygiF/d4xylw3EvHcinuTqY2eC8CE7siN3z6T0H9Ldqc
|
||||
HLWaZDf30SqLVd0MKprQ+GsKKIHFXtY5hxbZ1ybtmIrWjjl0oPnJOqFC5pW7xC0z
|
||||
9bmtozcKZxkmjpMYjN9zUQKBgQCqV6KLRerqunPgLfhE1/qTlE+l2QflDFhBEI3I
|
||||
j5NuNHZKnSphehK7sHAv1WD2Jc2OeRGb+BWCB8Ktqf5YBxwbOwW7EQnyUeW1OyP9
|
||||
SMs8uHj21P6oCNDLLr5LLUQHnPoyM1aBZLstICzziMR1JhY5bJjSpzBfEQmlKCSu
|
||||
LkrN6QKBgQCRXrBJRUxeJj7wCnCSq0Clf9NhCpQnwo4bEx8sKlj8K8ku8MvwQwoM
|
||||
3KfWc7bOl6A2/mM/k4yoHtBMM9X9xqYtsgeFhxuiWBcfTmTxWh73LQ48Kgbrgodt
|
||||
6yTccnjr7OtBidD85c6lgjAUgcL43QY8mlw0OhzXAZ2R5HWFp4ht+w==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC9TCCAd+gAwIBAgIRAJ6IIisIZxL86oe3oeoAgWUwCwYJKoZIhvcNAQELMCYx
|
||||
ETAPBgNVBAoTCFF1aWNrVExTMREwDwYDVQQDEwhRdWlja1RMUzAeFw0xNjAxMjgw
|
||||
MDQyMzNaFw0xOTAxMTIwMDQyMzNaMBMxETAPBgNVBAoTCFF1aWNrVExTMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3IXUwqSdO2QTj2ET6fJPGe+KWVnt
|
||||
QCQQWjkWVpOz8L2A29BRvv9z6lYNf9sOM0Xb5IUAgoZ/s3U6LNYT/RWYFBfeo40r
|
||||
Xd/MNKAn0kFsSb6BIKmUwPqFeqc8wiPX6yY4SbF1sUTkCTkw3yFHg/AIlwmhpFH3
|
||||
9mAmV+x0kTzFR/78ZDD5CUNS59bbu+7UqB06YrJuVEwPY98YixSPXTcaKimsUe+K
|
||||
IY8FQ6yN6l27MK56wlj4hw2gYz+cyBUBCExCgYMQlOSg2ilH4qYyFvccSDUH7jTA
|
||||
NwpsIBfdoUVbI+j2ivn+ZGD614LtIStGgUu0mDDVxVOWnRvq/z7LMaa2jwIDAQAB
|
||||
ozUwMzAOBgNVHQ8BAf8EBAMCAKAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0T
|
||||
AQH/BAIwADALBgkqhkiG9w0BAQsDggEBAJq3JzTLrIWCF8rHLTTm1icE9PjOO0sV
|
||||
a1wrmdJ6NwRbJ66dLZ/4G/NZjVOnce9WFHYLFSEG+wx5YVUPuJXpJaSdy0h8F0Uw
|
||||
hiJwgeVsGg7vcf4G6mWHrsauDOhylnD31UtYPX1Ao/jcntyyf+gCQpY1J/B8l1yU
|
||||
LNOwvWLVLpZwZ4ehbKA/UnDXgA+3uHvpzl//cPe0cnt+Mhrgzk5mIMwVR6zCZw1G
|
||||
oVutAHpv2PXxRwTMu51J+QtSL2b2w3mGHxDLpmz8UdXOtkxdpmDT8kIOtX0T5yGL
|
||||
29F3fa81iZPs02GWjSGOfOzmCCvaA4C5KJvY/WulF7OOgwvrBpQwqTI=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA3IXUwqSdO2QTj2ET6fJPGe+KWVntQCQQWjkWVpOz8L2A29BR
|
||||
vv9z6lYNf9sOM0Xb5IUAgoZ/s3U6LNYT/RWYFBfeo40rXd/MNKAn0kFsSb6BIKmU
|
||||
wPqFeqc8wiPX6yY4SbF1sUTkCTkw3yFHg/AIlwmhpFH39mAmV+x0kTzFR/78ZDD5
|
||||
CUNS59bbu+7UqB06YrJuVEwPY98YixSPXTcaKimsUe+KIY8FQ6yN6l27MK56wlj4
|
||||
hw2gYz+cyBUBCExCgYMQlOSg2ilH4qYyFvccSDUH7jTANwpsIBfdoUVbI+j2ivn+
|
||||
ZGD614LtIStGgUu0mDDVxVOWnRvq/z7LMaa2jwIDAQABAoIBAD2tiNZv6DImSXo+
|
||||
sq0qQomEf/OBvWPFMnWppd/NK/TXa+UPHO4I0MjoDJqIEC6zCU+fC4d2St1MmlrT
|
||||
/X85vPFRw8mGwGxfHeRSLxEVj04I5GDYTWy0JQUrJUk/cTKp2/Bwm/RaylTyFAM0
|
||||
caYrSpvD69vjuTDFr7PDxM6iaqM53zK/vD8kCe81z+wN0UbAKsLlUOKztjH6SzL9
|
||||
uVOkekIT/j3L2xxyQhjmhfA3TuCP4uNK/+6/4ovl9Nj4pQsFomsCk4phgqy9SOm1
|
||||
4yufmVd8k7J3cppMlMPNc+7tqe2Xn593Y8QT95y3yhtkFECF70yBw64HMDDpA22p
|
||||
5b/JV9ECgYEA9H4RBXOwbdjcpCa9H3mFjHqUQCqNme1vOSGiflZh9KBCDKgdqugm
|
||||
KHpvAECADie0p6XRHpxRvufKnGFkJwedfeiKz51T+0dqgPxWncYT1TC+cAjOSzfM
|
||||
wBpUOcAyvTTviwGbg4bLanHo4remzCbcnRvHQX4YfPFCjT9GhsU+XEUCgYEA5ubz
|
||||
IlSu1wwFJpoO24ZykGUyqGUQXzR0NrXiLrpF0764qjmHyF8SPJPv1XegSxP/nUTz
|
||||
SjVfJ7wye/X9qlOpBY8mzy9qQMMKc1cQBV1yVW8IRZ7pMYQZO7qmrZD/DWTa5qWt
|
||||
pqSbIH2FKedELsKJA/SBtczKjspOdDKyh0UelsMCgYA7DyTfc0XAEy2hPXZb3wgC
|
||||
mi2rnlvcPf2rCFPvPsCkzf2GfynDehaVmpWrsuj8Al1iTezI/yvD+Mv5oJEH2JAT
|
||||
tROq+S8rOOIiTFJEBHAQBJlMCOSESPNdyD5mQOZAzEO9CWNejzYd/WwrL//Luut5
|
||||
zBcC3AngTIsuAYXw0j6xHQKBgQDamkAJep7k3W5q82OplgoUhpqFLtlnKSP1QBFZ
|
||||
J+U/6Mqv7jONEeUUEQL42H6bVd2kqUikMw9ZcSVikquLfBUDPFoDwOIZWg4k0IJM
|
||||
cgHyvGHad+5SgLva/oUawbGWnqtXvfc/U4vCINPXrimxE1/grLW4xp/mu8W24OCA
|
||||
jIG/PQKBgD/Apl+sfqiB/6ONBjjIswA4yFkEXHSZNpAgcPwhA+cO5D0afEWz2HIx
|
||||
VeOh5NjN1EL0hX8clFW4bfkK1Vr0kjvbMUXnBWaibUgpiVQl9O9WjaKQLZrp4sRu
|
||||
x2kJ07Qn6ri7f/lsqOELZwBy95iHWRdePptaAKkRGxJstHI7dgUt
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
version: 0.1
|
||||
loglevel: debug
|
||||
storage:
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
filesystem:
|
||||
rootdirectory: /tmp/registry-dev
|
||||
http:
|
||||
addr: 0.0.0.0:5000
|
||||
compatibility:
|
||||
schema1:
|
||||
enabled: true
|
||||
auth:
|
||||
token:
|
||||
realm: "https://auth.localregistry:5559/token/"
|
||||
issuer: "registry-test"
|
||||
service: "registry-test"
|
||||
rootcertbundle: "/etc/docker/registry/tokenbundle.pem"
|
|
@ -1,21 +0,0 @@
|
|||
version: 0.1
|
||||
loglevel: debug
|
||||
storage:
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
filesystem:
|
||||
rootdirectory: /tmp/registry-dev
|
||||
http:
|
||||
addr: 0.0.0.0:5000
|
||||
tls:
|
||||
certificate: "/etc/docker/registry/localregistry.cert"
|
||||
key: "/etc/docker/registry/localregistry.key"
|
||||
compatibility:
|
||||
schema1:
|
||||
enabled: true
|
||||
auth:
|
||||
token:
|
||||
realm: "https://auth.localregistry:5559/token/"
|
||||
issuer: "registry-test"
|
||||
service: "registry-test"
|
||||
rootcertbundle: "/etc/docker/registry/tokenbundle.pem"
|
|
@ -1 +0,0 @@
|
|||
testuser:$2y$05$T2MlBvkN1R/yICNnLuf1leOlOfAY0DvybctbbWUFKlojfkShVgn4m
|
|
@ -1,8 +0,0 @@
|
|||
FROM dmcgowan/token-server@sha256:0eab50ebdff5b6b95b3addf4edbd8bd2f5b940f27b41b43c94afdf05863a81af
|
||||
|
||||
WORKDIR /
|
||||
|
||||
COPY ./.htpasswd /.htpasswd
|
||||
COPY ./certs/auth.localregistry.cert /tls.cert
|
||||
COPY ./certs/auth.localregistry.key /tls.key
|
||||
COPY ./certs/signing.key /sign.key
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDHDCCAgagAwIBAgIRAKhhQMnqZx+hkOmoUYgPb+kwCwYJKoZIhvcNAQELMCYx
|
||||
ETAPBgNVBAoTCFF1aWNrVExTMREwDwYDVQQDEwhRdWlja1RMUzAeFw0xNjAxMjgw
|
||||
MDQyMzFaFw0xOTAxMTIwMDQyMzFaMDAxETAPBgNVBAoTCFF1aWNrVExTMRswGQYD
|
||||
VQQDExJhdXRoLmxvY2FscmVnaXN0cnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQD1tUf1EghBlIRrE83yF4zDgRu7vH2Jo0kygKJUWtQQe+DfXyjjE/fg
|
||||
FdKnnoEjsIeF9hxNbTt0ldDz7/n97pbMhoiXULi9iq4jlgSzVL2XEAgrON0YSY/c
|
||||
Lmmd1KSa/pOUZr2WMAYPZ+FdQfE1W7SMNbErPefBqYdFzpZ+esAtvbajYwIjl8Vy
|
||||
9c4bidx4vgnNrR9GcFYibjC5sj8syh/OtbzzqiVGT8YcPpmMG6KNRkausa4gqpon
|
||||
NKYG8C3WDaiPCLYKcvFrFfdEWF/m2oj14eXACXT9iwp8r4bsLgXrZwqcpKOWfVRu
|
||||
qHC8aV476EYgxWCAOANExUdUaRt5wL/jAgMBAAGjPzA9MA4GA1UdDwEB/wQEAwIA
|
||||
oDAMBgNVHRMBAf8EAjAAMB0GA1UdEQQWMBSCEmF1dGgubG9jYWxyZWdpc3RyeTAL
|
||||
BgkqhkiG9w0BAQsDggEBABxPGK9FdGDxcLowNsExKnnZvmQT3H0u+Dux1gkp0AhH
|
||||
KOrmx3LUENUKLSgotzx133tgOgR5lzAWVFy7bhLwlPhOslxf2oEfztsAMd/tY8rW
|
||||
PrG2ZqYqlzEQQ9INbAc3woo5A3slN07uhP3F16jNqoMM4zRmw6Ba70CluGKT7x5+
|
||||
xVjKoWITLjWDXT5m35PnsN8CpBaFzXYcod/5p9XwCFp0s+aNxfpZECCV/3yqIr+J
|
||||
ALzroPh43FAlG96o4NyYZ2Msp63newN19R2+TgpV4nXuw2mLVDpvetP7RRqnpvj/
|
||||
qwRgt5j4hFjJWb61M0ELL7A9fA71h1ImdGCvnArdBQs=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA9bVH9RIIQZSEaxPN8heMw4Ebu7x9iaNJMoCiVFrUEHvg318o
|
||||
4xP34BXSp56BI7CHhfYcTW07dJXQ8+/5/e6WzIaIl1C4vYquI5YEs1S9lxAIKzjd
|
||||
GEmP3C5pndSkmv6TlGa9ljAGD2fhXUHxNVu0jDWxKz3nwamHRc6WfnrALb22o2MC
|
||||
I5fFcvXOG4nceL4Jza0fRnBWIm4wubI/LMofzrW886olRk/GHD6ZjBuijUZGrrGu
|
||||
IKqaJzSmBvAt1g2ojwi2CnLxaxX3RFhf5tqI9eHlwAl0/YsKfK+G7C4F62cKnKSj
|
||||
ln1UbqhwvGleO+hGIMVggDgDRMVHVGkbecC/4wIDAQABAoIBAQCrsjXKRwOF8CZo
|
||||
PLqZBWPT6hBbK+f9miC4LbNBhwbRTf9hl7mWlImOCTHe95/+NIk/Ty+P21jEqzwM
|
||||
ehETJPoziX9BXaL6sEHnlBlMx1aEjStoKKA3LJBeqAAdzk4IEQVHmlO4824IreqJ
|
||||
pF7Njnunzo0zTlr4tWJVoXsAfv5z9tNtdkxYBbIa0fjfGtlqXU3gLq58FCON3mB/
|
||||
NGc0AyA1UFGp0FzpdEcwTGD4InsXbcmsl2l/VPBJuZbryITRqWs6BbK++80DRhNt
|
||||
afMhP+IzKrWSCp0rBYrqqz6AevtlKdEfQK1yXPEjN/63QLMevt8mF/1JCp//TQnf
|
||||
Z6bIQbAhAoGBAP7vFA0PcvoXt9MXvvAwrKY1s6pNw4nWPG27qY1/m+DkBwP8IQms
|
||||
4AWGv1wscZzXJYTvaLO5/qjmGUj50ohcVEvyZJioh1pKXA8Chxvd6rBA/O/Lj5E0
|
||||
3MOSA5Q0gxJ0Mhv0zGbbyN5fY8D8zhxoqQP4LoW+UdZG2Oi6JxsQ9c9dAoGBAPa8
|
||||
U3bGuM5OGA9EWP7mkB/VnjDTL1aEIN3cOHbHIKwH/loxdYcNMBE7vwxV1CzgIzXT
|
||||
wsL0iE15fQdK938u0+um8aH5QtbWNI8tdk1XVjEC/i3C7N6WVUutneCKUDb4QxiB
|
||||
9OvWCbNNiN+xTKBBM93YlwO3GYfrW9Pmm9q1+hg/AoGBALJlUS22gun50PxaIJZq
|
||||
KVcCO2DQnCYHki/j48mN4+HjD/m85M2lePrFCYIR48syTyIQer9SR5+frVAA6k/b
|
||||
9G1VCQo+3MDVSkiCp1Nb3tBKGfYgB65ARMBinDiI6rPuNeaUTrkn0g+yxtaU0hLV
|
||||
Nnj9omia/x+oYj+xjI4HN0xNAoGARy92dSJIV104m88ATip/EnAzP6ruUWu1f8z1
|
||||
jW9OAdQckjEK03f+kjpGmGx61qekAPejjVO3r4KJi/0ZAtyjz61OsYiUvB748wYO
|
||||
x6mW+HUAmHtQk7eTzE2+6vV8xx9BXGTCIPiTu+N2xfMFRIcLS8odZ7j/6LMCv1Qd
|
||||
SzCNg0kCgYBaNlEs4pK1VxZZpEWwVmFpgIxfEfxLIaGrek6wBTcCn/VA2M0oHuez
|
||||
mlMio8VY0yWPBJz30JflDiTmYIvteLPMHT0N0J6isiXLhzJSFI4+cAMLE2Q5v8rz
|
||||
W+W5/L8YZeierW0qJat1BrgStaf5ZLpiOc9pKBSwycydPH5BfVdK/A==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC9TCCAd+gAwIBAgIQNS9SaFSFBN7Zvwjalrf2DDALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE2MDEyODAw
|
||||
NDIzMFoXDTE5MDExMjAwNDIzMFowJjERMA8GA1UEChMIUXVpY2tUTFMxETAPBgNV
|
||||
BAMTCFF1aWNrVExTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu/Pf
|
||||
fQ7VUTSXs12PRyrLDVDz7kPDbGNTt0vF7FYDmTTGOU3i62xZNOGuxBezAiVSV5A3
|
||||
lopwsv4OH7DRtSaPn+XCt1JDALna2WrjT0MshypMd5o2c3jmGUfAKf5gjizgIoEl
|
||||
d4e5aqEBuOQP+QCEde+8p8N1buQW+zMy9srM2O/7BFMIaQ07CWLlj3hIiF+L5rKD
|
||||
L6dWtKT7INRmRwpuZZnThEWnBSNgayrWek6G0i3y8QYTfVA1SwA+H3grJxy5NrLp
|
||||
GYXSmu2509mu0QAHhx05t1rJhwhFz/4sG7j8AggYeDXEqfQ/VIb/bvnW9bD+vrQ2
|
||||
ZnICvxnzNMYBx23BkQIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAKQwDwYDVR0TAQH/
|
||||
BAUwAwEB/zALBgkqhkiG9w0BAQsDggEBALvTi6E44Fltu83dFLVEj0kLtusI/TTH
|
||||
Tw6upoB5pRG+7A75w0Ii8bvvd2tNpBOg+L+80xyIFqaNkXhLKTN4lgtd7WiCuyb/
|
||||
w1BEuF/+RjCXhu6wQ/63ab46d6ctaQ1zjxlU2rQLQXQFALI8ntyn/TELc01HYkr2
|
||||
x3NHlbnBNlgI2CKXPeUBzvBylTCcdYGwoa+2ZPdIsFjle2aCIBoZ+WNZlIbFwgLh
|
||||
XCHwcbviC+thjqOneJpJZmRW9AxQ638ki6iGItdrJewCN/1dcL2KKjxnC5VHbpne
|
||||
SOjEPNXihY08Brl8myhFNtRRKZ55MJIYzDtVQSkCaT91Q3XX9tSZadY=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDETCCAfugAwIBAgIQN7rT95eAy75c4n6/AsDJODALBgkqhkiG9w0BAQswJjER
|
||||
MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE2MDEyODAw
|
||||
NDIzMloXDTE5MDExMjAwNDIzMlowKzERMA8GA1UEChMIUXVpY2tUTFMxFjAUBgNV
|
||||
BAMTDWxvY2FscmVnaXN0cnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQDLi75QEkl/qekcoOJlNv9y1IXvrbU2ssl4ViJiZRjWx+/CkyCCOyf9YUpAgRLr
|
||||
Pskqde2mwhuNP8yBlOBb17Sapz7N3+hJi5j9vLBAFcamPeF3PqxjFv7j5TKkRmSI
|
||||
dFYQclREwMUd3qEH322KkqOnsEEfdmCgFqWORe+QR5AxzxQP3Pnd4OYH1yZCh0MQ
|
||||
P2pJgrxxf2I5I/m1AUgoHV1cdBbCv9LGohJPpMtwPC0dJpgMFcnf6hT37At236AY
|
||||
V437HiRruY7iPWkYFrSPWpwdslJ32MZvRN5RS163jZXjiZ7qWnQOiiDJfXe4evB/
|
||||
yQLN4m0qVQxsMz7rkY7OsqaXAgMBAAGjOjA4MA4GA1UdDwEB/wQEAwIAoDAMBgNV
|
||||
HRMBAf8EAjAAMBgGA1UdEQQRMA+CDWxvY2FscmVnaXN0cnkwCwYJKoZIhvcNAQEL
|
||||
A4IBAQAyUb3EuMaOylBeV8+4KeBiE4lxykDOwLLSk3jXRsVVtfJpX3v8l5vwo/Jf
|
||||
iG8tzzz+7uiskI96u3TsekUtVkUxujfKevMP+369K/59s7NRmwwlFMyB2fvL14B2
|
||||
oweVjWvM/8fZl6irtFdbJFXXRm7paKso5cmfImxhojAwohgcd4XTVLE/7juYa582
|
||||
AaBdRuIiyL71MU9qa1mC5+57AaSLPYaPKpahemgYYkV1Z403Kd6rXchxdQ8JIAL8
|
||||
+0oYTSC+svnz1tUU/V5E5id9LQaTmDN5iIVFhNpqAaZmR45UI86woWvnkMb8Ants
|
||||
4aknwTwY3300PuTqBdQufvOFDRN5
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAy4u+UBJJf6npHKDiZTb/ctSF7621NrLJeFYiYmUY1sfvwpMg
|
||||
gjsn/WFKQIES6z7JKnXtpsIbjT/MgZTgW9e0mqc+zd/oSYuY/bywQBXGpj3hdz6s
|
||||
Yxb+4+UypEZkiHRWEHJURMDFHd6hB99tipKjp7BBH3ZgoBaljkXvkEeQMc8UD9z5
|
||||
3eDmB9cmQodDED9qSYK8cX9iOSP5tQFIKB1dXHQWwr/SxqIST6TLcDwtHSaYDBXJ
|
||||
3+oU9+wLdt+gGFeN+x4ka7mO4j1pGBa0j1qcHbJSd9jGb0TeUUtet42V44me6lp0
|
||||
DoogyX13uHrwf8kCzeJtKlUMbDM+65GOzrKmlwIDAQABAoIBAF6vFMp+lz4RteSh
|
||||
Wm8m1FGAVwWVUpStOlcGClynFpTi0L88XYT3K7UMStQSttBDlqRv0ysdZF+ia+lj
|
||||
bbKLdvHyFp8CJzX/AB4YZgyJlKzEYFtuBhbaHZu5hIMyU5W+OELSTCznV0p7w4C8
|
||||
CGLLr+FTdhfCo1QU9NJn6fa9s2/XRdSClBBalAHYs0ZS7ZckaF/sPiC/VapfBMet
|
||||
qjJXNYiO6pXYriGWKF9zdAMfk2CM0BVWbnwQZkMSEQirrTcJwm3ezyloXCv2nywK
|
||||
/VzbUT1HJVyzo5oAwTd0MwDc2oEMiFzlfO028zY4LDltpia+SyWvFi5NaIqzFESc
|
||||
yLgJacECgYEA3jvH+ZQHQf42Md8TCciokaYvwWIKJdk4WRjbvE5cBZekyXAm7/3b
|
||||
/1VFDKsy2RPlfmfHP3wy9rlnjzsRveB5qaclgS8aI67AYsWd/yRgfRatl7Ve9bHl
|
||||
LY6VM5L/DZTxykcqivwjc77XoDuBfUKs6tyuSLQku+FOTbLtNYlUCHECgYEA6nkR
|
||||
lkXufyLmDhNb3093RsYvPcs1kGaIIGTnz3cxWNh485DgsyLBuYQ5ugupQkzM8YSt
|
||||
ohDTmVpggqjlXQxCg0Zw8gkEV0v8KsLGjn1CuTJg/mBArXlelq1FEeRAYC9/YfOz
|
||||
ocXegHV7wDKKtcraNZFsEc7Z0LwbC9wtzSFG44cCgYASkMX1CLPOhJE8e1lY0OWc
|
||||
PVjx++HDJbF6aAQ7aARyBygiF/d4xylw3EvHcinuTqY2eC8CE7siN3z6T0H9Ldqc
|
||||
HLWaZDf30SqLVd0MKprQ+GsKKIHFXtY5hxbZ1ybtmIrWjjl0oPnJOqFC5pW7xC0z
|
||||
9bmtozcKZxkmjpMYjN9zUQKBgQCqV6KLRerqunPgLfhE1/qTlE+l2QflDFhBEI3I
|
||||
j5NuNHZKnSphehK7sHAv1WD2Jc2OeRGb+BWCB8Ktqf5YBxwbOwW7EQnyUeW1OyP9
|
||||
SMs8uHj21P6oCNDLLr5LLUQHnPoyM1aBZLstICzziMR1JhY5bJjSpzBfEQmlKCSu
|
||||
LkrN6QKBgQCRXrBJRUxeJj7wCnCSq0Clf9NhCpQnwo4bEx8sKlj8K8ku8MvwQwoM
|
||||
3KfWc7bOl6A2/mM/k4yoHtBMM9X9xqYtsgeFhxuiWBcfTmTxWh73LQ48Kgbrgodt
|
||||
6yTccnjr7OtBidD85c6lgjAUgcL43QY8mlw0OhzXAZ2R5HWFp4ht+w==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC9TCCAd+gAwIBAgIRAJ6IIisIZxL86oe3oeoAgWUwCwYJKoZIhvcNAQELMCYx
|
||||
ETAPBgNVBAoTCFF1aWNrVExTMREwDwYDVQQDEwhRdWlja1RMUzAeFw0xNjAxMjgw
|
||||
MDQyMzNaFw0xOTAxMTIwMDQyMzNaMBMxETAPBgNVBAoTCFF1aWNrVExTMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3IXUwqSdO2QTj2ET6fJPGe+KWVnt
|
||||
QCQQWjkWVpOz8L2A29BRvv9z6lYNf9sOM0Xb5IUAgoZ/s3U6LNYT/RWYFBfeo40r
|
||||
Xd/MNKAn0kFsSb6BIKmUwPqFeqc8wiPX6yY4SbF1sUTkCTkw3yFHg/AIlwmhpFH3
|
||||
9mAmV+x0kTzFR/78ZDD5CUNS59bbu+7UqB06YrJuVEwPY98YixSPXTcaKimsUe+K
|
||||
IY8FQ6yN6l27MK56wlj4hw2gYz+cyBUBCExCgYMQlOSg2ilH4qYyFvccSDUH7jTA
|
||||
NwpsIBfdoUVbI+j2ivn+ZGD614LtIStGgUu0mDDVxVOWnRvq/z7LMaa2jwIDAQAB
|
||||
ozUwMzAOBgNVHQ8BAf8EBAMCAKAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0T
|
||||
AQH/BAIwADALBgkqhkiG9w0BAQsDggEBAJq3JzTLrIWCF8rHLTTm1icE9PjOO0sV
|
||||
a1wrmdJ6NwRbJ66dLZ/4G/NZjVOnce9WFHYLFSEG+wx5YVUPuJXpJaSdy0h8F0Uw
|
||||
hiJwgeVsGg7vcf4G6mWHrsauDOhylnD31UtYPX1Ao/jcntyyf+gCQpY1J/B8l1yU
|
||||
LNOwvWLVLpZwZ4ehbKA/UnDXgA+3uHvpzl//cPe0cnt+Mhrgzk5mIMwVR6zCZw1G
|
||||
oVutAHpv2PXxRwTMu51J+QtSL2b2w3mGHxDLpmz8UdXOtkxdpmDT8kIOtX0T5yGL
|
||||
29F3fa81iZPs02GWjSGOfOzmCCvaA4C5KJvY/WulF7OOgwvrBpQwqTI=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA3IXUwqSdO2QTj2ET6fJPGe+KWVntQCQQWjkWVpOz8L2A29BR
|
||||
vv9z6lYNf9sOM0Xb5IUAgoZ/s3U6LNYT/RWYFBfeo40rXd/MNKAn0kFsSb6BIKmU
|
||||
wPqFeqc8wiPX6yY4SbF1sUTkCTkw3yFHg/AIlwmhpFH39mAmV+x0kTzFR/78ZDD5
|
||||
CUNS59bbu+7UqB06YrJuVEwPY98YixSPXTcaKimsUe+KIY8FQ6yN6l27MK56wlj4
|
||||
hw2gYz+cyBUBCExCgYMQlOSg2ilH4qYyFvccSDUH7jTANwpsIBfdoUVbI+j2ivn+
|
||||
ZGD614LtIStGgUu0mDDVxVOWnRvq/z7LMaa2jwIDAQABAoIBAD2tiNZv6DImSXo+
|
||||
sq0qQomEf/OBvWPFMnWppd/NK/TXa+UPHO4I0MjoDJqIEC6zCU+fC4d2St1MmlrT
|
||||
/X85vPFRw8mGwGxfHeRSLxEVj04I5GDYTWy0JQUrJUk/cTKp2/Bwm/RaylTyFAM0
|
||||
caYrSpvD69vjuTDFr7PDxM6iaqM53zK/vD8kCe81z+wN0UbAKsLlUOKztjH6SzL9
|
||||
uVOkekIT/j3L2xxyQhjmhfA3TuCP4uNK/+6/4ovl9Nj4pQsFomsCk4phgqy9SOm1
|
||||
4yufmVd8k7J3cppMlMPNc+7tqe2Xn593Y8QT95y3yhtkFECF70yBw64HMDDpA22p
|
||||
5b/JV9ECgYEA9H4RBXOwbdjcpCa9H3mFjHqUQCqNme1vOSGiflZh9KBCDKgdqugm
|
||||
KHpvAECADie0p6XRHpxRvufKnGFkJwedfeiKz51T+0dqgPxWncYT1TC+cAjOSzfM
|
||||
wBpUOcAyvTTviwGbg4bLanHo4remzCbcnRvHQX4YfPFCjT9GhsU+XEUCgYEA5ubz
|
||||
IlSu1wwFJpoO24ZykGUyqGUQXzR0NrXiLrpF0764qjmHyF8SPJPv1XegSxP/nUTz
|
||||
SjVfJ7wye/X9qlOpBY8mzy9qQMMKc1cQBV1yVW8IRZ7pMYQZO7qmrZD/DWTa5qWt
|
||||
pqSbIH2FKedELsKJA/SBtczKjspOdDKyh0UelsMCgYA7DyTfc0XAEy2hPXZb3wgC
|
||||
mi2rnlvcPf2rCFPvPsCkzf2GfynDehaVmpWrsuj8Al1iTezI/yvD+Mv5oJEH2JAT
|
||||
tROq+S8rOOIiTFJEBHAQBJlMCOSESPNdyD5mQOZAzEO9CWNejzYd/WwrL//Luut5
|
||||
zBcC3AngTIsuAYXw0j6xHQKBgQDamkAJep7k3W5q82OplgoUhpqFLtlnKSP1QBFZ
|
||||
J+U/6Mqv7jONEeUUEQL42H6bVd2kqUikMw9ZcSVikquLfBUDPFoDwOIZWg4k0IJM
|
||||
cgHyvGHad+5SgLva/oUawbGWnqtXvfc/U4vCINPXrimxE1/grLW4xp/mu8W24OCA
|
||||
jIG/PQKBgD/Apl+sfqiB/6ONBjjIswA4yFkEXHSZNpAgcPwhA+cO5D0afEWz2HIx
|
||||
VeOh5NjN1EL0hX8clFW4bfkK1Vr0kjvbMUXnBWaibUgpiVQl9O9WjaKQLZrp4sRu
|
||||
x2kJ07Qn6ri7f/lsqOELZwBy95iHWRdePptaAKkRGxJstHI7dgUt
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,21 +0,0 @@
|
|||
version: 0.1
|
||||
loglevel: debug
|
||||
storage:
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
filesystem:
|
||||
rootdirectory: /tmp/registry-dev
|
||||
http:
|
||||
addr: 0.0.0.0:5000
|
||||
tls:
|
||||
certificate: "/etc/docker/registry/localregistry.cert"
|
||||
key: "/etc/docker/registry/localregistry.key"
|
||||
compatibility:
|
||||
schema1:
|
||||
enabled: true
|
||||
auth:
|
||||
token:
|
||||
realm: "https://auth.localregistry:5556/token/"
|
||||
issuer: "registry-test"
|
||||
service: "registry-test"
|
||||
rootcertbundle: "/etc/docker/registry/tokenbundle.pem"
|
|
@ -1,38 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/distribution/registry/api/errcode"
|
||||
)
|
||||
|
||||
var (
|
||||
errGroup = "tokenserver"
|
||||
|
||||
// ErrorBadTokenOption is returned when a token parameter is invalid
|
||||
ErrorBadTokenOption = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
||||
Value: "BAD_TOKEN_OPTION",
|
||||
Message: "bad token option",
|
||||
Description: `This error may be returned when a request for a
|
||||
token contains an option which is not valid`,
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
})
|
||||
|
||||
// ErrorMissingRequiredField is returned when a required form field is missing
|
||||
ErrorMissingRequiredField = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
||||
Value: "MISSING_REQUIRED_FIELD",
|
||||
Message: "missing required field",
|
||||
Description: `This error may be returned when a request for a
|
||||
token does not contain a required form field`,
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
})
|
||||
|
||||
// ErrorUnsupportedValue is returned when a form field has an unsupported value
|
||||
ErrorUnsupportedValue = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
||||
Value: "UNSUPPORTED_VALUE",
|
||||
Message: "unsupported value",
|
||||
Description: `This error may be returned when a request for a
|
||||
token contains a form field with an unsupported value`,
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
})
|
||||
)
|
|
@ -1,26 +1,18 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
dcontext "github.com/docker/distribution/context"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/registry/api/errcode"
|
||||
"github.com/docker/distribution/registry/auth"
|
||||
_ "github.com/docker/distribution/registry/auth/htpasswd"
|
||||
"github.com/docker/libtrust"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
enforceRepoClass bool
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -49,8 +41,6 @@ func main() {
|
|||
flag.StringVar(&cert, "tlscert", "", "Certificate file for TLS")
|
||||
flag.StringVar(&certKey, "tlskey", "", "Certificate key for TLS")
|
||||
|
||||
flag.BoolVar(&enforceRepoClass, "enforce-class", false, "Enforce policy for single repository class")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if debug {
|
||||
|
@ -83,20 +73,15 @@ func main() {
|
|||
logrus.Fatalf("Error initializing access controller: %v", err)
|
||||
}
|
||||
|
||||
// TODO: Make configurable
|
||||
issuer.Expiration = 15 * time.Minute
|
||||
|
||||
ctx := dcontext.Background()
|
||||
ctx := context.Background()
|
||||
|
||||
ts := &tokenServer{
|
||||
issuer: issuer,
|
||||
accessController: ac,
|
||||
refreshCache: map[string]refreshToken{},
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.Path("/token/").Methods("GET").Handler(handlerWithContext(ctx, ts.getToken))
|
||||
router.Path("/token/").Methods("POST").Handler(handlerWithContext(ctx, ts.postToken))
|
||||
|
||||
if cert == "" {
|
||||
err = http.ListenAndServe(addr, router)
|
||||
|
@ -116,121 +101,38 @@ func main() {
|
|||
// request context from a base context.
|
||||
func handlerWithContext(ctx context.Context, handler func(context.Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := dcontext.WithRequest(ctx, r)
|
||||
logger := dcontext.GetRequestLogger(ctx)
|
||||
ctx = dcontext.WithLogger(ctx, logger)
|
||||
ctx := context.WithRequest(ctx, r)
|
||||
logger := context.GetRequestLogger(ctx)
|
||||
ctx = context.WithLogger(ctx, logger)
|
||||
|
||||
handler(ctx, w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func handleError(ctx context.Context, err error, w http.ResponseWriter) {
|
||||
ctx, w = dcontext.WithResponseWriter(ctx, w)
|
||||
ctx, w = context.WithResponseWriter(ctx, w)
|
||||
|
||||
if serveErr := errcode.ServeJSON(w, err); serveErr != nil {
|
||||
dcontext.GetResponseLogger(ctx).Errorf("error sending error response: %v", serveErr)
|
||||
context.GetResponseLogger(ctx).Errorf("error sending error response: %v", serveErr)
|
||||
return
|
||||
}
|
||||
|
||||
dcontext.GetResponseLogger(ctx).Info("application error")
|
||||
}
|
||||
|
||||
var refreshCharacters = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
|
||||
const refreshTokenLength = 15
|
||||
|
||||
func newRefreshToken() string {
|
||||
s := make([]rune, refreshTokenLength)
|
||||
for i := range s {
|
||||
s[i] = refreshCharacters[rand.Intn(len(refreshCharacters))]
|
||||
}
|
||||
return string(s)
|
||||
}
|
||||
|
||||
type refreshToken struct {
|
||||
subject string
|
||||
service string
|
||||
context.GetResponseLogger(ctx).Info("application error")
|
||||
}
|
||||
|
||||
type tokenServer struct {
|
||||
issuer *TokenIssuer
|
||||
accessController auth.AccessController
|
||||
refreshCache map[string]refreshToken
|
||||
}
|
||||
|
||||
type tokenResponse struct {
|
||||
Token string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token,omitempty"`
|
||||
ExpiresIn int `json:"expires_in,omitempty"`
|
||||
}
|
||||
|
||||
var repositoryClassCache = map[string]string{}
|
||||
|
||||
func filterAccessList(ctx context.Context, scope string, requestedAccessList []auth.Access) []auth.Access {
|
||||
if !strings.HasSuffix(scope, "/") {
|
||||
scope = scope + "/"
|
||||
}
|
||||
grantedAccessList := make([]auth.Access, 0, len(requestedAccessList))
|
||||
for _, access := range requestedAccessList {
|
||||
if access.Type == "repository" {
|
||||
if !strings.HasPrefix(access.Name, scope) {
|
||||
dcontext.GetLogger(ctx).Debugf("Resource scope not allowed: %s", access.Name)
|
||||
continue
|
||||
}
|
||||
if enforceRepoClass {
|
||||
if class, ok := repositoryClassCache[access.Name]; ok {
|
||||
if class != access.Class {
|
||||
dcontext.GetLogger(ctx).Debugf("Different repository class: %q, previously %q", access.Class, class)
|
||||
continue
|
||||
}
|
||||
} else if strings.EqualFold(access.Action, "push") {
|
||||
repositoryClassCache[access.Name] = access.Class
|
||||
}
|
||||
}
|
||||
} else if access.Type == "registry" {
|
||||
if access.Name != "catalog" {
|
||||
dcontext.GetLogger(ctx).Debugf("Unknown registry resource: %s", access.Name)
|
||||
continue
|
||||
}
|
||||
// TODO: Limit some actions to "admin" users
|
||||
} else {
|
||||
dcontext.GetLogger(ctx).Debugf("Skipping unsupported resource type: %s", access.Type)
|
||||
continue
|
||||
}
|
||||
grantedAccessList = append(grantedAccessList, access)
|
||||
}
|
||||
return grantedAccessList
|
||||
}
|
||||
|
||||
type acctSubject struct{}
|
||||
|
||||
func (acctSubject) String() string { return "acctSubject" }
|
||||
|
||||
type requestedAccess struct{}
|
||||
|
||||
func (requestedAccess) String() string { return "requestedAccess" }
|
||||
|
||||
type grantedAccess struct{}
|
||||
|
||||
func (grantedAccess) String() string { return "grantedAccess" }
|
||||
|
||||
// getToken handles authenticating the request and authorizing access to the
|
||||
// requested scopes.
|
||||
func (ts *tokenServer) getToken(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
dcontext.GetLogger(ctx).Info("getToken")
|
||||
context.GetLogger(ctx).Info("getToken")
|
||||
|
||||
params := r.URL.Query()
|
||||
service := params.Get("service")
|
||||
scopeSpecifiers := params["scope"]
|
||||
var offline bool
|
||||
if offlineStr := params.Get("offline_token"); offlineStr != "" {
|
||||
var err error
|
||||
offline, err = strconv.ParseBool(offlineStr)
|
||||
if err != nil {
|
||||
handleError(ctx, ErrorBadTokenOption.WithDetail(err), w)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
requestedAccessList := ResolveScopeSpecifiers(ctx, scopeSpecifiers)
|
||||
|
||||
|
@ -243,30 +145,43 @@ func (ts *tokenServer) getToken(ctx context.Context, w http.ResponseWriter, r *h
|
|||
}
|
||||
|
||||
// Get response context.
|
||||
ctx, w = dcontext.WithResponseWriter(ctx, w)
|
||||
ctx, w = context.WithResponseWriter(ctx, w)
|
||||
|
||||
challenge.SetHeaders(r, w)
|
||||
challenge.SetHeaders(w)
|
||||
handleError(ctx, errcode.ErrorCodeUnauthorized.WithDetail(challenge.Error()), w)
|
||||
|
||||
dcontext.GetResponseLogger(ctx).Info("get token authentication challenge")
|
||||
context.GetResponseLogger(ctx).Info("get token authentication challenge")
|
||||
|
||||
return
|
||||
}
|
||||
ctx = authorizedCtx
|
||||
|
||||
username := dcontext.GetStringValue(ctx, "auth.user.name")
|
||||
username := context.GetStringValue(ctx, "auth.user.name")
|
||||
|
||||
ctx = context.WithValue(ctx, acctSubject{}, username)
|
||||
ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx, acctSubject{}))
|
||||
ctx = context.WithValue(ctx, "acctSubject", username)
|
||||
ctx = context.WithLogger(ctx, context.GetLogger(ctx, "acctSubject"))
|
||||
|
||||
dcontext.GetLogger(ctx).Info("authenticated client")
|
||||
context.GetLogger(ctx).Info("authenticated client")
|
||||
|
||||
ctx = context.WithValue(ctx, requestedAccess{}, requestedAccessList)
|
||||
ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx, requestedAccess{}))
|
||||
ctx = context.WithValue(ctx, "requestedAccess", requestedAccessList)
|
||||
ctx = context.WithLogger(ctx, context.GetLogger(ctx, "requestedAccess"))
|
||||
|
||||
grantedAccessList := filterAccessList(ctx, username, requestedAccessList)
|
||||
ctx = context.WithValue(ctx, grantedAccess{}, grantedAccessList)
|
||||
ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx, grantedAccess{}))
|
||||
scopePrefix := username + "/"
|
||||
grantedAccessList := make([]auth.Access, 0, len(requestedAccessList))
|
||||
for _, access := range requestedAccessList {
|
||||
if access.Type != "repository" {
|
||||
context.GetLogger(ctx).Debugf("Skipping unsupported resource type: %s", access.Type)
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(access.Name, scopePrefix) {
|
||||
context.GetLogger(ctx).Debugf("Resource scope not allowed: %s", access.Name)
|
||||
continue
|
||||
}
|
||||
grantedAccessList = append(grantedAccessList, access)
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, "grantedAccess", grantedAccessList)
|
||||
ctx = context.WithLogger(ctx, context.GetLogger(ctx, "grantedAccess"))
|
||||
|
||||
token, err := ts.issuer.CreateJWT(username, service, grantedAccessList)
|
||||
if err != nil {
|
||||
|
@ -274,153 +189,13 @@ func (ts *tokenServer) getToken(ctx context.Context, w http.ResponseWriter, r *h
|
|||
return
|
||||
}
|
||||
|
||||
dcontext.GetLogger(ctx).Info("authorized client")
|
||||
context.GetLogger(ctx).Info("authorized client")
|
||||
|
||||
response := tokenResponse{
|
||||
Token: token,
|
||||
ExpiresIn: int(ts.issuer.Expiration.Seconds()),
|
||||
}
|
||||
|
||||
if offline {
|
||||
response.RefreshToken = newRefreshToken()
|
||||
ts.refreshCache[response.RefreshToken] = refreshToken{
|
||||
subject: username,
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
ctx, w = dcontext.WithResponseWriter(ctx, w)
|
||||
// Get response context.
|
||||
ctx, w = context.WithResponseWriter(ctx, w)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
json.NewEncoder(w).Encode(map[string]string{"token": token})
|
||||
|
||||
dcontext.GetResponseLogger(ctx).Info("get token complete")
|
||||
}
|
||||
|
||||
type postTokenResponse struct {
|
||||
Token string `json:"access_token"`
|
||||
Scope string `json:"scope,omitempty"`
|
||||
ExpiresIn int `json:"expires_in,omitempty"`
|
||||
IssuedAt string `json:"issued_at,omitempty"`
|
||||
RefreshToken string `json:"refresh_token,omitempty"`
|
||||
}
|
||||
|
||||
// postToken handles authenticating the request and authorizing access to the
|
||||
// requested scopes.
|
||||
func (ts *tokenServer) postToken(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
grantType := r.PostFormValue("grant_type")
|
||||
if grantType == "" {
|
||||
handleError(ctx, ErrorMissingRequiredField.WithDetail("missing grant_type value"), w)
|
||||
return
|
||||
}
|
||||
|
||||
service := r.PostFormValue("service")
|
||||
if service == "" {
|
||||
handleError(ctx, ErrorMissingRequiredField.WithDetail("missing service value"), w)
|
||||
return
|
||||
}
|
||||
|
||||
clientID := r.PostFormValue("client_id")
|
||||
if clientID == "" {
|
||||
handleError(ctx, ErrorMissingRequiredField.WithDetail("missing client_id value"), w)
|
||||
return
|
||||
}
|
||||
|
||||
var offline bool
|
||||
switch r.PostFormValue("access_type") {
|
||||
case "", "online":
|
||||
case "offline":
|
||||
offline = true
|
||||
default:
|
||||
handleError(ctx, ErrorUnsupportedValue.WithDetail("unknown access_type value"), w)
|
||||
return
|
||||
}
|
||||
|
||||
requestedAccessList := ResolveScopeList(ctx, r.PostFormValue("scope"))
|
||||
|
||||
var subject string
|
||||
var rToken string
|
||||
switch grantType {
|
||||
case "refresh_token":
|
||||
rToken = r.PostFormValue("refresh_token")
|
||||
if rToken == "" {
|
||||
handleError(ctx, ErrorUnsupportedValue.WithDetail("missing refresh_token value"), w)
|
||||
return
|
||||
}
|
||||
rt, ok := ts.refreshCache[rToken]
|
||||
if !ok || rt.service != service {
|
||||
handleError(ctx, errcode.ErrorCodeUnauthorized.WithDetail("invalid refresh token"), w)
|
||||
return
|
||||
}
|
||||
subject = rt.subject
|
||||
case "password":
|
||||
ca, ok := ts.accessController.(auth.CredentialAuthenticator)
|
||||
if !ok {
|
||||
handleError(ctx, ErrorUnsupportedValue.WithDetail("password grant type not supported"), w)
|
||||
return
|
||||
}
|
||||
subject = r.PostFormValue("username")
|
||||
if subject == "" {
|
||||
handleError(ctx, ErrorUnsupportedValue.WithDetail("missing username value"), w)
|
||||
return
|
||||
}
|
||||
password := r.PostFormValue("password")
|
||||
if password == "" {
|
||||
handleError(ctx, ErrorUnsupportedValue.WithDetail("missing password value"), w)
|
||||
return
|
||||
}
|
||||
if err := ca.AuthenticateUser(subject, password); err != nil {
|
||||
handleError(ctx, errcode.ErrorCodeUnauthorized.WithDetail("invalid credentials"), w)
|
||||
return
|
||||
}
|
||||
default:
|
||||
handleError(ctx, ErrorUnsupportedValue.WithDetail("unknown grant_type value"), w)
|
||||
return
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, acctSubject{}, subject)
|
||||
ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx, acctSubject{}))
|
||||
|
||||
dcontext.GetLogger(ctx).Info("authenticated client")
|
||||
|
||||
ctx = context.WithValue(ctx, requestedAccess{}, requestedAccessList)
|
||||
ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx, requestedAccess{}))
|
||||
|
||||
grantedAccessList := filterAccessList(ctx, subject, requestedAccessList)
|
||||
ctx = context.WithValue(ctx, grantedAccess{}, grantedAccessList)
|
||||
ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx, grantedAccess{}))
|
||||
|
||||
token, err := ts.issuer.CreateJWT(subject, service, grantedAccessList)
|
||||
if err != nil {
|
||||
handleError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
dcontext.GetLogger(ctx).Info("authorized client")
|
||||
|
||||
response := postTokenResponse{
|
||||
Token: token,
|
||||
ExpiresIn: int(ts.issuer.Expiration.Seconds()),
|
||||
IssuedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
Scope: ToScopeList(grantedAccessList),
|
||||
}
|
||||
|
||||
if offline {
|
||||
rToken = newRefreshToken()
|
||||
ts.refreshCache[rToken] = refreshToken{
|
||||
subject: subject,
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
if rToken != "" {
|
||||
response.RefreshToken = rToken
|
||||
}
|
||||
|
||||
ctx, w = dcontext.WithResponseWriter(ctx, w)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
|
||||
dcontext.GetResponseLogger(ctx).Info("post token complete")
|
||||
context.GetResponseLogger(ctx).Info("get token complete")
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
dcontext "github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/registry/auth"
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/docker/libtrust"
|
||||
|
@ -28,24 +26,18 @@ func ResolveScopeSpecifiers(ctx context.Context, scopeSpecs []string) []auth.Acc
|
|||
parts := strings.SplitN(scopeSpecifier, ":", 3)
|
||||
|
||||
if len(parts) != 3 {
|
||||
dcontext.GetLogger(ctx).Infof("ignoring unsupported scope format %s", scopeSpecifier)
|
||||
context.GetLogger(ctx).Infof("ignoring unsupported scope format %s", scopeSpecifier)
|
||||
continue
|
||||
}
|
||||
|
||||
resourceType, resourceName, actions := parts[0], parts[1], parts[2]
|
||||
|
||||
resourceType, resourceClass := splitResourceClass(resourceType)
|
||||
if resourceType == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Actions should be a comma-separated list of actions.
|
||||
for _, action := range strings.Split(actions, ",") {
|
||||
requestedAccess := auth.Access{
|
||||
Resource: auth.Resource{
|
||||
Type: resourceType,
|
||||
Class: resourceClass,
|
||||
Name: resourceName,
|
||||
Type: resourceType,
|
||||
Name: resourceName,
|
||||
},
|
||||
Action: action,
|
||||
}
|
||||
|
@ -63,43 +55,6 @@ func ResolveScopeSpecifiers(ctx context.Context, scopeSpecs []string) []auth.Acc
|
|||
return requestedAccessList
|
||||
}
|
||||
|
||||
var typeRegexp = regexp.MustCompile(`^([a-z0-9]+)(\([a-z0-9]+\))?$`)
|
||||
|
||||
func splitResourceClass(t string) (string, string) {
|
||||
matches := typeRegexp.FindStringSubmatch(t)
|
||||
if len(matches) < 2 {
|
||||
return "", ""
|
||||
}
|
||||
if len(matches) == 2 || len(matches[2]) < 2 {
|
||||
return matches[1], ""
|
||||
}
|
||||
return matches[1], matches[2][1 : len(matches[2])-1]
|
||||
}
|
||||
|
||||
// ResolveScopeList converts a scope list from a token request's
|
||||
// `scope` parameter into a list of standard access objects.
|
||||
func ResolveScopeList(ctx context.Context, scopeList string) []auth.Access {
|
||||
scopes := strings.Split(scopeList, " ")
|
||||
return ResolveScopeSpecifiers(ctx, scopes)
|
||||
}
|
||||
|
||||
func scopeString(a auth.Access) string {
|
||||
if a.Class != "" {
|
||||
return fmt.Sprintf("%s(%s):%s:%s", a.Type, a.Class, a.Name, a.Action)
|
||||
}
|
||||
return fmt.Sprintf("%s:%s:%s", a.Type, a.Name, a.Action)
|
||||
}
|
||||
|
||||
// ToScopeList converts a list of access to a
|
||||
// scope list string
|
||||
func ToScopeList(access []auth.Access) string {
|
||||
var s []string
|
||||
for _, a := range access {
|
||||
s = append(s, scopeString(a))
|
||||
}
|
||||
return strings.Join(s, ",")
|
||||
}
|
||||
|
||||
// TokenIssuer represents an issuer capable of generating JWT tokens
|
||||
type TokenIssuer struct {
|
||||
Issuer string
|
||||
|
@ -130,7 +85,6 @@ func (issuer *TokenIssuer) CreateJWT(subject string, audience string, grantedAcc
|
|||
|
||||
accessEntries = append(accessEntries, &token.ResourceActions{
|
||||
Type: resource.Type,
|
||||
Class: resource.Class,
|
||||
Name: resource.Name,
|
||||
Actions: actions,
|
||||
})
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/registry/auth"
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func TestCreateJWTSuccessWithEmptyACL(t *testing.T) {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pk, err := libtrust.FromCryptoPrivateKey(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tokenIssuer := TokenIssuer{
|
||||
Expiration: time.Duration(100),
|
||||
Issuer: "localhost",
|
||||
SigningKey: pk,
|
||||
}
|
||||
|
||||
grantedAccessList := make([]auth.Access, 0)
|
||||
token, err := tokenIssuer.CreateJWT("test", "test", grantedAccessList)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tokens := strings.Split(token, ".")
|
||||
|
||||
if len(token) == 0 {
|
||||
t.Fatal("token not generated.")
|
||||
}
|
||||
|
||||
json, err := decodeJWT(tokens[1])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !strings.Contains(json, "test") {
|
||||
t.Fatal("Valid token was not generated.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func decodeJWT(rawToken string) (string, error) {
|
||||
data, err := joseBase64Decode(rawToken)
|
||||
if err != nil {
|
||||
return "", errors.New("Error in Decoding base64 String")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func joseBase64Decode(s string) (string, error) {
|
||||
switch len(s) % 4 {
|
||||
case 0:
|
||||
case 2:
|
||||
s += "=="
|
||||
case 3:
|
||||
s += "="
|
||||
default:
|
||||
{
|
||||
return "", errors.New("Invalid base64 String")
|
||||
}
|
||||
}
|
||||
data, err := base64.StdEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return "", err //errors.New("Error in Decoding base64 String")
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
# Given a subpackage and the containing package, figures out which packages
|
||||
# need to be passed to `go test -coverpkg`: this includes all of the
|
||||
# subpackage's dependencies within the containing package, as well as the
|
||||
# subpackage itself.
|
||||
DEPENDENCIES="$(go list -f $'{{range $f := .Deps}}{{$f}}\n{{end}}' ${1} | grep ${2} | grep -v github.com/docker/distribution/vendor)"
|
||||
echo "${1} ${DEPENDENCIES}" | xargs echo -n | tr ' ' ','
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue