Browse Source

Update tobiko shell package

Change-Id: I18d87d1763d5b501bd3694f79940d2b1ee441dd9
changes/78/793778/2
Federico Ressi 2 weeks ago
parent
commit
2cde963248
6 changed files with 74 additions and 10 deletions
  1. +1
    -0
      tobiko/shell/sh/__init__.py
  2. +3
    -2
      tobiko/shell/sh/_io.py
  3. +52
    -7
      tobiko/shell/sh/_ps.py
  4. +3
    -0
      tobiko/shell/ssh/__init__.py
  5. +14
    -0
      tobiko/shell/ssh/_client.py
  6. +1
    -1
      zuul.d/infrared.yaml

+ 1
- 0
tobiko/shell/sh/__init__.py View File

@ -66,6 +66,7 @@ str_from_stream = _process.str_from_stream
ShellProcessFixture = _process.ShellProcessFixture
PsError = _ps.PsError
PsProcess = _ps.PsProcess
PsWaitTimeout = _ps.PsWaitTimeout
list_all_processes = _ps.list_all_processes
list_kernel_processes = _ps.list_kernel_processes


+ 3
- 2
tobiko/shell/sh/_io.py View File

@ -85,13 +85,12 @@ class ShellReadable(ShellIOBase):
def readable(self):
return True
def read(self, size=None):
def read(self, size: int = None) -> bytes:
size = size or self.buffer_size
try:
chunk = self.delegate.read(size)
except IOError:
LOG.exception('Error reading from %r', self)
chunk = None
try:
self.close()
except Exception:
@ -100,6 +99,8 @@ class ShellReadable(ShellIOBase):
if chunk:
self._data_chunks.append(chunk)
elif chunk is None:
chunk = 'b'
return chunk
@property


+ 52
- 7
tobiko/shell/sh/_ps.py View File

@ -18,12 +18,20 @@ from __future__ import absolute_import
import collections
import re
import time
import typing
from oslo_log import log
import tobiko
from tobiko.shell.sh import _command
from tobiko.shell.sh import _exception
from tobiko.shell.sh import _execute
from tobiko.shell.sh import _hostname
LOG = log.getLogger(__name__)
class PsError(tobiko.TobikoException):
message = "Unable to list processes from host: {error}"
@ -36,6 +44,9 @@ class PsWaitTimeout(PsError):
IS_KERNEL_RE = re.compile('^\\[.*\\]$')
_NOT_FOUND = object()
class PsProcess(collections.namedtuple('PsProcess', ['ssh_client',
'pid',
'command'])):
@ -46,6 +57,27 @@ class PsProcess(collections.namedtuple('PsProcess', ['ssh_client',
def is_kernel(self):
return IS_KERNEL_RE.match(self.command) is not None
@property
def command_line(self) -> typing.Optional[_command.ShellCommand]:
command_line = self.__dict__.get('_command_line', _NOT_FOUND)
if command_line is _NOT_FOUND:
command_line = None
try:
output = _execute.execute(f'cat /proc/{self.pid}/cmdline',
ssh_client=self.ssh_client).stdout
except _exception.ShellCommandFailed as ex:
LOG.error(f"Unable to get process command line: {ex.stderr}")
else:
line = _command.ShellCommand(output.strip().split('\0')[:-1])
if line[0] != self.command:
LOG.error(f"Command line of process {self.pid} "
"doesn't match its command "
f"({self.command}): {line}")
else:
command_line = line
self.__dict__['command_line'] = command_line
return command_line
def list_kernel_processes(**list_params):
return list_processes(is_kernel=True, **list_params)
@ -55,8 +87,12 @@ def list_all_processes(**list_params):
return list_processes(is_kernel=None, **list_params)
def list_processes(pid=None, command=None, is_kernel=False, ssh_client=None,
**execute_params):
def list_processes(pid=None,
command: typing.Optional[str] = None,
is_kernel=False,
ssh_client=None,
command_line: typing.Optional[str] = None,
**execute_params) -> tobiko.Selection[PsProcess]:
"""Returns the number of seconds passed since last host reboot
It reads and parses remote special file /proc/uptime and returns a floating
@ -70,7 +106,7 @@ def list_processes(pid=None, command=None, is_kernel=False, ssh_client=None,
raise PsError(error=result.stderr)
# Extract a list of PsProcess instances from table body
processes = tobiko.Selection()
processes = tobiko.Selection[PsProcess]()
for process_data in parse_table(lines=output.splitlines(),
schema=PS_TABLE_SCHEMA):
processes.append(PsProcess(ssh_client=ssh_client, **process_data))
@ -83,15 +119,24 @@ def list_processes(pid=None, command=None, is_kernel=False, ssh_client=None,
if processes and command is not None:
# filter processes by command
command = re.compile(command)
processes = tobiko.select(process
for process in processes
if command.match(process.command))
pattern = re.compile(command)
processes = tobiko.Selection[PsProcess](
process
for process in processes
if pattern.match(process.command))
if processes and is_kernel is not None:
# filter kernel processes
processes = processes.with_attributes(is_kernel=bool(is_kernel))
if processes and command_line is not None:
pattern = re.compile(command_line)
processes = tobiko.Selection[PsProcess](
process
for process in processes
if (process.command_line is not None and
pattern.match(f"{process.command_line}")))
return processes


+ 3
- 0
tobiko/shell/ssh/__init__.py View File

@ -31,6 +31,9 @@ ssh_command = _command.ssh_command
ssh_proxy_client = _client.ssh_proxy_client
SSHConnectFailure = _client.SSHConnectFailure
gather_ssh_connect_parameters = _client.gather_ssh_connect_parameters
SSHClientType = _client.SSHClientType
ssh_client_fixture = _client.ssh_client_fixture
reset_default_ssh_port_forward_manager = \
_forward.reset_default_ssh_port_forward_manager


+ 14
- 0
tobiko/shell/ssh/_client.py View File

@ -625,3 +625,17 @@ def check_ssh_connection(client):
transport.send_ignore()
return True
return False
SSHClientType = typing.Union[None, bool, SSHClientFixture]
def ssh_client_fixture(obj: SSHClientType) -> \
typing.Optional[SSHClientFixture]:
if obj is None:
return ssh_proxy_client()
if obj is False:
return None
if isinstance(obj, SSHClientFixture):
return obj
raise TypeError(f"Can't get an SSHClientFixture from objeck {obj}")

+ 1
- 1
zuul.d/infrared.yaml View File

@ -4,7 +4,7 @@
name: tobiko-infrared
parent: tox
nodeset: tobiko-infrared-centos
timeout: 1800
timeout: 3600
description: |
Run test cases using tobiko infrared plugin
pre-run: playbooks/infrared/pre.yaml


Loading…
Cancel
Save