os_session - OS-aware Remote Session ABC

OS-aware remote session.

DPDK supports multiple different operating systems, meaning it can run on these different operating systems. This module defines the common API that OS-unaware layers use and translates the API into OS-aware calls/utility usage.

Note

Running commands with administrative privileges requires OS awareness. This is the only layer that’s aware of OS differences, so this is where non-privileged command get converted to privileged commands.

Example

A user wishes to remove a directory on a remote SutNode. The SutNode object isn’t aware what OS the node is running - it delegates the OS translation logic to main_session. The SUT node calls remove_remote_dir() with a generic, OS-unaware path and the main_session translates that to rm -rf if the node’s OS is Linux and other commands for other OSs. It also translates the path to match the underlying OS.

class OSSessionInfo

Bases: object

Supplemental OS session information.

os_name

The name of the running operating system of the Node.

Type:

str

os_version

The version of the running operating system of the Node.

Type:

str

kernel_version

The kernel version of the running operating system of the Node.

Type:

str

__init__(os_name: str, os_version: str, kernel_version: str) None
class OSSession

Bases: ABC

OS-unaware to OS-aware translation API definition.

The OSSession classes create a remote session to a DTS node and implement OS specific behavior. There a few control methods implemented by the base class, the rest need to be implemented by subclasses.

name

The name of the session.

Type:

str

remote_session

The remote session maintaining the connection to the node.

Type:

framework.remote_session.remote_session.RemoteSession

interactive_session

The interactive remote session maintaining the connection to the node.

Type:

framework.remote_session.interactive_remote_session.InteractiveRemoteSession

__init__(node_config: NodeConfiguration, name: str, logger: DTSLogger)

Initialize the OS-aware session.

Connect to the node right away and also create an interactive remote session.

Parameters:
  • node_config (NodeConfiguration) – The test run configuration of the node to connect to.

  • name (str) – The name of the session.

  • logger (DTSLogger) – The logger instance this session will use.

is_alive() bool

Check whether the underlying remote session is still responding.

send_command(command: str, timeout: float = 15, privileged: bool = False, verify: bool = False, env: dict | None = None) CommandResult

An all-purpose API for OS-agnostic commands.

This can be used for an execution of a portable command that’s executed the same way on all operating systems, such as Python.

The --timeout command line argument and the DTS_TIMEOUT environment variable configure the timeout of command execution.

Parameters:
  • command (str) – The command to execute.

  • timeout (float) – Wait at most this long in seconds for command execution to complete.

  • privileged (bool) – Whether to run the command with administrative privileges.

  • verify (bool) – If True, will check the exit code of the command.

  • env (dict | None) – A dictionary with environment variables to be used with the command execution.

Raises:

RemoteCommandExecutionError – If verify is True and the command failed.

close() None

Close the underlying remote session.

abstract get_remote_tmp_dir() PurePath

Get the path of the temporary directory of the remote OS.

Returns:

The absolute path of the temporary directory.

Return type:

PurePath

abstract get_dpdk_build_env_vars(arch: Architecture) dict

Create extra environment variables needed for the target architecture.

Different architectures may require different configuration, such as setting 32-bit CFLAGS.

Returns:

A dictionary with keys as environment variables.

Return type:

dict

abstract join_remote_path(*args: str | pathlib.PurePath) PurePath

Join path parts using the path separator that fits the remote OS.

Parameters:

args (str | pathlib.PurePath) – Any number of paths to join.

Returns:

The resulting joined path.

Return type:

PurePath

abstract remote_path_exists(remote_path: str | pathlib.PurePath) bool

Check whether remote_path exists on the remote system.

Parameters:

remote_path (str | pathlib.PurePath) – The path to check.

Returns:

True if the path exists, False otherwise.

Return type:

bool

abstract copy_from(source_file: str | pathlib.PurePath, destination_dir: str | pathlib.Path) None

Copy a file from the remote node to the local filesystem.

Copy source_file from the remote node associated with this remote session to destination_dir on the local filesystem.

Parameters:
  • source_file (str | pathlib.PurePath) – The file on the remote node.

  • destination_dir (str | pathlib.Path) – The directory path on the local filesystem where the source_file will be saved.

abstract copy_to(source_file: str | pathlib.Path, destination_dir: str | pathlib.PurePath) None

Copy a file from local filesystem to the remote node.

Copy source_file from local filesystem to destination_dir on the remote node associated with this remote session.

Parameters:
  • source_file (str | pathlib.Path) – The file on the local filesystem.

  • destination_dir (str | pathlib.PurePath) – The directory path on the remote Node where the source_file will be saved.

abstract copy_dir_from(source_dir: str | pathlib.PurePath, destination_dir: str | pathlib.Path, compress_format: TarCompressionFormat = TarCompressionFormat.none, exclude: str | list[str] | None = None) None

