Accidental refactor, split out legacy.py into separate sumodules and update all call sites.

This commit is contained in:
Jake Moshenko 2015-07-15 17:25:41 -04:00
parent 2109d24483
commit 3efaa255e8
92 changed files with 4458 additions and 4269 deletions

View file

@ -26,4 +26,4 @@ def ping():
from endpoints.v1 import index
from endpoints.v1 import registry
from endpoints.v1 import tags
from endpoints.v1 import tag

View file

@ -2,20 +2,17 @@ import json
import logging
import urlparse
from flask import request, make_response, jsonify, session, Blueprint
from flask import request, make_response, jsonify, session
from functools import wraps
from collections import OrderedDict
from data import model
from data.model import oauth
from app import app, authentication, userevents, storage
from auth.auth import process_auth, generate_signed_token
from auth.auth_context import get_authenticated_user, get_validated_token, get_validated_oauth_token
from util.names import parse_repository_name
from util.useremails import send_confirmation_email
from auth.permissions import (ModifyRepositoryPermission, UserAdminPermission,
ReadRepositoryPermission, CreateRepositoryPermission,
AlwaysFailPermission, repository_read_grant, repository_write_grant)
repository_read_grant, repository_write_grant)
from util.http import abort
from endpoints.v1 import v1_bp
@ -23,8 +20,6 @@ from endpoints.trackhelper import track_and_log
from endpoints.notificationhelper import spawn_notification
from endpoints.decorators import anon_protect, anon_allowed
import features
logger = logging.getLogger(__name__)
@ -90,13 +85,13 @@ def create_user():
if username == '$token':
try:
model.load_token_data(password)
model.token.load_token_data(password)
return success
except model.InvalidTokenException:
abort(400, 'Invalid access token.', issue='invalid-access-token')
elif username == '$oauthtoken':
validated = oauth.validate_access_token(password)
validated = model.oauth.validate_access_token(password)
if validated is not None:
return success
else:
@ -104,7 +99,7 @@ def create_user():
elif '+' in username:
try:
model.verify_robot(username, password)
model.user.verify_robot(username, password)
return success
except model.InvalidRobotException:
abort(400, 'Invalid robot account or password.',
@ -157,12 +152,11 @@ def update_user(username):
if 'password' in update_request:
logger.debug('Updating user password')
model.change_password(get_authenticated_user(),
update_request['password'])
model.user.change_password(get_authenticated_user(), update_request['password'])
if 'email' in update_request:
logger.debug('Updating user email')
model.update_email(get_authenticated_user(), update_request['email'])
model.user.update_email(get_authenticated_user(), update_request['email'])
return jsonify({
'username': get_authenticated_user().username,
@ -178,11 +172,8 @@ def update_user(username):
@generate_headers(scope=GrantType.WRITE_REPOSITORY, add_grant_for_status=201)
@anon_allowed
def create_repository(namespace, repository):
logger.debug('Parsing image descriptions for repository %s/%s', namespace, repository)
image_descriptions = json.loads(request.data.decode('utf8'))
logger.debug('Looking up repository %s/%s', namespace, repository)
repo = model.get_repository(namespace, repository)
repo = model.repository.get_repository(namespace, repository)
logger.debug('Found repository %s/%s', namespace, repository)
if not repo and get_authenticated_user() is None:
@ -201,18 +192,16 @@ def create_repository(namespace, repository):
else:
permission = CreateRepositoryPermission(namespace)
if not permission.can():
logger.info('Attempt to create a new repo %s/%s with insufficient perms', namespace, repository)
abort(403,
message='You do not have permission to create repositories in namespace "%(namespace)s"',
issue='no-create-permission',
namespace=namespace)
logger.info('Attempt to create a new repo %s/%s with insufficient perms', namespace,
repository)
msg = 'You do not have permission to create repositories in namespace "%(namespace)s"'
abort(403, message=msg, issue='no-create-permission', namespace=namespace)
# Attempt to create the new repository.
logger.debug('Creating repository %s/%s with owner: %s', namespace, repository,
get_authenticated_user().username)
repo = model.create_repository(namespace, repository,
get_authenticated_user())
repo = model.repository.create_repository(namespace, repository, get_authenticated_user())
if get_authenticated_user():
user_event_data = {
@ -237,13 +226,13 @@ def update_images(namespace, repository):
if permission.can():
logger.debug('Looking up repository')
repo = model.get_repository(namespace, repository)
repo = model.repository.get_repository(namespace, repository)
if not repo:
# Make sure the repo actually exists.
abort(404, message='Unknown repository', issue='unknown-repo')
logger.debug('GCing repository')
model.garbage_collect_repository(namespace, repository)
model.repository.garbage_collect_repository(namespace, repository)
# Generate a job for each notification that has been added to this repo
logger.debug('Adding notifications for repository')
@ -269,10 +258,10 @@ def get_repository_images(namespace, repository):
permission = ReadRepositoryPermission(namespace, repository)
# TODO invalidate token?
if permission.can() or model.repository_is_public(namespace, repository):
if permission.can() or model.repository.repository_is_public(namespace, repository):
# We can't rely on permissions to tell us if a repo exists anymore
logger.debug('Looking up repository')
repo = model.get_repository(namespace, repository)
repo = model.repository.get_repository(namespace, repository)
if not repo:
abort(404, message='Unknown repository', issue='unknown-repo')
@ -320,7 +309,7 @@ def get_search():
username = user.username
if query:
matching = model.get_matching_repositories(query, username)
matching = model.repository.get_matching_repositories(query, username)
else:
matching = []

View file

@ -1,8 +1,7 @@
import logging
import json
from flask import (make_response, request, session, Response, redirect,
Blueprint, abort as flask_abort)
from flask import make_response, request, session, Response, redirect, abort as flask_abort
from functools import wraps
from datetime import datetime
from time import time
@ -61,7 +60,7 @@ def require_completion(f):
@wraps(f)
def wrapper(namespace, repository, *args, **kwargs):
image_id = kwargs['image_id']
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
if image_is_uploading(repo_image):
abort(400, 'Image %(image_id)s is being uploaded, retry later',
issue='upload-in-progress', image_id=kwargs['image_id'])
@ -104,9 +103,9 @@ def head_image_layer(namespace, repository, image_id, headers):
permission = ReadRepositoryPermission(namespace, repository)
logger.debug('Checking repo permissions')
if permission.can() or model.repository_is_public(namespace, repository):
if permission.can() or model.repository.repository_is_public(namespace, repository):
logger.debug('Looking up repo image')
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
if not repo_image:
logger.debug('Image not found')
abort(404, 'Image %(image_id)s not found', issue='unknown-image',
@ -138,9 +137,9 @@ def get_image_layer(namespace, repository, image_id, headers):
permission = ReadRepositoryPermission(namespace, repository)
logger.debug('Checking repo permissions')
if permission.can() or model.repository_is_public(namespace, repository):
if permission.can() or model.repository.repository_is_public(namespace, repository):
logger.debug('Looking up repo image')
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
if not repo_image:
logger.debug('Image not found')
abort(404, 'Image %(image_id)s not found', issue='unknown-image',
@ -183,7 +182,7 @@ def put_image_layer(namespace, repository, image_id):
abort(403)
logger.debug('Retrieving image')
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
try:
logger.debug('Retrieving image data')
uuid = repo_image.storage.uuid
@ -236,17 +235,16 @@ def put_image_layer(namespace, repository, image_id):
try:
# Save the size of the image.
model.set_image_size(image_id, namespace, repository, size_info.compressed_size,
size_info.uncompressed_size)
model.image.set_image_size(image_id, namespace, repository, size_info.compressed_size,
size_info.uncompressed_size)
if requires_tarsum:
tmp.seek(0)
csums.append(checksums.compute_tarsum(tmp, json_data))
tmp.close()
except (IOError, checksums.TarError) as e:
logger.debug('put_image_layer: Error when computing tarsum '
'{0}'.format(e))
except (IOError, checksums.TarError) as exc:
logger.debug('put_image_layer: Error when computing tarsum %s', exc)
if repo_image.storage.checksum is None:
# We don't have a checksum stored yet, that's fine skipping the check.
@ -268,7 +266,7 @@ def put_image_layer(namespace, repository, image_id):
# The layer is ready for download, send a job to the work queue to
# process it.
logger.debug('Adding layer to diff queue')
repo = model.get_repository(namespace, repository)
repo = model.repository.get_repository(namespace, repository)
image_diff_queue.put([repo.namespace_user.username, repository, image_id], json.dumps({
'namespace_user_id': repo.namespace_user.id,
'repository': repository,
@ -310,7 +308,7 @@ def put_image_checksum(namespace, repository, image_id):
issue='missing-checksum-cookie', image_id=image_id)
logger.debug('Looking up repo image')
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
if not repo_image or not repo_image.storage:
abort(404, 'Image not found: %(image_id)s', issue='unknown-image', image_id=image_id)
@ -331,8 +329,8 @@ def put_image_checksum(namespace, repository, image_id):
abort(400, err)
if checksum not in session.get('checksum', []):
logger.debug('session checksums: %s' % session.get('checksum', []))
logger.debug('client supplied checksum: %s' % checksum)
logger.debug('session checksums: %s', session.get('checksum', []))
logger.debug('client supplied checksum: %s', checksum)
logger.debug('put_image_checksum: Wrong checksum')
abort(400, 'Checksum mismatch for image: %(image_id)s',
issue='checksum-mismatch', image_id=image_id)
@ -343,7 +341,7 @@ def put_image_checksum(namespace, repository, image_id):
# The layer is ready for download, send a job to the work queue to
# process it.
logger.debug('Adding layer to diff queue')
repo = model.get_repository(namespace, repository)
repo = model.repository.get_repository(namespace, repository)
image_diff_queue.put([repo.namespace_user.username, repository, image_id], json.dumps({
'namespace_user_id': repo.namespace_user.id,
'repository': repository,
@ -362,12 +360,11 @@ def put_image_checksum(namespace, repository, image_id):
def get_image_json(namespace, repository, image_id, headers):
logger.debug('Checking repo permissions')
permission = ReadRepositoryPermission(namespace, repository)
if not permission.can() and not model.repository_is_public(namespace,
repository):
if not permission.can() and not model.repository.repository_is_public(namespace, repository):
abort(403)
logger.debug('Looking up repo image')
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
logger.debug('Looking up repo layer data')
try:
@ -394,12 +391,11 @@ def get_image_json(namespace, repository, image_id, headers):
def get_image_ancestry(namespace, repository, image_id, headers):
logger.debug('Checking repo permissions')
permission = ReadRepositoryPermission(namespace, repository)
if not permission.can() and not model.repository_is_public(namespace,
repository):
if not permission.can() and not model.repository.repository_is_public(namespace, repository):
abort(403)
logger.debug('Looking up repo image')
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
logger.debug('Looking up image data')
try:
@ -465,22 +461,23 @@ def put_image_json(namespace, repository, image_id):
logger.debug('Looking up repo image')
repo = model.get_repository(namespace, repository)
repo = model.repository.get_repository(namespace, repository)
if repo is None:
abort(404, 'Repository does not exist: %(namespace)s/%(repository)s', issue='no-repo',
namespace=namespace, repository=repository)
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
if not repo_image:
username = (get_authenticated_user() and get_authenticated_user().username or
get_grant_user_context())
logger.debug('Image not found, creating image with initiating user context: %s', username)
repo_image = model.find_create_or_link_image(image_id, repo, username, {},
store.preferred_locations[0])
repo_image = model.image.find_create_or_link_image(image_id, repo, username, {},
store.preferred_locations[0])
# Create a temporary tag to prevent this image from getting garbage collected while the push
# is in progress.
model.create_temporary_hidden_tag(repo, repo_image, app.config['PUSH_TEMP_TAG_EXPIRATION_SEC'])
model.tag.create_temporary_hidden_tag(repo, repo_image,
app.config['PUSH_TEMP_TAG_EXPIRATION_SEC'])
uuid = repo_image.storage.uuid
@ -493,7 +490,7 @@ def put_image_json(namespace, repository, image_id):
parent_image = None
if parent_id:
logger.debug('Looking up parent image')
parent_image = model.get_repo_image_extended(namespace, repository, parent_id)
parent_image = model.image.get_repo_image_extended(namespace, repository, parent_id)
parent_uuid = parent_image and parent_image.storage.uuid
parent_locations = parent_image and parent_image.storage.locations
@ -523,9 +520,8 @@ def put_image_json(namespace, repository, image_id):
command = json.dumps(command_list) if command_list else None
logger.debug('Setting image metadata')
model.set_image_metadata(image_id, namespace, repository,
data.get('created'), data.get('comment'), command,
parent_image)
model.image.set_image_metadata(image_id, namespace, repository, data.get('created'),
data.get('comment'), command, parent_image)
logger.debug('Putting json path')
store.put_content(repo_image.storage.locations, json_path, request.data)
@ -536,7 +532,7 @@ def put_image_json(namespace, repository, image_id):
generate_ancestry(image_id, uuid, repo_image.storage.locations, parent_id, parent_uuid,
parent_locations)
except IOError as ioe:
logger.debug('Error when generating ancestry: %s' % ioe.message)
logger.debug('Error when generating ancestry: %s', ioe.message)
abort(404)
logger.debug('Done')
@ -544,9 +540,9 @@ def put_image_json(namespace, repository, image_id):
def process_image_changes(namespace, repository, image_id):
logger.debug('Generating diffs for image: %s' % image_id)
logger.debug('Generating diffs for image: %s', image_id)
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
repo_image = model.image.get_repo_image_extended(namespace, repository, image_id)
if not repo_image:
logger.warning('No image for id: %s', image_id)
return None, None
@ -557,11 +553,11 @@ def process_image_changes(namespace, repository, image_id):
image_trie_path = store.image_file_trie_path(uuid)
if store.exists(repo_image.storage.locations, image_diffs_path):
logger.debug('Diffs already exist for image: %s' % image_id)
logger.debug('Diffs already exist for image: %s', image_id)
return image_trie_path, repo_image.storage.locations
image = model.get_image_by_id(namespace, repository, image_id)
parents = model.get_parent_images(namespace, repository, image)
image = model.image.get_image_by_id(namespace, repository, image_id)
parents = model.image.get_parent_images(namespace, repository, image)
# Compute the diffs and fs for the parent first if necessary
parent_trie_path = None

View file

@ -2,7 +2,7 @@
import logging
import json
from flask import abort, request, jsonify, make_response, Blueprint, session
from flask import abort, request, jsonify, make_response, session
from app import app
from util.names import parse_repository_name
@ -17,32 +17,30 @@ from endpoints.v1 import v1_bp
logger = logging.getLogger(__name__)
@v1_bp.route('/repositories/<path:repository>/tags',
methods=['GET'])
@v1_bp.route('/repositories/<path:repository>/tags', methods=['GET'])
@process_auth
@anon_protect
@parse_repository_name
def get_tags(namespace, repository):
permission = ReadRepositoryPermission(namespace, repository)
if permission.can() or model.repository_is_public(namespace, repository):
tags = model.list_repository_tags(namespace, repository)
if permission.can() or model.repository.repository_is_public(namespace, repository):
tags = model.tag.list_repository_tags(namespace, repository)
tag_map = {tag.name: tag.image.docker_image_id for tag in tags}
return jsonify(tag_map)
abort(403)
@v1_bp.route('/repositories/<path:repository>/tags/<tag>',
methods=['GET'])
@v1_bp.route('/repositories/<path:repository>/tags/<tag>', methods=['GET'])
@process_auth
@anon_protect
@parse_repository_name
def get_tag(namespace, repository, tag):
permission = ReadRepositoryPermission(namespace, repository)
if permission.can() or model.repository_is_public(namespace, repository):
tag_image = model.get_tag_image(namespace, repository, tag)
if permission.can() or model.repository.repository_is_public(namespace, repository):
tag_image = model.tag.get_tag_image(namespace, repository, tag)
resp = make_response('"%s"' % tag_image.docker_image_id)
resp.headers['Content-Type'] = 'application/json'
return resp
@ -50,8 +48,7 @@ def get_tag(namespace, repository, tag):
abort(403)
@v1_bp.route('/repositories/<path:repository>/tags/<tag>',
methods=['PUT'])
@v1_bp.route('/repositories/<path:repository>/tags/<tag>', methods=['PUT'])
@process_auth
@anon_protect
@parse_repository_name
@ -60,7 +57,7 @@ def put_tag(namespace, repository, tag):
if permission.can():
docker_image_id = json.loads(request.data)
model.create_or_update_tag(namespace, repository, tag, docker_image_id)
model.tag.create_or_update_tag(namespace, repository, tag, docker_image_id)
# Store the updated tag.
if not 'pushed_tags' in session:
@ -73,8 +70,7 @@ def put_tag(namespace, repository, tag):
abort(403)
@v1_bp.route('/repositories/<path:repository>/tags/<tag>',
methods=['DELETE'])
@v1_bp.route('/repositories/<path:repository>/tags/<tag>', methods=['DELETE'])
@process_auth
@anon_protect
@parse_repository_name
@ -82,8 +78,8 @@ def delete_tag(namespace, repository, tag):
permission = ModifyRepositoryPermission(namespace, repository)
if permission.can():
model.delete_tag(namespace, repository, tag)
model.garbage_collect_repository(namespace, repository)
model.tag.delete_tag(namespace, repository, tag)
model.repository.garbage_collect_repository(namespace, repository)
return make_response('Deleted', 200)