66from rest_framework .views import APIView
77from rest_framework .viewsets import ViewSet
88from rest_framework .exceptions import Throttled
9+ from rest_framework .response import Response
910from rest_framework .renderers import BaseRenderer
1011from django .core .exceptions import ObjectDoesNotExist
1112from django .shortcuts import redirect , get_object_or_404
2122
2223from pulpcore .plugin .util import get_domain
2324
24- from pulp_rust .app .models import RustDistribution , RustContent , _strip_sparse_prefix
25+ from pulpcore .plugin .tasking import dispatch
26+
27+ from pulp_rust .app .models import (
28+ RustDistribution ,
29+ RustContent ,
30+ RustPackageYank ,
31+ _strip_sparse_prefix ,
32+ )
33+ from pulp_rust .app .tasks import ayank_package , aunyank_package
2534from pulp_rust .app .serializers import (
2635 IndexRootSerializer ,
2736 RustContentSerializer ,
@@ -154,7 +163,12 @@ def retrieve(self, request, path, **kwargs):
154163 if content is not None :
155164 crate_versions = content .filter (name = crate_name ).order_by ("vers" )
156165 if crate_versions .exists ():
157- return self ._build_index_response (crate_versions )
166+ yanked_versions = set (
167+ RustPackageYank .objects .filter (
168+ pk__in = repo_ver .content , name = crate_name
169+ ).values_list ("vers" , flat = True )
170+ )
171+ return self ._build_index_response (crate_versions , yanked_versions )
158172
159173 # Fall back to proxying from the upstream remote
160174 if self .distribution .remote :
@@ -172,7 +186,7 @@ def retrieve(self, request, path, **kwargs):
172186 return HttpResponseNotFound (f"Crate '{ crate_name } ' not found" )
173187
174188 @staticmethod
175- def _build_index_response (crate_versions ):
189+ def _build_index_response (crate_versions , yanked_versions = frozenset () ):
176190 """Build a newline-delimited JSON response from local crate versions."""
177191 lines = []
178192 for crate_version in crate_versions :
@@ -198,7 +212,7 @@ def _build_index_response(crate_versions):
198212 "deps" : deps ,
199213 "cksum" : crate_version .cksum ,
200214 "features" : crate_version .features ,
201- "yanked" : crate_version .yanked ,
215+ "yanked" : crate_version .vers in yanked_versions ,
202216 "links" : crate_version .links ,
203217 "v" : crate_version .v ,
204218 }
@@ -291,7 +305,23 @@ def delete(self, request, name, version, rest, **kwargs):
291305 """
292306 if rest != "yank" :
293307 raise Http404 (f"Unknown action: { rest } " )
294- raise NotImplementedError ("Yank endpoint is not yet implemented" )
308+
309+ distro = self .get_distribution ()
310+ if not distro .repository :
311+ raise Http404 ("No repository associated with this distribution" )
312+
313+ task = dispatch (
314+ ayank_package ,
315+ exclusive_resources = [distro .repository ],
316+ immediate = True ,
317+ kwargs = {
318+ "repository_pk" : str (distro .repository .pk ),
319+ "name" : name ,
320+ "vers" : version ,
321+ },
322+ )
323+ has_task_completed (task )
324+ return Response ({"ok" : True })
295325
296326 def put (self , request , name , version , rest , ** kwargs ):
297327 """
@@ -302,7 +332,23 @@ def put(self, request, name, version, rest, **kwargs):
302332 """
303333 if rest != "unyank" :
304334 raise Http404 (f"Unknown action: { rest } " )
305- raise NotImplementedError ("Unyank endpoint is not yet implemented" )
335+
336+ distro = self .get_distribution ()
337+ if not distro .repository :
338+ raise Http404 ("No repository associated with this distribution" )
339+
340+ task = dispatch (
341+ aunyank_package ,
342+ exclusive_resources = [distro .repository ],
343+ immediate = True ,
344+ kwargs = {
345+ "repository_pk" : str (distro .repository .pk ),
346+ "name" : name ,
347+ "vers" : version ,
348+ },
349+ )
350+ has_task_completed (task )
351+ return Response ({"ok" : True })
306352
307353
308354def has_task_completed (task ):
0 commit comments