]> git.apps.os.sepia.ceph.com Git - teuthology.git/commitdiff
Make orchestra.console a subpackage
authorZack Cerza <zack@redhat.com>
Wed, 8 Nov 2017 20:02:12 +0000 (13:02 -0700)
committerZack Cerza <zack@redhat.com>
Wed, 8 Nov 2017 20:02:12 +0000 (13:02 -0700)
Signed-off-by: Zack Cerza <zack@redhat.com>
teuthology/orchestra/console.py [deleted file]
teuthology/orchestra/console/__init__.py [new file with mode: 0644]
teuthology/orchestra/console/physical.py [new file with mode: 0644]
teuthology/orchestra/console/virtual.py [new file with mode: 0644]
teuthology/orchestra/test/test_console.py

diff --git a/teuthology/orchestra/console.py b/teuthology/orchestra/console.py
deleted file mode 100644 (file)
index c59c366..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-import logging
-import os
-import pexpect
-import psutil
-import subprocess
-import sys
-import time
-
-import teuthology.lock.query
-import teuthology.lock.util
-from teuthology.config import config
-
-from ..exceptions import ConsoleError
-
-import remote
-
-try:
-    import libvirt
-except ImportError:
-    libvirt = None
-
-log = logging.getLogger(__name__)
-
-
-class PhysicalConsole():
-    """
-    Physical Console (set from getRemoteConsole)
-    """
-    def __init__(self, name, ipmiuser=None, ipmipass=None, ipmidomain=None,
-                 logfile=None, timeout=20):
-        self.name = name
-        self.shortname = remote.getShortName(name)
-        self.timeout = timeout
-        self.logfile = None
-        self.ipmiuser = ipmiuser or config.ipmi_user
-        self.ipmipass = ipmipass or config.ipmi_password
-        self.ipmidomain = ipmidomain or config.ipmi_domain
-        self.has_ipmi_credentials = all(
-            [self.ipmiuser, self.ipmipass, self.ipmidomain]
-        )
-        self.conserver_master = config.conserver_master
-        self.conserver_port = config.conserver_port
-        conserver_client_found = psutil.Popen(
-            'which console',
-            shell=True,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.STDOUT).wait() == 0
-        self.has_conserver = all([
-            config.use_conserver is not False,
-            self.conserver_master,
-            self.conserver_port,
-            conserver_client_found,
-        ])
-
-    def _pexpect_spawn_ipmi(self, ipmi_cmd):
-        """
-        Run the cmd specified using ipmitool.
-        """
-        full_command = self._ipmi_command(ipmi_cmd)
-        return self._pexpect_spawn(full_command)
-
-    def _pexpect_spawn(self, cmd):
-        """
-        Run a command using pexpect.spawn(). Return the child object.
-        """
-        log.debug('pexpect command: %s', cmd)
-        return pexpect.spawn(
-            cmd,
-            logfile=self.logfile,
-        )
-
-    def _get_console(self, readonly=True):
-        def start():
-            cmd = self._console_command(readonly=readonly)
-            return self._pexpect_spawn(cmd)
-
-        child = start()
-        if self.has_conserver and not child.isalive():
-            log.error("conserver failed to get the console; will try ipmitool")
-            self.has_conserver = False
-            child = start()
-        return child
-
-    def _console_command(self, readonly=True):
-        if self.has_conserver:
-            return 'console -M {master} -p {port} {mode} {host}'.format(
-                master=self.conserver_master,
-                port=self.conserver_port,
-                mode='-s' if readonly else '-f',
-                host=self.shortname,
-            )
-        else:
-            return self._ipmi_command('sol activate')
-
-    def _ipmi_command(self, subcommand):
-        self._check_ipmi_credentials()
-        template = \
-            'ipmitool -H {s}.{dn} -I lanplus -U {ipmiuser} -P {ipmipass} {cmd}'
-        return template.format(
-            cmd=subcommand,
-            s=self.shortname,
-            dn=self.ipmidomain,
-            ipmiuser=self.ipmiuser,
-            ipmipass=self.ipmipass,
-        )
-
-    def _check_ipmi_credentials(self):
-        if not self.has_ipmi_credentials:
-            log.error(
-                "Must set ipmi_user, ipmi_password, and ipmi_domain in "
-                ".teuthology.yaml"
-            )
-
-    def _exit_session(self, child, timeout=None):
-        t = timeout or self.timeout
-        if self.has_conserver:
-            child.sendcontrol('e')
-            child.send('c.')
-            r = child.expect(
-                ['[disconnect]', pexpect.TIMEOUT, pexpect.EOF],
-                timeout=t)
-            if r != 0:
-                child.kill(15)
-        else:
-            child.send('~.')
-            r = child.expect(
-                ['terminated ipmitool', pexpect.TIMEOUT, pexpect.EOF],
-                timeout=t)
-            if r != 0:
-                self._pexpect_spawn_ipmi('sol deactivate')
-
-    def _wait_for_login(self, timeout=None, attempts=2):
-        """
-        Wait for login.  Retry if timeouts occur on commands.
-        """
-        t = timeout or self.timeout
-        log.debug('Waiting for login prompt on {s}'.format(s=self.shortname))
-        # wait for login prompt to indicate boot completed
-        for i in range(0, attempts):
-            start = time.time()
-            while time.time() - start < t:
-                child = self._get_console(readonly=False)
-                child.send('\n')
-                log.debug('expect: {s} login'.format(s=self.shortname))
-                r = child.expect(
-                    ['{s} login: '.format(s=self.shortname),
-                     pexpect.TIMEOUT,
-                     pexpect.EOF],
-                    timeout=(t - (time.time() - start)))
-                log.debug('expect before: {b}'.format(b=child.before))
-                log.debug('expect after: {a}'.format(a=child.after))
-
-                self._exit_session(child)
-                if r == 0:
-                    return
-        raise ConsoleError("Did not get a login prompt from %s!" % self.name)
-
-    def check_power(self, state, timeout=None):
-        """
-        Check power.  Retry if EOF encountered on power check read.
-        """
-        timeout = timeout or self.timeout
-        t = 1
-        total = t
-        ta = time.time()
-        while total < timeout:
-            c = self._pexpect_spawn_ipmi('power status')
-            r = c.expect(['Chassis Power is {s}'.format(
-                s=state), pexpect.EOF, pexpect.TIMEOUT], timeout=t)
-            tb = time.time()
-            if r == 0:
-                return True
-            elif r == 1:
-                # keep trying if EOF is reached, first sleep for remaining
-                # timeout interval
-                if tb - ta < t:
-                    time.sleep(t - (tb - ta))
-            # go around again if EOF or TIMEOUT
-            ta = tb
-            t *= 2
-            total += t
-        return False
-
-    def check_status(self, timeout=None):
-        """
-        Check status.  Returns True if console is at login prompt
-        """
-        try:
-            # check for login prompt at console
-            self._wait_for_login(timeout)
-            return True
-        except Exception as e:
-            log.info('Failed to get ipmi console status for {s}: {e}'.format(
-                s=self.shortname, e=e))
-            return False
-
-    def power_cycle(self):
-        """
-        Power cycle and wait for login.
-        """
-        log.info('Power cycling {s}'.format(s=self.shortname))
-        child = self._pexpect_spawn_ipmi('power cycle')
-        child.expect('Chassis Power Control: Cycle', timeout=self.timeout)
-        self._wait_for_login(timeout=300)
-        log.info('Power cycle for {s} completed'.format(s=self.shortname))
-
-    def hard_reset(self):
-        """
-        Perform physical hard reset.  Retry if EOF returned from read
-        and wait for login when complete.
-        """
-        log.info('Performing hard reset of {s}'.format(s=self.shortname))
-        start = time.time()
-        while time.time() - start < self.timeout:
-            child = self._pexpect_spawn_ipmi('power reset')
-            r = child.expect(['Chassis Power Control: Reset', pexpect.EOF],
-                             timeout=self.timeout)
-            if r == 0:
-                break
-        self._wait_for_login()
-        log.info('Hard reset for {s} completed'.format(s=self.shortname))
-
-    def power_on(self):
-        """
-        Physical power on.  Loop checking cmd return.
-        """
-        log.info('Power on {s}'.format(s=self.shortname))
-        start = time.time()
-        while time.time() - start < self.timeout:
-            child = self._pexpect_spawn_ipmi('power on')
-            r = child.expect(['Chassis Power Control: Up/On', pexpect.EOF],
-                             timeout=self.timeout)
-            if r == 0:
-                break
-        if not self.check_power('on'):
-            log.error('Failed to power on {s}'.format(s=self.shortname))
-        log.info('Power on for {s} completed'.format(s=self.shortname))
-
-    def power_off(self):
-        """
-        Physical power off.  Loop checking cmd return.
-        """
-        log.info('Power off {s}'.format(s=self.shortname))
-        start = time.time()
-        while time.time() - start < self.timeout:
-            child = self._pexpect_spawn_ipmi('power off')
-            r = child.expect(['Chassis Power Control: Down/Off', pexpect.EOF],
-                             timeout=self.timeout)
-            if r == 0:
-                break
-        if not self.check_power('off', 60):
-            log.error('Failed to power off {s}'.format(s=self.shortname))
-        log.info('Power off for {s} completed'.format(s=self.shortname))
-
-    def power_off_for_interval(self, interval=30):
-        """
-        Physical power off for an interval. Wait for login when complete.
-
-        :param interval: Length of power-off period.
-        """
-        log.info('Power off {s} for {i} seconds'.format(
-            s=self.shortname, i=interval))
-        child = self._pexpect_spawn_ipmi('power off')
-        child.expect('Chassis Power Control: Down/Off', timeout=self.timeout)
-
-        time.sleep(interval)
-
-        child = self._pexpect_spawn_ipmi('power on')
-        child.expect('Chassis Power Control: Up/On', timeout=self.timeout)
-        self._wait_for_login()
-        log.info('Power off for {i} seconds completed'.format(
-            s=self.shortname, i=interval))
-
-    def spawn_sol_log(self, dest_path):
-        """
-        Using the subprocess module, spawn an ipmitool process using 'sol
-        activate' and redirect its output to a file.
-
-        :returns: a psutil.Popen object
-        """
-        pexpect_templ = \
-            "import pexpect; " \
-            "pexpect.run('{cmd}', logfile=file('{log}', 'w'), timeout=None)"
-
-        def start():
-            console_cmd = self._console_command()
-            # use sys.executable to find python rather than /usr/bin/env.
-            # The latter relies on PATH, which is set in a virtualenv
-            # that's been activated, but is not set when binaries are
-            # run directly from the virtualenv's bin/ directory.
-            python_cmd = [
-                sys.executable, '-c',
-                pexpect_templ.format(
-                    cmd=console_cmd,
-                    log=dest_path,
-                ),
-            ]
-            return psutil.Popen(
-                python_cmd,
-                env=os.environ,
-            )
-
-        proc = start()
-        if self.has_conserver and proc.poll() is not None:
-            log.error("conserver failed to get the console; will try ipmitool")
-            self.has_conserver = False
-            proc = start()
-        return proc
-
-
-class VirtualConsole():
-    """
-    Virtual Console (set from getRemoteConsole)
-    """
-    def __init__(self, name):
-        if libvirt is None:
-            raise RuntimeError("libvirt not found")
-
-        self.shortname = remote.getShortName(name)
-        status_info = teuthology.lock.query.get_status(self.shortname)
-        try:
-            if teuthology.lock.query.is_vm(status=status_info):
-                phys_host = status_info['vm_host']['name'].split('.')[0]
-        except TypeError:
-            raise RuntimeError("Cannot create a virtual console for %s", name)
-        self.connection = libvirt.open(phys_host)
-        for i in self.connection.listDomainsID():
-            d = self.connection.lookupByID(i)
-            if d.name() == self.shortname:
-                self.vm_domain = d
-                break
-        return
-
-    def check_power(self, state, timeout=None):
-        """
-        Return true if vm domain state indicates power is on.
-        """
-        return self.vm_domain.info[0] in [libvirt.VIR_DOMAIN_RUNNING,
-                                          libvirt.VIR_DOMAIN_BLOCKED,
-                                          libvirt.VIR_DOMAIN_PAUSED]
-
-    def check_status(self, timeout=None):
-        """
-        Return true if running.
-        """
-        return self.vm_domain.info()[0] == libvirt.VIR_DOMAIN_RUNNING
-
-    def power_cycle(self):
-        """
-        Simiulate virtual machine power cycle
-        """
-        self.vm_domain.info().destroy()
-        self.vm_domain.info().create()
-
-    def hard_reset(self):
-        """
-        Simiulate hard reset
-        """
-        self.vm_domain.info().destroy()
-
-    def power_on(self):
-        """
-        Simiulate power on
-        """
-        self.vm_domain.info().create()
-
-    def power_off(self):
-        """
-        Simiulate power off
-        """
-        self.vm_domain.info().destroy()
-
-    def power_off_for_interval(self, interval=30):
-        """
-        Simiulate power off for an interval.
-        """
-        log.info('Power off {s} for {i} seconds'.format(
-            s=self.shortname, i=interval))
-        self.vm_domain.info().destroy()
-        time.sleep(interval)
-        self.vm_domain.info().create()
-        log.info('Power off for {i} seconds completed'.format(
-            s=self.shortname, i=interval))
diff --git a/teuthology/orchestra/console/__init__.py b/teuthology/orchestra/console/__init__.py
new file mode 100644 (file)
index 0000000..5615a7d
--- /dev/null
@@ -0,0 +1,5 @@
+import physical
+import virtual
+
+PhysicalConsole = physical.PhysicalConsole
+VirtualConsole = virtual.VirtualConsole
diff --git a/teuthology/orchestra/console/physical.py b/teuthology/orchestra/console/physical.py
new file mode 100644 (file)
index 0000000..d6546ec
--- /dev/null
@@ -0,0 +1,301 @@
+import logging
+import os
+import pexpect
+import psutil
+import subprocess
+import sys
+import time
+
+import teuthology.orchestra.remote
+
+from teuthology.config import config
+
+from teuthology.exceptions import ConsoleError
+
+log = logging.getLogger(__name__)
+
+
+class PhysicalConsole():
+    """
+    Physical Console (set from getRemoteConsole)
+    """
+    def __init__(self, name, ipmiuser=None, ipmipass=None, ipmidomain=None,
+                 logfile=None, timeout=20):
+        self.name = name
+        self.shortname = teuthology.orchestra.remote.getShortName(name)
+        self.timeout = timeout
+        self.logfile = None
+        self.ipmiuser = ipmiuser or config.ipmi_user
+        self.ipmipass = ipmipass or config.ipmi_password
+        self.ipmidomain = ipmidomain or config.ipmi_domain
+        self.has_ipmi_credentials = all(
+            [self.ipmiuser, self.ipmipass, self.ipmidomain]
+        )
+        self.conserver_master = config.conserver_master
+        self.conserver_port = config.conserver_port
+        conserver_client_found = psutil.Popen(
+            'which console',
+            shell=True,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT).wait() == 0
+        self.has_conserver = all([
+            config.use_conserver is not False,
+            self.conserver_master,
+            self.conserver_port,
+            conserver_client_found,
+        ])
+
+    def _pexpect_spawn_ipmi(self, ipmi_cmd):
+        """
+        Run the cmd specified using ipmitool.
+        """
+        full_command = self._ipmi_command(ipmi_cmd)
+        return self._pexpect_spawn(full_command)
+
+    def _pexpect_spawn(self, cmd):
+        """
+        Run a command using pexpect.spawn(). Return the child object.
+        """
+        log.debug('pexpect command: %s', cmd)
+        return pexpect.spawn(
+            cmd,
+            logfile=self.logfile,
+        )
+
+    def _get_console(self, readonly=True):
+        def start():
+            cmd = self._console_command(readonly=readonly)
+            return self._pexpect_spawn(cmd)
+
+        child = start()
+        if self.has_conserver and not child.isalive():
+            log.error("conserver failed to get the console; will try ipmitool")
+            self.has_conserver = False
+            child = start()
+        return child
+
+    def _console_command(self, readonly=True):
+        if self.has_conserver:
+            return 'console -M {master} -p {port} {mode} {host}'.format(
+                master=self.conserver_master,
+                port=self.conserver_port,
+                mode='-s' if readonly else '-f',
+                host=self.shortname,
+            )
+        else:
+            return self._ipmi_command('sol activate')
+
+    def _ipmi_command(self, subcommand):
+        self._check_ipmi_credentials()
+        template = \
+            'ipmitool -H {s}.{dn} -I lanplus -U {ipmiuser} -P {ipmipass} {cmd}'
+        return template.format(
+            cmd=subcommand,
+            s=self.shortname,
+            dn=self.ipmidomain,
+            ipmiuser=self.ipmiuser,
+            ipmipass=self.ipmipass,
+        )
+
+    def _check_ipmi_credentials(self):
+        if not self.has_ipmi_credentials:
+            log.error(
+                "Must set ipmi_user, ipmi_password, and ipmi_domain in "
+                ".teuthology.yaml"
+            )
+
+    def _exit_session(self, child, timeout=None):
+        t = timeout or self.timeout
+        if self.has_conserver:
+            child.sendcontrol('e')
+            child.send('c.')
+            r = child.expect(
+                ['[disconnect]', pexpect.TIMEOUT, pexpect.EOF],
+                timeout=t)
+            if r != 0:
+                child.kill(15)
+        else:
+            child.send('~.')
+            r = child.expect(
+                ['terminated ipmitool', pexpect.TIMEOUT, pexpect.EOF],
+                timeout=t)
+            if r != 0:
+                self._pexpect_spawn_ipmi('sol deactivate')
+
+    def _wait_for_login(self, timeout=None, attempts=2):
+        """
+        Wait for login.  Retry if timeouts occur on commands.
+        """
+        t = timeout or self.timeout
+        log.debug('Waiting for login prompt on {s}'.format(s=self.shortname))
+        # wait for login prompt to indicate boot completed
+        for i in range(0, attempts):
+            start = time.time()
+            while time.time() - start < t:
+                child = self._get_console(readonly=False)
+                child.send('\n')
+                log.debug('expect: {s} login'.format(s=self.shortname))
+                r = child.expect(
+                    ['{s} login: '.format(s=self.shortname),
+                     pexpect.TIMEOUT,
+                     pexpect.EOF],
+                    timeout=(t - (time.time() - start)))
+                log.debug('expect before: {b}'.format(b=child.before))
+                log.debug('expect after: {a}'.format(a=child.after))
+
+                self._exit_session(child)
+                if r == 0:
+                    return
+        raise ConsoleError("Did not get a login prompt from %s!" % self.name)
+
+    def check_power(self, state, timeout=None):
+        """
+        Check power.  Retry if EOF encountered on power check read.
+        """
+        timeout = timeout or self.timeout
+        t = 1
+        total = t
+        ta = time.time()
+        while total < timeout:
+            c = self._pexpect_spawn_ipmi('power status')
+            r = c.expect(['Chassis Power is {s}'.format(
+                s=state), pexpect.EOF, pexpect.TIMEOUT], timeout=t)
+            tb = time.time()
+            if r == 0:
+                return True
+            elif r == 1:
+                # keep trying if EOF is reached, first sleep for remaining
+                # timeout interval
+                if tb - ta < t:
+                    time.sleep(t - (tb - ta))
+            # go around again if EOF or TIMEOUT
+            ta = tb
+            t *= 2
+            total += t
+        return False
+
+    def check_status(self, timeout=None):
+        """
+        Check status.  Returns True if console is at login prompt
+        """
+        try:
+            # check for login prompt at console
+            self._wait_for_login(timeout)
+            return True
+        except Exception as e:
+            log.info('Failed to get ipmi console status for {s}: {e}'.format(
+                s=self.shortname, e=e))
+            return False
+
+    def power_cycle(self):
+        """
+        Power cycle and wait for login.
+        """
+        log.info('Power cycling {s}'.format(s=self.shortname))
+        child = self._pexpect_spawn_ipmi('power cycle')
+        child.expect('Chassis Power Control: Cycle', timeout=self.timeout)
+        self._wait_for_login(timeout=300)
+        log.info('Power cycle for {s} completed'.format(s=self.shortname))
+
+    def hard_reset(self):
+        """
+        Perform physical hard reset.  Retry if EOF returned from read
+        and wait for login when complete.
+        """
+        log.info('Performing hard reset of {s}'.format(s=self.shortname))
+        start = time.time()
+        while time.time() - start < self.timeout:
+            child = self._pexpect_spawn_ipmi('power reset')
+            r = child.expect(['Chassis Power Control: Reset', pexpect.EOF],
+                             timeout=self.timeout)
+            if r == 0:
+                break
+        self._wait_for_login()
+        log.info('Hard reset for {s} completed'.format(s=self.shortname))
+
+    def power_on(self):
+        """
+        Physical power on.  Loop checking cmd return.
+        """
+        log.info('Power on {s}'.format(s=self.shortname))
+        start = time.time()
+        while time.time() - start < self.timeout:
+            child = self._pexpect_spawn_ipmi('power on')
+            r = child.expect(['Chassis Power Control: Up/On', pexpect.EOF],
+                             timeout=self.timeout)
+            if r == 0:
+                break
+        if not self.check_power('on'):
+            log.error('Failed to power on {s}'.format(s=self.shortname))
+        log.info('Power on for {s} completed'.format(s=self.shortname))
+
+    def power_off(self):
+        """
+        Physical power off.  Loop checking cmd return.
+        """
+        log.info('Power off {s}'.format(s=self.shortname))
+        start = time.time()
+        while time.time() - start < self.timeout:
+            child = self._pexpect_spawn_ipmi('power off')
+            r = child.expect(['Chassis Power Control: Down/Off', pexpect.EOF],
+                             timeout=self.timeout)
+            if r == 0:
+                break
+        if not self.check_power('off', 60):
+            log.error('Failed to power off {s}'.format(s=self.shortname))
+        log.info('Power off for {s} completed'.format(s=self.shortname))
+
+    def power_off_for_interval(self, interval=30):
+        """
+        Physical power off for an interval. Wait for login when complete.
+
+        :param interval: Length of power-off period.
+        """
+        log.info('Power off {s} for {i} seconds'.format(
+            s=self.shortname, i=interval))
+        child = self._pexpect_spawn_ipmi('power off')
+        child.expect('Chassis Power Control: Down/Off', timeout=self.timeout)
+
+        time.sleep(interval)
+
+        child = self._pexpect_spawn_ipmi('power on')
+        child.expect('Chassis Power Control: Up/On', timeout=self.timeout)
+        self._wait_for_login()
+        log.info('Power off for {i} seconds completed'.format(
+            s=self.shortname, i=interval))
+
+    def spawn_sol_log(self, dest_path):
+        """
+        Using the subprocess module, spawn an ipmitool process using 'sol
+        activate' and redirect its output to a file.
+
+        :returns: a psutil.Popen object
+        """
+        pexpect_templ = \
+            "import pexpect; " \
+            "pexpect.run('{cmd}', logfile=file('{log}', 'w'), timeout=None)"
+
+        def start():
+            console_cmd = self._console_command()
+            # use sys.executable to find python rather than /usr/bin/env.
+            # The latter relies on PATH, which is set in a virtualenv
+            # that's been activated, but is not set when binaries are
+            # run directly from the virtualenv's bin/ directory.
+            python_cmd = [
+                sys.executable, '-c',
+                pexpect_templ.format(
+                    cmd=console_cmd,
+                    log=dest_path,
+                ),
+            ]
+            return psutil.Popen(
+                python_cmd,
+                env=os.environ,
+            )
+
+        proc = start()
+        if self.has_conserver and proc.poll() is not None:
+            log.error("conserver failed to get the console; will try ipmitool")
+            self.has_conserver = False
+            proc = start()
+        return proc
diff --git a/teuthology/orchestra/console/virtual.py b/teuthology/orchestra/console/virtual.py
new file mode 100644 (file)
index 0000000..a89f51a
--- /dev/null
@@ -0,0 +1,86 @@
+import logging
+import time
+try:
+    import libvirt
+except ImportError:
+    libvirt = None
+
+import teuthology.lock.query
+import teuthology.lock.util
+
+log = logging.getLogger(__name__)
+
+
+class VirtualConsole():
+    """
+    Virtual Console (set from getRemoteConsole)
+    """
+    def __init__(self, name):
+        if libvirt is None:
+            raise RuntimeError("libvirt not found")
+
+        self.shortname = remote.getShortName(name)
+        status_info = teuthology.lock.query.get_status(self.shortname)
+        try:
+            if teuthology.lock.query.is_vm(status=status_info):
+                phys_host = status_info['vm_host']['name'].split('.')[0]
+        except TypeError:
+            raise RuntimeError("Cannot create a virtual console for %s", name)
+        self.connection = libvirt.open(phys_host)
+        for i in self.connection.listDomainsID():
+            d = self.connection.lookupByID(i)
+            if d.name() == self.shortname:
+                self.vm_domain = d
+                break
+        return
+
+    def check_power(self, state, timeout=None):
+        """
+        Return true if vm domain state indicates power is on.
+        """
+        return self.vm_domain.info[0] in [libvirt.VIR_DOMAIN_RUNNING,
+                                          libvirt.VIR_DOMAIN_BLOCKED,
+                                          libvirt.VIR_DOMAIN_PAUSED]
+
+    def check_status(self, timeout=None):
+        """
+        Return true if running.
+        """
+        return self.vm_domain.info()[0] == libvirt.VIR_DOMAIN_RUNNING
+
+    def power_cycle(self):
+        """
+        Simiulate virtual machine power cycle
+        """
+        self.vm_domain.info().destroy()
+        self.vm_domain.info().create()
+
+    def hard_reset(self):
+        """
+        Simiulate hard reset
+        """
+        self.vm_domain.info().destroy()
+
+    def power_on(self):
+        """
+        Simiulate power on
+        """
+        self.vm_domain.info().create()
+
+    def power_off(self):
+        """
+        Simiulate power off
+        """
+        self.vm_domain.info().destroy()
+
+    def power_off_for_interval(self, interval=30):
+        """
+        Simiulate power off for an interval.
+        """
+        log.info('Power off {s} for {i} seconds'.format(
+            s=self.shortname, i=interval))
+        self.vm_domain.info().destroy()
+        time.sleep(interval)
+        self.vm_domain.info().create()
+        log.info('Power off for {i} seconds completed'.format(
+            s=self.shortname, i=interval))
index 1e37abd73c3272fc0969f73dae21aee61836addc..dd219fc1af57450584087a061ae3190bcf7a7e91 100644 (file)
@@ -88,7 +88,7 @@ class TestPhysicalConsole(TestConsole):
 
     def test_spawn_log_conserver(self):
         with patch(
-            'teuthology.orchestra.console.psutil.subprocess.Popen',
+            'teuthology.orchestra.console.physical.psutil.subprocess.Popen',
             autospec=True,
         ) as m_popen:
             m_popen.return_value.pid = 42
