Refactoring Freezer Engines

Added engine loading automatically using option --engine.
Added manager module to load engines automatically
manager module will be used to list available engines
added exceptions package to group all exceptions in one place

Change-Id: I0c25553ec168e0b6fa825e98a77b625956016117
Implements: blueprint pluggable-freezer-engines
changes/04/381904/9
Saad Zaher 7 years ago
parent 965381d109
commit 982c7ef818

@ -78,7 +78,7 @@ DEFAULT_PARAMS = {
'overwrite': False, 'incremental': None,
'consistency_check': False, 'consistency_checksum': None,
'nova_restore_network': None, 'cindernative_backup_id': None,
'sync': True
'sync': True, 'engine_name': 'tar'
}
_COMMON = [
@ -110,6 +110,11 @@ _COMMON = [
help="Set the technology to back from. Options are, fs "
"(filesystem),mongo (MongoDB), mysql (MySQL), sqlserver "
"(SQL Server) Default set to fs"),
cfg.StrOpt('engine',
short='e',
dest='engine_name',
default=DEFAULT_PARAMS['engine_name'],
help="Engine to be used for backup/restore."),
cfg.StrOpt('container',
short='C',
default=DEFAULT_PARAMS['container'],

@ -13,7 +13,6 @@ 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.
Freezer general utils functions
"""
import abc
@ -29,7 +28,7 @@ import time
from oslo_log import log
from freezer.engine.exceptions import EngineException
from freezer.exceptions import engine as engine_exceptions
from freezer.storage import base
from freezer.utils import streaming
from freezer.utils import utils
@ -178,8 +177,10 @@ class BackupEngine(object):
got_exception = (handle_except_queue(write_except_queue) or
got_exception)
if (got_exception):
raise EngineException("Engine error. Failed to backup.")
if got_exception:
raise engine_exceptions.EngineException(
"Engine error. Failed to backup."
)
with open(freezer_meta, mode='wb') as b_file:
b_file.write(json.dumps(self.metadata()))
@ -288,7 +289,9 @@ class BackupEngine(object):
got_exception)
if tar_stream.exitcode or got_exception:
raise EngineException("Engine error. Failed to restore.")
raise engine_exceptions.EngineException(
"Engine error. Failed to restore."
)
LOG.info(
'Restore completed successfully for backup name '

@ -1,19 +0,0 @@
# (c) Copyright 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# 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.
class EngineException(Exception):
def __init__(self, message):
super(EngineException, self).__init__(message)

@ -0,0 +1,77 @@
"""
(c) Copyright 2016 Hewlett-Packard Development Enterprise, L.P.
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 os
from oslo_config import cfg
from oslo_log import log
from oslo_utils import importutils
from freezer.exceptions import engine as engine_exceptions
CONF = cfg.CONF
LOG = log.getLogger(__name__)
class EngineManager(object):
"""
EngineManager, this class handles engines.
Lists all available engines
Load an engine
Checks if an engine does exists or not
"""
def __init__(self):
"""
This function does some initialization for the engine manager and
register some variables from the CONF variable into the local class
"""
self.engine_name = CONF.engine_name
self.engine_store = os.path.abspath(os.path.dirname(__file__))
self.engines = []
def load_engine(self, **kwargs):
""" Check if the engine exists or not. If not raise EngineNotFound
Error. If the engine exists then try to get an instance of this engine.
"""
if not self._check_engine_exists():
raise engine_exceptions.EngineNotFound(
"Engine {0} not found".format(self.engine_name)
)
return importutils.import_object(
"freezer.engine.{0}.{0}.{1}Engine".format(
self.engine_name,
self.engine_name.capitalize()
),
**kwargs
)
def _check_engine_exists(self):
engines = self.list_engines()
if self.engine_name not in engines:
return False
return True
def list_engines(self):
"""
Lists all engines in the engine directory
:return:
"""
engines = [
name for name in os.listdir(self.engine_store) if
os.path.isdir(os.path.join(self.engine_store, name))
]
self.engines = engines
return engines

@ -27,25 +27,25 @@ from freezer.utils import winutils
LOG = log.getLogger(__name__)
class TarBackupEngine(engine.BackupEngine):
class TarEngine(engine.BackupEngine):
def __init__(
self, compression_algo, dereference_symlink, exclude, storage,
is_windows, max_segment_size, encrypt_pass_file=None,
self, compression, symlinks, exclude, storage,
max_segment_size, encrypt_key=None,
dry_run=False):
"""
:type storage: freezer.storage.base.Storage
:return:
"""
self.compression_algo = compression_algo
self.encrypt_pass_file = encrypt_pass_file
self.dereference_symlink = dereference_symlink
self.compression_algo = compression
self.encrypt_pass_file = encrypt_key
self.dereference_symlink = symlinks
self.exclude = exclude
self.storage = storage
self.is_windows = is_windows
self.is_windows = winutils.is_windows()
self.dry_run = dry_run
self.max_segment_size = max_segment_size
super(TarBackupEngine, self).__init__(storage=storage)
super(TarEngine, self).__init__(storage=storage)
@property
def name(self):

@ -0,0 +1,31 @@
"""
(c) Copyright 2016 Hewlett-Packard Development Enterprise, L.P.
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.
"""
class EngineException(Exception):
msg = "An unknown error occurred."
def __init__(self, message=None, **kwargs):
if not message:
message = self.msg
super(EngineException, self).__init__(message, kwargs)
class EngineNotFound(EngineException):
def __init__(self, message):
super(EngineNotFound, self).__init__(message)

@ -26,7 +26,7 @@ from oslo_config import cfg
from oslo_log import log
from freezer.common import config as freezer_config
from freezer.engine.tar import tar_engine
from freezer.engine import manager as engine_manager
from freezer import job
from freezer.openstack import osclients
from freezer.storage import local
@ -35,7 +35,6 @@ from freezer.storage import ssh
from freezer.storage import swift
from freezer.utils import config
from freezer.utils import utils
from freezer.utils import winutils
CONF = cfg.CONF
LOG = log.getLogger(__name__)
@ -69,16 +68,16 @@ def freezer_main(backup_args):
else:
storage = storage_from_dict(backup_args.__dict__, max_segment_size)
backup_args.engine = tar_engine.TarBackupEngine(
backup_args.compression,
backup_args.dereference_symlink,
backup_args.exclude,
storage,
winutils.is_windows(),
backup_args.max_segment_size,
backup_args.encrypt_pass_file,
backup_args.dry_run)
engine_loader = engine_manager.EngineManager()
backup_args.engine = engine_loader.load_engine(
compression=backup_args.compression,
symlinks=backup_args.dereference_symlink,
exclude=backup_args.exclude,
storage=storage,
max_segment_size=backup_args.max_segment_size,
encrypt_key=backup_args.encrypt_pass_file,
dry_run=backup_args.dry_run
)
if hasattr(backup_args, 'trickle_command'):
if "tricklecount" in os.environ:
if int(os.environ.get("tricklecount")) > 1:

@ -31,12 +31,12 @@ from oslo_config import cfg
from oslo_config import fixture as cfg_fixture
from glanceclient.common.utils import IterableWithLength
from freezer.common import config
from freezer.storage import swift
from freezer.utils import utils
from freezer.engine.tar import tar as tar_engine
from freezer.openstack.osclients import OpenstackOpts
from freezer.openstack.osclients import OSClientManager
from freezer.engine.tar import tar_engine
from freezer.common import config
CONF = cfg.CONF
@ -340,7 +340,7 @@ class BackupOpt1(object):
self.storage = swift.SwiftStorage(self.client_manager,
self.container,
self.max_segment_size)
self.engine = tar_engine.TarBackupEngine(
self.engine = tar_engine.TarEngine(
self.compression, self.dereference_symlink,
self.exclude, self.storage, 1000, False)
self.client_manager.get_glance = Mock(return_value=FakeGlanceClient())

Loading…
Cancel
Save