LAA manager (aka. laam) - Python3

The LAA Manager is a python application that allows to interact with the LAA REST API.

This is the documentation to use laam in a python script.

LAA manager v0.8.3

The documentation refers to laam v0.8.3. Version notes at the bottom

Installation

laam is available from PyPI:

python3 -m venv venv
source venv/bin/activate
python3 -m pip install --upgrade  laam 
laam --help
laam --version

Configuration

You can create identities via console

The identities can then be used in this way:

import laam
LAA_1 = laam.LAA("identity-1");

Local Commands

β€œlocal” commands are not defined for python.

LAA class

class laam.LAA

Main Abstraction class to interact with a Linaro Automation Appliance.

This class provides the core object model and methods required to remotely interact with an LAA from the host machine using LAAM. It abstracts the underlying communication protocols (e.g., REST, WebSockets) necessary to control the Appliance’s primary functions to control the Device Under Test mounted on the LAA itself. The functions include power cycling, logs, usb control, serial interaction, etc…

__init__(self, laa_identity='default')

Initializes the interface object for the target LAA.

This method prepares the interface object using the provided identity. The identity is critical for addressing and authenticating a specific LAA

** Authentication Note ** To authenticate and enable control, you must:

  1. Create an API token on the LAA

  2. Manually configure the LAAM environment to use the token

Parameters:

  • laa_identity (str): A required unique string identifier the target LAA

Properties, Classes, and Methods

identities

There is no identities property. identities commands are supposed to be configured manually via the console interface, not through automated Python scripts.

dut

There is no dut property. Device configuration files are supposed to be configured manually via the console interface, not through automated Python scripts.

files

Manage files in /var/lib/lava/dispatcher/tmp on the LAA.

property laam.LAA.files

Interface for remote file management on the LAA. Based on the class Files.

help(laam.LAA.Files) for more info.

class laam.LAA.Files

Class for file management and transfer on the LAA.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

list(self) list

Lists all the files in the working folder.

Returns:

  • A list of file names.

Raises:

  • LAAError: If the LAA is offline or the request fails.

pull(self, name: str, file: pathlib.Path, force: bool = False) bool

Downloads a file from the LAA the working folder to the local machine.

Args:

  • name (str): The name of the file on the LAA to be downloaded.

  • file (pathlib.Path): The file path to save the file downloaded from the LAA.

Returns:

  • bool: True if the file was downloaded successfully, False otherwise.

Raises:

  • LAAError: If the LAA is offline or the request fails.

push(self, name: str, file) bool

Uploads a file from local machine to the LAA the working folder.

Args:

  • name (str): The name of the file to be saved on the LAA as.

  • file (str, pathlib.Path, os.PathLike, io.BufferedReader): The file on the local machine to be uploaded. It can be a path to the object file itself.

Returns:

  • bool: True if the file was uploaded successfully, False otherwise.

Raises:

  • LAAError: If the LAA is offline or the request fails.

remove(self, name: str) bool

Removes a file in the LAA the working folder.

Args:

  • name (str): The name of the file to be removed.

Returns:

  • bool: True if the file was removed successfully, False otherwise.

Raises:

  • LAAError: If the LAA is offline or the request fails.

laacli

Execute laacli commands on the LAA.

property laam.LAA.laacli

Interface for executing laacli commands. Based on the class LAACli.

help(laam.LAA.LAACli) for more info.

class laam.LAA.LAACli

Class for executing laacli commands on the LAA.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

button(self, button: str, state: str) dict

Controls the virtual buttons on the LAA.

Args:

  • button (str): The virtual button to control. Available choices are: β€œ1”, β€œ2”, β€œpower”, β€œreset”.

  • state (str): State to set on the button. Available choices are: β€œon”, β€œoff”, β€œstatus”.

Returns:

  • dict: Returned command execution object.

Raises:

  • LAAError: If the LAA is offline or the request fails.

led(self, state: str) dict

Controls the status LED on the LAA.

Args:

  • state (str): The state of the LED. Available choices are: β€œon”, β€œoff”.

Returns:

  • dict: Returned command execution object

Raises:

  • LAAError: If the LAA is offline or the request fails.

power(self, vbus: str, state: str) dict

Controls the power rails on the LAA.