@@ -107,7 +107,7 @@ class TestPhysicalConsole(TestConsole):
 
     def test_spawn_log_ipmi(self):
         with patch(
-            'teuthology.orchestra.console.psutil.subprocess.Popen',
+            'teuthology.orchestra.console.physical.psutil.subprocess.Popen',
             autospec=True,
         ) as m_popen:
             m_popen.return_value.pid = 42
@@ -126,7 +126,7 @@ class TestPhysicalConsole(TestConsole):
 
     def test_spawn_log_fallback(self):
         with patch(
-            'teuthology.orchestra.console.psutil.subprocess.Popen',
+            'teuthology.orchestra.console.physical.psutil.subprocess.Popen',
             autospec=True,
         ) as m_popen:
             m_popen.return_value.pid = 42
@@ -146,7 +146,7 @@ class TestPhysicalConsole(TestConsole):
 
     def test_get_console_conserver(self):
         with patch(
-            'teuthology.orchestra.console.psutil.subprocess.Popen',
+            'teuthology.orchestra.console.physical.psutil.subprocess.Popen',
             autospec=True,
         ) as m_popen:
             m_popen.return_value.pid = 42
@@ -155,7 +155,7 @@ class TestPhysicalConsole(TestConsole):
             cons = self.klass(self.hostname)
         assert cons.has_conserver is True
         with patch(
-            'teuthology.orchestra.console.pexpect.spawn',
+            'teuthology.orchestra.console.physical.pexpect.spawn',
             autospec=True,
         ) as m_spawn:
             cons._get_console()
