""" client.py: implementation of the VnodeClient class for issuing commands over a control channel to the vnoded process running in a network namespace. The control channel can be accessed via calls using the vcmd shell. """ from pathlib import Path from core import utils from core.executables import BASH, VCMD class VnodeClient: """ Provides client functionality for interacting with a virtual node. """ def __init__(self, name: str, ctrlchnlname: Path) -> None: """ Create a VnodeClient instance. :param name: name for client :param ctrlchnlname: control channel name """ self.name: str = name self.ctrlchnlname: Path = ctrlchnlname def _verify_connection(self) -> None: """ Checks that the vcmd client is properly connected. :return: nothing :raises IOError: when not connected """ if not self.connected(): raise IOError("vcmd not connected") def connected(self) -> bool: """ Check if node is connected or not. :return: True if connected, False otherwise """ return True def close(self) -> None: """ Close the client connection. :return: nothing """ pass def create_cmd(self, args: str, shell: bool = False) -> str: if shell: args = f'{BASH} -c "{args}"' return f"{VCMD} -c {self.ctrlchnlname} -- {args}" def check_cmd(self, args: str, wait: bool = True, shell: bool = False) -> str: """ Run command and return exit status and combined stdout and stderr. :param args: command to run :param wait: True to wait for command status, False otherwise :param shell: True to use shell, False otherwise :return: combined stdout and stderr :raises core.CoreCommandError: when there is a non-zero exit status """ self._verify_connection() args = self.create_cmd(args, shell) return utils.cmd(args, wait=wait, shell=shell)