From 6ed705be15c73582efeb62b2ee282ca4c3c96cbd Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Tue, 24 Nov 2015 18:38:29 -0500 Subject: [PATCH] Make manifest generation safe for multiple callers Fixes #985 --- endpoints/v2/manifest.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/endpoints/v2/manifest.py b/endpoints/v2/manifest.py index c5ceafeac..13b637845 100644 --- a/endpoints/v2/manifest.py +++ b/endpoints/v2/manifest.py @@ -2,6 +2,7 @@ import logging import jwt.utils import json +from peewee import IntegrityError from flask import make_response, request, url_for from collections import namedtuple, OrderedDict from jwkest.jws import SIGNER_ALGS, keyrep @@ -404,7 +405,15 @@ def _generate_and_store_manifest(namespace, repo_name, tag_name): # Sign the manifest with our signing key. manifest = builder.build(docker_v2_signing_key) - manifest_row = model.tag.associate_generated_tag_manifest(namespace, repo_name, tag_name, - manifest.digest, manifest.bytes) - return manifest_row + # Write the manifest to the DB. If an existing manifest already exists, return the + # one found. + try: + return model.tag.associate_generated_tag_manifest(namespace, repo_name, tag_name, + manifest.digest, manifest.bytes) + except IntegrityError: + try: + return model.tag.load_tag_manifest(namespace, repo_name, tag_name) + except model.InvalidManifestException: + raise model.DataModelException('Could not load or generate manifest') +