trio2o/novaproxy/nova/image/sync/drivers/filesystem.py

107 lines
3.8 KiB
Python

import logging
import sys
from oslo.config import cfg
import pxssh
import pexpect
from nova.i18n import _
from nova.image import exception
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
sync_opt = [
cfg.IntOpt('scp_copy_timeout', default=3600,
help=_('when snapshot, max wait (second)time for snapshot '
'status become active.'),
deprecated_opts=[cfg.DeprecatedOpt('scp_copy_timeout',
group='DEFAULT')]),
]
CONF.register_opts(sync_opt, group='sync')
def _get_ssh(hostname, username, password):
s = pxssh.pxssh()
s.login(hostname, username, password, original_prompt='[#$>]')
s.logfile = sys.stdout
return s
class Store(object):
def copy_to(self, from_location, to_location, candidate_path=None):
from_store_loc = from_location
to_store_loc = to_location
LOG.debug(_('from_store_loc is: %s'), from_store_loc)
if from_store_loc['host'] == to_store_loc['host'] and \
from_store_loc['path'] == to_store_loc['path']:
LOG.info(_('The from_loc is same to to_loc, no need to copy. the '
'host:path is %s:%s') % (from_store_loc['host'],
from_store_loc['path']))
return 'file://%s' % to_store_loc['path']
to_host = r"""{username}@{host}""".format(
username=to_store_loc['login_user'],
host=to_store_loc['host'])
to_path = r"""{to_host}:{path}""".format(to_host=to_host,
path=to_store_loc['path'])
copy_path = from_store_loc['path']
try:
from_ssh = _get_ssh(from_store_loc['host'],
from_store_loc['login_user'],
from_store_loc['login_password'])
except Exception:
msg = _('ssh login failed to %(user)s:%(passwd)s %(host)s' %
{'user': from_store_loc['login_user'],
'passwd': from_store_loc['login_password'],
'host': from_store_loc['host']
})
LOG.exception(msg)
raise exception.GlanceSyncException(reason=msg)
from_ssh.sendline('ls %s' % copy_path)
from_ssh.prompt()
if 'cannot access' in from_ssh.before or \
'No such file' in from_ssh.before:
if candidate_path:
from_ssh.sendline('ls %s' % candidate_path)
from_ssh.prompt()
if 'cannot access' not in from_ssh.before and \
'No such file' not in from_ssh.before:
copy_path = candidate_path
else:
msg = _("the image path for copy to is not exists, file copy"
"failed: path is %s" % copy_path)
LOG.exception(msg)
raise exception.GlanceSyncException(reason=msg)
from_ssh.sendline('scp -P 22 %s %s' % (copy_path, to_path))
while True:
scp_index = from_ssh.expect(['.yes/no.', '.assword:.',
pexpect.TIMEOUT])
if scp_index == 0:
from_ssh.sendline('yes')
from_ssh.prompt()
elif scp_index == 1:
from_ssh.sendline(to_store_loc['login_password'])
from_ssh.prompt(timeout=CONF.sync.scp_copy_timeout)
break
else:
msg = _("scp commond execute failed, with copy_path %s and "
"to_path %s" % (copy_path, to_path))
LOG.exception(msg)
raise exception.GlanceSyncException(reason=msg)
if from_ssh:
from_ssh.logout()
return 'file://%s' % to_store_loc['path']