Skip to content

Commit b025029

Browse files
authored
Bug/remove container-aap 40077 (#1284)
Objectives for this bug [https://issues.redhat.com/browse/AAP-40077]: - Update restart API endpoint such that, when a user attempts to restart, we detect if the deployment type is 'podman' and the 'activation-worker-node' is offline, we should block the restart and return an error warning the user that a running container will be orphaned. - Enhance restart API endpoint with a force option where, if enabled, the restart will go through. <!-- Why is this change needed? --> Activation containers are being left behind (orphaned) on nodes that go offline in an multi-node deployment. <!-- Why is this change needed? --> The user has no way of knowing they they are leaving behind these orphaned containers. <!-- How it can be tested? -->
1 parent 40efb47 commit b025029

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/aap_eda/api/views/activation.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import redis
1717
from ansible_base.rbac.api.related import check_related_permissions
1818
from ansible_base.rbac.models import RoleDefinition
19+
from django.conf import settings
1920
from django.db import transaction
2021
from django.forms import model_to_dict
2122
from django_filters import rest_framework as defaultfilters
@@ -40,6 +41,7 @@
4041
start_rulebook_process,
4142
stop_rulebook_process,
4243
)
44+
from aap_eda.utils import str_to_bool
4345

4446
from .mixins import RedisDependencyMixin
4547

@@ -476,15 +478,42 @@ def disable(self, request, pk):
476478
None,
477479
description="Activation not enabled.",
478480
),
481+
status.HTTP_409_CONFLICT: OpenApiResponse(
482+
None,
483+
description="Activation blocked while Workers offline.",
484+
),
479485
}
480486
| RedisDependencyMixin.redis_unavailable_response(),
487+
parameters=[
488+
OpenApiParameter(
489+
name="force",
490+
description="Force restart after worker node offline",
491+
required=False,
492+
type=bool,
493+
)
494+
],
481495
)
482496
@action(methods=["post"], detail=True, rbac_action=Action.RESTART)
483497
def restart(self, request, pk):
484498
activation = self.get_object()
485-
486499
self._check_deleting(activation)
500+
force_restart = str_to_bool(
501+
request.query_params.get("force", "false"),
502+
)
487503

504+
if (
505+
settings.DEPLOYMENT_TYPE == "podman"
506+
and activation.status == ActivationStatus.WORKERS_OFFLINE
507+
and not force_restart
508+
):
509+
# block the restart and return an error
510+
raise api_exc.Conflict(
511+
"An activation with an activation_status of 'Workers offline' "
512+
"cannot be Restarted because this will leave an orphaned "
513+
"container running on one of the 'activation-worker-node's. "
514+
"If you want to force a restart, please add the "
515+
"/?force=true query param."
516+
)
488517
if not activation.is_enabled:
489518
raise api_exc.Forbidden(
490519
detail="Activation is disabled and cannot be run."

tests/integration/api/test_activation.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,38 @@ def test_restart_activation(
584584
assert response.status_code == status.HTTP_204_NO_CONTENT
585585

586586

587+
@pytest.mark.django_db
588+
@pytest.mark.parametrize(
589+
("force_restart", "expected_response"),
590+
[
591+
(
592+
"true",
593+
status.HTTP_204_NO_CONTENT,
594+
),
595+
(
596+
"false",
597+
status.HTTP_409_CONFLICT,
598+
),
599+
],
600+
)
601+
@patch("aap_eda.api.serializers.activation.settings.DEPLOYMENT_TYPE", "podman")
602+
def test_restart_activation_workers_offline(
603+
force_restart,
604+
expected_response,
605+
default_activation: models.Activation,
606+
admin_client: APIClient,
607+
preseed_credential_types,
608+
):
609+
default_activation.status = enums.ActivationStatus.WORKERS_OFFLINE
610+
default_activation.save(update_fields=["status"])
611+
612+
response = admin_client.post(
613+
f"{api_url_v1}/activations/{default_activation.id}/restart/"
614+
f"?force={force_restart}"
615+
)
616+
assert response.status_code == expected_response
617+
618+
587619
@pytest.mark.parametrize(
588620
("missing_field", "error_message"),
589621
[

0 commit comments

Comments
 (0)