2013-11-11 21:41:33 +00:00
|
|
|
import tempfile
|
|
|
|
|
|
|
|
|
2014-04-03 21:31:46 +00:00
|
|
|
class BaseStorage(object):
|
2013-11-07 04:21:12 +00:00
|
|
|
|
|
|
|
"""Storage is organized as follow:
|
|
|
|
$ROOT/images/<image_id>/json
|
|
|
|
$ROOT/images/<image_id>/layer
|
|
|
|
$ROOT/repositories/<namespace>/<repository_name>/<tag_name>
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Useful if we want to change those locations later without rewriting
|
|
|
|
# the code which uses Storage
|
|
|
|
repositories = 'repositories'
|
|
|
|
images = 'images'
|
2014-02-14 21:06:30 +00:00
|
|
|
shared_images = 'sharedimages'
|
2013-11-07 04:21:12 +00:00
|
|
|
# Set the IO buffer to 64kB
|
|
|
|
buffer_size = 64 * 1024
|
|
|
|
|
2013-11-11 21:41:33 +00:00
|
|
|
@staticmethod
|
|
|
|
def temp_store_handler():
|
|
|
|
tmpf = tempfile.TemporaryFile()
|
|
|
|
|
|
|
|
def fn(buf):
|
|
|
|
try:
|
|
|
|
tmpf.write(buf)
|
|
|
|
except IOError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
return tmpf, fn
|
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_path(self, namespace, repository, image_id, storage_uuid):
|
|
|
|
if storage_uuid:
|
|
|
|
return '{0}/{1}/'.format(self.shared_images, storage_uuid)
|
|
|
|
else:
|
|
|
|
return '{0}/{1}/{2}/{3}/'.format(self.images, namespace, repository,
|
|
|
|
image_id)
|
2013-11-07 04:21:12 +00:00
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_json_path(self, namespace, repository, image_id, storage_uuid):
|
|
|
|
base_path = self.image_path(namespace, repository, image_id, storage_uuid)
|
2014-02-21 17:05:03 +00:00
|
|
|
return '{0}json'.format(base_path)
|
2014-01-09 22:13:26 +00:00
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_mark_path(self, namespace, repository, image_id, storage_uuid):
|
|
|
|
base_path = self.image_path(namespace, repository, image_id, storage_uuid)
|
2014-02-21 17:05:03 +00:00
|
|
|
return '{0}_inprogress'.format(base_path)
|
2013-11-07 04:21:12 +00:00
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_checksum_path(self, namespace, repository, image_id, storage_uuid):
|
|
|
|
base_path = self.image_path(namespace, repository, image_id, storage_uuid)
|
2014-02-21 17:05:03 +00:00
|
|
|
return '{0}_checksum'.format(base_path)
|
2013-11-07 04:21:12 +00:00
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_layer_path(self, namespace, repository, image_id, storage_uuid):
|
|
|
|
base_path = self.image_path(namespace, repository, image_id, storage_uuid)
|
2014-02-21 17:05:03 +00:00
|
|
|
return '{0}layer'.format(base_path)
|
2013-11-07 04:21:12 +00:00
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_ancestry_path(self, namespace, repository, image_id, storage_uuid):
|
|
|
|
base_path = self.image_path(namespace, repository, image_id, storage_uuid)
|
2014-02-21 17:05:03 +00:00
|
|
|
return '{0}ancestry'.format(base_path)
|
2013-11-07 04:21:12 +00:00
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_file_trie_path(self, namespace, repository, image_id,
|
|
|
|
storage_uuid):
|
|
|
|
base_path = self.image_path(namespace, repository, image_id, storage_uuid)
|
2014-02-21 17:05:03 +00:00
|
|
|
return '{0}files.trie'.format(base_path)
|
2013-11-07 04:21:12 +00:00
|
|
|
|
2014-02-14 21:06:30 +00:00
|
|
|
def image_file_diffs_path(self, namespace, repository, image_id,
|
|
|
|
storage_uuid):
|
|
|
|
base_path = self.image_path(namespace, repository, image_id, storage_uuid)
|
2014-02-21 17:05:03 +00:00
|
|
|
return '{0}diffs.json'.format(base_path)
|
2013-11-07 04:21:12 +00:00
|
|
|
|
2013-12-04 00:39:07 +00:00
|
|
|
def get_direct_download_url(self, path, expires_in=60):
|
|
|
|
return None
|
|
|
|
|
2013-11-07 04:21:12 +00:00
|
|
|
def get_content(self, path):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def put_content(self, path, content):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def stream_read(self, path):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def stream_read_file(self, path):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def stream_write(self, path, fp):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def list_directory(self, path=None):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def exists(self, path):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def remove(self, path):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def get_size(self, path):
|
|
|
|
raise NotImplementedError
|