Source code for avocado_i2n.vmnet.node

# Copyright 2013-2020 Intranet AG and contributors
#
# avocado-i2n is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# avocado-i2n is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with avocado-i2n.  If not, see <http://www.gnu.org/licenses/>.

"""
VMNode object for the vmnet utility.

SUMMARY
------------------------------------------------------

Copyright: Intra2net AG


CONTENTS
------------------------------------------------------
This class wraps up the functionality shared among the interfaces of
the same platform like session management, etc.

INTERFACE
------------------------------------------------------

"""

from typing import Callable
import logging as log

from aexpect.client import RemoteSession
from virttest.utils_params import Params
from virttest.qemu_vm import VM

logging = log.getLogger("avocado.job." + __name__)


[docs] class VMNode(object): """Get the vmnode class - a collection of interfaces sharing the same platform.""" """Structural properties""" @property def interfaces(self) -> dict[str, "VMInterface"]: """Get a collection of interfaces the vm node represents.""" return self._interfaces @property def ephemeral(self) -> bool: """ Check if the vm node is ephemeral. returns: whether the vm node is ephemeral (spawned in a network). """ return self._ephemeral """Platform properties""" def platform(self, value: VM = None) -> VM | None: """Get a reference to the virtual machine object whose network configuration is represented by the vm node.""" if value is not None: self._platform = value return None else: return self._platform platform = property(fget=platform, fset=platform) def name(self, value: str = None) -> str | None: """Get a proxy reference to the vm name.""" if value is not None: self._platform.name = value return None else: return self._platform.name name = property(fget=name, fset=name) @property def params(self) -> Params: """ Get a proxy reference to the vm params. .. note:: this is just a shallow copy to preserve the hierarchy: network level params = test level params -> vmnode level params = test object params -> interface level params = rarely used outside of the vm network """ return self._platform.params def remote_sessions( self, value: list[RemoteSession] = None ) -> list[RemoteSession] | None: """Get a proxy reference to the vm sessions.""" if value is not None: self._platform.remote_sessions = value return None else: return self._platform.remote_sessions remote_sessions = property(fget=remote_sessions, fset=remote_sessions) def last_session(self, value: RemoteSession = None) -> RemoteSession | None: """ Get a pointer to the last created vm session. Used to facilitate the frequent access to a single session. """ if value is not None: self._last_session = value return None else: return self._last_session last_session = property(fget=last_session, fset=last_session) def __init__(self, platform: VM, ephemeral: bool = False) -> None: """ Construct a vm node from a vm platform. :param platform: the vm platform that communicates in the vm network :param ephemeral: whether the node is ephemeral (spawned in a network) """ self._interfaces = {} self._ephemeral = ephemeral self._platform = platform self._last_session = None def __repr__(self) -> str: """Provide a representation of the object.""" vm_tuple = (self.name, len(self.remote_sessions)) return "[node] name='%s', sessions='%s'" % vm_tuple
[docs] def check_interface( self, condition: Callable[["VMInterface"], bool] ) -> "VMInterface | None": """ Check whether one of node's interfaces satisfies a boolean condition. :param condition: condition to try each interface on :returns: the first interface satisfying the provided criteria or None """ for interface in self.interfaces.values(): if condition(interface): return interface return None
def get_single_interface(self) -> "VMInterface": """ Get a single (first) interface of the node. This is useful for nodes having just one interface. """ return list(self.interfaces.values())[0] def get_session(self, serial: bool = False) -> RemoteSession: """ Obtain a session from a vmnode by performing the basic network login. :param serial: whether to use serial connection """ self.platform.verify_alive() timeout = float(self.params.get("login_timeout", 240)) logging.info("Log in to %s with timeout %s", self.name, timeout) if serial: self.last_session = self.platform.wait_for_serial_login(timeout=timeout) else: self.last_session = self.platform.wait_for_login(timeout=timeout) # TODO: possibly use the original vm session list or remove this wrapper entirely self.platform.session = self.last_session return self.last_session