Files
test/keywords/docker/docker_table_parser_base.py
croy 82d417b9e6 New StarlingX Automation Framework
Fresh start for the StarlingX automation framework.

Change-Id: Ie265e0791024f45f71faad6315c2b91b022934d1
2024-11-29 16:01:57 -05:00

108 lines
4.5 KiB
Python

from typing import List
from framework.exceptions.keyword_exception import KeywordException
from framework.logging.automation_logger import get_logger
from keywords.docker.docker_table_parser_header import DockerTableParserHeader
class DockerTableParserBase:
"""
Base Class for parsing the output of Table-Like Docker commands.
This class shouldn't be used directly. Instead, it should be inherited by specific docker table parser implementations.
See DockerImagesTableParser as an example.
"""
def __init__(self, docker_output):
"""
Constructor
Args:
docker_output: The raw String output of a docker command that returns a table.
"""
self.docker_output = docker_output
self.possible_headers = [] # This needs to be defined in child classes of DockerTableParser
def get_output_values_list(self):
"""
This function will take the raw String output of a docker command that returns a table
and will parse it into a list of dictionaries. For example, if self.docker_output is:
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 1d34ffeaf190 4 weeks ago 7.79MB
busybox latest 65ad0d468eb1 13 months ago 4.26MB
registry.local:9001/node-hello latest 4c7ea8709739 8 years ago 644MB
then the function will return:
[{'REPOSITORY': 'alpine', 'TAG': 'latest', 'IMAGE ID': '1d34ffeaf190', 'CREATED': '4 weeks ago', 'SIZE': '7.79MB'},
{'REPOSITORY': 'busybox', 'TAG': 'latest', 'IMAGE ID': '65ad0d468eb1', 'CREATED': '13 months ago', 'SIZE': '4.26MB'},
{'REPOSITORY': 'registry.local:9001/node-hello', 'TAG': 'latest', 'IMAGE ID': '4c7ea8709739', 'CREATED': '8 years ago', 'SIZE': '644MB'}]
"""
if not self.possible_headers:
get_logger().log_error("There are no 'possible_headers' defined. Please use the specific child class of the docker_table_parser that has the headers that you need.")
raise KeywordException("Undefined 'possible_headers'.")
headers = []
output_values_list = []
found_headers = False
for line in self.docker_output:
if not found_headers:
# Handle Headers.
found_headers = True
headers = self.get_headers(line)
else:
# Handle entry detail lines.
line = line.rstrip("\n")
if ':~$' in line: # this would be a prompt and we want to skip it
continue
output_values = {}
for header in headers:
value = line[header.get_start_position() : header.get_end_position()]
output_values[header.get_name()] = value.strip()
output_values_list.append(output_values)
return output_values_list
def get_headers(self, line: str) -> List[DockerTableParserHeader]:
"""
This function will extract the headers from the header line passed in.
Args:
line: Line containing all the headers to be parsed.
Returns: List of DockerTableParserHeader that have been found, in order.
"""
headers = []
line = f"{line}\n"
# Find all the known headers.
for header in self.possible_headers:
if header in line:
# Find the header followed by a space or end of line.
# This is to avoid headers that are substrings of other headers.
header_index = line.find(header + " ")
header_index_last = line.find(header + "\n")
index = max(header_index, header_index_last)
header_in_line = DockerTableParserHeader(header, index)
headers.append(header_in_line)
# Sort the headers by reverse order in the line.
headers.sort(key=lambda x: x.get_start_position(), reverse=True)
# Fill in the end_position of the Header objects.
next_header_start = max([len(line) for line in self.docker_output]) # End of the longest line.
for header in headers:
header.set_end_position(next_header_start)
next_header_start = header.get_start_position()
# Sort the headers by order in the line.
headers.sort(key=lambda x: x.get_start_position(), reverse=True)
return headers