Args:

  • vbus (str): Power rail to control. Available choices are: β€œ1v8”, β€œ3v3”, β€œ5v”, β€œ12v”.

  • state (str): State to set the rail. Available choices are: β€œon”, β€œoff”, β€œreset”, β€œstatus”.

Returns:

  • dict: Returned command execution object.

Raises:

  • LAAError: If the LAA is offline or the request fails.

rev(self) dict

Returns the hardware revision of the LAA.

Returns:

  • dict: Returned revision object.

Raises:

  • LAAError: If the LAA is offline or the request fails.

screenshot(self, filename) dict

Screenshots the current OLED and downloads it as a file on the local machine.

Args:

  • filename (str, os.PathLike, pathlib.Path, io.BufferedWriter): It can be the file path to save the file downloaded from the LAA, or the opened file object itself.

Returns:

  • dict: Returned command execution object.

Raises:

  • LAAError: If the LAA is offline or the request fails.

temp(self, probe: str) dict

Returns temperature information from the LAA.

Args:

  • probe (str): Temperature probe to check. Available choices are: β€œamb”, β€œdut”, β€œsys”.

Returns:

  • dict: Temperature information.

Raises:

  • LAAError: If the LAA is offline or the request fails.

usb(self, port: int, state: str) dict

Controls the four USB ports on the LAA (the ones pointing upwards).

Args:

  • port (int): USB port to control. Available choices are: 0, 1, 2, 3, 4. Where 0 is the USB Hub controlling USB ports 1, 2, 3, 4.

  • state (str): State to set the port or just check the status. Available choices are: β€œon”, β€œoff”, β€œreset”, β€œstart”, β€œstatus”.

Returns:

  • dict: Returned command execution object.

Raises:

  • LAAError: If the LAA is offline or the request fails.

usbg_ms(self, state: str, filename: str = '') dict

Controls the USBG-MS port on the LAA (the ones at the front marked as USB-OTG).

Args:

  • state (str): State to set the port or just check the status. Available choices are: β€œon”, β€œoff”, β€œstatus”.

  • filename (str): File name of the image to be used, It is assumed to be located in the working LAA folder. Parameter needed only if the status is set to β€œon”.

Returns:

  • dict: Returned command execution object.

Raises:

  • LAAError: If the LAA is offline or the request fails.

watt(self, vbus: str) dict

Returns power usage information from the LAA.

Args:

  • vbus (str): Power rail to check. Available choices are: β€œ1v8”, β€œ3v3”, β€œ5v”, β€œ12v”.

Returns:

  • dict: Power usage information.

Raises:

  • LAAError: If the LAA is offline or the request fails.

network

Manage LAA network configuration

property laam.LAA.network

Interface for monitoring the LAA’s network interfaces. Based on the class Network.

help(laam.LAA.Network) for more info.

class laam.LAA.Network

Class for monitoring the LAA’s network interfaces.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

addresses(self) dict

Returns the addresses of the LAA.

Returns:

  • dict: Addresses information.

Raises:

  • LAAError: If the LAA is offline or the request fails.

hostname(self) dict

Returns the hostname of the LAA.

Returns:

  • dict: Returns the hostname.

Raises:

  • LAAError: If the LAA is offline or the request fails.

interfaces(self) list

Returns the interfaces of the LAA.

Returns:

  • list: Returns the interfaces.

Raises:

  • LAAError: If the LAA is offline or the request fails.

routes(self) dict

Returns the network routes of the LAA.

Returns:

  • dict: Returns the routes.

Raises:

  • LAAError: If the LAA is offline or the request fails.

settings(self) str

Returns the network settings of the LAA.

Returns:

  • str: Returns the settings.

Raises:

  • LAAError: If the LAA is offline or the request fails.

serials

List and interact with the different serial consoles provided by the LAA.

property laam.LAA.serials

Interface for managing and interacting with the LAA’s serial consoles. Based on the class Serials.

help(laam.LAA.Serials) for more info.

class laam.LAA.Serials

Class for managing and interacting with the LAA’s serial consoles with the DUT.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

list(self, ser_filter=None) list

Lists all the serials accessible via the LAA.

Args:

  • ser_filter: Filter value to log out specific serials.

Returns:

  • list: Returns a list of serials.

Raises:

  • LAAError: If the LAA is offline or the request fails.

get(self, name: str) dict

Returns the details of a specific serial console.

Args:

  • name (str): Name of the serial console, example β€œttyUSB0”.

