Merge pull request #1076 from coreos-inc/squashfloat
Ensure the squashed estimated size is an int
This commit is contained in:
commit
2a8dde4ac2
2 changed files with 41 additions and 2 deletions
|
@ -5,6 +5,7 @@ from formats.tarimageformatter import TarImageFormatter
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
|
|
||||||
class FileEstimationException(Exception):
|
class FileEstimationException(Exception):
|
||||||
""" Exception raised by build_docker_load_stream if the estimated size of the layer TAR
|
""" Exception raised by build_docker_load_stream if the estimated size of the layer TAR
|
||||||
|
@ -68,6 +69,9 @@ class SquashedDockerImage(TarImageFormatter):
|
||||||
image_json = get_image_json(image)
|
image_json = get_image_json(image)
|
||||||
estimated_file_size += image_json.get('Size', 0) * SquashedDockerImage.SIZE_MULTIPLIER
|
estimated_file_size += image_json.get('Size', 0) * SquashedDockerImage.SIZE_MULTIPLIER
|
||||||
|
|
||||||
|
# Make sure the estimated file size is an integer number of bytes.
|
||||||
|
estimated_file_size = int(math.ceil(estimated_file_size))
|
||||||
|
|
||||||
yield self.tar_file_header(synthetic_image_id + '/layer.tar', estimated_file_size)
|
yield self.tar_file_header(synthetic_image_id + '/layer.tar', estimated_file_size)
|
||||||
|
|
||||||
# Yield the contents of the merged layer.
|
# Yield the contents of the merged layer.
|
||||||
|
|
|
@ -60,6 +60,7 @@ logger = logging.getLogger(__name__)
|
||||||
def generate_csrf():
|
def generate_csrf():
|
||||||
return generate_csrf_token()
|
return generate_csrf_token()
|
||||||
|
|
||||||
|
|
||||||
@testbp.route('/feature/<feature_name>', methods=['POST'])
|
@testbp.route('/feature/<feature_name>', methods=['POST'])
|
||||||
def set_feature(feature_name):
|
def set_feature(feature_name):
|
||||||
import features
|
import features
|
||||||
|
@ -67,6 +68,15 @@ def set_feature(feature_name):
|
||||||
features._FEATURES[feature_name].value = request.get_json()['value']
|
features._FEATURES[feature_name].value = request.get_json()['value']
|
||||||
return jsonify({'old_value': old_value})
|
return jsonify({'old_value': old_value})
|
||||||
|
|
||||||
|
|
||||||
|
@testbp.route('/removeuncompressed/<image_id>', methods=['POST'])
|
||||||
|
def removeuncompressed(image_id):
|
||||||
|
image = model.image.get_image_by_id('devtable', 'newrepo', image_id)
|
||||||
|
image.storage.uncompressed_size = None
|
||||||
|
image.storage.save()
|
||||||
|
return 'OK'
|
||||||
|
|
||||||
|
|
||||||
@testbp.route('/addtoken', methods=['POST'])
|
@testbp.route('/addtoken', methods=['POST'])
|
||||||
def addtoken():
|
def addtoken():
|
||||||
another_token = model.token.create_delegate_token('devtable', 'newrepo', 'my-new-token', 'write')
|
another_token = model.token.create_delegate_token('devtable', 'newrepo', 'my-new-token', 'write')
|
||||||
|
@ -263,8 +273,12 @@ class V1RegistryPushMixin(V1RegistryMixin):
|
||||||
last_image_id = image_id
|
last_image_id = image_id
|
||||||
|
|
||||||
# PUT /v1/images/{imageID}/json
|
# PUT /v1/images/{imageID}/json
|
||||||
|
image_json_data = {'id': image_id}
|
||||||
|
if 'size' in image_data:
|
||||||
|
image_json_data['Size'] = image_data['size']
|
||||||
|
|
||||||
self.conduct('PUT', '/v1/images/%s/json' % image_id,
|
self.conduct('PUT', '/v1/images/%s/json' % image_id,
|
||||||
data=json.dumps({'id': image_id}), auth='sig')
|
data=json.dumps(image_json_data), auth='sig')
|
||||||
|
|
||||||
# PUT /v1/images/{imageID}/layer
|
# PUT /v1/images/{imageID}/layer
|
||||||
tar_file_info = tarfile.TarInfo(name='image_name')
|
tar_file_info = tarfile.TarInfo(name='image_name')
|
||||||
|
@ -284,7 +298,7 @@ class V1RegistryPushMixin(V1RegistryMixin):
|
||||||
data=StringIO(layer_bytes), auth='sig')
|
data=StringIO(layer_bytes), auth='sig')
|
||||||
|
|
||||||
# PUT /v1/images/{imageID}/checksum
|
# PUT /v1/images/{imageID}/checksum
|
||||||
checksum = compute_simple(StringIO(layer_bytes), json.dumps({'id': image_id}))
|
checksum = compute_simple(StringIO(layer_bytes), json.dumps(image_json_data))
|
||||||
self.conduct('PUT', '/v1/images/%s/checksum' % image_id,
|
self.conduct('PUT', '/v1/images/%s/checksum' % image_id,
|
||||||
headers={'X-Docker-Checksum-Payload': checksum},
|
headers={'X-Docker-Checksum-Payload': checksum},
|
||||||
auth='sig')
|
auth='sig')
|
||||||
|
@ -1112,6 +1126,27 @@ class VerbTests(RegistryTestCaseMixin, V1RegistryPushMixin, LiveServerTestCase):
|
||||||
self.assertTrue(updated_image_id in tar.getnames())
|
self.assertTrue(updated_image_id in tar.getnames())
|
||||||
|
|
||||||
|
|
||||||
|
def test_estimated_squashing(self):
|
||||||
|
initial_images = [
|
||||||
|
{
|
||||||
|
'id': 'initialid',
|
||||||
|
'contents': 'the initial image',
|
||||||
|
'size': 2002,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
# Create the repo.
|
||||||
|
self.do_push('devtable', 'newrepo', 'devtable', 'password', images=initial_images)
|
||||||
|
|
||||||
|
# NULL out the uncompressed size to force estimation.
|
||||||
|
self.conduct('POST', '/__test/removeuncompressed/initialid')
|
||||||
|
|
||||||
|
# Pull the squashed version of the tag.
|
||||||
|
initial_image_id = '91081df45b58dc62dd207441785eef2b895f0383fbe601c99a3cf643c79957dc'
|
||||||
|
tar = self.get_squashed_image()
|
||||||
|
self.assertTrue(initial_image_id in tar.getnames())
|
||||||
|
|
||||||
|
|
||||||
def test_multilayer_squashing(self):
|
def test_multilayer_squashing(self):
|
||||||
images = [
|
images = [
|
||||||
{
|
{
|
||||||
|
|
Reference in a new issue