Skip to content

Commit 5a90a1b

Browse files
fix: stop running instance if activation restart failed at validation (#1093)
Co-authored-by: Alex <aizquier@redhat.com>
1 parent 9180121 commit 5a90a1b

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

src/aap_eda/api/views/activation.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,15 @@ def restart(self, request, pk):
413413
detail="Activation is disabled and cannot be run."
414414
)
415415

416+
# Redis must be available in order to perform the restart.
417+
self.redis_is_available()
418+
416419
valid, error = is_activation_valid(activation)
417420
if not valid:
421+
stop_rulebook_process(
422+
process_parent_type=ProcessParentType.ACTIVATION,
423+
process_parent_id=activation.id,
424+
)
418425
activation.status = ActivationStatus.ERROR
419426
activation.status_message = error
420427
activation.save(update_fields=["status", "status_message"])
@@ -424,9 +431,6 @@ def restart(self, request, pk):
424431
{"errors": error}, status=status.HTTP_400_BAD_REQUEST
425432
)
426433

427-
# Redis must be available in order to perform the restart.
428-
self.redis_is_available()
429-
430434
restart_rulebook_process(
431435
process_parent_type=ProcessParentType.ACTIVATION,
432436
process_parent_id=activation.id,

src/aap_eda/services/activation/activation_manager.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,8 @@ def stop(self):
718718
return
719719

720720
try:
721-
self.set_status(ActivationStatus.STOPPING)
721+
if self.db_instance.status != ActivationStatus.ERROR:
722+
self.set_status(ActivationStatus.STOPPING)
722723
self._stop_instance()
723724

724725
except engine_exceptions.ContainerEngineError as exc:
@@ -730,7 +731,10 @@ def stop(self):
730731
self._error_activation(msg)
731732
raise exceptions.ActivationStopError(msg) from exc
732733
user_msg = "Stop requested by user."
733-
self.set_status(ActivationStatus.STOPPED, user_msg)
734+
if self.db_instance.status != ActivationStatus.ERROR:
735+
# do not overwrite the status and message if the activation
736+
# is already in error status
737+
self.set_status(ActivationStatus.STOPPED, user_msg)
734738
container_logger = self.container_logger_class(self.latest_instance.id)
735739
container_logger.write(user_msg, flush=True)
736740
LOGGER.info(

tests/integration/api/test_activation.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -961,14 +961,23 @@ def test_restart_activation_with_required_token_deleted(
961961
assert response.status_code == status.HTTP_201_CREATED
962962
token = models.AwxToken.objects.get(id=admin_awx_token.id)
963963
token.delete()
964+
activation_id = response.data["id"]
964965

965-
response = admin_client.post(
966-
f"{api_url_v1}/activations/{response.data['id']}/restart/",
967-
)
968-
assert response.status_code == status.HTTP_400_BAD_REQUEST
969-
assert (
970-
"The rulebook requires a RH AAP credential." in response.data["errors"]
971-
)
966+
with mock.patch(
967+
"aap_eda.api.views.activation.stop_rulebook_process"
968+
) as mock_stop:
969+
response = admin_client.post(
970+
f"{api_url_v1}/activations/{activation_id}/restart/",
971+
)
972+
assert response.status_code == status.HTTP_400_BAD_REQUEST
973+
assert (
974+
"The rulebook requires a RH AAP credential."
975+
in response.data["errors"]
976+
)
977+
mock_stop.assert_called_once_with(
978+
process_parent_type=enums.ProcessParentType.ACTIVATION,
979+
process_parent_id=activation_id,
980+
)
972981

973982

974983
@pytest.mark.django_db

tests/integration/services/activation/test_manager.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,37 @@ def test_stop_already_stopped(
403403
assert not container_engine_mock.cleanup.called
404404

405405

406+
@pytest.mark.parametrize(
407+
("before_status", "after_status", "before_msg", "after_msg"),
408+
[
409+
(
410+
enums.ActivationStatus.RUNNING,
411+
enums.ActivationStatus.STOPPED,
412+
"running",
413+
"Stop requested by user.",
414+
),
415+
(
416+
enums.ActivationStatus.ERROR,
417+
enums.ActivationStatus.ERROR,
418+
"activation validation failed",
419+
"activation validation failed",
420+
),
421+
],
422+
)
406423
@pytest.mark.django_db
407424
def test_stop_running(
408425
running_activation: models.Activation,
409426
container_engine_mock: MagicMock,
410427
eda_caplog: LogCaptureFixture,
428+
before_status,
429+
after_status,
430+
before_msg,
431+
after_msg,
411432
):
412433
"""Test stop verb when activation is running."""
434+
running_activation.status = before_status
435+
running_activation.status_message = before_msg
436+
running_activation.save(update_fields=["status", "status_message"])
413437
activation_manager = ActivationManager(
414438
container_engine=container_engine_mock,
415439
db_instance=running_activation,
@@ -419,13 +443,13 @@ def test_stop_running(
419443
assert "Stopping" in eda_caplog.text
420444
assert "Cleanup operation requested" in eda_caplog.text
421445
assert "Activation stopped." in eda_caplog.text
422-
assert running_activation.status == enums.ActivationStatus.STOPPED
446+
assert running_activation.status == after_status
423447
assert (
424448
running_activation.latest_instance.status
425449
== enums.ActivationStatus.STOPPED
426450
)
427451
assert running_activation.latest_instance.activation_pod_id is None
428-
assert running_activation.status_message == "Stop requested by user."
452+
assert running_activation.status_message == after_msg
429453
assert container_engine_mock.cleanup.called
430454

431455

0 commit comments

Comments
 (0)