Possibility to use ssh transports with password

Change-Id: I4a3ccd734c409e7e7821bd8669d59e63b55077e5
Closes-bug: #1530174
This commit is contained in:
Jedrzej Nowak 2015-12-30 19:59:47 +01:00
parent eb703d5ff8
commit de2ae20db3
4 changed files with 53 additions and 11 deletions

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
from solar.core.log import log
from solar.core.transports.base import Executor
from solar.core.transports.base import SyncTransport
@ -31,31 +33,49 @@ class RsyncSyncTransport(SyncTransport):
user = transport['user']
# port = transport['port']
# TODO: user port somehow
key = transport['key']
key = transport.get('key')
password = transport.get('password')
return {
'ssh_key': key,
'ssh_password': password,
'ssh_user': user,
'host_string': '{}@{}'.format(user, host)
}
def _ssh_cmd(self, settings):
if settings['ssh_key']:
return ('ssh', '-i', settings['ssh_key'])
elif settings['ssh_password']:
return ('sshpass', '-e', 'ssh')
else:
raise Exception("No key and no password given")
def copy(self, resource, _from, _to, use_sudo=False):
log.debug("RSYNC: %s -> %s", _from, _to)
if use_sudo:
rsync_path = "sudo rsync"
else:
rsync_path = "rsync"
rsync_props = self._rsync_props(resource)
rsync_cmd = ('rsync -az -e "ssh -i %(ssh_key)s" '
ssh_cmd = ' '.join(self._ssh_cmd(rsync_props))
rsync_cmd = ('rsync -az -e "%(ssh_cmd)s" '
'--rsync-path="%(rsync_path)s" %(_from)s '
'%(rsync_host)s:%(_to)s') % dict(
rsync_path=rsync_path,
ssh_key=rsync_props['ssh_key'],
ssh_cmd=ssh_cmd,
rsync_host=rsync_props['host_string'],
_from=_from,
_to=_to)
if rsync_props.get('ssh_password'):
env = os.environ.copy()
env['SSHPASS'] = rsync_props['ssh_password']
else:
env = os.environ
rsync_executor = lambda transport: execute(
rsync_cmd, shell=True)
rsync_cmd, shell=True, env=env)
log.debug("RSYNC CMD: %r" % rsync_cmd)

View File

@ -32,11 +32,18 @@ class _SSHTransport(object):
host = resource.ip()
user = transport['user']
port = transport['port']
key = transport['key']
return {
settings = {
'host_string': "{}@{}:{}".format(user, host, port),
'key_filename': key,
}
key = transport.get('key', None)
password = transport.get('password', None)
if not key and not password:
raise Exception("No key and no password given")
elif not key:
settings['password'] = password
elif not password:
settings['key'] = key
return settings
class SSHSyncTransport(SyncTransport, _SSHTransport):

View File

@ -13,6 +13,8 @@
# under the License.
import os
from solar.core.log import log
from solar.core.transports.base import RunTransport
from solar.utils import execute
@ -25,9 +27,11 @@ class _RawSSHTransport(object):
host = resource.ip()
user = transport['user']
port = transport['port']
key = transport['key']
key = transport.get('key')
password = transport.get('password')
return {'ssh_user': user,
'ssh_key': key,
'ssh_password': password,
'port': port,
'ip': host}
@ -36,7 +40,12 @@ class _RawSSHTransport(object):
settings['ip'])
def _ssh_cmd(self, settings):
return ('ssh', '-i', settings['ssh_key'])
if settings['ssh_key']:
return ('ssh', '-i', settings['ssh_key'])
elif settings['ssh_password']:
return ('sshpass', '-e', 'ssh')
else:
raise Exception("No key and no password given")
class RawSSHRunTransport(RunTransport, _RawSSHTransport):
@ -64,10 +73,15 @@ class RawSSHRunTransport(RunTransport, _RawSSHTransport):
remote_cmd = '\"%s\"' % ' && '.join(commands)
settings = self.settings(resource)
if settings.get('ssh_password'):
env = os.environ.copy()
env['SSHPASS'] = settings['ssh_password']
else:
env = os.environ
ssh_cmd = self._ssh_cmd(settings)
ssh_cmd += (self._ssh_command_host(settings), remote_cmd)
log.debug("RAW SSH CMD: %r", ssh_cmd)
# TODO convert it to SolarRunResult
return execute(' '.join(ssh_cmd), shell=True)
return execute(' '.join(ssh_cmd), shell=True, env=env)

View File

@ -47,11 +47,12 @@ def communicate(command, data):
return popen.communicate(input=data)[0]
def execute(command, shell=False):
def execute(command, shell=False, env=None):
popen = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
shell=shell)
out, err = popen.communicate()
return popen.returncode, out, err