Merge "Add ftp support framework in freezer"
This commit is contained in:
commit
d6a0088676
|
@ -37,6 +37,7 @@ home = os.path.expanduser("~")
|
|||
DEFAULT_LVM_SNAPSIZE = '1G'
|
||||
DEFAULT_LVM_MOUNT_BASEDIR = '/var/lib/freezer'
|
||||
DEFAULT_LVM_SNAP_BASENAME = 'freezer_backup_snap'
|
||||
DEFAULT_FTP_PORT = 21
|
||||
DEFAULT_SSH_PORT = 22
|
||||
|
||||
_DEFAULT_LOG_LEVELS = ['amqp=WARN', 'amqplib=WARN', 'boto=WARN',
|
||||
|
@ -86,7 +87,8 @@ DEFAULT_PARAMS = {
|
|||
'incremental': None, 'consistency_check': False,
|
||||
'consistency_checksum': None, 'nova_restore_network': None,
|
||||
'cindernative_backup_id': None, 'sync': True, 'engine_name': 'tar',
|
||||
'timeout': 120, 'project_id': None,
|
||||
'timeout': 120, 'project_id': None, 'ftp_username': '',
|
||||
'ftp_password': '', 'ftp_host': '', 'ftp_port': DEFAULT_FTP_PORT,
|
||||
}
|
||||
|
||||
_COMMON = [
|
||||
|
@ -435,12 +437,12 @@ _COMMON = [
|
|||
cfg.StrOpt('storage',
|
||||
dest='storage',
|
||||
default=DEFAULT_PARAMS['storage'],
|
||||
choices=['local', 'swift', 'ssh', 's3'],
|
||||
help="Storage for backups. Can be Swift, Local, SSH and S3 "
|
||||
"now. Swift is default storage now. Local stores backups"
|
||||
"on the same defined path, swift will store files in "
|
||||
"container, and s3 will store files in bucket in S3 "
|
||||
"compatible storage."
|
||||
choices=['local', 'swift', 'ssh', 's3', 'ftp', 'ftps'],
|
||||
help="Storage for backups. Can be Swift, Local, SSH(SFTP), "
|
||||
"FTP, FTPS and S3 now. Swift is default storage now. "
|
||||
"Local stores backups on the same defined path, "
|
||||
"swift will store files in container, and S3 will "
|
||||
"store files in bucket in S3 compatible storage."
|
||||
),
|
||||
cfg.StrOpt('access-key',
|
||||
dest='access_key',
|
||||
|
@ -465,22 +467,22 @@ _COMMON = [
|
|||
cfg.StrOpt('ssh-password',
|
||||
dest='ssh_password',
|
||||
default=DEFAULT_PARAMS['ssh_password'],
|
||||
help="Remote password for ssh(sftp) storage"
|
||||
help="Remote password for SSH(SFTP) storage"
|
||||
),
|
||||
cfg.StrOpt('ssh-username',
|
||||
dest='ssh_username',
|
||||
default=DEFAULT_PARAMS['ssh_username'],
|
||||
help="Remote username for ssh(sftp) storage only"
|
||||
help="Remote username for SSH(SFTP)) storage only"
|
||||
),
|
||||
cfg.StrOpt('ssh-host',
|
||||
dest='ssh_host',
|
||||
default=DEFAULT_PARAMS['ssh_host'],
|
||||
help="Remote host for ssh(sftp) storage only"
|
||||
help="Remote host for SSH(SFTP) storage only"
|
||||
),
|
||||
cfg.IntOpt('ssh-port',
|
||||
dest='ssh_port',
|
||||
default=DEFAULT_PARAMS['ssh_port'],
|
||||
help="Remote port for ssh(sftp) storage"
|
||||
help="Remote port for SSH(SFTP) storage"
|
||||
" only (default 22)"
|
||||
),
|
||||
cfg.StrOpt('config',
|
||||
|
@ -542,6 +544,26 @@ _COMMON = [
|
|||
"If set action to admin and set the parameter, "
|
||||
"it should keep the last N fullbackups, "
|
||||
"other backups should be deleted"),
|
||||
cfg.StrOpt('ftp-password',
|
||||
dest='ftp_password',
|
||||
default=DEFAULT_PARAMS['ftp_password'],
|
||||
help="Remote password for FTP, FTPS storage"
|
||||
),
|
||||
cfg.StrOpt('ftp-username',
|
||||
dest='ftp_username',
|
||||
default=DEFAULT_PARAMS['ftp_username'],
|
||||
help="Remote username for FTP, FTPS storage"
|
||||
),
|
||||
cfg.StrOpt('ftp-host',
|
||||
dest='ftp_host',
|
||||
default=DEFAULT_PARAMS['ftp_host'],
|
||||
help="Remote host for FTP, FTPS storage"
|
||||
),
|
||||
cfg.IntOpt('ftp-port',
|
||||
dest='ftp_port',
|
||||
default=DEFAULT_PARAMS['ftp_port'],
|
||||
help="Remote port for FTP, FTPS storage (default 21)"
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ class NovaEngine(engine.BackupEngine):
|
|||
bucket_name=bucket_name,
|
||||
key=object_name
|
||||
)['Body'].read()
|
||||
elif self.storage._type in ['local', 'ssh']:
|
||||
elif self.storage._type in ['local', 'ssh', 'ftp', 'ftps']:
|
||||
backup_basepath = os.path.join(self.storage.storage_path,
|
||||
'project_' + project_id)
|
||||
with self.storage.open(backup_basepath, 'rb') as backup_file:
|
||||
|
@ -186,7 +186,7 @@ class NovaEngine(engine.BackupEngine):
|
|||
key=object_name,
|
||||
data=data
|
||||
)
|
||||
elif self.storage._type in ['local', 'ssh']:
|
||||
elif self.storage._type in ['local', 'ssh', 'ftp', 'ftps']:
|
||||
backup_basepath = os.path.join(self.storage.storage_path,
|
||||
"project_" + project_id)
|
||||
with self.storage.open(backup_basepath, 'wb') as backup_file:
|
||||
|
|
|
@ -593,7 +593,8 @@ class AdminJob(Job):
|
|||
self.storage.segments,
|
||||
cinder_vol_id
|
||||
)
|
||||
elif self.storage.type in ['local', 'ssh', 's3']:
|
||||
elif self.storage.type in \
|
||||
['local', 'ssh', 's3', 'ftp', 'ftps']:
|
||||
path_prefix = "{0}/{1}".format(
|
||||
self.storage.storage_path,
|
||||
cinder_vol_id
|
||||
|
|
|
@ -26,6 +26,7 @@ import sys
|
|||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
from oslo_utils import importutils
|
||||
|
||||
from freezer.common import client_manager
|
||||
from freezer.common import config as freezer_config
|
||||
|
@ -229,6 +230,14 @@ def storage_from_dict(backup_args, max_segment_size):
|
|||
int(backup_args['ssh_port']),
|
||||
max_segment_size=max_segment_size,
|
||||
ssh_key_path=backup_args['ssh_key'])
|
||||
elif storage_name in ["ftp", "ftps"]:
|
||||
args = [container, backup_args['ftp_password'],
|
||||
backup_args['ftp_username'],
|
||||
backup_args['ftp_host'], int(backup_args['ftp_port']),
|
||||
max_segment_size]
|
||||
storage = importutils.import_object(
|
||||
"freezer.storage.{0}.{1}Storage".format(
|
||||
storage_name, storage_name.capitalize()), *args)
|
||||
else:
|
||||
raise Exception("No storage found for name {0}".format(
|
||||
backup_args['storage']))
|
||||
|
|
|
@ -62,12 +62,13 @@ class RestoreOs(object):
|
|||
elif self.storage.type == "local":
|
||||
path = "{0}/{1}".format(self.container, path)
|
||||
backups = os.listdir(os.path.abspath(path))
|
||||
elif self.storage.type == "ssh":
|
||||
elif self.storage.type in ["ssh", 'ftp', 'ftps']:
|
||||
path = "{0}/{1}".format(self.container, path)
|
||||
backups = self.storage.listdir(path)
|
||||
else:
|
||||
msg = ("{} storage type is not supported at the moment."
|
||||
" Try local, swift or ssh".format(self.storage.type))
|
||||
" Try local, SWIFT, SSH(SFTP), FTP or FTPS ".
|
||||
format(self.storage.type))
|
||||
print(msg)
|
||||
raise BaseException(msg)
|
||||
backups = list(filter(lambda x: x >= restore_from_timestamp, backups))
|
||||
|
@ -160,7 +161,7 @@ class RestoreOs(object):
|
|||
disk_format="raw",
|
||||
data=data)
|
||||
return info, image
|
||||
elif self.storage.type == 'ssh':
|
||||
elif self.storage.type in ['ssh', 'ftp', 'ftps']:
|
||||
image_file = "{0}/{1}/{2}/{3}".format(self.container, path,
|
||||
backup, path)
|
||||
metadata_file = "{0}/{1}/{2}/metadata".format(self.container,
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
"""
|
||||
(c) Copyright 2018 ZTE Corporation.
|
||||
|
||||
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 errno
|
||||
# import ftplib
|
||||
# import os
|
||||
# import shutil
|
||||
# import socket
|
||||
# import tempfile
|
||||
from oslo_log import log
|
||||
|
||||
from freezer.storage import fslike
|
||||
# from freezer.utils import utils
|
||||
|
||||
CHUNK_SIZE = 32768
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class FtpStorage(fslike.FsLikeStorage):
|
||||
"""
|
||||
:type ftp: paramiko.SFTPClient
|
||||
"""
|
||||
_type = 'ftp'
|
||||
|
||||
def __init__(self, storage_path, remote_pwd,
|
||||
remote_username, remote_ip, port, max_segment_size):
|
||||
pass
|
|
@ -0,0 +1,41 @@
|
|||
"""
|
||||
(c) Copyright 2018 ZTE Corporation.
|
||||
|
||||
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 errno
|
||||
# import ftplib
|
||||
# import os
|
||||
# import shutil
|
||||
# import socket
|
||||
# import tempfile
|
||||
from oslo_log import log
|
||||
|
||||
from freezer.storage import fslike
|
||||
# from freezer.utils import utils
|
||||
|
||||
CHUNK_SIZE = 32768
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class FtpsStorage(fslike.FsLikeStorage):
|
||||
"""
|
||||
:type ftps: paramiko.SFTPClient
|
||||
"""
|
||||
_type = 'ftps'
|
||||
|
||||
def __init__(self, storage_path, remote_pwd,
|
||||
remote_username, remote_ip, port, max_segment_size):
|
||||
pass
|
Loading…
Reference in New Issue