2121
2222from pulpcore .plugin .util import get_domain
2323
24- from pulp_rust .app .models import RustDistribution , RustContent , _strip_sparse_prefix
24+ from pulpcore .plugin .tasking import dispatch
25+
26+ from pulp_rust .app .models import (
27+ RustDistribution ,
28+ RustContent ,
29+ RustPackageYank ,
30+ _strip_sparse_prefix ,
31+ )
32+ from pulp_rust .app .tasks import ayank_package , aunyank_package
2533from pulp_rust .app .serializers import (
2634 IndexRootSerializer ,
2735 RustContentSerializer ,
@@ -154,7 +162,12 @@ def retrieve(self, request, path, **kwargs):
154162 if content is not None :
155163 crate_versions = content .filter (name = crate_name ).order_by ("vers" )
156164 if crate_versions .exists ():
157- return self ._build_index_response (crate_versions )
165+ yanked_versions = set (
166+ RustPackageYank .objects .filter (
167+ pk__in = repo_ver .content , name = crate_name
168+ ).values_list ("vers" , flat = True )
169+ )
170+ return self ._build_index_response (crate_versions , yanked_versions )
158171
159172 # Fall back to proxying from the upstream remote
160173 if self .distribution .remote :
@@ -172,7 +185,7 @@ def retrieve(self, request, path, **kwargs):
172185 return HttpResponseNotFound (f"Crate '{ crate_name } ' not found" )
173186
174187 @staticmethod
175- def _build_index_response (crate_versions ):
188+ def _build_index_response (crate_versions , yanked_versions = frozenset () ):
176189 """Build a newline-delimited JSON response from local crate versions."""
177190 lines = []
178191 for crate_version in crate_versions :
@@ -200,7 +213,7 @@ def _build_index_response(crate_versions):
200213 "deps" : deps ,
201214 "cksum" : crate_version .cksum ,
202215 "features" : crate_version .features ,
203- "yanked" : crate_version .yanked ,
216+ "yanked" : crate_version .vers in yanked_versions ,
204217 "links" : crate_version .links ,
205218 "v" : crate_version .v ,
206219 }
@@ -293,7 +306,35 @@ def delete(self, request, name, version, rest, **kwargs):
293306 """
294307 if rest != "yank" :
295308 raise Http404 (f"Unknown action: { rest } " )
296- raise NotImplementedError ("Yank endpoint is not yet implemented" )
309+
310+ distro = self .get_distribution ()
311+ if not distro .repository :
312+ raise Http404 ("No repository associated with this distribution" )
313+
314+ repo_version = distro .repository .latest_version ()
315+ if not RustContent .objects .filter (
316+ pk__in = repo_version .content , name = name , vers = version
317+ ).exists ():
318+ return HttpResponse (
319+ json .dumps (
320+ {"errors" : [{"detail" : f"crate `{ name } ` does not have a version `{ version } `" }]}
321+ ),
322+ content_type = "application/json" ,
323+ status = 404 ,
324+ )
325+
326+ task = dispatch (
327+ ayank_package ,
328+ exclusive_resources = [distro .repository ],
329+ immediate = True ,
330+ kwargs = {
331+ "repository_pk" : str (distro .repository .pk ),
332+ "name" : name ,
333+ "vers" : version ,
334+ },
335+ )
336+ has_task_completed (task )
337+ return HttpResponse (json .dumps ({"ok" : True }), content_type = "application/json" )
297338
298339 def put (self , request , name , version , rest , ** kwargs ):
299340 """
@@ -304,7 +345,23 @@ def put(self, request, name, version, rest, **kwargs):
304345 """
305346 if rest != "unyank" :
306347 raise Http404 (f"Unknown action: { rest } " )
307- raise NotImplementedError ("Unyank endpoint is not yet implemented" )
348+
349+ distro = self .get_distribution ()
350+ if not distro .repository :
351+ raise Http404 ("No repository associated with this distribution" )
352+
353+ task = dispatch (
354+ aunyank_package ,
355+ exclusive_resources = [distro .repository ],
356+ immediate = True ,
357+ kwargs = {
358+ "repository_pk" : str (distro .repository .pk ),
359+ "name" : name ,
360+ "vers" : version ,
361+ },
362+ )
363+ has_task_completed (task )
364+ return HttpResponse (json .dumps ({"ok" : True }), content_type = "application/json" )
308365
309366
310367def has_task_completed (task ):
0 commit comments