From ba15c690194043cd8363fcf45e5bc1c3faf934e6 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Wed, 21 May 2014 10:49:44 +0200 Subject: [PATCH 01/14] Packaging clean-up Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- .travis.yml | 8 +++----- MANIFEST.in | 3 ++- depends/docker-registry-core/.travis.yml | 4 ++-- depends/docker-registry-core/MANIFEST.in | 4 ++-- .../{tests => }/requirements-style.txt | 0 ...equirements-tests.txt => requirements-test.txt} | 0 depends/docker-registry-core/setup.cfg | 4 ---- depends/docker-registry-core/setup.py | 4 +--- depends/docker-registry-core/tox.ini | 4 ++-- requirements-style.txt | 1 + tests/requirements.txt => requirements-test.txt | 0 requirements.txt | 2 -- setup.cfg | 4 ---- setup.py | 14 ++++++++++++-- tests/requirements-tox.txt | 10 ---------- 15 files changed, 25 insertions(+), 37 deletions(-) rename depends/docker-registry-core/{tests => }/requirements-style.txt (100%) rename depends/docker-registry-core/{tests/requirements-tests.txt => requirements-test.txt} (100%) create mode 100644 requirements-style.txt rename tests/requirements.txt => requirements-test.txt (100%) delete mode 100644 tests/requirements-tox.txt diff --git a/.travis.yml b/.travis.yml index 1a4e78e5e..d44f8525e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,13 @@ python: install: ## This below should be separated when core lives elsewhere # Install core tests reqs - - pip install -rdepends/docker-registry-core/tests/requirements-tests.txt - - pip install -rdepends/docker-registry-core/tests/requirements-style.txt + - pip install -rdepends/docker-registry-core/requirements-test.txt + - pip install -rdepends/docker-registry-core/requirements-style.txt # Install core itself - pip install depends/docker-registry-core/ # Install our tests requirements, and ourselves - - pip install -rtests/requirements.txt + - pip install -rrequirements-test.txt - pip install . # XXX should run the core tests as well @@ -22,5 +22,3 @@ script: SETTINGS_FLAVOR=test DOCKER_REGISTRY_CONFIG=config_sample.yml flake8 . & before_install: - sudo apt-get update - sudo apt-get install libevent-dev liblzma-dev - -# build-essential python-dev diff --git a/MANIFEST.in b/MANIFEST.in index 6370dd3a0..d0ad254fa 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ include requirements.txt -include tests/requirements.txt +include requirements-test.txt +include requirements-style.txt include README.md include LICENSE diff --git a/depends/docker-registry-core/.travis.yml b/depends/docker-registry-core/.travis.yml index c35dec7f8..15fd33a2a 100644 --- a/depends/docker-registry-core/.travis.yml +++ b/depends/docker-registry-core/.travis.yml @@ -7,8 +7,8 @@ python: - "3.4" install: - - pip install -rtests/requirements-test.txt - - pip install -rtests/requirements-style.txt + - pip install -rrequirements-test.txt + - pip install -rrequirements-style.txt - pip install . script: flake8 . && python setup.py nosetests diff --git a/depends/docker-registry-core/MANIFEST.in b/depends/docker-registry-core/MANIFEST.in index 58b49cdae..d0ad254fa 100644 --- a/depends/docker-registry-core/MANIFEST.in +++ b/depends/docker-registry-core/MANIFEST.in @@ -1,5 +1,5 @@ include requirements.txt -include tests/requirements-tests.txt -include tests/requirements-style.txt +include requirements-test.txt +include requirements-style.txt include README.md include LICENSE diff --git a/depends/docker-registry-core/tests/requirements-style.txt b/depends/docker-registry-core/requirements-style.txt similarity index 100% rename from depends/docker-registry-core/tests/requirements-style.txt rename to depends/docker-registry-core/requirements-style.txt diff --git a/depends/docker-registry-core/tests/requirements-tests.txt b/depends/docker-registry-core/requirements-test.txt similarity index 100% rename from depends/docker-registry-core/tests/requirements-tests.txt rename to depends/docker-registry-core/requirements-test.txt diff --git a/depends/docker-registry-core/setup.cfg b/depends/docker-registry-core/setup.cfg index 636a27fbd..f81003cb5 100644 --- a/depends/docker-registry-core/setup.cfg +++ b/depends/docker-registry-core/setup.cfg @@ -7,7 +7,3 @@ cover-package=docker_registry cover-erase=1 cover-html=1 cover-html-dir=reports - -[flake8] -ignore = H304 -exclude = .tox,.git,*.egg,build diff --git a/depends/docker-registry-core/setup.py b/depends/docker-registry-core/setup.py index 60596e048..045996dbb 100644 --- a/depends/docker-registry-core/setup.py +++ b/depends/docker-registry-core/setup.py @@ -72,8 +72,6 @@ 'docker_registry.drivers', 'docker_registry.testing'], install_requires=requirements, zip_safe=True, - tests_require="%s\n%s" % ( - open('./tests/requirements-tests.txt').read(), - open('./tests/requirements-style.txt').read()), + tests_require=open('./requirements-test.txt').read(), test_suite='nose.collector' ) diff --git a/depends/docker-registry-core/tox.ini b/depends/docker-registry-core/tox.ini index 318a4d573..d548c5e65 100644 --- a/depends/docker-registry-core/tox.ini +++ b/depends/docker-registry-core/tox.ini @@ -10,9 +10,9 @@ ignore = H304 [testenv] deps = -rrequirements.txt - -rtests/requirements-tests.txt + -rrequirements-test.txt commands = python setup.py nosetests [testenv:flake8] -deps = -rtests/requirements-style.txt +deps = -rrequirements-style.txt commands = flake8 {toxinidir} diff --git a/requirements-style.txt b/requirements-style.txt new file mode 100644 index 000000000..0f312dbe0 --- /dev/null +++ b/requirements-style.txt @@ -0,0 +1 @@ +hacking==0.8.1 diff --git a/tests/requirements.txt b/requirements-test.txt similarity index 100% rename from tests/requirements.txt rename to requirements-test.txt diff --git a/requirements.txt b/requirements.txt index e658343d6..fab877893 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,4 @@ PyYAML==3.11 blinker==1.3 gevent==1.0.1 sqlalchemy==0.9.4 -bugsnag==2.0.1 gunicorn==18.0 -docker-registry-core>=1,<2 diff --git a/setup.cfg b/setup.cfg index bd4fb3e33..43fe31b01 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,7 +8,3 @@ cover-erase=1 cover-html=1 cover-html-dir=reports ignore-files=(?:workflow|base)[.]py - -[flake8] -ignore = H102,H304 -exclude = .tox,.git,*.egg,build diff --git a/setup.py b/setup.py index 6edecdd82..1a89a9f0a 100644 --- a/setup.py +++ b/setup.py @@ -14,11 +14,17 @@ ver = sys.version_info if ver[0] == 2: + # Python 2 requires lzma backport requirements.insert(0, 'backports.lzma>=0.0.2') if ver[1] <= 6: + # Python 2.6 requires additional libraries requirements.insert(0, 'argparse>=1.2.1') requirements.insert(0, 'importlib>=1.0.3') +# Require core (the reason this is out of req.txt is to ease tox) +requirements.insert(0, 'docker-registry-core>=1,<2') + +# Explicit packages list to avoid setup_tools funkyness packages = ['docker_registry', 'docker_registry.drivers', 'docker_registry.lib', @@ -53,6 +59,10 @@ ] }, zip_safe=False, - tests_require=open('./tests/requirements.txt').read(), - test_suite='nose.collector' + test_suite='nose.collector', + install_requires=requirements, + tests_require=open('./requirements-test.txt').read(), + extras_require={ + 'bugsnag': ['bugsnag==2.0.1'] + } ) diff --git a/tests/requirements-tox.txt b/tests/requirements-tox.txt deleted file mode 100644 index 209d05d97..000000000 --- a/tests/requirements-tox.txt +++ /dev/null @@ -1,10 +0,0 @@ -Flask==0.10.1 -Flask-cors==1.3.0 -requests==2.3.0 -rsa==3.1.4 -PyYAML==3.11 -blinker==1.3 -gevent==1.0.1 -sqlalchemy==0.9.4 -bugsnag==2.0.1 -gunicorn==18.0 From 9924d77473e7b749bede6ab88c8aab3efe5c5ce5 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Wed, 21 May 2014 10:50:20 +0200 Subject: [PATCH 02/14] Packaging cleanup Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- tox.ini | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/tox.ini b/tox.ini index b1986cf81..b64fe0224 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,4 @@ -# py26 support: .format calls to cleanup in lib/index/db -# py34 support: upgrade flask required +# py34 support: flask is borked [tox] envlist = flake8, py26, py27 @@ -7,11 +6,11 @@ envlist = flake8, py26, py27 # skipsdist = True [flake8] -ignore = H102,H304 -exclude = .tox,.git,*.egg,build +ignore = H102,H304 +exclude = .tox,.git,*.egg,build [testenv] -# XXX cryptography, clang, latest OSX, drugs and rock and roll: +# XXX clang, latest OSX: # http://bruteforce.gr/bypassing-clang-error-unknown-argument.html # XXX you might also need extra includes (for lzma-dev / xz) if you are on OSX # XXX and you might also need extra linkage (for gevent), same reason @@ -26,26 +25,15 @@ setenv = ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-futu install_command = pip install --egg {opts} {packages} # Link manually to docker-registry-core so that tests runs the local copy deps = ./depends/docker-registry-core/ - -rtests/requirements-tox.txt - -rtests/requirements.txt - + -rrequirements-test.txt commands = python setup.py nosetests -#commands = nosetests -w tests -# commands = nosetests -w tests --ignore-files=workflow.py --ignore-files=base.py --with-coverage --cover-package=docker_registry.lib,docker_registry.drivers,docker_registry.storage --cover-inclusive --cover-min-percentage=40 --cover-erase --cover-html --cover-html-dir=reports - [testenv:flake8] # XXX Like all openstack packages, hacking can't be installed as an egg # so we need a special stance for flake8 env (that will break namespaces, # but we don't care because flake8 is not running the code) install_command = pip install {opts} {packages} deps = ./depends/docker-registry-core/ - hacking==0.8.1 -commands = flake8 {toxinidir} - + -rrequirements-style.txt +commands = flake8 . -# To be ported -#gunicorn==18.0 -#python-glanceclient==0.10.0 -#python-keystoneclient==0.3.1 -#gcs-oauth2-boto-plugin>=1.3 From ef7bb14d46c7f3696e733b36fba91963ea48bb67 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Wed, 21 May 2014 11:20:20 +0200 Subject: [PATCH 03/14] More packaging cleanup + version and package metadata is now centralized in lib/__init__.py Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- .dotcloudignore | 2 +- .gitignore | 3 +- AUTHORS | 1 + CHANGELOG.md | 1 + Dockerfile | 2 +- README.md | 11 +++++-- build.sh | 2 +- docker_registry/app.py | 8 ++--- docker_registry/lib/__init__.py | 18 ++++++++++++ setup.py | 52 ++++++++++++++++++++------------- 10 files changed, 69 insertions(+), 31 deletions(-) diff --git a/.dotcloudignore b/.dotcloudignore index 9e103b3f0..57c9fadf0 100644 --- a/.dotcloudignore +++ b/.dotcloudignore @@ -1,4 +1,4 @@ contrib .tox reports -test +tests diff --git a/.gitignore b/.gitignore index 59c8fa9cc..45b9a7065 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,7 @@ eggs Vagrantfile .vagrant -docker-registry-core.sublime-workspace - *tmp +*.sublime-workspace *.sublime-project diff --git a/AUTHORS b/AUTHORS index 00b460413..c25e34299 100644 --- a/AUTHORS +++ b/AUTHORS @@ -46,6 +46,7 @@ Ken Cochrane Kevin Clark Leon Xiang Lucas Clemente +Mangled Deutz Marc Tamsky Marek Goldmann Mario Rodas diff --git a/CHANGELOG.md b/CHANGELOG.md index ab945e122..cd9a0403d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Major architecture rehaul, with potentially breaking changes: * largely enhanced configuration mechanism (setup-configs.sh is no more) * cookies are no longer used * CORS is now enabled on a number of endpoints + * extras requirements * [BUGFIX] unicode issues. Depending on the storage driver you are using, you may encounter unicode issues on already published content (likely garbled content). * [BUGFIX] content-length fix for bytes ranges diff --git a/Dockerfile b/Dockerfile index f17162154..040bd7408 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,7 @@ add ./config/boto.cfg /etc/boto.cfg run pip install /docker-registry/depends/docker-registry-core # Install registry -run pip install /docker-registry/ +run pip install file:///docker-registry#egg=docker-registry[bugsnag] env DOCKER_REGISTRY_CONFIG /docker-registry/config/config_sample.yml env SETTINGS_FLAVOR dev diff --git a/README.md b/README.md index e4883647d..3d2d6ac2f 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ When using the `config_sample.yml`, you can pass all options through as environm *non*-Amazon S3-compliant object store, in one of the boto config files' `[Credentials]` section, set `boto_host`, `boto_port` as appropriate for the service you are using. -1. `bugsnag`: The bugsnag API key +1. `bugsnag`: The bugsnag API key (note that if you don't use the official docker container, you need to install the registry with bugsnag enabled: `pip install docker-registry[bugsnag]`) ### Authentication options @@ -404,6 +404,13 @@ Then install the Registry app: sudo pip install docker-registry ``` +If you need extra requirements, like bugsnag, specify them: + +``` +sudo pip install docker-registry[bugsnag] +``` + + (or clone the repository and `pip install .`) #### On Red Hat-based systems: @@ -420,7 +427,7 @@ should not require the additional repositories. Then install the Registry app: ``` -sudo python-pip install docker-registry +sudo python-pip install docker-registry[bugsnag] ``` (or clone the repository and `pip install .`) diff --git a/build.sh b/build.sh index 866024333..6c6db33a3 100755 --- a/build.sh +++ b/build.sh @@ -7,7 +7,7 @@ cd $SERVICE_APPROOT . ~/env/bin/activate pip install --download-cache=~/.pip-cache ./depends/docker-registry-core || exit 1 -pip install --download-cache=~/.pip-cache . || exit 1 +pip install --download-cache=~/.pip-cache file://`pwd`#egg=docker-registry[bugsnag] || exit 1 cp -R * ~/ diff --git a/docker_registry/app.py b/docker_registry/app.py index f5beb6a4d..6c3a883ca 100644 --- a/docker_registry/app.py +++ b/docker_registry/app.py @@ -13,9 +13,9 @@ import flask from . import toolkit +from .lib import __version__ from .lib import config -VERSION = '0.7.0' app = flask.Flask('docker-registry') cfg = config.load() loglevel = getattr(logging, cfg.get('loglevel', 'INFO').upper()) @@ -34,12 +34,12 @@ def ping(): @app.route('/') def root(): return toolkit.response('docker-registry server ({0}) (v{1})' - .format(cfg.flavor, VERSION)) + .format(cfg.flavor, __version__)) @app.after_request def after_request(response): - response.headers['X-Docker-Registry-Version'] = VERSION + response.headers['X-Docker-Registry-Version'] = __version__ response.headers['X-Docker-Registry-Config'] = cfg.flavor return response @@ -75,7 +75,7 @@ def init(): project_root=root_path, release_stage=cfg.flavor, notify_release_stages=[cfg.flavor], - app_version=VERSION + app_version=__version__ ) bugsnag.flask.handle_exceptions(app) diff --git a/docker_registry/lib/__init__.py b/docker_registry/lib/__init__.py index e69de29bb..12b2d3b5b 100644 --- a/docker_registry/lib/__init__.py +++ b/docker_registry/lib/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +__author__ = 'Docker Registry Contributors' +__copyright__ = '{{driver.copyright}}' +__credits__ = [] + +__license__ = 'Apache 2.0' +__version__ = '0.7.0' +__maintainer__ = __author__ +__email__ = 'docker-dev@googlegroups.com' +__status__ = 'Production' + +__title__ = 'docker-registry' +__build__ = 0x000000 + +__url__ = 'https://github.com/dotcloud/docker-registry' +__description__ = 'Registry server for Docker' +__download__ = 'https://github.com/dotcloud/docker-registry/archive/master.zip' diff --git a/setup.py b/setup.py index 1a89a9f0a..eb0f682d5 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,8 @@ import sys +import docker_registry.lib as lib + requirements_txt = open('./requirements.txt') requirements = [line for line in requirements_txt] @@ -31,33 +33,43 @@ 'docker_registry.storage', 'docker_registry.lib.index'] +namespaces = ['docker_registry', 'docker_registry.drivers'] + +package_data = {'docker_registry': ['../config/*']} + setuptools.setup( - name='docker-registry', - # TODO: Load the version programatically, which is currently available in - # docker_registry.app. This is not possible yet because importing - # causes config files to be loaded - version='0.7.0', - description='Registry server for Docker', - long_description=open('README.md').read(), - namespace_packages=['docker_registry', 'docker_registry.drivers'], + name=lib.__title__, + version=lib.__version__, + author=lib.__author__, + author_email=lib.__email__, + maintainer=lib.__maintainer__, + maintainer_email=lib.__email__, + url=lib.__url__, + description=lib.__description__, + download_url=lib.__download__, + long_description=open('./README.md').read(), + namespace_packages=namespaces, packages=packages, - license=open('LICENSE').read(), - author='Docker Registry Contributors', - author_email='docker-dev@googlegroups.com', - url='https://github.com/dotcloud/docker-registry', - install_requires=requirements, - classifiers=( - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - ), - platforms=['Independent'], - package_data={'docker_registry': ['../config/*']}, + package_data=package_data, entry_points={ 'console_scripts': [ 'docker-registry = docker_registry.run:run_gunicorn' ] }, + + classifiers=['Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + # 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + # 'Programming Language :: Python :: 3.2', + # 'Programming Language :: Python :: 3.3', + # 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: Implementation :: CPython', + 'Operating System :: OS Independent', + 'Topic :: Utilities', + 'License :: OSI Approved :: Apache Software License'], + platforms=['Independent'], + license=open('./LICENSE').read(), zip_safe=False, test_suite='nose.collector', install_requires=requirements, From 73f7bb53fff1c23d68abae43a0f0ac637a8e7d6d Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Wed, 21 May 2014 11:26:32 +0200 Subject: [PATCH 04/14] More cleanup Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- CONTRIBUTE.md | 4 ++-- .../docker-registry-core/docker_registry/core/driver.py | 7 ++++--- requirements.txt | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md index 98cd3ec3f..50f8a6c39 100644 --- a/CONTRIBUTE.md +++ b/CONTRIBUTE.md @@ -2,9 +2,9 @@ ## Bare minimum -You need `git`, `pip` and `tox`. +System-wide, you need `git` and `pip`. You also need (`pip`) `tox`. -You might need `nose`, `coverage` and `flake`. +You optionally need (recommended, `pip`) `nose`, `coverage` and `flake`. ## Architecture diff --git a/depends/docker-registry-core/docker_registry/core/driver.py b/depends/docker-registry-core/docker_registry/core/driver.py index f3947b03d..b73c83ebb 100644 --- a/depends/docker-registry-core/docker_registry/core/driver.py +++ b/depends/docker-registry-core/docker_registry/core/driver.py @@ -232,13 +232,14 @@ def fetch(name): module = __import__('docker_registry.drivers.%s' % name, globals(), locals(), ['Storage'], 0) # noqa logger.debug("Will return docker-registry.drivers.%s.Storage" % name) - except ImportError: + except ImportError as e: + logger.warn("Got exception: %s" % e) raise NotImplementedError( """You requested storage driver docker_registry.drivers.%s which is not installed. Try `pip install docker-registry-driver-%s` or check your configuration. The following are currently -available on your system: %s""" - % (name, name, available()) +available on your system: %s. Exception was: %s""" + % (name, name, available(), e) ) module.Storage.scheme = name return module.Storage diff --git a/requirements.txt b/requirements.txt index fab877893..fd73ba355 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,9 @@ Flask==0.10.1 Flask-cors==1.3.0 requests==2.3.0 -rsa==3.1.4 PyYAML==3.11 blinker==1.3 gevent==1.0.1 sqlalchemy==0.9.4 gunicorn==18.0 +rsa==3.1.4 From 27fe9d2ebe064767dce59e5efd141dbef56872ac Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Thu, 22 May 2014 21:21:55 +0200 Subject: [PATCH 05/14] Cleanup Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- .../docker-registry-core/docker_registry/core/__init__.py | 2 +- depends/docker-registry-core/docker_registry/core/driver.py | 3 +++ depends/docker-registry-core/setup.py | 5 +++-- depends/docker-registry-core/tests/test_driver.py | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/depends/docker-registry-core/docker_registry/core/__init__.py b/depends/docker-registry-core/docker_registry/core/__init__.py index d4633f688..50c1fc3fa 100644 --- a/depends/docker-registry-core/docker_registry/core/__init__.py +++ b/depends/docker-registry-core/docker_registry/core/__init__.py @@ -39,7 +39,7 @@ __credits__ = [] __license__ = 'Apache 2.0' -__version__ = '1.0.6' +__version__ = '1.0.7' __maintainer__ = 'Docker' __email__ = 'dev@docker.com' __status__ = 'Production' diff --git a/depends/docker-registry-core/docker_registry/core/driver.py b/depends/docker-registry-core/docker_registry/core/driver.py index b73c83ebb..e8ed47619 100644 --- a/depends/docker-registry-core/docker_registry/core/driver.py +++ b/depends/docker-registry-core/docker_registry/core/driver.py @@ -63,6 +63,9 @@ class Base(object): # By default no storage plugin supports it supports_bytes_range = False + def __init__(self, path=None, config=None): + pass + # FIXME(samalba): Move all path resolver in each module (out of the base) def images_list_path(self, namespace, repository): repository_path = self.repository_path( diff --git a/depends/docker-registry-core/setup.py b/depends/docker-registry-core/setup.py index 045996dbb..ebb721e7c 100644 --- a/depends/docker-registry-core/setup.py +++ b/depends/docker-registry-core/setup.py @@ -22,7 +22,7 @@ import sys -from docker_registry import core # noqa +import docker_registry.core as core if sys.version_info < (2, 6): raise Exception("Docker registry requires Python 2.6 or higher.") @@ -45,7 +45,8 @@ author_email=core.__email__, maintainer=core.__maintainer__, maintainer_email=core.__email__, - url='https://github.com/dotclout/docker-registry', + keywords="docker registry core", + url='https://github.com/dotcloud/docker-registry', description="Docker registry core package", long_description=open('./README.md').read(), # download_url=d, diff --git a/depends/docker-registry-core/tests/test_driver.py b/depends/docker-registry-core/tests/test_driver.py index 1ea3e7ec5..d5674c37b 100644 --- a/depends/docker-registry-core/tests/test_driver.py +++ b/depends/docker-registry-core/tests/test_driver.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from docker_registry import testing +import docker_registry.testing as testing class TestQueryDumb(testing.Query): From ab250234b5ceb2a31d67a54d4fbd16e70bdfcdf3 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Fri, 23 May 2014 12:15:34 +0200 Subject: [PATCH 06/14] Fix workflow test Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- tests/workflow.py | 160 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 129 insertions(+), 31 deletions(-) diff --git a/tests/workflow.py b/tests/workflow.py index 1574e422f..912e3c411 100644 --- a/tests/workflow.py +++ b/tests/workflow.py @@ -13,13 +13,68 @@ import base +import colorama +colorama.init() + from docker_registry.core import compat json = compat.json StringIO = compat.StringIO +import time + cfg = config.load() -ua = 'docker/1.0.0 registry test pretending to be docker' +ua = 'docker/0.11 registry test pretending to be docker' + + +def control(resp, method, data, start, end): + print('----------------------------') + print('%sConsumed: %s - %s' % (colorama.Fore.RED, method, resp.url)) + print('%sTime: %s' % (colorama.Fore.RED, end - start)) + print(colorama.Fore.RESET) + print(resp.status_code) + for i in resp.headers.keys(): + print('%s: %s' % (i, resp.headers[i])) + print('----------------------------') + try: + print(data[:500]) + except Exception: + pass + print('----------------------------') + print(resp.content[:500]) + print('----------------------------') + +p = requests.put +g = requests.get +d = requests.delete + + +def pp(*args, **kwargs): + start = time.time() + ret = p(*args, **kwargs) + end = time.time() + control(ret, 'PUT', kwargs["data"], start, end) + return ret + + +def gg(*args, **kwargs): + start = time.time() + ret = g(*args, **kwargs) + end = time.time() + control(ret, 'GET', None, start, end) + return ret + + +def dd(*args, **kwargs): + start = time.time() + ret = d(*args, **kwargs) + end = time.time() + control(ret, 'DEL', None, start, end) + return ret + +requests.put = pp +requests.get = gg +requests.delete = dd class TestWorkflow(base.TestCase): @@ -34,7 +89,7 @@ class TestWorkflow(base.TestCase): 'https://indexstaging-docker.dotcloud.com') # export DOCKER_CREDS="login:password" user_credentials = os.environ['DOCKER_CREDS'].split(':') - cookies = None + # cookies = None def generate_chunk(self, data): bufsize = 1024 @@ -46,12 +101,13 @@ def generate_chunk(self, data): yield buf io.close() - def update_cookies(self, response): - cookies = response.cookies - if cookies: - self.cookies = cookies + # def update_cookies(self, response): + # cookies = response.cookies + # if cookies: + # self.cookies = cookies def upload_image(self, image_id, parent_id, token): + # XXX revert layer = self.gen_random_string(7 * 1024 * 1024) json_obj = { 'id': image_id @@ -68,26 +124,37 @@ def upload_image(self, image_id, parent_id, token): headers={'Authorization': 'Token ' + token, 'User-Agent': ua, 'X-Docker-Checksum': layer_checksum}, - cookies=self.cookies) + ) + self.assertEqual(resp.status_code, 200, resp.text) - self.update_cookies(resp) + # self.update_cookies(resp) resp = requests.put('{0}/v1/images/{1}/layer'.format( self.registry_endpoint, image_id), data=self.generate_chunk(layer), headers={'Authorization': 'Token ' + token, 'User-Agent': ua}, - cookies=self.cookies) + ) + + resp = requests.put('{0}/v1/images/{1}/checksum'.format( + self.registry_endpoint, image_id), + data={}, + headers={'Authorization': 'Token ' + token, + 'X-Docker-Checksum-Payload': layer_checksum, + 'User-Agent': ua} + ) + self.assertEqual(resp.status_code, 200, resp.text) - self.update_cookies(resp) + # self.update_cookies(resp) return {'id': image_id, 'checksum': layer_checksum} def update_tag(self, namespace, repos, image_id, tag_name): resp = requests.put('{0}/v1/repositories/{1}/{2}/tags/{3}'.format( self.registry_endpoint, namespace, repos, tag_name), data=json.dumps(image_id), - cookies=self.cookies) + ) + self.assertEqual(resp.status_code, 200, resp.text) - self.update_cookies(resp) + # self.update_cookies(resp) def docker_push(self): # Test Push @@ -106,11 +173,11 @@ def docker_push(self): 'User-Agent': ua}, data=images_json) self.assertEqual(resp.status_code, 200, resp.text) - token = resp.headers.get('x-docker-token') + self.token = resp.headers.get('x-docker-token') # Docker -> Registry images_json = [] - images_json.append(self.upload_image(parent_id, None, token)) - images_json.append(self.upload_image(image_id, parent_id, token)) + images_json.append(self.upload_image(parent_id, None, self.token)) + images_json.append(self.upload_image(image_id, parent_id, self.token)) # Updating the tags does not need a token, it will use the Cookie self.update_tag(namespace, repos, image_id, 'latest') # Docker -> Index @@ -127,41 +194,66 @@ def fetch_image(self, image_id): """Return image json metadata, checksum and its blob.""" resp = requests.get('{0}/v1/images/{1}/json'.format( self.registry_endpoint, image_id), - cookies=self.cookies) + ) + self.assertEqual(resp.status_code, 200, resp.text) + + resp = requests.get('{0}/v1/images/{1}/json'.format( + self.registry_endpoint, image_id), + headers={'Authorization': 'Token ' + self.token} + ) self.assertEqual(resp.status_code, 200, resp.text) - self.update_cookies(resp) + + # self.update_cookies(resp) json_data = resp.text - checksum = resp.headers['x-docker-checksum'] + checksum = resp.headers['x-docker-payload-checksum'] + resp = requests.get('{0}/v1/images/{1}/layer'.format( self.registry_endpoint, image_id), - cookies=self.cookies) + ) self.assertEqual(resp.status_code, 200, resp.text) - self.update_cookies(resp) + + resp = requests.get('{0}/v1/images/{1}/layer'.format( + self.registry_endpoint, image_id), + headers={'Authorization': 'Token ' + self.token} + ) + self.assertEqual(resp.status_code, 200, resp.text) + # self.update_cookies(resp) return (json_data, checksum, resp.text) def docker_pull(self, namespace, repos): # Test pull # Docker -> Index + + resp = requests.get('{0}/v1/repositories/{1}/{2}/images'.format( + self.index_endpoint, namespace, repos),) + self.assertEqual(resp.status_code, 200) + resp = requests.get('{0}/v1/repositories/{1}/{2}/images'.format( self.index_endpoint, namespace, repos), auth=tuple(self.user_credentials), headers={'X-Docker-Token': 'true'}) self.assertEqual(resp.status_code, 200) - token = resp.headers.get('x-docker-token') + self.token = resp.headers.get('x-docker-token') # Here we should use the 'X-Endpoints' returned in a real environment # Docker -> Registry resp = requests.get('{0}/v1/repositories/{1}/{2}/tags/latest'.format( self.registry_endpoint, namespace, repos), - headers={'Authorization': 'Token ' + token}) + headers={'Authorization': 'Token ' + self.token}) self.assertEqual(resp.status_code, 200, resp.text) - self.cookies = resp.cookies + + resp = requests.get('{0}/v1/repositories/{1}/{2}/tags/latest'.format( + self.registry_endpoint, namespace, repos), + ) + self.assertEqual(resp.status_code, 200, resp.text) + + # self.cookies = resp.cookies # Docker -> Registry # Note(dmp): unicode patch XXX not applied assume requests does the job image_id = json.loads(resp.text) resp = requests.get('{0}/v1/images/{1}/ancestry'.format( self.registry_endpoint, image_id), - cookies=self.cookies) - self.update_cookies(resp) + ) + # self.update_cookies(resp) self.assertEqual(resp.status_code, 200, resp.text) # Note(dmp): unicode patch XXX not applied assume requests does the job ancestry = json.loads(resp.text) @@ -177,14 +269,20 @@ def docker_pull(self, namespace, repos): tmpfile.close() self.assertEqual(checksum, computed_checksum) # Remove the repository - resp = requests.delete('{0}/v1/repositories/{1}/{2}/'.format( - self.registry_endpoint, namespace, repos), cookies=self.cookies) - self.assertEqual(resp.status_code, 200, resp.text) - self.update_cookies(resp) + resp = requests.delete('{0}/v1/repositories/{1}/{2}/images'.format( + self.registry_endpoint, namespace, repos), ) + self.assertEqual(resp.status_code, 204, resp.text) + # self.update_cookies(resp) # Remove image_id, then parent_id store = storage.load() - store.remove(os.path.join(store.images, self.image_id)) - store.remove(os.path.join(store.images, self.parent_id)) + try: + store.remove(os.path.join(store.images, self.image_id)) + except: + pass + try: + store.remove(os.path.join(store.images, self.parent_id)) + except: + pass def test_workflow(self): (namespace, repos) = self.docker_push() From 7b7d02199f1cad2c8b618bf4dcba706a89c58931 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Fri, 23 May 2014 12:16:39 +0200 Subject: [PATCH 07/14] Fix namespace collision Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- setup.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/setup.py b/setup.py index eb0f682d5..87075a8f9 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,9 @@ import sys -import docker_registry.lib as lib +# XXX as ugly as this looks, namespaces break terribly otherwise +# import docker_registry.lib as lib +execfile('./docker_registry/lib/__init__.py') requirements_txt = open('./requirements.txt') requirements = [line for line in requirements_txt] @@ -37,16 +39,17 @@ package_data = {'docker_registry': ['../config/*']} + setuptools.setup( - name=lib.__title__, - version=lib.__version__, - author=lib.__author__, - author_email=lib.__email__, - maintainer=lib.__maintainer__, - maintainer_email=lib.__email__, - url=lib.__url__, - description=lib.__description__, - download_url=lib.__download__, + name=__title__, # noqa + version=__version__, # noqa + author=__author__, # noqa + author_email=__email__, # noqa + maintainer=__maintainer__, # noqa + maintainer_email=__email__, # noqa + url=__url__, # noqa + description=__description__, # noqa + download_url=__download__, # noqa long_description=open('./README.md').read(), namespace_packages=namespaces, packages=packages, From 96f01a358fbd6685c278a995ec7e8ef7664fb790 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Fri, 23 May 2014 12:21:31 +0200 Subject: [PATCH 08/14] Flake Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- tests/workflow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/workflow.py b/tests/workflow.py index 912e3c411..ea5d438be 100644 --- a/tests/workflow.py +++ b/tests/workflow.py @@ -277,11 +277,11 @@ def docker_pull(self, namespace, repos): store = storage.load() try: store.remove(os.path.join(store.images, self.image_id)) - except: + except Exception: pass try: store.remove(os.path.join(store.images, self.parent_id)) - except: + except Exception: pass def test_workflow(self): From 7b76a4fd9ae38ad4568bb28b72d44393e76ec00e Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Fri, 23 May 2014 12:22:22 +0200 Subject: [PATCH 09/14] Test deletion more throughly Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- .../docker_registry/drivers/dumb.py | 15 ++++++++++-- .../docker_registry/testing/driver.py | 24 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/depends/docker-registry-core/docker_registry/drivers/dumb.py b/depends/docker-registry-core/docker_registry/drivers/dumb.py index e68935582..42d09bffa 100644 --- a/depends/docker-registry-core/docker_registry/drivers/dumb.py +++ b/depends/docker-registry-core/docker_registry/drivers/dumb.py @@ -53,9 +53,20 @@ def put_content(self, path, content): self._storage[path] = content def remove(self, path): - if path not in self._storage: + # Straight key, delete + if path in self._storage: + del self._storage[path] + return + # Directory like, get the list + ls = [] + for k in self._storage.keys(): + if (not k == path) and k.startswith(path): + ls.append(k) + + if not len(ls): raise exceptions.FileNotFoundError('%s is not there' % path) - del self._storage[path] + for item in ls: + self.remove(item) def stream_read(self, path, bytes_range=None): if path not in self._storage: diff --git a/depends/docker-registry-core/docker_registry/testing/driver.py b/depends/docker-registry-core/docker_registry/testing/driver.py index ac1ff0d80..0bc106968 100644 --- a/depends/docker-registry-core/docker_registry/testing/driver.py +++ b/depends/docker-registry-core/docker_registry/testing/driver.py @@ -167,6 +167,30 @@ def test_remove_existent(self): self._storage.remove(filename) assert not self._storage.exists(filename) + def test_remove_folder(self): + dirname = self.gen_random_string() + filename1 = self.gen_random_string() + filename2 = self.gen_random_string() + content = self.gen_random_string().encode('utf8') + self._storage.put_content('%s/%s' % (dirname, filename1), content) + self._storage.put_content('%s/%s' % (dirname, filename2), content) + self._storage.remove(dirname) + assert not self._storage.exists(filename1) + assert not self._storage.exists(filename2) + assert not self._storage.exists(dirname) + # Check the lru is ok + try: + self._storage.get_content(filename1) + assert False + except Exception: + pass + + try: + self._storage.get_content(filename2) + assert False + except Exception: + pass + @tools.raises(exceptions.FileNotFoundError) def test_remove_inexistent(self): filename = self.gen_random_string() From e7cbbb470653330b632d74fe53cc125db7d9e35e Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Fri, 23 May 2014 12:39:31 +0200 Subject: [PATCH 10/14] Note about how to use workflow Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- tests/workflow.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/workflow.py b/tests/workflow.py index ea5d438be..415a73c07 100644 --- a/tests/workflow.py +++ b/tests/workflow.py @@ -1,3 +1,12 @@ +""" +How to run locally: +Start your local registry: + * INDEX_ENDPOINT=https://indexstaging-docker.dotcloud.com SETTINGS_FLAVOR=test DOCKER_REGISTRY_CONFIG=config_sample.yml docker-registry + +Start the tests: + * DOCKER_REGISTRY_ENDPOINT=http://localhost:5000 SETTINGS_FLAVOR=test DOCKER_REGISTRY_CONFIG=config_sample.yml DOCKER_CREDS=USER:PASS nosetests --tests=tests/workflow.py +""" + import hashlib import os From d44e249915af3b574dcfa553fb5d5e2f29c5af14 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Tue, 27 May 2014 12:41:18 +0200 Subject: [PATCH 11/14] Fix flake Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- tests/workflow.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/workflow.py b/tests/workflow.py index 415a73c07..754155169 100644 --- a/tests/workflow.py +++ b/tests/workflow.py @@ -1,10 +1,13 @@ """ How to run locally: Start your local registry: - * INDEX_ENDPOINT=https://indexstaging-docker.dotcloud.com SETTINGS_FLAVOR=test DOCKER_REGISTRY_CONFIG=config_sample.yml docker-registry +`INDEX_ENDPOINT=https://indexstaging-docker.dotcloud.com \ + SETTINGS_FLAVOR=test DOCKER_REGISTRY_CONFIG=config_sample.yml docker-registry` Start the tests: - * DOCKER_REGISTRY_ENDPOINT=http://localhost:5000 SETTINGS_FLAVOR=test DOCKER_REGISTRY_CONFIG=config_sample.yml DOCKER_CREDS=USER:PASS nosetests --tests=tests/workflow.py +`DOCKER_REGISTRY_ENDPOINT=http://localhost:5000 SETTINGS_FLAVOR=test \ +DOCKER_REGISTRY_CONFIG=config_sample.yml DOCKER_CREDS=USER:PASS \ +nosetests --tests=tests/workflow.py` """ import hashlib From 1ac4228d0a0ceb8507f511c0214ca2bd848d0747 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Tue, 27 May 2014 13:00:19 +0200 Subject: [PATCH 12/14] Minimal maintenance on contrib scripts Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- contrib/docker-registry.conf | 7 ++++--- contrib/docker-registry_RHEL.sh | 2 +- contrib/docker-registry_debian.sh | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/contrib/docker-registry.conf b/contrib/docker-registry.conf index 2324b1844..912f430fd 100644 --- a/contrib/docker-registry.conf +++ b/contrib/docker-registry.conf @@ -9,9 +9,10 @@ env REGISTRY_DIR=/srv/docker/registry env USER=www-data env GROUP=www-data env LOG_FILE=/var/log/docker/registry.log -env NUM_WORKERS=9 +env GUNICORN_WORKERS=9 -env ADDRESS=127.0.0.1:5000 +env REGISTRY_PORT=5000 +env REGISTRY_HOST=127.0.0.1 pre-start script @@ -27,5 +28,5 @@ script [ -r $REGISTRY_DIR/.venv/bin/activate ] && . $REGISTRY_DIR/.venv/bin/activate cd $REGISTRY_DIR - exec gunicorn -w $NUM_WORKERS --bind=$ADDRESS --user=$USER --group=$GROUP --log-level=$LOG_LEVEL --log-file=$LOG_FILE 2>>$LOG_FILE wsgi:application + exec gunicorn -w $GUNICORN_WORKERS --bind=$REGISTRY_HOST:$REGISTRY_PORT --user=$USER --group=$GROUP --log-level=$LOG_LEVEL --log-file=$LOG_FILE 2>>$LOG_FILE docker_registry.wsgi:application end script diff --git a/contrib/docker-registry_RHEL.sh b/contrib/docker-registry_RHEL.sh index 95987d674..95f769bc6 100755 --- a/contrib/docker-registry_RHEL.sh +++ b/contrib/docker-registry_RHEL.sh @@ -43,7 +43,7 @@ self_dir="${self_path%%/${self_path##*/}}" NAME="Docker Registry" DAEMON="/usr/bin/gunicorn" -DAEMON_OPTS="-D --error-logfile ${ERROR_LOGFILE} --access-logfile ${ACCESS_LOGFILE} --log-file ${LOGFILE} --pid ${PIDFILE} --max-requests 500 --graceful-timeout 3600 -t 3600 -k gevent -b ${LISTEN_IP}:${LISTEN_PORT} -w ${GUNICORN_WORKERS:-2} wsgi:application" +DAEMON_OPTS="-D --error-logfile ${ERROR_LOGFILE} --access-logfile ${ACCESS_LOGFILE} --log-file ${LOGFILE} --pid ${PIDFILE} --max-requests 500 --graceful-timeout 3600 -t 3600 -k gevent -b ${LISTEN_IP}:${LISTEN_PORT} -w ${GUNICORN_WORKERS:-2} docker_registry.wsgi:application" RED='\e[0;31m' GREEN='\e[0;32m' diff --git a/contrib/docker-registry_debian.sh b/contrib/docker-registry_debian.sh index a789afe8a..ab297d48e 100755 --- a/contrib/docker-registry_debian.sh +++ b/contrib/docker-registry_debian.sh @@ -5,7 +5,7 @@ # Required-Start: $network $remote_fs $syslog # Required-Stop: $network $remote_fs $syslog # Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 +# Default-Stop: 0 1 6 # Short-Description: Start Docker-Registry ### END INIT INFO @@ -33,7 +33,7 @@ self_dir="${self_path%%/${self_path##*/}}" # set defaults if they are not set by config [[ -z "$RUNAS" ]] && RUNAS=$(stat --format "%U" $self_path) # defaults to user owning this init script [[ -z "$LOGFILE" ]] && LOGFILE=/var/log/docker-registry.log # will be chowned to $RUNAS -[[ -z "$PIDFILE" ]] && PIDFILE=/var/run/docker-registry/docker-registry.pid # path will created and chowned to $RUNAS +[[ -z "$PIDFILE" ]] && PIDFILE=/var/run/docker-registry/docker-registry.pid # path will created and chowned to $RUNAS [[ -z "$LISTEN_IP" ]] && LISTEN_IP="0.0.0.0" [[ -z "$LISTEN_PORT" ]] && LISTEN_PORT=5000 [[ -z "$GUNICORN_WORKERS" ]] && GUNICORN_WORKERS=2 @@ -41,7 +41,7 @@ self_dir="${self_path%%/${self_path##*/}}" NAME="Docker Registry" DAEMON="/usr/local/bin/gunicorn" -DAEMON_OPTS="-D --access-logfile ${LOGFILE} --pid ${PIDFILE} --max-requests 500 --graceful-timeout 3600 -t 3600 -k gevent -b ${LISTEN_IP}:${LISTEN_PORT} -w ${GUNICORN_WORKERS:-2} wsgi:application" +DAEMON_OPTS="-D --access-logfile ${LOGFILE} --pid ${PIDFILE} --max-requests 500 --graceful-timeout 3600 -t 3600 -k gevent -b ${LISTEN_IP}:${LISTEN_PORT} -w ${GUNICORN_WORKERS:-2} docker_registry.wsgi:application" RED='\e[0;31m' GREEN='\e[0;32m' From 718ecf02c094fbb9b489ed9d96ab3acbeed5cced Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Thu, 29 May 2014 16:45:07 +0200 Subject: [PATCH 13/14] Fix #368 and more configuration cleanup Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- docker_registry/app.py | 2 +- docker_registry/lib/__init__.py | 17 ----------------- docker_registry/lib/cache.py | 1 - docker_registry/run.py | 12 +++++++----- docker_registry/server/__init__.py | 18 ++++++++++++++++++ docker_registry/server/env.py | 18 ++++++++++++++++++ docker_registry/wsgi.py | 7 ++++--- setup.py | 3 ++- 8 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 docker_registry/server/__init__.py create mode 100644 docker_registry/server/env.py diff --git a/docker_registry/app.py b/docker_registry/app.py index 6c3a883ca..d151dc2a0 100644 --- a/docker_registry/app.py +++ b/docker_registry/app.py @@ -13,8 +13,8 @@ import flask from . import toolkit -from .lib import __version__ from .lib import config +from .server import __version__ app = flask.Flask('docker-registry') cfg = config.load() diff --git a/docker_registry/lib/__init__.py b/docker_registry/lib/__init__.py index 12b2d3b5b..40a96afc6 100644 --- a/docker_registry/lib/__init__.py +++ b/docker_registry/lib/__init__.py @@ -1,18 +1 @@ # -*- coding: utf-8 -*- - -__author__ = 'Docker Registry Contributors' -__copyright__ = '{{driver.copyright}}' -__credits__ = [] - -__license__ = 'Apache 2.0' -__version__ = '0.7.0' -__maintainer__ = __author__ -__email__ = 'docker-dev@googlegroups.com' -__status__ = 'Production' - -__title__ = 'docker-registry' -__build__ = 0x000000 - -__url__ = 'https://github.com/dotcloud/docker-registry' -__description__ = 'Registry server for Docker' -__download__ = 'https://github.com/dotcloud/docker-registry/archive/master.zip' diff --git a/docker_registry/lib/cache.py b/docker_registry/lib/cache.py index b6511af45..1bcf95421 100644 --- a/docker_registry/lib/cache.py +++ b/docker_registry/lib/cache.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import logging - import redis from docker_registry.core import lru diff --git a/docker_registry/run.py b/docker_registry/run.py index 466292506..fb05ba83b 100644 --- a/docker_registry/run.py +++ b/docker_registry/run.py @@ -16,6 +16,7 @@ from .tags import * # noqa from .images import * # noqa from .lib import config +from .server import env from .status import * # noqa from .search import * # noqa @@ -47,12 +48,13 @@ def run_gunicorn(): formatter_class=RawTextHelpFormatter) parser.parse_args() - workers = os.environ.get('GUNICORN_WORKERS', '4') - port = os.environ.get('REGISTRY_PORT', '5000') - graceful_timeout = os.environ.get('GUNICORN_GRACEFUL_TIMEOUT', '3600') - silent_timeout = os.environ.get('GUNICORN_SILENT_TIMEOUT', '3600') + workers = env.source('GUNICORN_WORKERS') + host = env.source('REGISTRY_HOST') + port = env.source('REGISTRY_PORT') + graceful_timeout = env.source('GUNICORN_GRACEFUL_TIMEOUT') + silent_timeout = env.source('GUNICORN_SILENT_TIMEOUT') - address = '0.0.0.0:{0}'.format(port) + address = '%s:%s' % (host, port) gunicorn_path = distutils.spawn.find_executable('gunicorn') if gunicorn_path is None: diff --git a/docker_registry/server/__init__.py b/docker_registry/server/__init__.py new file mode 100644 index 000000000..8950d48fa --- /dev/null +++ b/docker_registry/server/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +__author__ = 'Docker Registry Contributors' +__copyright__ = 'Copyright 2014 Docker' +__credits__ = [] + +__license__ = 'Apache 2.0' +__version__ = '0.7.0' +__maintainer__ = __author__ +__email__ = 'docker-dev@googlegroups.com' +__status__ = 'Production' + +__title__ = 'docker-registry' +__build__ = 0x000000 + +__url__ = 'https://github.com/dotcloud/docker-registry' +__description__ = 'Registry server for Docker' +__download__ = 'https://github.com/dotcloud/docker-registry/archive/master.zip' diff --git a/docker_registry/server/env.py b/docker_registry/server/env.py new file mode 100644 index 000000000..275c2c4d5 --- /dev/null +++ b/docker_registry/server/env.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +import os + +__all__ = ['source'] + +defined = { + 'REGISTRY_PORT': 5000, + 'REGISTRY_HOST': '0.0.0.0', + 'SETTINGS_FLAVOR': 'dev', + 'GUNICORN_WORKERS': 4, + 'GUNICORN_GRACEFUL_TIMEOUT': 3600, + 'GUNICORN_SILENT_TIMEOUT': 3600 +} + + +def source(key, override=None): + return os.environ.get(key, defined[key] if key in defined else override) diff --git a/docker_registry/wsgi.py b/docker_registry/wsgi.py index 4b4587fd7..be5b4c7aa 100755 --- a/docker_registry/wsgi.py +++ b/docker_registry/wsgi.py @@ -2,16 +2,17 @@ # -*- coding: utf-8 -*- import logging -import os from .run import app +from .server import env if __name__ == '__main__': # Bind to PORT if defined, otherwise default to 5000. - port = int(os.environ.get('PORT_WWW', 5000)) + host = env.source('REGISTRY_HOST') + port = int(env.source('REGISTRY_PORT')) app.debug = True - app.run(host='0.0.0.0', port=port) + app.run(host=host, port=port) # Or you can run: # gunicorn --access-logfile - --log-level debug --debug -b 0.0.0.0:5000 \ # -w 1 wsgi:application diff --git a/setup.py b/setup.py index 87075a8f9..6ec886d33 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ # XXX as ugly as this looks, namespaces break terribly otherwise # import docker_registry.lib as lib -execfile('./docker_registry/lib/__init__.py') +execfile('./docker_registry/server/__init__.py') requirements_txt = open('./requirements.txt') requirements = [line for line in requirements_txt] @@ -31,6 +31,7 @@ # Explicit packages list to avoid setup_tools funkyness packages = ['docker_registry', 'docker_registry.drivers', + 'docker_registry.server', 'docker_registry.lib', 'docker_registry.storage', 'docker_registry.lib.index'] From c943b41241a970c786bf93a41c929529634f9e83 Mon Sep 17 00:00:00 2001 From: Mangled Deutz Date: Thu, 29 May 2014 16:53:30 +0200 Subject: [PATCH 14/14] Remove debug Docker-DCO-1.1-Signed-off-by: Mangled Deutz (github: dmp42) --- tests/workflow.py | 52 ----------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/tests/workflow.py b/tests/workflow.py index 754155169..80de7d298 100644 --- a/tests/workflow.py +++ b/tests/workflow.py @@ -32,63 +32,11 @@ json = compat.json StringIO = compat.StringIO -import time - cfg = config.load() ua = 'docker/0.11 registry test pretending to be docker' -def control(resp, method, data, start, end): - print('----------------------------') - print('%sConsumed: %s - %s' % (colorama.Fore.RED, method, resp.url)) - print('%sTime: %s' % (colorama.Fore.RED, end - start)) - print(colorama.Fore.RESET) - print(resp.status_code) - for i in resp.headers.keys(): - print('%s: %s' % (i, resp.headers[i])) - print('----------------------------') - try: - print(data[:500]) - except Exception: - pass - print('----------------------------') - print(resp.content[:500]) - print('----------------------------') - -p = requests.put -g = requests.get -d = requests.delete - - -def pp(*args, **kwargs): - start = time.time() - ret = p(*args, **kwargs) - end = time.time() - control(ret, 'PUT', kwargs["data"], start, end) - return ret - - -def gg(*args, **kwargs): - start = time.time() - ret = g(*args, **kwargs) - end = time.time() - control(ret, 'GET', None, start, end) - return ret - - -def dd(*args, **kwargs): - start = time.time() - ret = d(*args, **kwargs) - end = time.time() - control(ret, 'DEL', None, start, end) - return ret - -requests.put = pp -requests.get = gg -requests.delete = dd - - class TestWorkflow(base.TestCase): # Dev server needs to run on port 5000 in order to run this test