Add migration code for calculating the uncompressed size from the layer data itself

This commit is contained in:
Joseph Schorr 2014-09-26 12:21:50 -04:00
parent 48ed255a55
commit 77c46af70b

View file

@ -5,12 +5,14 @@ from data import model
from data.database import ImageStorage from data.database import ImageStorage
from app import app, storage as store from app import app, storage as store
from data.database import db from data.database import db
from gzip import GzipFile
from StringIO import StringIO
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def backfill_sizes(): def backfill_sizes_from_json():
query = (ImageStorage query = (ImageStorage
.select() .select()
.where(ImageStorage.uncompressed_size == None, ImageStorage.uploading == False) .where(ImageStorage.uncompressed_size == None, ImageStorage.uploading == False)
@ -47,8 +49,57 @@ def backfill_sizes():
image_storage.save() image_storage.save()
def backfill_sizes_from_data():
storage_ids = list(ImageStorage
.select(ImageStorage.uuid)
.where(ImageStorage.uncompressed_size == -1, ImageStorage.uploading == False))
counter = 0
for uuid in [s.uuid for s in storage_ids]:
counter += 1
# Load the storage with locations.
logger.debug('Loading entry: %s (%s/%s)', uuid, counter, len(storage_ids))
with_locations = model.get_storage_by_uuid(uuid)
layer_size = -2
# Read the layer from backing storage.
logger.debug('Reading entry: %s (%s bytes)', uuid, with_locations.image_size)
try:
layer_data = store.get_content(with_locations.locations, store.image_layer_path(uuid))
except Exception as ex:
logger.debug('Could not read entry: %s. Reason: %s', uuid, ex)
continue
# Calculate the uncompressed size.
try:
layer_stream = StringIO(layer_data)
with GzipFile(fileobj=layer_stream, mode='rb') as gzip_file:
layer_size = len(gzip_file.read())
logger.debug('%s' % gzip_file.size)
layer_stream.close()
except Exception as ex:
logger.debug('Could not gunzip entry: %s. Reason: %s', uuid, ex)
continue
# Write the size to the image storage. We do so under a transaction AFTER checking to
# make sure the image storage still exists and has not changed.
logger.debug('Writing entry: %s. Size: %s', uuid, layer_size)
with app.config['DB_TRANSACTION_FACTORY'](db):
try:
current_record = model.get_storage_by_uuid(uuid)
except:
# Record no longer exists.
continue
if not current_record.uploading and current_record.uncompressed_size == -1:
current_record.uncompressed_size = layer_size
current_record.save()
if __name__ == "__main__": if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
logging.getLogger('boto').setLevel(logging.CRITICAL) logging.getLogger('boto').setLevel(logging.CRITICAL)
backfill_sizes() backfill_sizes_from_data()