On Mon, May 15, 2017 at 04:33:57PM +0200, Jiri Pirko wrote:
Thu, May 11, 2017 at 02:41:07PM CEST, olichtne(a)redhat.com wrote:
>From: Ondrej Lichtner <olichtne(a)redhat.com>
>
>Defines the Host class that acts as the tester facing API to manipulate
>and work with remote machines running the LNST Slave. Documented in the
>class doc strings.
>
>Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
>---
> lnst/Controller/Host.py | 143 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 143 insertions(+)
> create mode 100644 lnst/Controller/Host.py
>
>diff --git a/lnst/Controller/Host.py b/lnst/Controller/Host.py
>new file mode 100644
>index 0000000..c36a428
>--- /dev/null
>+++ b/lnst/Controller/Host.py
>@@ -0,0 +1,143 @@
>+"""
>+Defines the Host class that acts as the tester facing API to manipulate and
>+work with remote machines running the LNST Slave.
>+
>+Copyright 2017 Red Hat, Inc.
>+Licensed under the GNU General Public License, version 2 as
>+published by the Free Software Foundation; see COPYING for details.
>+"""
>+
>+__author__ = """
>+olichtne(a)redhat.com (Ondrej Lichtner)
>+"""
>+
>+import logging
>+from lnst.Common.Colours import decorate_with_preset
>+from lnst.Common.Parameters import Parameters
>+from lnst.Common.TestModule import BaseTestModule
>+from lnst.Common.NetTestCommand import DEFAULT_TIMEOUT
>+from lnst.Devices import Devices
>+from lnst.Devices.VirtualDevice import VirtualDevice
>+from lnst.Devices.RemoteDevice import RemoteDevice
>+from lnst.Controller.Common import ControllerError
>+from lnst.Controller.Job import Job
>+from pprint import pprint
Debug leftover?
indeed, will remove, they might be in more than this one module so I'll
double check...
>+
>+class HostError(ControllerError):
>+ pass
>+
>+class Hosts(object):
>+ def __iter__(self):
>+ for x in dir(self):
>+ val = getattr(self, x)
>+ if isinstance(val, Host):
>+ yield val
Funky stuff. Some comment perhaps?
It's an iterator container class for Host class instances. I'll add this
to the doc string
>+
>+class Host(object):
>+ """Tester facing slave Host API
>+
>+ Objects of this class are created by the Controller and provided to the
>+ Recipe object to use from it's 'test()' method. This tester facing
API
>+ allows the tester to create new Devices and run Jobs on the remote Host.
>+ Example:
>+ m1.bond0 = Bond() # to create a new bond device
>+ m1.run("ip a") # to run a shell command
>+ """
>+ #TODO add packet capture options
>+ def __init__(self, host, **kwargs):
>+ self._host = host
>+ self.params = Parameters()
>+ self.params._from_dict(self._host._slave_desc)
>+
>+ self.devices = Devices(self._host)
>+ self._device_mapping = {}
>+
>+ def __getattr__(self, name):
This attr abuse needs a comment for sure.
ok.
>+ try:
>+ return self._device_mapping[name]
>+ except:
>+ raise AttributeError("%s object has no attribute named %r" %
>+ (self.__class__.__name__, name))
>+
>+ def __setattr__(self, name, value):
>+ if isinstance(value, VirtualDevice):
>+ # msg = "Creating VirtualDevices in recipe execution is "\
>+ # "not supported right now."
Hmm. I kind of don't like this. All these exception should be ideally
handled in device classes themselves
This particular one is commented out. This is because we kind of agreed
to forbid the tester to add VirtualDevices from inside the test()
method of a recipe. However when LNST adds VirtualDevices (before
test()), it uses the same code so I disabled this until I figure out a
nice way to forbid this just during test execution.
>+ # raise HostError(msg)
>+ if name in self._device_mapping:
>+ raise HostError("Device with name '%s' already
assigned." % name)
>+
>+ value.host = self._host
>+ self._host.add_tmp_device(value)
>+ value.create()
>+ self._host.wait_for_tmp_devices(DEFAULT_TIMEOUT)
>+
>+ self._device_mapping[name] = value
>+ elif isinstance(value, RemoteDevice):
>+ if name in self._device_mapping:
>+ raise HostError("Device with name '%s' already
assigned." % name)
>+
>+ if value.if_index is None:
>+ value.host = self._host
>+ self._host.create_remote_device(value)
>+ self._device_mapping[name] = value
>+ else:
>+ super(Host, self).__setattr__(name, value)
>+
>+ def _map_device(self, dev_id, how):
>+ hwaddr = how["hwaddr"]
>+ dev = self._host.get_dev_by_hwaddr(hwaddr)
>+ self._device_mapping[dev_id] = dev
>+
>+ def run(self, what, bg=False, fail=False, timeout=DEFAULT_TIMEOUT,
>+ json=False, netns=None, desc=None):
>+ """
>+ Args:
>+ what (mandatory) -- what should be run on the host. Can be either a
>+ string, that will be executed on the Host as a shell command,
>+ or a TestModule object.
>+ bg -- run in background flag. Default 'False'. When True, the
>+ method will return immediately after the Job request is sent
>+ to the Slave Host.
>+ fail -- default 'False'. If True, a Failure will be reported as
PASS
>+ timeout: time limit in seconds. Default is 60. Only respected for
>+ jobs running in foreground (background Jobs don't have a time
>+ limit)
>+ json: Process JSON output into dictionary. Default 'False'.
>+ netns: Run in the specified network namespace. Currently not
>+ functional.
So put up an exception or something. Better than silent fail.
ok.
>+ desc: Decription printed in logs. Accepts a string value.
>+
>+ Returns:
>+ a Job object that acts as a handle to access the remote Job. If
>+ the Job was ran on foreground, the returned Job object will be
>+ filled with result data. If the Job was ran in background, the
>+ immediately returned Job object can be used to manipulate the
>+ running Job remotely and when the result data arrives from the Slave
>+ the Job object will be automatically updated.
>+ """
>+ job = Job(self._host,
>+ what,
>+ expect=not fail,
>+ json=json,
>+ netns=netns,
>+ desc=desc)
Just put those one one line :)
ok.
>+
>+ try:
>+ self._host.run_job(job)
>+
>+ if not bg:
>+ if not job.wait(timeout):
>+ logging.debug("Killing timeouted job")
"timed-out"?
ok.
>
> >+ job.kill()
> >+ except:
> >+ raise
> >+ finally:
> >+ pass
> >+ #TODO check expect result here
> >+ # if bg=True:
> >+ # add "job started" result
> >+ # else:
> >+ # add job result
> >+
> >+ return job
> >--
> >2.12.2
> >_______________________________________________
> >LNST-developers mailing list -- lnst-developers(a)lists.fedorahosted.org
> >To unsubscribe send an email to lnst-developers-leave(a)lists.fedorahosted.org