Returns:

  • dict: Returns serial information.

Raises:

  • LAAError: If the LAA is offline or the request fails.

connect_async_fun(self, name: str, readonly: bool = False, istream: io.TextIOBase = sys.stdin, ostream: io.TextIOBase = sys.stdout, force_str: bool | None = None) int

Connects to a serial console with the DUT in an async function.

Args:

  • name (str): Name of the serial console, example β€œttyUSB0”.

  • readonly (bool): True to start a readonly serial connection. (Default) False for an interactive connection

  • istream (io.TextIOBase): Input stream used to send data to the DUT on the LAA. Defaults to sys.stdin.

  • ostream (io.TextIOBase): Output stream used to receive data from the DUT on the LAA. Defaults to sys.stdout.

  • force_str (Optional[bool]): True to exchange data as string. False to exchange data as bytes. (Default) None to automatically use the best option. Exposed mostly for testing purposes.

Returns:

  • int: 0 if the serial connection completed by itself without errors. 1 if it failed or got interrupted.

Raises:

  • LAAError: If the LAA is offline or the request fails.

connect_async(self, name: str, readonly: bool = False, istream: io.TextIOBase = sys.stdin, ostream: io.TextIOBase = sys.stdout, force_str: bool | None = None) asyncio.Task

Connects to a serial console with the DUT in an async task. Basically a wrapper for connect_async_fun that returns the task.

Args:

  • name (str): Name of the serial console, example β€œttyUSB0”.

  • readonly (bool): True to start a readonly serial connection. (Default) False for an interactive connection

  • istream (io.TextIOBase): Input stream used to send data to the DUT on the LAA. Defaults to sys.stdin.

  • ostream (io.TextIOBase): Output stream used to receive data from the DUT on the LAA. Defaults to sys.stdout.

  • force_str (Optional[bool]): True to exchange data as string. False to exchange data as bytes. (Default) None to automatically use the best option. Exposed mostly for testing purposes.

Returns:

  • asyncio.Task: Returns an async tasks that can be easily managed.

Raises:

  • LAAError: If the LAA is offline or the request fails.

connect_pexpect(self, name: str, readonly: bool = False) laam.utils.ConnectPexpect

Connects to a serial console with the DUT in an Pexpect object.

Args:

  • name (str): Name of the serial console, example β€œttyUSB0”.

  • readonly (bool): True to start a readonly serial connection. (Default) False for an interactive connection.

Returns:

  • laam.utils.ConnectPexpect: Custom Pexpect object.

Raises:

  • LAAError: If the LAA is offline or the request fails.

services

Monitor systemd services running on the LAA.

property laam.LAA.services

Interface for monitoring system services on the LAA. Based on the class Services.

help(laam.LAA.Services) for more info.

class laam.LAA.Services

Class for monitoring system services on the LAA.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

list(self) list

Lists all the services on the LAA.

Returns:

  • list: Returns a list of services.

Raises:

  • LAAError: If the LAA is offline or the request fails.

logs(self, name: str) list

Returns the logs of a specific service.

Args:

  • name (str): Name of the service.

Returns:

  • list: Returns logs information.

Raises:

  • LAAError: If the LAA is offline or the request fails.

system

Display LAA system information.

property laam.LAA.system

Interface for general system-level monitoring. Based on the class System.

help(laam.LAA.System) for more info.

class laam.LAA.System

Class for general system-level monitoring.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

version(self) list

Returns the OS software version on the LAA.

Returns:

  • str: Returns the version.

Raises:

  • LAAError: If the LAA is offline or the request fails.

fleet(self) list

Returns information of the fleet that the LAA is registered with.

Returns:

  • dict: Returns fleet information.

Raises:

  • LAAError: If the LAA is offline or the request fails.

logs(self) list

Returns system logs from the LAA.

Returns:

  • list: Returns logs.

Raises:

  • LAAError: If the LAA is offline or the request fails.

usbs

Display usb devices.

property laam.LAA.usbs

Interface for monitoring the LAA’s USB sub-system. Based on the class USBs.

help(laam.LAA.USBs) for more info.

class laam.LAA.USBs

Class for monitoring the LAA’s USB sub-system.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

list(self) list

Lists all the active usb connections seen by the operating system.

Returns:

  • list: Returns a list of active usb connections with bus and device details.

