Skip to content

Commit ac7b8c7

Browse files
committed
Add execute_reboot dbus_interface
1 parent b7f26d4 commit ac7b8c7

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

host_modules/systemd_service.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
"""Systemd service handler"""
22

3+
from enum import Enum
34
from host_modules import host_service
45
import subprocess
56

67
MOD_NAME = 'systemd'
78
ALLOWED_SERVICES = ['snmp', 'swss', 'dhcp_relay', 'radv', 'restapi', 'lldp', 'sshd', 'pmon', 'rsyslog', 'telemetry']
89
EXIT_FAILURE = 1
910

11+
# Define an Enum for Reboot Methods which are defined as in
12+
# https://github.com/openconfig/gnoi/blob/main/system/system.pb.go#L27
13+
class RebootMethod(Enum):
14+
COLD = 1
15+
HALT = 3
1016

1117
class SystemdService(host_service.HostModule):
1218
"""
@@ -48,3 +54,19 @@ def stop_service(self, service):
4854
if result.returncode:
4955
msg = result.stderr.decode()
5056
return result.returncode, msg
57+
58+
@host_service.method(host_service.bus_name(MOD_NAME), in_signature='s', out_signature='is')
59+
def execute_reboot(self, rebootmethod):
60+
if rebootmethod == RebootMethod.COLD:
61+
cmd = ['/usr/local/bin/reboot']
62+
elif rebootmethod == RebootMethod.HALT:
63+
cmd = ['/usr/local/bin/reboot','-p']
64+
else:
65+
return EXIT_FAILURE, "{}: Invalid reboot method: {}".format(MOD_NAME, rebootmethod)
66+
67+
result = subprocess.run(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
68+
msg = ''
69+
if result.returncode:
70+
msg = result.stderr.decode()
71+
72+
return result.returncode, msg

tests/host_modules/systemd_service_test.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,57 @@ def test_service_stop_empty(self, MockInit, MockBusName, MockSystemBus):
8484
ret, msg = systemd_service_stub.stop_service(service)
8585
assert ret == 1
8686
assert "stop_service called with no service specified" in msg
87+
88+
@mock.patch("dbus.SystemBus")
89+
@mock.patch("dbus.service.BusName")
90+
@mock.patch("dbus.service.Object.__init__")
91+
def test_execute_reboot_cold(self, MockInit, MockBusName, MockSystemBus):
92+
# Mock subprocess.run
93+
with mock.patch("subprocess.run") as mock_run:
94+
# Mock the result of subprocess.run
95+
res_mock = mock.Mock()
96+
test_ret = 0
97+
test_msg = b"Succeeded"
98+
res_mock.configure_mock(returncode=test_ret, stderr=test_msg)
99+
mock_run.return_value = res_mock
100+
101+
method = systemd_service.RebootMethod.COLD
102+
systemd_service_stub = systemd_service.SystemdService(systemd_service.MOD_NAME)
103+
104+
# Execute the reboot method
105+
ret, msg = systemd_service_stub.execute_reboot(method)
106+
107+
# Assert the correct command was called
108+
call_args = mock_run.call_args[0][0]
109+
assert "/usr/local/bin/reboot" in call_args, f"Expected 'reboot' command, but got: {call_args}"
110+
111+
# Assert the return values are correct
112+
assert ret == test_ret, f"Expected return code {test_ret}, got {ret}"
113+
assert msg == "", f"Expected return message '', got {msg}"
114+
115+
@mock.patch("dbus.SystemBus")
116+
@mock.patch("dbus.service.BusName")
117+
@mock.patch("dbus.service.Object.__init__")
118+
def test_execute_reboot_halt(self, MockInit, MockBusName, MockSystemBus):
119+
# Mock subprocess.run
120+
with mock.patch("subprocess.run") as mock_run:
121+
# Mock the result of subprocess.run
122+
res_mock = mock.Mock()
123+
test_ret = 0
124+
test_msg = b"Succeeded"
125+
res_mock.configure_mock(returncode=test_ret, stderr=test_msg)
126+
mock_run.return_value = res_mock
127+
128+
method = systemd_service.RebootMethod.HALT
129+
systemd_service_stub = systemd_service.SystemdService(systemd_service.MOD_NAME)
130+
131+
# Execute the reboot method
132+
ret, msg = systemd_service_stub.execute_reboot(method)
133+
134+
# Assert the correct command was called
135+
call_args = mock_run.call_args[0][0]
136+
assert "/usr/local/bin/reboot" in call_args, f"Expected 'reboot' command, but got: {call_args}"
137+
138+
# Assert the return values are correct
139+
assert ret == test_ret, f"Expected return code {test_ret}, got {ret}"
140+
assert msg == "", f"Expected return message '', got {msg}"

0 commit comments

Comments
 (0)