# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import abc from oslo_config import cfg from oslo_log import log as logging from oslo_utils import importutils import six from cinder import exception from cinder.i18n import _ LOG = logging.getLogger(__name__) CONF = cfg.CONF # NOTE(ZhengMa): The order of the option is improtant, accelerators # are looked by this list order # Be careful to edit it _ACCEL_PATH_PREFERENCE_ORDER_LIST = [ 'cinder.image.accelerators.qat.AccelQAT', 'cinder.image.accelerators.gzip.AccelGZIP', ] @six.add_metaclass(abc.ABCMeta) class AccelBase(object): def __init__(self): return @abc.abstractmethod def is_accel_exist(self): return @abc.abstractmethod def compress_img(self, run_as_root): return @abc.abstractmethod def decompress_img(self, run_as_root): return class ImageAccel(object): def __init__(self, src, dest): self.src = src self.dest = dest self.compression_format = CONF.compression_format if(self.compression_format == 'gzip'): self._accel_engine_path = _ACCEL_PATH_PREFERENCE_ORDER_LIST else: self._accel_engine_path = None self.engine = self._get_engine() def _get_engine(self, *args, **kwargs): if self._accel_engine_path: for accel in self._accel_engine_path: engine_cls = importutils.import_class(accel) eng = engine_cls(*args, **kwargs) if eng.is_accel_exist(): return eng ex_msg = _("No valid accelerator") raise exception.CinderException(ex_msg) def is_engine_ready(self): if not self.engine: return False if not self.engine.is_accel_exist(): return False return True def compress_img(self, run_as_root): if not self.is_engine_ready(): return self.engine.compress_img(self.src, self.dest, run_as_root) def decompress_img(self, run_as_root): if not self.is_engine_ready(): return self.engine.decompress_img(self.src, self.dest, run_as_root) def is_gzip_compressed(image_file): # The first two bytes of a gzip file are: 1f 8b GZIP_MAGIC_BYTES = b'\x1f\x8b' with open(image_file, 'rb') as f: return f.read(2) == GZIP_MAGIC_BYTES