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