Skip to content

Commit

Permalink
fix(registry): gc should mark recurse until blob
Browse files Browse the repository at this point in the history
  • Loading branch information
morlay committed May 27, 2024
1 parent 481ab32 commit 42abf6a
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 15 deletions.
22 changes: 11 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/octohelm/courier v0.0.0-20240516021431-5cf7af6666a1
github.com/octohelm/gengo v0.0.0-20240510051519-974fb897453b
github.com/octohelm/kubekit v0.0.0-20240508035712-15cb61729772
github.com/octohelm/kubepkgspec v0.0.0-20240521081130-9d5671cedd7a
github.com/octohelm/kubepkgspec v0.0.0-20240521102121-31a405691640
github.com/octohelm/storage v0.0.0-20240516030302-1ac2cc1ea347
github.com/octohelm/x v0.0.0-20240513022938-1bd86d96adef
github.com/opencontainers/go-digest v1.0.0
Expand All @@ -23,7 +23,7 @@ require (
golang.org/x/sync v0.7.0
k8s.io/api v0.30.1
k8s.io/apimachinery v0.30.1
sigs.k8s.io/controller-runtime v0.18.2
sigs.k8s.io/controller-runtime v0.18.3
)

require (
Expand All @@ -35,21 +35,21 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/docker/cli v24.0.0+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/cli v26.1.3+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v26.1.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-json-experiment/json v0.0.0-20240418180308-af2d5061e6c2 // indirect
github.com/go-json-experiment/json v0.0.0-20240524174822-2d9f40f7385b // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
Expand Down Expand Up @@ -91,7 +91,7 @@ require (
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 // indirect
go.opentelemetry.io/otel v1.27.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 // indirect
Expand All @@ -105,7 +105,7 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect
go.opentelemetry.io/otel/trace v1.27.0 // indirect
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
Expand All @@ -125,7 +125,7 @@ require (
k8s.io/apiextensions-apiserver v0.30.1 // indirect
k8s.io/client-go v0.30.1 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/kube-openapi v0.0.0-20240521025948-451ce29f5b89 // indirect
k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a // indirect
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
Expand Down
24 changes: 24 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -46,12 +48,20 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM=
github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v26.1.3+incompatible h1:bUpXT/N0kDE3VUHI2r5VMsYQgi38kYuoC0oL9yt3lqc=
github.com/docker/cli v26.1.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM=
github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo=
github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
Expand All @@ -74,6 +84,8 @@ github.com/go-courier/logr v0.3.0 h1:0VEQB1b53EmYQ+ZehrIgD8l2IO+WX7TY+CqzlykIFmo
github.com/go-courier/logr v0.3.0/go.mod h1:OI7f/JCFZ1ZMD5qG3bIJr5WMNnGzd24+II1D9D9w5x4=
github.com/go-json-experiment/json v0.0.0-20240418180308-af2d5061e6c2 h1:lhCu2IkNoFfDdcjHos2ZtLdAsyxLZbkpijNzhvvM6BY=
github.com/go-json-experiment/json v0.0.0-20240418180308-af2d5061e6c2/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA=
github.com/go-json-experiment/json v0.0.0-20240524174822-2d9f40f7385b h1:IM96IiRXFcd7l+mU8Sys9pcggoBLbH/dEgzOESrS8F8=
github.com/go-json-experiment/json v0.0.0-20240524174822-2d9f40f7385b/go.mod h1:uDEMZSTQMj7V6Lxdrx4ZwchmHEGdICbjuY+GQd7j9LM=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
Expand Down Expand Up @@ -125,6 +137,7 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ=
Expand Down Expand Up @@ -192,6 +205,8 @@ github.com/octohelm/kubekit v0.0.0-20240508035712-15cb61729772 h1:X+mCc0CTxFo0BM
github.com/octohelm/kubekit v0.0.0-20240508035712-15cb61729772/go.mod h1:wbxe94x0pWeoE77qvcBDjvn7tnndvZ0pv2VeSz0UscA=
github.com/octohelm/kubepkgspec v0.0.0-20240521081130-9d5671cedd7a h1:QxAFlskN3U5utaurL8BBRTUea/VeFcheM1DSEOkcNhU=
github.com/octohelm/kubepkgspec v0.0.0-20240521081130-9d5671cedd7a/go.mod h1:3uGib69YOZGZYd8olCV3l/cHt0HkNhdJAyBfWjZxWsc=
github.com/octohelm/kubepkgspec v0.0.0-20240521102121-31a405691640 h1:4zDMCG3UNPXeIVWc054Dpr2vy6IUVLuPXEptu3YqEHA=
github.com/octohelm/kubepkgspec v0.0.0-20240521102121-31a405691640/go.mod h1:3uGib69YOZGZYd8olCV3l/cHt0HkNhdJAyBfWjZxWsc=
github.com/octohelm/storage v0.0.0-20240516030302-1ac2cc1ea347 h1:uZmxLDxIXcQ/hOFVMuY0GM2zL62kMxzo6/gsikJVjxk=
github.com/octohelm/storage v0.0.0-20240516030302-1ac2cc1ea347/go.mod h1:1+SA6QeF6FGn54B9L0grBYV0X+l5xMuAyIPGRo5zDEY=
github.com/octohelm/x v0.0.0-20240513022938-1bd86d96adef h1:BoG/tg33jwNZ8BZA6nFc1wIl88P+2SgTzJmr4c+E8sY=
Expand All @@ -204,6 +219,7 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -269,6 +285,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 h1:IjgxbomVrV9za6bRi8fWCNXENs0co37SZedQilP2hm0=
Expand Down Expand Up @@ -309,6 +327,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d h1:N0hmiNbwsSNwHBAvR3QB5w25pUwH4tK0Y/RltD1j1h4=
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
Expand Down Expand Up @@ -397,10 +417,14 @@ k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240521025948-451ce29f5b89 h1:PVDt+zAAka/NPJmeBw9xmTwbMKVVAcB2wYGOHrbWKdA=
k8s.io/kube-openapi v0.0.0-20240521025948-451ce29f5b89/go.mod h1:PMabYkVfJJ5KPe2D98XW9A3kZYKnxJnBRsKLWIPyFv0=
k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a h1:zD1uj3Jf+mD4zmA7W+goE5TxDkI7OGJjBNBzq5fJtLA=
k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.18.2 h1:RqVW6Kpeaji67CY5nPEfRz6ZfFMk0lWQlNrLqlNpx+Q=
sigs.k8s.io/controller-runtime v0.18.2/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw=
sigs.k8s.io/controller-runtime v0.18.3 h1:B5Wmmo8WMWK7izei+2LlXLVDGzMwAHBNLX68lwtlSR4=
sigs.k8s.io/controller-runtime v0.18.3/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
Expand Down
2 changes: 1 addition & 1 deletion pkg/registry/cleaner.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (c *Cleaner) Run(ctx context.Context) error {
}

func (c *Cleaner) remoteUntaggedBlobs(ctx context.Context) error {
return storage.MarkAndSweep(ctx, c.driver, c.registry, storage.GCOpts{
return MarkAndSweep(ctx, c.driver, c.registry, storage.GCOpts{
DryRun: false,
RemoveUntagged: true,
})
Expand Down
192 changes: 192 additions & 0 deletions pkg/registry/gc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package registry

import (
"context"
"fmt"
"github.com/distribution/distribution/v3/manifest/schema2"
specv1 "github.com/opencontainers/image-spec/specs-go/v1"
"log/slog"

"github.com/distribution/distribution/v3"
"github.com/distribution/distribution/v3/registry/storage"
"github.com/distribution/distribution/v3/registry/storage/driver"
"github.com/distribution/reference"
"github.com/go-courier/logr"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
)

func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, registry distribution.Namespace, opts storage.GCOpts) error {
s := &sweeper{
opts: opts,
registry: registry,
vacuum: storage.NewVacuum(ctx, storageDriver),
markSet: map[digest.Digest]struct{}{},
}

if err := s.Mark(ctx); err != nil {
return err
}

return s.Sweep(ctx)
}

type sweeper struct {
opts storage.GCOpts
registry distribution.Namespace
vacuum storage.Vacuum
markSet map[digest.Digest]struct{}
manifestArr []storage.ManifestDel
}

func (s *sweeper) Mark(ctx context.Context) error {
ctx, l := logr.FromContext(ctx).Start(ctx, "Mark")
defer l.End()

repositoryEnumerator, ok := s.registry.(distribution.RepositoryEnumerator)
if !ok {
return errors.New("unable to convert Namespace to RepositoryEnumerator")
}

return repositoryEnumerator.Enumerate(ctx, func(repoName string) error {
named, err := reference.WithName(repoName)
if err != nil {
return errors.Wrapf(err, "failed to parse repo name %s", repoName)
}
repository, err := s.registry.Repository(ctx, named)
if err != nil {
return errors.Wrapf(err, "failed to construct repository")
}
manifestService, err := repository.Manifests(ctx)
if err != nil {
return errors.Wrapf(err, "failed to construct manifest service")
}

manifestEnumerator, ok := manifestService.(distribution.ManifestEnumerator)
if !ok {
return errors.Wrap(err, "unable to convert ManifestService into ManifestEnumerator")
}

err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error {
if s.opts.RemoveUntagged {
// fetch all tags where this manifest is the latest one
tags, err := repository.Tags(ctx).Lookup(ctx, distribution.Descriptor{Digest: dgst})
if err != nil {
return errors.Wrapf(err, "failed to retrieve tags for digest %v", dgst)
}
if len(tags) == 0 {
l.Info("manifest eligible for deletion: %s", dgst)
// fetch all tags from repository
// all of these tags could contain manifest in history
// which means that we need check (and delete) those references when deleting manifest
allTags, err := repository.Tags(ctx).All(ctx)
if err != nil {
return errors.Wrapf(err, "failed to retrieve tags")
}
s.manifestArr = append(s.manifestArr, storage.ManifestDel{Name: repoName, Digest: dgst, Tags: allTags})
return nil
}
}

return s.MarkManifest(ctx, named, dgst)
})

// In certain situations such as unfinished uploads, deleting all
// tags in S3 or removing the _manifests folder manually, this
// error may be of type PathNotFound.
//
// In these cases we can continue marking other manifests safely.
if errors.As(err, &driver.PathNotFoundError{}) {
return nil
}

return err
})
}

func (s *sweeper) MarkManifest(ctx context.Context, named reference.Named, dgst digest.Digest) error {
ctx, l := logr.FromContext(ctx).Start(ctx, "MarkManifest", slog.String("repo", named.String()))
defer l.End()

repository, err := s.registry.Repository(ctx, named)
if err != nil {
return errors.Wrapf(err, "failed to construct repository")
}

manifestService, err := repository.Manifests(ctx)
if err != nil {
return errors.Wrapf(err, "failed to construct manifest service")
}

// Mark the manifest's blob
l.Info(fmt.Sprintf("%s: marking manifest %s ", named, dgst))
s.markSet[dgst] = struct{}{}

manifest, err := manifestService.Get(ctx, dgst)
if err != nil {
return errors.Wrapf(err, "failed to retrieve manifest for digest %v", dgst)
}

descriptors := manifest.References()
for _, descriptor := range descriptors {
switch descriptor.MediaType {
case specv1.MediaTypeImageIndex, schema2.MediaTypeManifest:
if err := s.MarkManifest(ctx, named, descriptor.Digest); err != nil {
return err
}
continue
}
s.markSet[descriptor.Digest] = struct{}{}
l.Info("%s: marking blob %s %s", named, descriptor.Digest, descriptor.MediaType)
}

return nil
}

func (s *sweeper) Sweep(ctx context.Context) error {
if len(s.markSet) == 0 || len(s.manifestArr) == 0 {
return nil
}

ctx, l := logr.FromContext(ctx).Start(ctx, "Sweep")
defer l.End()

opts := s.opts
vacuum := s.vacuum

if !opts.DryRun {
for _, obj := range s.manifestArr {
err := vacuum.RemoveManifest(obj.Name, obj.Digest, obj.Tags)
if err != nil {
return errors.Wrapf(err, "failed to delete manifest %s", obj.Digest)
}
}
}

blobService := s.registry.Blobs()
deleteSet := make(map[digest.Digest]struct{})
err := blobService.Enumerate(ctx, func(dgst digest.Digest) error {
// check if digest is in markSet. If not, delete it!
if _, ok := s.markSet[dgst]; !ok {
deleteSet[dgst] = struct{}{}
}
return nil
})
if err != nil {
return errors.Wrap(err, "error enumerating blobs")
}

l.Info("%d blobs marked, %d blobs and %d manifests eligible for deletion", len(s.markSet), len(deleteSet), len(s.manifestArr))
for dgst := range deleteSet {
l.Info("blob eligible for deletion: %s", dgst)
if opts.DryRun {
continue
}
err = vacuum.RemoveBlob(string(dgst))
if err != nil {
return errors.Wrapf(err, "failed to delete blob %s", dgst)
}
}

return err
}
9 changes: 6 additions & 3 deletions pkg/registry/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import (
"strings"

"github.com/go-courier/logr"
"github.com/octohelm/crkit/pkg/containerdhost"
containerdhostcontroller "github.com/octohelm/crkit/pkg/containerdhost/controller"
"github.com/octohelm/kubekit/pkg/kubeclient"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/octohelm/crkit/pkg/containerdhost"
containerdhostcontroller "github.com/octohelm/crkit/pkg/containerdhost/controller"
)

type Publisher struct {
Expand Down Expand Up @@ -45,6 +44,10 @@ func (s *Publisher) Run(ctx context.Context) error {
return nil
}

if err := corev1.AddToScheme(c.Scheme()); err != nil {
return err
}

data, err := containerdhost.MirrorAsHostToml(s.mirror)
if err != nil {
return err
Expand Down

0 comments on commit 42abf6a

Please sign in to comment.