Copy a directory from the remote node to the local filesystem.

Copy source_dir from the remote node associated with this remote session to destination_dir on the local filesystem. The new local directory will be created at destination_dir path.

Example

source_dir = ‘/remote/path/to/source’ destination_dir = ‘/local/path/to/destination’ compress_format = TarCompressionFormat.xz

The method will:
  1. Create a tarball from source_dir, resulting in:

    ‘/remote/path/to/source.tar.xz’,

  2. Copy ‘/remote/path/to/source.tar.xz’ to

    ‘/local/path/to/destination/source.tar.xz’,

  3. Extract the contents of the tarball, resulting in:

    ‘/local/path/to/destination/source/’,

  4. Remove the tarball after extraction

    (‘/local/path/to/destination/source.tar.xz’).

Final Path Structure:

‘/local/path/to/destination/source/’

Parameters:
  • source_dir (str | pathlib.PurePath) – The directory on the remote node.

  • destination_dir (str | pathlib.Path) – The directory path on the local filesystem.

  • compress_format (TarCompressionFormat) – The compression format to use. Defaults to no compression.

  • exclude (str | list[str] | None) – Patterns for files or directories to exclude from the tarball. These patterns are used with tar’s –exclude option.

abstract copy_dir_to(source_dir: str | pathlib.Path, destination_dir: str | pathlib.PurePath, compress_format: TarCompressionFormat = TarCompressionFormat.none, exclude: str | list[str] | None = None) None

Copy a directory from the local filesystem to the remote node.

Copy source_dir from the local filesystem to destination_dir on the remote node associated with this remote session. The new remote directory will be created at destination_dir path.

Example

source_dir = ‘/local/path/to/source’ destination_dir = ‘/remote/path/to/destination’ compress_format = TarCompressionFormat.xz

The method will:
  1. Create a tarball from source_dir, resulting in:

    ‘/local/path/to/source.tar.xz’,

  2. Copy ‘/local/path/to/source.tar.xz’ to

    ‘/remote/path/to/destination/source.tar.xz’,

  3. Extract the contents of the tarball, resulting in:

    ‘/remote/path/to/destination/source/’,

  4. Remove the tarball after extraction

    (‘/remote/path/to/destination/source.tar.xz’).

Final Path Structure:

‘/remote/path/to/destination/source/’

Parameters:
  • source_dir (str | pathlib.Path) – The directory on the local filesystem.

  • destination_dir (str | pathlib.PurePath) – The directory path on the remote node.

  • compress_format (TarCompressionFormat) – The compression format to use. Defaults to no compression.

  • exclude (str | list[str] | None) – Patterns for files or directories to exclude from the tarball. These patterns are used with fnmatch.fnmatch to filter out files.

abstract remove_remote_file(remote_file_path: str | pathlib.PurePath, force: bool = True) None

Remove remote file, by default remove forcefully.

Parameters:
  • remote_file_path (str | pathlib.PurePath) – The file path to remove.

  • force (bool) – If True, ignore all warnings and try to remove at all costs.

abstract remove_remote_dir(remote_dir_path: str | pathlib.PurePath, recursive: bool = True, force: bool = True) None

Remove remote directory, by default remove recursively and forcefully.

Parameters:
  • remote_dir_path (str | pathlib.PurePath) – The directory path to remove.

  • recursive (bool) – If True, also remove all contents inside the directory.

  • force (bool) – If True, ignore all warnings and try to remove at all costs.

abstract create_remote_tarball(remote_dir_path: str | pathlib.PurePath, compress_format: TarCompressionFormat = TarCompressionFormat.none, exclude: str | list[str] | None = None) PurePosixPath

Create a tarball from the contents of the specified remote directory.

This method creates a tarball containing all files and directories within remote_dir_path. The tarball will be saved in the directory of remote_dir_path and will be named based on remote_dir_path.

Parameters:
  • remote_dir_path (str | pathlib.PurePath) – The directory path on the remote node.

  • compress_format (TarCompressionFormat) – The compression format to use. Defaults to no compression.

  • exclude (str | list[str] | None) – Patterns for files or directories to exclude from the tarball. These patterns are used with tar’s –exclude option.

Returns:

The path to the created tarball on the remote node.

Return type:

PurePosixPath

abstract extract_remote_tarball(remote_tarball_path: str | pathlib.PurePath, expected_dir: str | pathlib.PurePath | None = None) None

Extract remote tarball in its remote directory.

Parameters:
  • remote_tarball_path (str | pathlib.PurePath) – The tarball path on the remote node.

  • expected_dir (str | pathlib.PurePath | None) – If non-empty, check whether expected_dir exists after extracting the archive.

abstract is_remote_dir(remote_path: PurePath) bool