Raises:

  • LAAError: If the LAA is offline or the request fails.

get(self, bus: str, device: str) str

Get details of a USB device on a particular bus.

Args:

  • bus (str): Name of the bus to look into.

  • device (str): Name of the device to get details of.

Returns:

  • str: Returns the details of the device.

Raises:

  • LAAError: If the LAA is offline or the request fails.

workers

Manage LAVA workers running on the LAA.

property laam.LAA.workers

Interface for monitoring workers on the LAA. Based on the class Workers.

help(laam.LAA.Workers) for more info.

class laam.LAA.Workers

Class for monitoring workers on the LAA.

NOTE: This class should NOT be instantiated directly by the user. Access to these functions is available only via the main LAA object..

dockerfile(self, worker_id: int) str

Returns the dockerfile of the specified worker.

Args:

  • worker_id (int): identifier of the worker.

Returns:

  • str: Returns a dockerfile content.

Raises:

  • LAAError: If the LAA is offline or the request fails.

list(self) list

Lists all the workers active on the LAA.

Returns:

  • str: Returns a list of workers with main information.

Raises:

  • LAAError: If the LAA is offline or the request fails.

logs(self, worker_id: int) list

Returns the logs of the specified worker.

Args:

  • worker_id (int): identifier of the worker.

Returns:

  • str: Returns logs.

Raises:

  • LAAError: If the LAA is offline or the request fails.

get(self, worker_id: int) dict

Returns details of the specified worker.

Args:

  • worker_id (int): identifier of the worker.

Returns:

  • str: Returns worker details.

Raises:

  • LAAError: If the LAA is offline or the request fails.

test(self, worker_id: int) dict

Returns the connection status of the worker with its LAVA instance.

Args:

  • worker_id (int): identifier of the worker.

Returns:

  • str: Returns connection status.

Raises:

  • LAAError: If the LAA is offline or the request fails.

Exceptions

The following are the main exceptions that can be thrown by using an LAA object.

exception LAAError(Exception)

Base exception class for all LAA application errors.

Attributes:

  • message (str): The detailed error message describing the issue.

exception LAAConnectionError(LAAError)

Exception class for connection errors with the LAA (like wrong IP address or device offline).

Attributes:

  • message (str): The detailed error message describing the issue.

exception LAAApiError(LAAError)

Exception class for all HTTP API errors from the LAA.

Attributes:

  • message (str): The detailed error message describing the issue.

  • http_code (int): The relevant HTTP status code (e.g., 400, 500).

exception LAACliError(LAAError)

Exception class for all errors when running commands of the LAA itself.

Attributes:

  • message (str): The detailed error message describing the issue.

  • ret_json (dict): The error object returned from the LAA with β€˜stdout’,’sterr’, and β€˜code’

ConnectPexpect class

The laam.utils.ConnectPexpect is based on Pexpect.spawn class

class ConnectPexpect(pexpect.spawn)

Examples

Here a few examples on how to use the LAA object in a script.

Example 1

List Files in my LAA

from laam import LAA
my_laa = LAA("my_laa_id")
print(my_laa.files.list()) 

=> ["file1", "file2", "file2"]

Example 2

Connect to a Serial in my LAA

from laam import LAA
import time
my_laa = LAA("my_laa_id")

# Assuming the DUT on the LAA uses `ttymxc3`
pexp_connection = my_laa.serials.connect_pexpect(name="ttymxc3")
time.sleep(1)

pexp_connection.expect("Connected to port 2001", timeout=2)
pexp_connection.sendline("")

 # Waiting for uBoot on the DUT on my LAA
pexp_connection.expect("=>", timeout=40)
pexp_connection.send(b"usb start; usb info\n")
pexp_connection.expect("LAA USB Mass Storage Gadget", timeout=1)

Issues

In case you of problems Open an Issue

Version notes

LAA module availability

The LAA python object is available from laam => v0.8.2.

LED sub-command

laa.laacli.led(state) is working from LAA OS > v1.6.1.

LAA OS v1.4

The REST API used by laam is only available in LAA OS v1.4 and after.

LAA manager =< v0.8.1

laa.serials.connect_async_fun(), laa.serials.connect_async(), and laa.serials.connect_pexpect() cannot connect with LAA OS =< v1.5.5.

LAA manager v0.8.3

β€œlaa,network.settings()” command fails. This has been fixed in laam v0.8.3