From d2e6b1752a925db8e7298efb901ce23bef6de9a9 Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Tue, 27 Sep 2022 11:00:41 +0200 Subject: [PATCH] TT#15305 build: provide end point to delete latest build of release-trunk-{distribution} * /build/release-trunk-{version}/ DELETE when we trigger the deletion of the repository, we should remove the non-finised instance of it, so we can later create another one Change-Id: Ie7e96aebfbe719dee4a9c6e1da25be08e6a38ab7 --- build/test/test_rest.py | 35 +++++++++++++++++++++++++++++++++++ build/urls.py | 5 +++++ build/views.py | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/build/test/test_rest.py b/build/test/test_rest.py index df3b5cd..12bdb2e 100644 --- a/build/test/test_rest.py +++ b/build/test/test_rest.py @@ -14,9 +14,11 @@ # with this program. If not, see . from django.test import override_settings from django.urls import reverse +from django.urls.exceptions import NoReverseMatch from rest_framework import status from rest_framework.test import APISimpleTestCase +from .test_models import set_build_done from build import models from repoapi.test.base import APIAuthenticatedTestCase @@ -241,3 +243,36 @@ class TestCheckConfig(APISimpleTestCase): self.data["jenkins-jobs"]["build_deps"] = {"A": ["A1", "A"]} response = self.client.post(self.url, self.data, format="json") self.assertEqual(response.status_code, status.HTTP_406_NOT_ACCEPTABLE) + + +@override_settings(JBI_ALLOWED_HOSTS=["fake.local"]) +class TestTrunkCleanup(APIAuthenticatedTestCase): + fixtures = ["test_weekly"] + + def test_mrXX(self): + with self.assertRaises(NoReverseMatch): + reverse("build:trunk-cleanup", args=["mr10.1"]) + + def test_none(self): + url = reverse("build:trunk-cleanup", args=["release-trunk-wheezy"]) + response = self.client.delete(url, {}, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_weekly_not_done(self): + qs = models.BuildRelease.objects.filter(release="release-trunk-weekly") + self.assertEqual(qs.count(), 1) + self.assertFalse(qs.first().done) + url = reverse("build:trunk-cleanup", args=["release-trunk-weekly"]) + response = self.client.delete(url, {}, format="json") + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + self.assertEqual(qs.count(), 0) + + def test_weekly_done(self): + qs = models.BuildRelease.objects.filter(release="release-trunk-weekly") + self.assertEqual(qs.count(), 1) + set_build_done(qs) + self.assertTrue(qs.first().done) + url = reverse("build:trunk-cleanup", args=["release-trunk-weekly"]) + response = self.client.delete(url, {}, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(qs.count(), 1) diff --git a/build/urls.py b/build/urls.py index a9badd2..85baf18 100644 --- a/build/urls.py +++ b/build/urls.py @@ -19,6 +19,11 @@ from . import views app_name = "build" urlpatterns = [ re_path(r"^$", views.BuildReleaseList.as_view(), name="list"), + re_path( + r"^(?Prelease-trunk-[^/]+)/$", + views.BuildReleaseCleanup.as_view(), + name="trunk-cleanup", + ), re_path( r"^(?P[0-9]+)/?$", views.BuildReleaseDetail.as_view(), diff --git a/build/views.py b/build/views.py index f0dbd06..0b27f71 100644 --- a/build/views.py +++ b/build/views.py @@ -13,6 +13,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . import django_filters +from django.forms.models import model_to_dict from django.http import JsonResponse from django.shortcuts import get_object_or_404 from rest_framework import generics @@ -46,6 +47,25 @@ class BuildReleaseList(generics.ListCreateAPIView): filter_class = BuildReleaseFilter +class BuildReleaseCleanup(APIView): + permission_classes = [HasAPIKey | DjangoModelPermissions] + + def delete(self, request, version, format=None): + if not version.startswith("release-trunk-"): + return JsonResponse( + {"error": f"{version} can not be removed"}, status=403 + ) + qs = models.BuildRelease.objects.filter(release=version).order_by( + "-start_date" + ) + build = qs.first() + if not build or build.done: + return JsonResponse({}, status=200) + res = model_to_dict(build) + qs.delete() + return JsonResponse(res, status=202) + + class BuildReleaseDetail(generics.RetrieveDestroyAPIView): permission_classes = [HasAPIKey | DjangoModelPermissions] queryset = models.BuildRelease.objects.all().order_by("id")