Skip to content

Commit

Permalink
Merge branch 'microsoft:main' into rydailey/OSBoot
Browse files Browse the repository at this point in the history
  • Loading branch information
r-dailey authored Sep 4, 2024
2 parents 6942544 + 225fb52 commit 04f1a16
Show file tree
Hide file tree
Showing 38 changed files with 1,593 additions and 85 deletions.
17 changes: 15 additions & 2 deletions lisa/executable.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
if TYPE_CHECKING:
from lisa.node import Node


T = TypeVar("T")


Expand Down Expand Up @@ -168,6 +167,10 @@ def create(cls, node: Node, *args: Any, **kwargs: Any) -> Tool:
freebsd_tool = cls._freebsd_tool()
if freebsd_tool:
tool_cls = freebsd_tool
elif "VMWareESXi" in node.os.name:
vmware_esxi_tool = cls._vmware_esxi_tool()
if vmware_esxi_tool:
tool_cls = vmware_esxi_tool
return tool_cls(node, *args, **kwargs)

@classmethod
Expand All @@ -184,11 +187,21 @@ def _freebsd_tool(cls) -> Optional[Type[Tool]]:
"""
return None

@classmethod
def _vmware_esxi_tool(cls) -> Optional[Type[Tool]]:
"""
return a vmware esxi version tool class, if it's needed
"""
return None

def command_exists(self, command: str) -> Tuple[bool, bool]:
exists = False
use_sudo = False
if self.node.is_posix:
where_command = "command -v"
if "VMWareESXi" in self.node.os.name:
where_command = "which"
else:
where_command = "command -v"
else:
where_command = "where"
where_command = f"{where_command} {command}"
Expand Down
2 changes: 1 addition & 1 deletion lisa/notifiers/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def finalize(self) -> None:
def _received_message(self, message: messages.MessageBase) -> None:
simplify_message(message)
# write every time to refresh the content immediately.
with open(self._file_path, "a") as f:
with open(self._file_path, "a", encoding="utf-8") as f:
f.write(f"{datetime.now(timezone.utc):%Y-%m-%d %H:%M:%S.%ff}: {message}\n")

def _subscribed_message_type(self) -> List[Type[messages.MessageBase]]:
Expand Down
12 changes: 12 additions & 0 deletions lisa/operating_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ class OperatingSystem:
__release_pattern = re.compile(r"^DISTRIB_ID='?([^ \n']+).*$", re.M)
__suse_release_pattern = re.compile(r"^(SUSE).*$", re.M)
__bmc_release_pattern = re.compile(r".*(wcscli).*$", re.M)
# VMware ESXi 8.0.2 build-23305546
# VMware ESXi 8.0 Update 2
__vmware_esxi_release_pattern = re.compile(r"^(VMware ESXi).*$", re.M)

__posix_factory: Optional[Factory[Any]] = None

Expand Down Expand Up @@ -250,6 +253,9 @@ def _get_detect_string(cls, node: Any) -> Iterable[str]:
cmd_result = typed_node.execute(cmd="wcscli", no_error_log=True)
yield get_matched_str(cmd_result.stdout, cls.__bmc_release_pattern)

cmd_result = typed_node.execute(cmd="vmware -lv", no_error_log=True)
yield get_matched_str(cmd_result.stdout, cls.__vmware_esxi_release_pattern)

# try best from distros'family through ID_LIKE
yield get_matched_str(
cmd_result_os_release.stdout, cls.__os_release_pattern_idlike
Expand Down Expand Up @@ -681,6 +687,12 @@ def name_pattern(cls) -> Pattern[str]:
return re.compile("^wcscli$")


class VMWareESXi(Posix):
@classmethod
def name_pattern(cls) -> Pattern[str]:
return re.compile("^VMware ESXi$")


class MacOS(Posix):
@classmethod
def name_pattern(cls) -> Pattern[str]:
Expand Down
21 changes: 16 additions & 5 deletions lisa/sut_orchestrator/azure/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
from marshmallow import fields, validate
from msrestazure.azure_cloud import AZURE_PUBLIC_CLOUD, Cloud # type: ignore
from PIL import Image, UnidentifiedImageError
from requests.exceptions import ChunkedEncodingError
from retry import retry

from lisa import feature, schema, search_space
Expand Down Expand Up @@ -2025,12 +2026,22 @@ def save_console_log(
)
screenshot_raw_name.unlink()

log_response = requests.get(diagnostic_data.serial_console_log_blob_uri, timeout=60)
if log_response.status_code == 404:
log.debug(
"The serial console is not generated. "
"The reason may be the VM is not started."
try:
log_response = requests.get(
diagnostic_data.serial_console_log_blob_uri, timeout=60
)
if log_response.status_code == 404:
log.debug(
"The serial console is not generated. "
"The reason may be the VM is not started."
)
except ChunkedEncodingError as ex:
log.debug(f"ChunkedEncodingError occurred: {ex}")
return b""
except Exception as ex:
log.debug(f"Failed to save console log: {ex}")
return b""

return log_response.content


Expand Down
4 changes: 2 additions & 2 deletions lisa/sut_orchestrator/baremetal/context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass
from dataclasses import dataclass, field

from lisa import schema
from lisa.environment import Environment
Expand All @@ -14,7 +14,7 @@ class EnvironmentContext:

@dataclass
class NodeContext:
connection: schema.ConnectionInfo = schema.ConnectionInfo(password="mock")
connection: schema.ConnectionInfo = field(default_factory=schema.ConnectionInfo)


@dataclass
Expand Down
19 changes: 17 additions & 2 deletions lisa/sut_orchestrator/hyperv/context.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

from dataclasses import dataclass
from dataclasses import dataclass, field
from pathlib import PurePath
from typing import Optional
from typing import List, Optional

from lisa import Node, RemoteNode
from lisa.sut_orchestrator.hyperv.schema import DeviceAddressSchema
from lisa.sut_orchestrator.util.schema import HostDevicePoolType
from lisa.util.process import Process


@dataclass
class DevicePassthroughContext:
pool_type: HostDevicePoolType = HostDevicePoolType.PCI_NIC
device_list: List[DeviceAddressSchema] = field(
default_factory=list,
)


@dataclass
class NodeContext:
vm_name: str = ""
host: Optional[RemoteNode] = None
working_path = PurePath()
serial_log_process: Optional[Process] = None

# Device pass through configuration
passthrough_devices: List[DevicePassthroughContext] = field(
default_factory=list,
)

@property
def console_log_path(self) -> PurePath:
return self.working_path / f"{self.vm_name}-console.log"
Expand Down
Loading

0 comments on commit 04f1a16

Please sign in to comment.