Skip to content

Commit

Permalink
Windows support for the Service tool.
Browse files Browse the repository at this point in the history
This pull request adds Windows support for the Service tool.
  • Loading branch information
SRIKKANTH committed Jan 2, 2025
1 parent d225696 commit 30a8249
Showing 1 changed file with 97 additions and 1 deletion.
98 changes: 97 additions & 1 deletion lisa/base_tools/service.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
import re
from typing import Type
from enum import Enum
from time import sleep
from typing import Optional, Type

from lisa.executable import ExecutableResult, Tool
from lisa.tools.powershell import PowerShell
from lisa.util import (
LisaException,
UnsupportedDistroException,
create_timer,
filter_ansi_escape,
find_group_in_lines,
)
Expand All @@ -25,6 +30,10 @@ def command(self) -> str:
def can_install(self) -> bool:
return False

@classmethod
def _windows_tool(cls) -> Optional[Type[Tool]]:
return WindowsService

def _check_exists(self) -> bool:
cmd_result = self.node.execute(
"ls -lt /run/systemd/system", shell=True, sudo=True
Expand Down Expand Up @@ -200,3 +209,90 @@ def _check_service_running(self, name: str) -> bool:

def _check_error_codes(cmd_result: ExecutableResult, error_code: int = 0) -> None:
cmd_result.assert_exit_code(expected_exit_code=[0, error_code])


class WindowsServiceStatus(int, Enum):
CONTINUE_PENDING = 5
PAUSE_PENDING = 6
PAUSED = 7
RUNNING = 4
START_PENDING = 2
STOP_PENDING = 3
STOPPED = 1


class WindowsService(Tool):
@property
def can_install(self) -> bool:
return False

@property
def command(self) -> str:
return ""

def enable_service(self, name: str) -> None:
pass

def restart_service(self, name: str, ignore_exit_code: int = 0) -> None:
self.node.tools[PowerShell].run_cmdlet(
f"Restart-service {name}",
force_run=True,
)
self.wait_for_service_start(name)

def stop_service(self, name: str) -> None:
self.node.tools[PowerShell].run_cmdlet(
f"Stop-Service {name} -Force",
force_run=True,
output_json=True,
fail_on_error=False,
)
self.wait_for_service_stop(name)

def wait_for_service_start(self, name: str) -> None:
self._wait_for_service(name, WindowsServiceStatus.RUNNING)

def wait_for_service_stop(self, name: str) -> None:
self._wait_for_service(name, WindowsServiceStatus.STOPPED)

def _check_exists(self) -> bool:
return True

def _check_service_exists(self, name: str) -> bool:
try:
self._get_status(name)
return True
except LisaException:
return False

def _check_service_running(self, name: str) -> bool:
return self._get_status(name) == WindowsServiceStatus.RUNNING

def _get_status(self, name: str = "") -> WindowsServiceStatus:
service_status = self.node.tools[PowerShell].run_cmdlet(
f"Get-Service {name}",
force_run=True,
output_json=True,
fail_on_error=False,
)
if not service_status:
raise LisaException(f"service '{name}' does not exist")
return WindowsServiceStatus(int(service_status["Status"]))

def _is_service_inactive(self, name: str) -> bool:
return self._get_status(name) == WindowsServiceStatus.STOPPED

def _wait_for_service(self, name: str, status: WindowsServiceStatus) -> None:
timeout = 60
timer = create_timer()
self._log.debug(f"waiting for service '{name}' to be in '{status}' state")
while timeout > timer.elapsed(False):
current_service_status = self._get_status(name)
if status == current_service_status:
return
sleep(0.5)

if timeout < timer.elapsed():
raise LisaException(
f"service '{name}' still in '{current_service_status}' state after '{timeout}' seconds" # noqa: E501
)

0 comments on commit 30a8249

Please sign in to comment.