Skip to content

Commit d2cc1a8

Browse files
authored
Add ImageService.set_next_boot for GNOI Activate OS. (#207)
* Add ImageService.set_next_boot for GNOI Activate OS. * address copilot comment. * more logs. * update unit test.
1 parent 9c49913 commit d2cc1a8

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

host_modules/image_service.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,27 @@ def list_images(self):
160160
logger.error(msg)
161161
return e.returncode, msg
162162

163+
@host_service.method(
164+
host_service.bus_name(MOD_NAME), in_signature="s", out_signature="is"
165+
)
166+
def set_next_boot(self, image):
167+
"""
168+
Set the image to be used for the next boot.
169+
170+
Args:
171+
image: The name of the image to set for the next boot.
172+
"""
173+
logger.info("Setting the next boot image to {}".format(image))
174+
cmd = ["/usr/local/bin/sonic-installer", "set-next-boot", image]
175+
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
176+
msg = "Boot image set to {}".format(image)
177+
logger.info(msg)
178+
if result.returncode:
179+
logger.error("Failed to set next boot image: {}".format(result.stderr.decode()))
180+
msg = result.stderr.decode()
181+
return result.returncode, msg
182+
183+
163184
def _parse_sonic_installer_list(self, output):
164185
"""
165186
Parse the output of the sonic-installer list command.

tests/host_modules/image_service_test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,3 +568,59 @@ def test_list_images_failed(self, mock_check_output, MockInit, MockBusName, Mock
568568
stderr=subprocess.STDOUT,
569569
)
570570

571+
@mock.patch("dbus.SystemBus")
572+
@mock.patch("dbus.service.BusName")
573+
@mock.patch("dbus.service.Object.__init__")
574+
@mock.patch("subprocess.run")
575+
def test_image_set_next_boot_success(self, mock_run, MockInit, MockBusName, MockSystemBus):
576+
"""
577+
Test that the `set_next_boot` method successfully sets the next boot image.
578+
"""
579+
# Arrange
580+
image_service = ImageService(mod_name="image_service")
581+
image = "sonic_image"
582+
mock_result = mock.Mock()
583+
mock_result.returncode = 0
584+
mock_result.stderr = b""
585+
mock_run.return_value = mock_result
586+
587+
# Act
588+
rc, msg = image_service.set_next_boot(image)
589+
590+
# Assert
591+
assert rc == 0, "wrong return value"
592+
assert image in msg, "message should contain the name of the new image"
593+
mock_run.assert_called_once_with(
594+
["/usr/local/bin/sonic-installer", "set-next-boot", image],
595+
stdout=subprocess.PIPE,
596+
stderr=subprocess.PIPE,
597+
)
598+
599+
@mock.patch("dbus.SystemBus")
600+
@mock.patch("dbus.service.BusName")
601+
@mock.patch("dbus.service.Object.__init__")
602+
@mock.patch("subprocess.run")
603+
def test_image_set_next_boot_fail_not_exists(self, mock_run, MockInit, MockBusName, MockSystemBus):
604+
"""
605+
Test that the `set_next_boot` method fails when the image does not exist.
606+
"""
607+
# Arrange
608+
image_service = ImageService(mod_name="image_service")
609+
image = "nonexistent_image"
610+
mock_result = mock.Mock()
611+
mock_result.returncode = 1
612+
mock_result.stderr = b"Error: Image does not exist"
613+
mock_run.return_value = mock_result
614+
615+
# Act
616+
rc, msg = image_service.set_next_boot(image)
617+
618+
# Assert
619+
assert rc != 0, "wrong return value"
620+
assert "Error: Image does not exist" in msg, "message should contain 'Error: Image does not exist'"
621+
mock_run.assert_called_once_with(
622+
["/usr/local/bin/sonic-installer", "set-next-boot", image],
623+
stdout=subprocess.PIPE,
624+
stderr=subprocess.PIPE,
625+
)
626+

0 commit comments

Comments
 (0)