@@ -165,7 +165,7 @@ class TestPhysicalConsole(TestConsole):
 
     def test_get_console_ipmitool(self):
         with patch(
-            'teuthology.orchestra.console.psutil.subprocess.Popen',
+            'teuthology.orchestra.console.physical.psutil.subprocess.Popen',
             autospec=True,
         ) as m_popen:
             m_popen.return_value.pid = 42
@@ -174,7 +174,7 @@ class TestPhysicalConsole(TestConsole):
             cons = self.klass(self.hostname)
         assert cons.has_conserver is True
         with patch(
-            'teuthology.orchestra.console.pexpect.spawn',
+            'teuthology.orchestra.console.physical.pexpect.spawn',
             autospec=True,
         ) as m_spawn:
             cons.has_conserver = False
@@ -184,7 +184,7 @@ class TestPhysicalConsole(TestConsole):
 
     def test_get_console_fallback(self):
         with patch(
-            'teuthology.orchestra.console.psutil.subprocess.Popen',
+            'teuthology.orchestra.console.physical.psutil.subprocess.Popen',
             autospec=True,
         ) as m_popen:
             m_popen.return_value.pid = 42
@@ -193,7 +193,7 @@ class TestPhysicalConsole(TestConsole):
             cons = self.klass(self.hostname)
         assert cons.has_conserver is True
         with patch(
-            'teuthology.orchestra.console.pexpect.spawn',
+            'teuthology.orchestra.console.physical.pexpect.spawn',
             autospec=True,
         ) as m_spawn:
             cons.has_conserver = True
@@ -206,7 +206,7 @@ class TestPhysicalConsole(TestConsole):
 
     def test_disable_conserver(self):
         with patch(
-            'teuthology.orchestra.console.psutil.subprocess.Popen',
+            'teuthology.orchestra.console.physical.psutil.subprocess.Popen',
             autospec=True,
         ) as m_popen:
             m_popen.return_value.pid = 42