Merge pull request #556 from coreos-inc/python-registry-v2-fixsmallthings
Lots o'small fixes for V2
This commit is contained in:
commit
fe31eb5c84
6 changed files with 30 additions and 11 deletions
11
app.py
11
app.py
|
@ -8,6 +8,8 @@ from flask.ext.principal import Principal
|
||||||
from flask.ext.login import LoginManager, UserMixin
|
from flask.ext.login import LoginManager, UserMixin
|
||||||
from flask.ext.mail import Mail
|
from flask.ext.mail import Mail
|
||||||
from werkzeug.routing import BaseConverter
|
from werkzeug.routing import BaseConverter
|
||||||
|
from jwkest.jwk import RSAKey
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
|
||||||
import features
|
import features
|
||||||
|
|
||||||
|
@ -42,6 +44,8 @@ OVERRIDE_CONFIG_PY_FILENAME = 'conf/stack/config.py'
|
||||||
|
|
||||||
OVERRIDE_CONFIG_KEY = 'QUAY_OVERRIDE_CONFIG'
|
OVERRIDE_CONFIG_KEY = 'QUAY_OVERRIDE_CONFIG'
|
||||||
|
|
||||||
|
DOCKER_V2_SIGNINGKEY_FILENAME = 'docker_v2.pem'
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -154,6 +158,13 @@ dockerfile_build_queue = WorkQueue(app.config['DOCKERFILE_BUILD_QUEUE_NAME'], tf
|
||||||
reporter=MetricQueueReporter(metric_queue))
|
reporter=MetricQueueReporter(metric_queue))
|
||||||
notification_queue = WorkQueue(app.config['NOTIFICATION_QUEUE_NAME'], tf, metric_queue=metric_queue)
|
notification_queue = WorkQueue(app.config['NOTIFICATION_QUEUE_NAME'], tf, metric_queue=metric_queue)
|
||||||
|
|
||||||
|
# Check for a key in config. If none found, generate a new signing key for Docker V2 manifests.
|
||||||
|
_v2_key_path = os.path.join(OVERRIDE_CONFIG_DIRECTORY, DOCKER_V2_SIGNINGKEY_FILENAME)
|
||||||
|
if os.path.exists(_v2_key_path):
|
||||||
|
docker_v2_signing_key = RSAKey().load(_v2_key_path)
|
||||||
|
else:
|
||||||
|
docker_v2_signing_key = RSAKey(key=RSA.generate(2048))
|
||||||
|
|
||||||
database.configure(app.config)
|
database.configure(app.config)
|
||||||
model.config.app_config = app.config
|
model.config.app_config = app.config
|
||||||
model.config.store = storage
|
model.config.store = storage
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from Crypto import Random
|
||||||
|
|
||||||
bind = '0.0.0.0:5000'
|
bind = '0.0.0.0:5000'
|
||||||
workers = 2
|
workers = 2
|
||||||
worker_class = 'gevent'
|
worker_class = 'gevent'
|
||||||
|
@ -5,3 +7,8 @@ daemon = False
|
||||||
logconfig = 'conf/logging_debug.conf'
|
logconfig = 'conf/logging_debug.conf'
|
||||||
pythonpath = '.'
|
pythonpath = '.'
|
||||||
preload_app = True
|
preload_app = True
|
||||||
|
|
||||||
|
def post_fork(server, worker):
|
||||||
|
# Reset the Random library to ensure it won't raise the "PID check failed." error after
|
||||||
|
# gunicorn forks.
|
||||||
|
Random.atfork()
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
|
from Crypto import Random
|
||||||
|
|
||||||
bind = 'unix:/tmp/gunicorn_registry.sock'
|
bind = 'unix:/tmp/gunicorn_registry.sock'
|
||||||
workers = 8
|
workers = 8
|
||||||
worker_class = 'gevent'
|
worker_class = 'gevent'
|
||||||
logconfig = 'conf/logging.conf'
|
logconfig = 'conf/logging.conf'
|
||||||
pythonpath = '.'
|
pythonpath = '.'
|
||||||
preload_app = True
|
preload_app = True
|
||||||
|
|
||||||
|
def post_fork(server, worker):
|
||||||
|
# Reset the Random library to ensure it won't raise the "PID check failed." error after
|
||||||
|
# gunicorn forks.
|
||||||
|
Random.atfork()
|
||||||
|
|
|
@ -9,11 +9,9 @@ import json
|
||||||
from flask import make_response, request, url_for
|
from flask import make_response, request, url_for
|
||||||
from collections import namedtuple, OrderedDict
|
from collections import namedtuple, OrderedDict
|
||||||
from jwkest.jws import SIGNER_ALGS
|
from jwkest.jws import SIGNER_ALGS
|
||||||
from jwkest.jwk import RSAKey
|
|
||||||
from Crypto.PublicKey import RSA
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from app import storage
|
from app import storage, docker_v2_signing_key
|
||||||
from auth.jwt_auth import process_jwt_auth
|
from auth.jwt_auth import process_jwt_auth
|
||||||
from endpoints.decorators import anon_protect
|
from endpoints.decorators import anon_protect
|
||||||
from endpoints.v2 import v2_bp, require_repo_read, require_repo_write
|
from endpoints.v2 import v2_bp, require_repo_read, require_repo_write
|
||||||
|
@ -332,12 +330,8 @@ def _generate_and_store_manifest(namespace, repo_name, tag_name):
|
||||||
for parent in parents:
|
for parent in parents:
|
||||||
builder.add_layer(parent.storage.checksum, __get_and_backfill_image_metadata(parent))
|
builder.add_layer(parent.storage.checksum, __get_and_backfill_image_metadata(parent))
|
||||||
|
|
||||||
# TODO, stop generating a new key every time we sign a manifest, publish our key
|
# Sign the manifest with our signing key.
|
||||||
new_key = RSA.generate(2048)
|
manifest = builder.build(docker_v2_signing_key)
|
||||||
jwk = RSAKey(key=new_key)
|
|
||||||
|
|
||||||
manifest = builder.build(jwk)
|
|
||||||
|
|
||||||
manifest_row = model.tag.associate_generated_tag_manifest(namespace, repo_name, tag_name,
|
manifest_row = model.tag.associate_generated_tag_manifest(namespace, repo_name, tag_name,
|
||||||
manifest.digest, manifest.bytes)
|
manifest.digest, manifest.bytes)
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ def __create_subtree(repo, structure, creator_username, parent, tag_map):
|
||||||
|
|
||||||
new_image = model.image.set_image_metadata(docker_image_id, repo.namespace_user.username,
|
new_image = model.image.set_image_metadata(docker_image_id, repo.namespace_user.username,
|
||||||
repo.name, str(creation_time), 'no comment', command,
|
repo.name, str(creation_time), 'no comment', command,
|
||||||
v1_metadata, parent)
|
json.dumps(v1_metadata), parent)
|
||||||
|
|
||||||
compressed_size = random.randrange(1, 1024 * 1024 * 1024)
|
compressed_size = random.randrange(1, 1024 * 1024 * 1024)
|
||||||
model.image.set_image_size(docker_image_id, repo.namespace_user.username, repo.name,
|
model.image.set_image_size(docker_image_id, repo.namespace_user.username, repo.name,
|
||||||
|
|
|
@ -218,7 +218,7 @@ class V1RegistryPushMixin(V1RegistryMixin):
|
||||||
self.v1_ping()
|
self.v1_ping()
|
||||||
|
|
||||||
# PUT /v1/repositories/{namespace}/{repository}/
|
# PUT /v1/repositories/{namespace}/{repository}/
|
||||||
data = [{"id": image['id']} for image in images]
|
data = [{"id": image_id} for image_id, _ in images.iteritems()]
|
||||||
self.conduct('PUT', '/v1/repositories/%s/%s' % (namespace, repository),
|
self.conduct('PUT', '/v1/repositories/%s/%s' % (namespace, repository),
|
||||||
data=json.dumps(data), auth=auth,
|
data=json.dumps(data), auth=auth,
|
||||||
expected_code=201)
|
expected_code=201)
|
||||||
|
|
Reference in a new issue