import tempfile class Storage(object): """Storage is organized as follow: $ROOT/images//json $ROOT/images//layer $ROOT/repositories/// """ # Useful if we want to change those locations later without rewriting # the code which uses Storage repositories = 'repositories' images = 'images' shared_images = 'sharedimages' # Set the IO buffer to 64kB buffer_size = 64 * 1024 @staticmethod def temp_store_handler(): tmpf = tempfile.TemporaryFile() def fn(buf): try: tmpf.write(buf) except IOError: pass return tmpf, fn 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) def image_json_path(self, namespace, repository, image_id, storage_uuid): base_path = self.image_path(namespace, repository, image_id, storage_uuid) return '{0}/json'.format(base_path) def image_mark_path(self, namespace, repository, image_id, storage_uuid): base_path = self.image_path(namespace, repository, image_id, storage_uuid) return '{0}/_inprogress'.format(base_path) def image_checksum_path(self, namespace, repository, image_id, storage_uuid): base_path = self.image_path(namespace, repository, image_id, storage_uuid) return '{0}/_checksum'.format(base_path) def image_layer_path(self, namespace, repository, image_id, storage_uuid): base_path = self.image_path(namespace, repository, image_id, storage_uuid) return '{0}/layer'.format(base_path) def image_ancestry_path(self, namespace, repository, image_id, storage_uuid): base_path = self.image_path(namespace, repository, image_id, storage_uuid) return '{0}/ancestry'.format(base_path) def image_file_trie_path(self, namespace, repository, image_id, storage_uuid): base_path = self.image_path(namespace, repository, image_id, storage_uuid) return '{0}/files.trie'.format(base_path) def image_file_diffs_path(self, namespace, repository, image_id, storage_uuid): base_path = self.image_path(namespace, repository, image_id, storage_uuid) return '{0}/diffs.json'.format(base_path) def get_direct_download_url(self, path, expires_in=60): return None 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