Simplify the SSH clients

Realistically we just want to execute a command, potentially inside a
container. No need for all the context managers cleverness.

Change-Id: I1a85dcd310f9ec0b24435dcd2d8446de7f48d65b
This commit is contained in:
Artom Lifshitz 2019-01-21 16:13:57 -05:00
parent 22697b5f5b
commit 9534b5f682

View File

@ -12,83 +12,48 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from contextlib import contextmanager
try:
from shlex import quote
except ImportError:
from pipes import quote
from oslo_log import log as logging
from tempest import config
from tempest.lib.common import ssh
CONF = config.CONF
LOG = logging.getLogger(__name__)
def sudo(command):
return 'sudo %s' % command
def in_container(container_name, command):
if CONF.whitebox.containers:
return 'docker exec -u root %s %s' % (container_name, command)
return command
class SSHClient(object):
"""A client to execute remote commands, based on tempest.lib.common.ssh."""
_prefix_command = '/bin/bash -c'
def __init__(self):
def __init__(self, hostname):
self.ssh_key = CONF.whitebox.ctlplane_ssh_private_key_path
self.ssh_user = CONF.whitebox.ctlplane_ssh_username
self.host = hostname
def execute(self, hostname=None, cmd=None):
ssh_client = ssh.Client(hostname, self.ssh_user,
def execute(self, command):
ssh_client = ssh.Client(self.host, self.ssh_user,
key_filename=self.ssh_key)
cmd = self._prefix_command + ' ' + quote(cmd)
return ssh_client.exec_command(cmd)
@contextmanager
def prefix_command(self, prefix_command=None):
saved_prefix = self._prefix_command
self._prefix_command = prefix_command
yield self
self._prefix_command = saved_prefix
@contextmanager
def sudo_command(self, user=None):
if user is not None:
user_arg = '-u {}'.format(user)
else:
user_arg = ''
cmd = 'sudo {} /bin/bash -c'.format(user_arg)
with self.prefix_command(cmd) as p:
yield p
@contextmanager
def container_command(self, container_name, user=None):
if user is not None:
user_arg = '-u {}'.format(user)
else:
user_arg = ''
cmd = 'sudo docker exec {} -i {} /bin/bash -c'.format(
user_arg, container_name)
with self.prefix_command(cmd) as p:
yield p
LOG.debug("Executing %s", command)
return ssh_client.exec_command(command)
class VirshXMLClient(SSHClient):
"""A client to obtain libvirt XML from a remote host."""
def __init__(self, hostname=None):
super(VirshXMLClient, self).__init__()
self.host = hostname
def dumpxml(self, domain):
if CONF.whitebox.containers:
ctx = self.container_command('nova_compute', user='root')
else:
ctx = self.sudo_command()
with ctx:
command = "virsh dumpxml {}".format(domain)
return self.execute(self.host, command)
command = sudo(in_container('nova_libvirt',
'virsh dumpxml %s' % domain))
return self.execute(command)
def capabilities(self):
if CONF.whitebox.containers:
ctx = self.container_command('nova_compute', user='root')
else:
ctx = self.sudo_command()
with ctx:
command = "virsh capabilities"
return self.execute(self.host, command)
command = sudo(in_container('nova_libvirt', 'virsh capabilities'))
return self.execute(command)