Check if the remote_path is a directory.

Parameters:

remote_tarball_path – The path to the remote tarball.

Returns:

If True the remote_path is a directory, otherwise False.

Return type:

bool

abstract is_remote_tarfile(remote_tarball_path: PurePath) bool

Check if the remote_tarball_path is a tar archive.

Parameters:

remote_tarball_path (PurePath) – The path to the remote tarball.

Returns:

If True the remote_tarball_path is a tar archive, otherwise False.

Return type:

bool

abstract get_tarball_top_dir(remote_tarball_path: str | pathlib.PurePath) str | pathlib.PurePosixPath | None

Get the top directory of the remote tarball.

Examines the contents of a tarball located at the given remote_tarball_path and determines the top-level directory. If all files and directories in the tarball share the same top-level directory, that directory name is returned. If the tarball contains multiple top-level directories or is empty, the method return None.

Parameters:

remote_tarball_path (str | pathlib.PurePath) – The path to the remote tarball.

Returns:

The top directory of the tarball. If there are multiple top directories or the tarball is empty, returns None.

Return type:

str | pathlib.PurePosixPath | None

abstract build_dpdk(env_vars: dict, meson_args: MesonArgs, remote_dpdk_dir: str | pathlib.PurePath, remote_dpdk_build_dir: str | pathlib.PurePath, rebuild: bool = False, timeout: float = 1200) None

Build DPDK on the remote node.

An extracted DPDK tarball must be present on the node. The build consists of two steps:

meson setup <meson args> remote_dpdk_dir remote_dpdk_build_dir
ninja -C remote_dpdk_build_dir

The --compile-timeout command line argument and the DTS_COMPILE_TIMEOUT environment variable configure the timeout of DPDK build.

Parameters:
  • env_vars (dict) – Use these environment variables when building DPDK.

  • meson_args (MesonArgs) – Use these meson arguments when building DPDK.

  • remote_dpdk_dir (str | pathlib.PurePath) – The directory on the remote node where DPDK will be built.

  • remote_dpdk_build_dir (str | pathlib.PurePath) – The target build directory on the remote node.

  • rebuild (bool) – If True, do a subsequent build with meson configure instead of meson setup.

  • timeout (float) – Wait at most this long in seconds for the build execution to complete.

abstract get_dpdk_version(version_path: str | pathlib.PurePath) str

Inspect the DPDK version on the remote node.

Parameters:

version_path (str | pathlib.PurePath) – The path to the VERSION file containing the DPDK version.

Returns:

The DPDK version.

Return type:

str

abstract get_remote_cpus(use_first_core: bool) list[framework.testbed_model.cpu.LogicalCore]

Get the list of LogicalCores on the remote node.

Parameters:

use_first_core (bool) – If False, the first physical core won’t be used.

Returns:

The logical cores present on the node.

Return type:

list[framework.testbed_model.cpu.LogicalCore]

abstract kill_cleanup_dpdk_apps(dpdk_prefix_list: Iterable[str]) None

Kill and cleanup all DPDK apps.

Parameters:

dpdk_prefix_list (Iterable[str]) – Kill all apps identified by dpdk_prefix_list. If dpdk_prefix_list is empty, attempt to find running DPDK apps to kill and clean.

abstract get_dpdk_file_prefix(dpdk_prefix: str) str

Make OS-specific modification to the DPDK file prefix.

Parameters:

dpdk_prefix (str) – The OS-unaware file prefix.

Returns:

The OS-specific file prefix.

Return type:

str

abstract setup_hugepages(number_of: int, hugepage_size: int, force_first_numa: bool) None

Configure hugepages on the node.

Get the node’s Hugepage Size, configure the specified count of hugepages if needed and mount the hugepages if needed.

Parameters:
  • number_of (int) – Configure this many hugepages.

  • hugepage_size (int) – Configure hugepages of this size.

  • force_first_numa (bool) – If True, configure just on the first numa node.

abstract get_compiler_version(compiler_name: str) str

Get installed version of compiler used for DPDK.

Parameters:

compiler_name (str) – The name of the compiler executable.

Returns:

The compiler’s version.

Return type:

str

abstract get_node_info() OSSessionInfo

Collect additional information about the node.

Returns:

Node information.

Return type:

OSSessionInfo

abstract update_ports(ports: list[framework.testbed_model.port.Port]) None

Get additional information about ports from the operating system and update them.

The additional information is:

  • Logical name (e.g. enp7s0) if applicable,

  • Mac address.

Parameters:

ports (list[framework.testbed_model.port.Port]) – The ports to update.

abstract configure_port_mtu(mtu: int, port: Port) None

Configure mtu on port.

Parameters:
  • mtu (int) – Desired MTU value.

  • port (Port) – Port to set mtu on.