diff --git a/Makefile b/Makefile index 832d104..4acebfb 100644 --- a/Makefile +++ b/Makefile @@ -10,29 +10,11 @@ export KUBECONFIG = ${HOME}/.kube_config/config--algo-staging.yaml export PIPER_BUILDER_HOST = serve.registry: - $(CRKIT) serve registry \ - --kubeconfig=${KUBECONFIG} \ - --storage-root=.tmp/container-registry \ - --addr=:5050 - -serve.registry.proxied: $(CRKIT) serve registry -c \ - --kubeconfig=${KUBECONFIG} \ - --remote-registry-endpoint=https://${CONTAINER_REGISTRY} \ - --remote-registry-username=${CONTAINER_REGISTRY_USERNAME} \ - --remote-registry-password=${CONTAINER_REGISTRY_PASSWORD} \ - --storage-root=.tmp/container-registry \ --addr=:5050 -serve.operator: - $(CRKIT) serve operator -c \ - --containerd-host-config-path=target/containerd/certs.d/ \ - --kubeconfig=${KUBECONFIG} \ - --watch-namespace=kube-system - dump.k8s: $(CRKIT) serve registry --dump-k8s - $(CRKIT) serve operator --dump-k8s gen: go run ./internal/cmd/tool gen ./internal/cmd/crkit diff --git a/go.mod b/go.mod index a992cb1..b9e4906 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/octohelm/crkit -go 1.23.0 +go 1.23.1 require ( github.com/containerd/containerd v1.7.21 @@ -10,14 +10,16 @@ require ( github.com/go-courier/logr v0.3.0 github.com/gobwas/glob v0.2.3 github.com/google/go-containerregistry v0.20.2 + github.com/google/uuid v1.6.0 github.com/hashicorp/golang-lru/v2 v2.0.7 - github.com/innoai-tech/infra v0.0.0-20240828065440-823baddc18c0 - github.com/octohelm/courier v0.0.0-20240828072746-af3b5bc1f867 - github.com/octohelm/gengo v0.0.0-20240622092313-cc61f99ecd84 + github.com/innoai-tech/infra v0.0.0-20240920044133-bd9089f58588 + github.com/octohelm/courier v0.0.0-20240925100810-e1b35fc61507 + github.com/octohelm/gengo v0.0.0-20240919101245-4bc8a41dd2f4 github.com/octohelm/kubekit v0.0.0-20240816091736-f2433647d633 github.com/octohelm/kubepkgspec v0.0.0-20240820101422-8f85dc2940ad - github.com/octohelm/storage v0.0.0-20240828070144-acf8c5de2b4f - github.com/octohelm/x v0.0.0-20240819031507-95d7ab05c4cf + github.com/octohelm/storage v0.0.0-20240923082032-9c037f4e0c05 + github.com/octohelm/unifs v0.0.0-20240906103445-29045af3bc39 + github.com/octohelm/x v0.0.0-20240904081416-42a1ee2d28a9 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/pelletier/go-toml/v2 v2.2.3 @@ -46,89 +48,102 @@ require ( 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/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // 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/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-json-experiment/json v0.0.0-20240815175050-ebd3a8989ca1 // 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 github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/innoai-tech/openapi-playground v0.0.0-20240909062817-20f99d67805e // indirect + github.com/jlaffaye/ftp v0.2.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/juju/ansiterm v1.0.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/lunixbochs/vtclean v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/minio/md5-simd v1.1.2 // indirect + github.com/minio/minio-go/v7 v7.0.75 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/gomega v1.34.1 // indirect - github.com/prometheus/client_golang v1.20.2 // indirect + github.com/onsi/gomega v1.34.2 // indirect + github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.57.0 // indirect + github.com/prometheus/common v0.59.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.5.3 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.5.3 // indirect github.com/redis/go-redis/v9 v9.6.1 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/rs/xid v1.5.0 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/vbatts/tar-split v0.11.5 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/contrib/bridges/prometheus v0.54.0 // indirect go.opentelemetry.io/contrib/exporters/autoexport v0.54.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.29.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.30.0 // indirect + go.opentelemetry.io/otel v1.30.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.51.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.52.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.5.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0 // indirect - go.opentelemetry.io/otel/log v0.5.0 // indirect - go.opentelemetry.io/otel/metric v1.29.0 // indirect - go.opentelemetry.io/otel/sdk v1.29.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.5.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect + go.opentelemetry.io/otel/log v0.6.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/sdk v1.30.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.6.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect + go.opentelemetry.io/otel/trace v1.30.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/tools v0.25.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/grpc v1.66.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/grpc v1.66.1 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 5d00731..8ce0ee2 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/aws/aws-sdk-go v1.55.3 h1:0B5hOX+mIx7I5XPOrjrHlKSDQV/+ypFZpIHOx5LOk3E= +github.com/aws/aws-sdk-go v1.55.3/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -51,6 +53,8 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ 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= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY= @@ -61,6 +65,10 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0 github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fclairamb/ftpserverlib v0.24.1 h1:D+dDP+KibZKI182zQlITMJmaayCyIYpLpprzg8ZhtqA= +github.com/fclairamb/ftpserverlib v0.24.1/go.mod h1:aAwyOAC6IIe+IZeeGD1QjuE3GGDzqW/c5Xtn+Dp0JUM= +github.com/fclairamb/go-log v0.5.0 h1:Gz9wSamEaA6lta4IU2cjJc2xSq5sV5VYSB5w/SUHhVc= +github.com/fclairamb/go-log v0.5.0/go.mod h1:XoRO1dYezpsGmLLkZE9I+sHqpqY65p8JA+Vqblb7k40= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -69,6 +77,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= 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-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-json-experiment/json v0.0.0-20240815175050-ebd3a8989ca1 h1:xcuWappghOVI8iNWoF2OKahVejd1LSVi/v4JED44Amo= github.com/go-json-experiment/json v0.0.0-20240815175050-ebd3a8989ca1/go.mod h1:BWmvoE1Xia34f3l/ibJweyhrT+aROb/FQ6d+37F0e2s= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -94,6 +104,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -115,8 +127,8 @@ github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEva github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= @@ -125,6 +137,11 @@ 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/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ= github.com/hashicorp/golang-lru/arc/v2 v2.0.7/go.mod h1:Pe7gBlGdc8clY5LJ0LpJXMt5AmgmWNH1g+oFFVUHOEc= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -133,8 +150,14 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/innoai-tech/infra v0.0.0-20240828065440-823baddc18c0 h1:VZuE/ZdtHftpOQ+fqVCelZG4sFg87MXv023E+3Vy72w= -github.com/innoai-tech/infra v0.0.0-20240828065440-823baddc18c0/go.mod h1:NFgw4p/BhnsVYD2EyOqUSqNq9NaxJtFY+uT7XVe2zo0= +github.com/innoai-tech/infra v0.0.0-20240920044133-bd9089f58588 h1:z533YRLCmcF+9cM3N7WG9paJKALUaAb5EZ4QQkZ2nAU= +github.com/innoai-tech/infra v0.0.0-20240920044133-bd9089f58588/go.mod h1:HkPC7CHAaE5yRnCeT081SvDCAI1Pz4EaTG5WbyNdrn8= +github.com/innoai-tech/openapi-playground v0.0.0-20240909062817-20f99d67805e h1:2x5pVpGEOBX6mo0IyT+clX++hUVgXgS5RVPzncrIjf4= +github.com/innoai-tech/openapi-playground v0.0.0-20240909062817-20f99d67805e/go.mod h1:XF6gAVE9R8xSKHWbG0TtH/7RbWrTh16PH23eGZk69po= +github.com/jlaffaye/ftp v0.2.0 h1:lXNvW7cBu7R/68bknOX3MrRIIqZ61zELs1P2RAiA3lg= +github.com/jlaffaye/ftp v0.2.0/go.mod h1:is2Ds5qkhceAPy2xD6RLI6hmp/qysSoymZ+Z2uTnspI= +github.com/johannesboyne/gofakes3 v0.0.0-20230506070712-04da935ef877 h1:O7syWuYGzre3s73s+NkgB8e0ZvsIVhT/zxNU7V1gHK8= +github.com/johannesboyne/gofakes3 v0.0.0-20230506070712-04da935ef877/go.mod h1:AxgWC4DDX54O2WDoQO1Ceabtn6IbktjU/7bigor+66g= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -150,10 +173,16 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= @@ -164,12 +193,19 @@ github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+L github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.10/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.75 h1:0uLrB6u6teY2Jt+cJUVi9cTvDRuBKWSRzSAcznRkwlE= +github.com/minio/minio-go/v7 v7.0.75/go.mod h1:qydcVzV8Hqtj1VtEocfxbmVFa2siu6HGa+LDEPogjD8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -184,22 +220,24 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/octohelm/courier v0.0.0-20240828072746-af3b5bc1f867 h1:FhpgRED0HaNGVghf88HlpmAqqY7Fc+91cJXQqJlcIBY= -github.com/octohelm/courier v0.0.0-20240828072746-af3b5bc1f867/go.mod h1:7/HqHA78AhEV1nVVsjZH+oeafksPALncRFUBoncTY5o= -github.com/octohelm/gengo v0.0.0-20240622092313-cc61f99ecd84 h1:VH5E6nJ3UR60bOmXojgzu6mQPmuWzG0+dm2AIGnRxVo= -github.com/octohelm/gengo v0.0.0-20240622092313-cc61f99ecd84/go.mod h1:bAzrvsK8CvH1QYU9zBVm9qIiiQ6rsxqDK5KDfCY1KDU= +github.com/octohelm/courier v0.0.0-20240925100810-e1b35fc61507 h1:gYIrc2O4CdRVHHn7j7zmsvv6QPX/qWPp1EvU3iUCYdM= +github.com/octohelm/courier v0.0.0-20240925100810-e1b35fc61507/go.mod h1:WTM484kbV7BFRqWVpG60zAY+e7yJSs76rvmGvGuMhp0= +github.com/octohelm/gengo v0.0.0-20240919101245-4bc8a41dd2f4 h1:id6V5MUVYljRaukW8qm0jT+aUgq21YmOzaiqE+dzTq4= +github.com/octohelm/gengo v0.0.0-20240919101245-4bc8a41dd2f4/go.mod h1:IIloUgLGOyAJJXLgt3oJ5G7NX8Wxv1CBYH4sPcYrMpE= github.com/octohelm/kubekit v0.0.0-20240816091736-f2433647d633 h1:pLd+NUgPr6suaX8I/rhoRf8iFFoGeRFjiqYAF3mXgYE= github.com/octohelm/kubekit v0.0.0-20240816091736-f2433647d633/go.mod h1:JgyIpmmWjpJztnbNjdAX6pDEgW60gS9d2IJknmseLQY= github.com/octohelm/kubepkgspec v0.0.0-20240820101422-8f85dc2940ad h1:ytKCzk/nkBDGl9yq/LcOMqpWptNhNkd/G4TKMmAIQEE= github.com/octohelm/kubepkgspec v0.0.0-20240820101422-8f85dc2940ad/go.mod h1:51UkYeh08UCNnSsDIVTna3A5V6ITF2J8+tfRA2//3iY= -github.com/octohelm/storage v0.0.0-20240828070144-acf8c5de2b4f h1:Oh6nvFFSy4GBQBfeO14e6KOfd0T8Xid2s4+z2+SuXPE= -github.com/octohelm/storage v0.0.0-20240828070144-acf8c5de2b4f/go.mod h1:h22RCkA8yPAgxe2QtRDg96NOLsb6xGPdEHAsD0NOUUE= -github.com/octohelm/x v0.0.0-20240819031507-95d7ab05c4cf h1:47FDhmnnobDoi/Ljerm3Adt4P8+6Tu8AjwLsvtqLMsg= -github.com/octohelm/x v0.0.0-20240819031507-95d7ab05c4cf/go.mod h1:WzVz9wvBY4Htys5cF+lV5hxW1eybmtjMUDzJUJNp7pU= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/octohelm/storage v0.0.0-20240923082032-9c037f4e0c05 h1:kCBdlT2mRwLN3YF2W2iQMCNJuf7c0NJQ7ry8ama9+Rg= +github.com/octohelm/storage v0.0.0-20240923082032-9c037f4e0c05/go.mod h1:IYiOv6MMWkyPqXngyrfMix0ZTbXVAnl5e1mjU3kYw08= +github.com/octohelm/unifs v0.0.0-20240906103445-29045af3bc39 h1:OmHWxPlZ5Vtbvd5SFWx/HVE652rgNBFGZsJOXYayUeQ= +github.com/octohelm/unifs v0.0.0-20240906103445-29045af3bc39/go.mod h1:QflhQAyLs37BlcCpg2Bw8JfGEnYjVq//skiZR8AN/jg= +github.com/octohelm/x v0.0.0-20240904081416-42a1ee2d28a9 h1:PlgBSARdazQ9dBicDlI8sWILYXyh54yDa9XI4is4MTM= +github.com/octohelm/x v0.0.0-20240904081416-42a1ee2d28a9/go.mod h1:Tql/GYN4vR5X+2LcjgX1r/Qbjr8epCjkvRZgKg4MH3c= +github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo= +github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 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= @@ -215,16 +253,16 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= -github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= -github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= +github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= +github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= @@ -242,10 +280,18 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21 h1:igWZJluD8KtEtAgRyF4x6lqcxDry1ULztksMJh2mnQE= github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21/go.mod h1:RMRJLmBOqWacUkmJHRMiPKh1S1m3PA7Zh4W80/kWPpg= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8= +github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= +github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500 h1:WnNuhiq+FOY3jNj6JXFT+eLN3CQ/oPIsDPRanvwsmbI= +github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500/go.mod h1:+njLrG5wSeoG4Ds61rFgEzKvenR2UHbjMoDHsczxly0= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -267,42 +313,42 @@ go.opentelemetry.io/contrib/bridges/prometheus v0.54.0 h1:WWL67oxtknNVMb70lJXxXr go.opentelemetry.io/contrib/bridges/prometheus v0.54.0/go.mod h1:LqNcnXmyULp8ertk4hUTVtSUvKXj4h1Mx7gUCSSr/q0= go.opentelemetry.io/contrib/exporters/autoexport v0.54.0 h1:dTmcmVm4J54IRPGm5oVjLci1uYat4UDea84E2tyBaAk= go.opentelemetry.io/contrib/exporters/autoexport v0.54.0/go.mod h1:zPp5Fwpq2Hc7xMtVttg6GhZMcfTESjVbY9ONw2o/Dc4= -go.opentelemetry.io/contrib/propagators/b3 v1.29.0 h1:hNjyoRsAACnhoOLWupItUjABzeYmX3GTTZLzwJluJlk= -go.opentelemetry.io/contrib/propagators/b3 v1.29.0/go.mod h1:E76MTitU1Niwo5NSN+mVxkyLu4h4h7Dp/yh38F2WuIU= -go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/contrib/propagators/b3 v1.30.0 h1:vumy4r1KMyaoQRltX7cJ37p3nluzALX9nugCjNNefuY= +go.opentelemetry.io/contrib/propagators/b3 v1.30.0/go.mod h1:fRbvRsaeVZ82LIl3u0rIvusIel2UUf+JcaaIpy5taho= +go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= +go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 h1:4d++HQ+Ihdl+53zSjtsCUFDmNMju2FC9qFkUlTxPLqo= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0/go.mod h1:mQX5dTO3Mh5ZF7bPKDkt5c/7C41u/SiDr9XgTpzXXn8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0/go.mod h1:t4BrYLHU450Zo9fnydWlIuswB1bm7rM8havDpWOJeDo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 h1:WypxHH02KX2poqqbaadmkMYalGyy/vil4HE4PM4nRJc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0/go.mod h1:U79SV99vtvGSEBeeHnpgGJfTsnsdkWLpPN/CcHAzBSI= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 h1:xvhQxJ/C9+RTnAj5DpTg7LSM1vbbMTiXt7e9hsfqHNw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0/go.mod h1:Fcvs2Bz1jkDM+Wf5/ozBGmi3tQ/c9zPKLnsipnfhGAo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc= -go.opentelemetry.io/otel/exporters/prometheus v0.51.0 h1:G7uexXb/K3T+T9fNLCCKncweEtNEBMTO+46hKX5EdKw= -go.opentelemetry.io/otel/exporters/prometheus v0.51.0/go.mod h1:v0mFe5Kk7woIh938mrZBJBmENYquyA0IICrlYm4Y0t4= +go.opentelemetry.io/otel/exporters/prometheus v0.52.0 h1:kmU3H0b9ufFSi8IQCcxack+sWUblKkFbqWYs6YiACGQ= +go.opentelemetry.io/otel/exporters/prometheus v0.52.0/go.mod h1:+wsAp2+JhuGXX7YRkjlkx6hyWY3ogFPfNA4x3nyiAh0= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.5.0 h1:ThVXnEsdwNcxdBO+r96ci1xbF+PgNjwlk457VNuJODo= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.5.0/go.mod h1:rHWcSmC4q2h3gje/yOq6sAOaq8+UHxN/Ru3BbmDXOfY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0 h1:X3ZjNp36/WlkSYx0ul2jw4PtbNEDDeLskw3VPsrpYM0= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0/go.mod h1:2uL/xnOXh0CHOBFCWXz5u1A4GXLiW+0IQIzVbeOEQ0U= -go.opentelemetry.io/otel/log v0.5.0 h1:x1Pr6Y3gnXgl1iFBwtGy1W/mnzENoK0w0ZoaeOI3i30= -go.opentelemetry.io/otel/log v0.5.0/go.mod h1:NU/ozXeGuOR5/mjCRXYbTC00NFJ3NYuraV/7O78F0rE= -go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= -go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= -go.opentelemetry.io/otel/sdk/log v0.5.0 h1:A+9lSjlZGxkQOr7QSBJcuyyYBw79CufQ69saiJLey7o= -go.opentelemetry.io/otel/sdk/log v0.5.0/go.mod h1:zjxIW7sw1IHolZL2KlSAtrUi8JHttoeiQy43Yl3WuVQ= -go.opentelemetry.io/otel/sdk/metric v1.29.0 h1:K2CfmJohnRgvZ9UAj2/FhIf/okdWcNdBwe1m8xFXiSY= -go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ= -go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= +go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8= +go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= +go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= +go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= +go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= +go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= +go.opentelemetry.io/otel/sdk/log v0.6.0 h1:4J8BwXY4EeDE9Mowg+CyhWVBhTSLXVXodiXxS/+PGqI= +go.opentelemetry.io/otel/sdk/log v0.6.0/go.mod h1:L1DN8RMAduKkrwRAFDEX3E3TLOq46+XMGSbUfHU/+vE= +go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= +go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= +go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= +go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -315,20 +361,22 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= 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.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -343,38 +391,42 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= -google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= -google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= +google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= diff --git a/internal/cmd/crkit/serve_operator.go b/internal/cmd/crkit/serve_operator.go deleted file mode 100644 index b946f39..0000000 --- a/internal/cmd/crkit/serve_operator.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "github.com/innoai-tech/infra/pkg/cli" - "github.com/innoai-tech/infra/pkg/otel" - - containerdhostcontroller "github.com/octohelm/crkit/pkg/containerdhost/controller" - "github.com/octohelm/kubekit/pkg/kubeclient" - "github.com/octohelm/kubekit/pkg/operator" -) - -func init() { - cli.AddTo(Serve, &Operator{}) -} - -// Container Registry -type Operator struct { - cli.C `component:"containerd-operator,kind=DaemonSet"` - - otel.Otel - - kubeclient.KubeClient - - operator.Operator - - // register reconcilers - ContainerdHost containerdhostcontroller.Reconciler -} diff --git a/internal/cmd/crkit/serve_registry.go b/internal/cmd/crkit/serve_registry.go index 5dcfc40..dd1b914 100644 --- a/internal/cmd/crkit/serve_registry.go +++ b/internal/cmd/crkit/serve_registry.go @@ -1,14 +1,10 @@ package main import ( - "context" - "github.com/innoai-tech/infra/pkg/cli" "github.com/innoai-tech/infra/pkg/otel" - "github.com/octohelm/crkit/pkg/registry" - "github.com/octohelm/kubekit/pkg/kubeclient" - - "sigs.k8s.io/controller-runtime/pkg/client" + contentfs "github.com/octohelm/crkit/pkg/content/fs" + "github.com/octohelm/crkit/pkg/registryhttp" ) func init() { @@ -20,28 +16,7 @@ type Registry struct { cli.C `component:"container-registry"` otel.Otel - KubeClient - - registry.Server -} - -type KubeClient struct { - // Paths to a kubeconfig. Only required if out-of-cluster. - Kubeconfig string `flag:",omitempty"` - - c client.Client -} - -func (c *KubeClient) Init(ctx context.Context) error { - if c.c == nil { - c.c, _ = kubeclient.NewClient(c.Kubeconfig) - } - return nil -} + Content contentfs.NamespaceProvider -func (c *KubeClient) InjectContext(ctx context.Context) context.Context { - if c.c != nil { - return kubeclient.Context.Inject(ctx, c.c) - } - return ctx + registryhttp.Server } diff --git a/internal/cmd/crkit/zz_generated.runtimedoc.go b/internal/cmd/crkit/zz_generated.runtimedoc.go index cb8e519..b9b5620 100644 --- a/internal/cmd/crkit/zz_generated.runtimedoc.go +++ b/internal/cmd/crkit/zz_generated.runtimedoc.go @@ -14,59 +14,12 @@ func runtimeDoc(v any, names ...string) ([]string, bool) { return nil, false } -func (v KubeClient) RuntimeDoc(names ...string) ([]string, bool) { - if len(names) > 0 { - switch names[0] { - case "Kubeconfig": - return []string{ - "Paths to a kubeconfig. Only required if out-of-cluster.", - }, true - - } - - return nil, false - } - return []string{}, true -} - -func (v Operator) RuntimeDoc(names ...string) ([]string, bool) { - if len(names) > 0 { - switch names[0] { - case "Otel": - return []string{}, true - case "KubeClient": - return []string{}, true - case "Operator": - return []string{}, true - case "ContainerdHost": - return []string{ - "register reconcilers", - }, true - - } - if doc, ok := runtimeDoc(v.Otel, names...); ok { - return doc, ok - } - if doc, ok := runtimeDoc(v.KubeClient, names...); ok { - return doc, ok - } - if doc, ok := runtimeDoc(v.Operator, names...); ok { - return doc, ok - } - - return nil, false - } - return []string{ - "Container Registry", - }, true -} - func (v Registry) RuntimeDoc(names ...string) ([]string, bool) { if len(names) > 0 { switch names[0] { case "Otel": return []string{}, true - case "KubeClient": + case "Content": return []string{}, true case "Server": return []string{}, true @@ -75,9 +28,6 @@ func (v Registry) RuntimeDoc(names ...string) ([]string, bool) { if doc, ok := runtimeDoc(v.Otel, names...); ok { return doc, ok } - if doc, ok := runtimeDoc(v.KubeClient, names...); ok { - return doc, ok - } if doc, ok := runtimeDoc(v.Server, names...); ok { return doc, ok } diff --git a/internal/testingutil/ctx.go b/internal/testingutil/ctx.go new file mode 100644 index 0000000..f4c57e9 --- /dev/null +++ b/internal/testingutil/ctx.go @@ -0,0 +1,63 @@ +package testingutil + +import ( + "context" + "os" + "testing" + + testingx "github.com/octohelm/x/testing" + + "github.com/innoai-tech/infra/pkg/configuration" + "golang.org/x/sync/errgroup" +) + +func NewContext(t testing.TB, v any) context.Context { + tmp := t.TempDir() + _ = os.Chdir(tmp) + + t.Cleanup(func() { + _ = os.RemoveAll(tmp) + }) + + ctx := context.Background() + if v != nil { + singletons := configuration.SingletonsFromStruct(v) + c, err := singletons.Init(ctx) + testingx.Expect(t, err, testingx.Be[error](nil)) + ctx = c + + for i := range singletons { + if r, ok := singletons[i].(configuration.Runner); ok { + err := r.Run(ctx) + testingx.Expect(t, err, testingx.Be[error](nil)) + } + } + + go func() { + g, c := errgroup.WithContext(ctx) + + for i := range singletons { + if server, ok := singletons[i].(configuration.Server); ok { + g.Go(func() error { + err := server.Serve(c) + return err + }) + } + } + + _ = g.Wait() + }() + + t.Cleanup(func() { + c := configuration.ContextInjectorFromContext(ctx).InjectContext(ctx) + + for _, s := range singletons { + if canShutdown, ok := s.(configuration.CanShutdown); ok { + _ = configuration.Shutdown(c, canShutdown) + } + } + }) + } + + return configuration.ContextInjectorFromContext(ctx).InjectContext(ctx) +} diff --git a/pkg/content/blob_store.go b/pkg/content/blob_store.go new file mode 100644 index 0000000..b12ed5c --- /dev/null +++ b/pkg/content/blob_store.go @@ -0,0 +1,41 @@ +package content + +import ( + "context" + "io" + "iter" + + "github.com/opencontainers/go-digest" + specv1 "github.com/opencontainers/image-spec/specs-go/v1" +) + +type Descriptor = specv1.Descriptor + +type BlobStore interface { + Ingester + Provider +} + +type Provider interface { + Info(ctx context.Context, digest digest.Digest) (Descriptor, error) + Open(ctx context.Context, digest digest.Digest) (io.ReadCloser, error) +} + +type Ingester interface { + Writer(ctx context.Context) (Writer, error) +} + +type Remover interface { + Remove(ctx context.Context, digest digest.Digest) error +} + +type BlobLister interface { + Blob(ctx context.Context) iter.Seq[digest.Digest] +} + +type Writer interface { + io.WriteCloser + Digest(ctx context.Context) digest.Digest + Size(ctx context.Context) int64 + Commit(ctx context.Context, expected Descriptor) (Descriptor, error) +} diff --git a/pkg/content/errors.go b/pkg/content/errors.go new file mode 100644 index 0000000..cce6dd4 --- /dev/null +++ b/pkg/content/errors.go @@ -0,0 +1,95 @@ +package content + +import ( + "errors" + "fmt" + "github.com/octohelm/courier/pkg/statuserror" + "github.com/opencontainers/go-digest" +) + +var ErrAccessDenied = errors.New("access denied") +var ErrManifestNotModified = errors.New("manifest not modified") +var ErrUnsupported = errors.New("operation unsupported") +var ErrSchemaV1Unsupported = errors.New("manifest schema v1 unsupported") + +type ErrTagUnknown struct { + statuserror.NotFound + + Tag string +} + +func (err ErrTagUnknown) Error() string { + return fmt.Sprintf("unknown tag=%s", err.Tag) +} + +type ErrRepositoryUnknown struct { + statuserror.NotFound + + Name string +} + +func (err ErrRepositoryUnknown) Error() string { + return fmt.Sprintf("unknown repository name=%s", err.Name) +} + +type ErrRepositoryNameInvalid struct { + statuserror.BadRequest + + Name string + Reason error +} + +func (err ErrRepositoryNameInvalid) Error() string { + return fmt.Sprintf("repository name %q invalid: %v", err.Name, err.Reason) +} + +type ErrManifestUnknown struct { + statuserror.NotFound + + Name string + Tag string +} + +func (err ErrManifestUnknown) Error() string { + return fmt.Sprintf("unknown manifest name=%s tag=%s", err.Name, err.Tag) +} + +type ErrManifestUnknownRevision struct { + statuserror.NotFound + + Name string + Revision digest.Digest +} + +func (err ErrManifestUnknownRevision) Error() string { + return fmt.Sprintf("unknown manifest name=%s revision=%s", err.Name, err.Revision) +} + +type ErrManifestUnverified struct { + statuserror.BadRequest +} + +func (ErrManifestUnverified) Error() string { + return "unverified manifest" +} + +type ErrManifestBlobUnknown struct { + statuserror.NotFound + + Digest digest.Digest +} + +func (err ErrManifestBlobUnknown) Error() string { + return fmt.Sprintf("unknown blob %v on manifest", err.Digest) +} + +type ErrManifestNameInvalid struct { + statuserror.BadRequest + + Name string + Reason error +} + +func (err ErrManifestNameInvalid) Error() string { + return fmt.Sprintf("manifest name %q invalid: %v", err.Name, err.Reason) +} diff --git a/pkg/content/fs/.gitignore b/pkg/content/fs/.gitignore new file mode 100644 index 0000000..fb94ebf --- /dev/null +++ b/pkg/content/fs/.gitignore @@ -0,0 +1 @@ +testdata/ \ No newline at end of file diff --git a/pkg/content/fs/api.go b/pkg/content/fs/api.go new file mode 100644 index 0000000..94c8a0e --- /dev/null +++ b/pkg/content/fs/api.go @@ -0,0 +1,44 @@ +package fs + +import ( + "context" + "github.com/octohelm/crkit/pkg/content" + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/octohelm/unifs/pkg/filesystem/api" + "github.com/octohelm/unifs/pkg/strfmt" + "os" + "path/filepath" +) + +type NamespaceProvider struct { + api.FileSystemBackend + + namespace content.Namespace +} + +func (s *NamespaceProvider) Init(ctx context.Context) error { + if s.Backend.IsZero() { + cwd, err := os.Getwd() + if err != nil { + return err + } + endpoint, _ := strfmt.ParseEndpoint("file://" + filepath.Join(cwd, ".tmp/container-registry")) + s.Backend = *endpoint + } + + if err := s.FileSystemBackend.Init(ctx); err != nil { + return err + } + + if err := filesystem.MkdirAll(ctx, s.FileSystem(), "."); err != nil { + return err + } + + s.namespace = NewNamespace(s.FileSystem()) + + return nil +} + +func (s *NamespaceProvider) InjectContext(ctx context.Context) context.Context { + return content.NamespaceContext.Inject(ctx, s.namespace) +} diff --git a/pkg/content/fs/blob_store.go b/pkg/content/fs/blob_store.go new file mode 100644 index 0000000..1bc7bfe --- /dev/null +++ b/pkg/content/fs/blob_store.go @@ -0,0 +1,154 @@ +package fs + +import ( + "context" + "fmt" + "io" + "os" + "path/filepath" + "sync" + + "github.com/google/uuid" + "github.com/octohelm/crkit/pkg/content" + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/opencontainers/go-digest" +) + +func NewBlobStore(fsys filesystem.FileSystem) content.BlobStore { + return &blobStore{fs: fsys} +} + +type blobStore struct { + fs filesystem.FileSystem +} + +func (f *blobStore) Info(ctx context.Context, dgst digest.Digest) (content.Descriptor, error) { + s, err := f.fs.Stat(ctx, defaultLayout.BlobDataPath(dgst)) + if err != nil { + if os.IsNotExist(err) { + return content.Descriptor{}, &content.ErrManifestBlobUnknown{ + Digest: dgst, + } + } + return content.Descriptor{}, err + } + return content.Descriptor{ + Digest: dgst, + Size: s.Size(), + }, nil +} + +func (f *blobStore) Open(ctx context.Context, dgst digest.Digest) (io.ReadCloser, error) { + file, err := f.fs.OpenFile(ctx, defaultLayout.BlobDataPath(dgst), os.O_RDONLY, os.ModePerm) + if err != nil { + if os.IsNotExist(err) { + return nil, &content.ErrManifestBlobUnknown{ + Digest: dgst, + } + } + return nil, err + } + return file, nil +} + +func (f *blobStore) Writer(ctx context.Context) (content.Writer, error) { + uploadPath := defaultLayout.UploadDataPath(uuid.New().String()) + + if err := filesystem.MkdirAll(ctx, f.fs, filepath.Dir(uploadPath)); err != nil { + return nil, err + } + + file, err := f.fs.OpenFile(ctx, uploadPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.ModePerm) + if err != nil { + return nil, err + } + + return &writer{ + path: uploadPath, + digester: digest.SHA256.Digester(), + file: file, + store: f, + }, nil +} + +type writer struct { + digester digest.Digester + file filesystem.File + path string + + store *blobStore + offset int64 + once sync.Once + + err error +} + +func (w *writer) Write(p []byte) (n int, err error) { + n, err = w.file.Write(p) + w.digester.Hash().Write(p[:n]) + w.offset += int64(len(p)) + return n, err +} + +func (w *writer) Close() error { + w.once.Do(func() { + w.err = w.file.Close() + }) + + return w.err +} + +func (w *writer) Digest(ctx context.Context) digest.Digest { + return w.digester.Digest() +} + +func (w *writer) Size(ctx context.Context) int64 { + return w.offset +} + +func (w *writer) Commit(ctx context.Context, expected content.Descriptor) (content.Descriptor, error) { + defer func() { + _ = w.store.fs.RemoveAll(ctx, filepath.Dir(w.path)) + }() + + if err := w.Close(); err != nil { + return content.Descriptor{}, err + } + + size := w.Size(ctx) + dgst := w.Digest(ctx) + + if expected.Size > 0 && expected.Size != size { + return content.Descriptor{}, fmt.Errorf("unexpected commit size %d, expected %d", size, expected.Size) + } + + if expected.Digest != "" && expected.Digest != dgst { + return content.Descriptor{}, fmt.Errorf("unexpected commit digest %s, expected %s", dgst, expected.Digest) + } + + target := defaultLayout.BlobDataPath(dgst) + + _, err := w.store.fs.Stat(ctx, target) + if err == nil { + // remove uploaded + return content.Descriptor{ + Size: size, + Digest: dgst, + MediaType: expected.MediaType, + }, nil + } + + if err := filesystem.MkdirAll(ctx, w.store.fs, filepath.Dir(target)); err != nil { + return content.Descriptor{}, err + } + + if err := w.store.fs.Rename(ctx, w.path, target); err != nil { + return content.Descriptor{}, err + } + + return content.Descriptor{ + Size: size, + Digest: dgst, + MediaType: expected.MediaType, + }, nil +} diff --git a/pkg/content/fs/blob_store_test.go b/pkg/content/fs/blob_store_test.go new file mode 100644 index 0000000..7c586b3 --- /dev/null +++ b/pkg/content/fs/blob_store_test.go @@ -0,0 +1,57 @@ +package fs_test + +import ( + "bytes" + "context" + "io" + "os" + "path/filepath" + "testing" + + "github.com/octohelm/crkit/pkg/content" + contentfs "github.com/octohelm/crkit/pkg/content/fs" + "github.com/octohelm/unifs/pkg/filesystem/local" + testingx "github.com/octohelm/x/testing" + "github.com/opencontainers/go-digest" +) + +func TestBlobStore(t *testing.T) { + cwd, _ := os.Getwd() + fs := local.NewFS(filepath.Join(cwd, "testdata/registry")) + + s := contentfs.NewBlobStore(fs) + + str := "12345678" + + t.Run("put contents", func(t *testing.T) { + ctx := context.Background() + + w, err := s.Writer(ctx) + testingx.Expect(t, err, testingx.Be[error](nil)) + defer w.Close() + + buf := bytes.NewBufferString(str) + _, _ = io.Copy(w, buf) + + d, err := w.Commit(ctx, content.Descriptor{}) + testingx.Expect(t, err, testingx.Be[error](nil)) + testingx.Expect(t, d.Size, testingx.Be(int64(len(str)))) + testingx.Expect(t, d.Digest, testingx.Be(digest.FromString(str))) + + t.Run("info", func(t *testing.T) { + d, err := s.Info(ctx, digest.FromString(str)) + testingx.Expect(t, err, testingx.Be[error](nil)) + testingx.Expect(t, d.Size, testingx.Be(int64(len(str)))) + }) + + t.Run("open", func(t *testing.T) { + r, err := s.Open(ctx, digest.FromString(str)) + testingx.Expect(t, err, testingx.Be[error](nil)) + defer r.Close() + + data, _ := io.ReadAll(r) + testingx.Expect(t, string(data), testingx.Be(str)) + }) + }) + +} diff --git a/pkg/content/fs/layout.go b/pkg/content/fs/layout.go new file mode 100644 index 0000000..ed67a82 --- /dev/null +++ b/pkg/content/fs/layout.go @@ -0,0 +1,50 @@ +package fs + +import ( + "github.com/distribution/reference" + "github.com/opencontainers/go-digest" + "path/filepath" +) + +const defaultLayout = Layout("docker/registry/v2") + +type Layout string + +func (b Layout) UploadDataPath(id string) string { + return filepath.Join(string(b), "_uploads", id, "data") +} + +// blobs/sha256/00/005d377afc9750aefc6652bfd4460282014776a79c282c5c2f74cc9c14ac427d/data +func (b Layout) BlobDataPath(digest digest.Digest) string { + return filepath.Join(string(b), "blobs", digest.Algorithm().String(), digest.Hex()[0:2], digest.Hex(), "data") +} + +// repositories/{name}/_layers/sha256/1b0f66f8c4464296a323f93ad39c9fc70054f24a23452eaf52440858c025967b/link +func (b Layout) RepositoryLayerLinkPath(name reference.Named, digest digest.Digest) string { + return filepath.Join(string(b), "repositories", name.Name(), "_layers", digest.Algorithm().String(), digest.Hex(), "link") +} + +// repositories/{name}/_manifests/revisions/sha256/1b0f66f8c4464296a323f93ad39c9fc70054f24a23452eaf52440858c025967b/link +func (b Layout) RepositoryManifestRevisionLinkPath(name reference.Named, digest digest.Digest) string { + return filepath.Join(string(b), "repositories", name.Name(), "_manifests", "revisions", digest.Algorithm().String(), digest.Hex(), "link") +} + +// repositories/{name}/_manifests/tags +func (b Layout) RepositoryManifestTagsPath(name reference.Named) string { + return filepath.Join(string(b), "repositories", name.Name(), "_manifests", "tags") +} + +// repositories/{name}/_manifests/tags/{tag} +func (b Layout) RepositoryManifestTagPath(name reference.Named, tag string) string { + return filepath.Join(b.RepositoryManifestTagsPath(name), tag) +} + +// repositories/{name}/_manifests/tags/{tag}/current/link +func (b Layout) RepositoryManifestTagCurrentLinkPath(name reference.Named, tag string) string { + return filepath.Join(b.RepositoryManifestTagPath(name, tag), "current/link") +} + +// repositories/{name}/_manifests/tags/{tag}/index/sha256/1b0f66f8c4464296a323f93ad39c9fc70054f24a23452eaf52440858c025967b/link +func (b Layout) RepositoryManifestTagIndexLinkPath(name reference.Named, tag string, digest digest.Digest) string { + return filepath.Join(b.RepositoryManifestTagPath(name, tag), "index", digest.Algorithm().String(), digest.Hex(), "link") +} diff --git a/pkg/content/fs/manifest_service.go b/pkg/content/fs/manifest_service.go new file mode 100644 index 0000000..4f6dcb7 --- /dev/null +++ b/pkg/content/fs/manifest_service.go @@ -0,0 +1,89 @@ +package fs + +import ( + "context" + "encoding/json" + "github.com/distribution/reference" + "github.com/octohelm/crkit/pkg/content" + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/opencontainers/go-digest" + "os" +) + +var _ content.ManifestService = &manifestService{} + +type manifestService struct { + named reference.Named + fs filesystem.FileSystem + blobStore content.BlobStore +} + +func (m *manifestService) Info(ctx context.Context, dgst digest.Digest) (content.Descriptor, error) { + p := defaultLayout.RepositoryManifestRevisionLinkPath(m.named, dgst) + + _, err := m.fs.Stat(ctx, p) + if err != nil { + if os.IsNotExist(err) { + return content.Descriptor{}, &content.ErrManifestUnknownRevision{ + Name: m.named.Name(), + Revision: dgst, + } + } + return content.Descriptor{}, err + } + + return m.blobStore.Info(ctx, dgst) +} + +func (m *manifestService) Get(ctx context.Context, dgst digest.Digest) (content.Media, error) { + info, err := m.Info(ctx, dgst) + if err != nil { + return nil, err + } + + blob, err := m.blobStore.Open(ctx, info.Digest) + if err != nil { + return nil, err + } + defer blob.Close() + + media := &content.Payload{} + if err := json.NewDecoder(blob).Decode(media); err != nil { + return nil, err + } + return media, nil +} + +func (m *manifestService) Put(ctx context.Context, manifest content.Media) (digest.Digest, error) { + data, err := json.Marshal(manifest) + if err != nil { + return "", nil + } + + w, err := m.blobStore.Writer(ctx) + if err != nil { + return "", err + } + defer w.Close() + + if _, err := w.Write(data); err != nil { + return "", err + } + + d, err := w.Commit(ctx, content.Descriptor{}) + if err != nil { + return "", err + } + + revision := defaultLayout.RepositoryManifestRevisionLinkPath(m.named, d.Digest) + if err := filesystem.Write(ctx, m.fs, revision, []byte(d.Digest)); err != nil { + return "", err + } + return d.Digest, nil +} + +func (m *manifestService) Delete(ctx context.Context, dgst digest.Digest) error { + revisionLinkPath := defaultLayout.RepositoryManifestRevisionLinkPath(m.named, dgst) + + return m.fs.RemoveAll(ctx, revisionLinkPath) +} diff --git a/pkg/content/fs/namespace.go b/pkg/content/fs/namespace.go new file mode 100644 index 0000000..01d9eba --- /dev/null +++ b/pkg/content/fs/namespace.go @@ -0,0 +1,26 @@ +package fs + +import ( + "context" + "github.com/octohelm/crkit/pkg/content" + "github.com/octohelm/unifs/pkg/filesystem" + + "github.com/distribution/reference" +) + +func NewNamespace(fs filesystem.FileSystem) content.Namespace { + return &namespace{ + fs: fs, + } +} + +type namespace struct { + fs filesystem.FileSystem +} + +func (n *namespace) Repository(ctx context.Context, named reference.Named) content.Repository { + return &repository{ + named: named, + fs: n.fs, + } +} diff --git a/pkg/content/fs/repository.go b/pkg/content/fs/repository.go new file mode 100644 index 0000000..df5b758 --- /dev/null +++ b/pkg/content/fs/repository.go @@ -0,0 +1,46 @@ +package fs + +import ( + "context" + "github.com/distribution/reference" + "github.com/octohelm/crkit/pkg/content" + "github.com/octohelm/unifs/pkg/filesystem" +) + +type repository struct { + named reference.Named + fs filesystem.FileSystem +} + +func (r *repository) Named() reference.Named { + return r.named +} + +func (r *repository) Blobs(ctx context.Context) (content.BlobStore, error) { + return NewBlobStore(r.fs), nil +} + +func (r *repository) Manifests(ctx context.Context) (content.ManifestService, error) { + bs, err := r.Blobs(ctx) + if err != nil { + return nil, err + } + return &manifestService{ + named: r.named, + fs: r.fs, + blobStore: bs, + }, nil +} + +func (r *repository) Tags(ctx context.Context) (content.TagService, error) { + ms, err := r.Manifests(ctx) + if err != nil { + return nil, err + } + + return &tagService{ + named: r.named, + fs: r.fs, + manifestService: ms, + }, err +} diff --git a/pkg/content/fs/tag_service.go b/pkg/content/fs/tag_service.go new file mode 100644 index 0000000..a14095f --- /dev/null +++ b/pkg/content/fs/tag_service.go @@ -0,0 +1,87 @@ +package fs + +import ( + "context" + "github.com/distribution/reference" + "github.com/octohelm/crkit/pkg/content" + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/opencontainers/go-digest" + "io" + "io/fs" + "os" +) + +var _ content.TagService = &tagService{} + +type tagService struct { + named reference.Named + fs filesystem.FileSystem + manifestService content.ManifestService +} + +func (t *tagService) Get(ctx context.Context, tag string) (content.Descriptor, error) { + tagCurrentLinkPath := defaultLayout.RepositoryManifestTagCurrentLinkPath(t.named, tag) + f, err := filesystem.Open(ctx, t.fs, tagCurrentLinkPath) + if err != nil { + if os.IsNotExist(err) { + return content.Descriptor{}, &content.ErrTagUnknown{ + Tag: tag, + } + } + return content.Descriptor{}, err + } + defer f.Close() + data, err := io.ReadAll(f) + if err != nil { + return content.Descriptor{}, err + } + dgst, err := digest.Parse(string(data)) + if err != nil { + return content.Descriptor{}, err + } + return t.manifestService.Info(ctx, dgst) +} + +func (t *tagService) Tag(ctx context.Context, tag string, desc content.Descriptor) error { + info, err := t.manifestService.Info(ctx, desc.Digest) + if err != nil { + return err + } + + tagIndexLinkPath := defaultLayout.RepositoryManifestTagIndexLinkPath(t.named, tag, info.Digest) + if err := filesystem.Write(ctx, t.fs, tagIndexLinkPath, []byte(info.Digest)); err != nil { + return err + } + + tagCurrentLinkPath := defaultLayout.RepositoryManifestTagCurrentLinkPath(t.named, tag) + if err := filesystem.Write(ctx, t.fs, tagCurrentLinkPath, []byte(info.Digest)); err != nil { + return err + } + + return nil +} + +func (t *tagService) Untag(ctx context.Context, tag string) error { + return t.fs.RemoveAll(ctx, defaultLayout.RepositoryManifestTagPath(t.named, tag)) +} + +func (t *tagService) All(ctx context.Context) ([]string, error) { + tags := make([]string, 0) + + if err := filesystem.WalkDir(ctx, filesystem.Sub(t.fs, defaultLayout.RepositoryManifestTagsPath(t.named)), ".", func(path string, d fs.DirEntry, err error) error { + if path == "." { + return nil + } + + if d.IsDir() { + tags = append(tags, d.Name()) + return nil + } + + return fs.SkipDir + }); err != nil { + return nil, err + } + + return tags, nil +} diff --git a/pkg/content/fs/zz_generated.runtimedoc.go b/pkg/content/fs/zz_generated.runtimedoc.go new file mode 100644 index 0000000..fb3457d --- /dev/null +++ b/pkg/content/fs/zz_generated.runtimedoc.go @@ -0,0 +1,31 @@ +/* +Package fs GENERATED BY gengo:runtimedoc +DON'T EDIT THIS FILE +*/ +package fs + +// nolint:deadcode,unused +func runtimeDoc(v any, names ...string) ([]string, bool) { + if c, ok := v.(interface { + RuntimeDoc(names ...string) ([]string, bool) + }); ok { + return c.RuntimeDoc(names...) + } + return nil, false +} + +func (v NamespaceProvider) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "FileSystemBackend": + return []string{}, true + + } + if doc, ok := runtimeDoc(v.FileSystemBackend, names...); ok { + return doc, ok + } + + return nil, false + } + return []string{}, true +} diff --git a/pkg/content/manifest_service.go b/pkg/content/manifest_service.go new file mode 100644 index 0000000..fe5c187 --- /dev/null +++ b/pkg/content/manifest_service.go @@ -0,0 +1,13 @@ +package content + +import ( + "context" + "github.com/opencontainers/go-digest" +) + +type ManifestService interface { + Info(ctx context.Context, dgst digest.Digest) (Descriptor, error) + Get(ctx context.Context, dgst digest.Digest) (Media, error) + Put(ctx context.Context, manifest Media) (digest.Digest, error) + Delete(ctx context.Context, dgst digest.Digest) error +} diff --git a/pkg/content/media.go b/pkg/content/media.go new file mode 100644 index 0000000..50d398e --- /dev/null +++ b/pkg/content/media.go @@ -0,0 +1,106 @@ +package content + +import ( + "encoding/json" + + "github.com/octohelm/courier/pkg/openapi/jsonschema/util" + specv1 "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" +) + +type Media interface { + GetMediaType() string +} + +type Manifest specv1.Manifest + +func (Manifest) GetMediaType() string { + return specv1.MediaTypeImageManifest +} + +type Index specv1.Index + +func (Index) GetMediaType() string { + return specv1.MediaTypeImageIndex +} + +const ( + DockerMediaTypeManifest = "application/vnd.docker.distribution.manifest.v2+json" + DockerMediaTypeManifestList = "application/vnd.docker.distribution.manifest.list.v2+json" +) + +type DockerManifest specv1.Manifest + +func (DockerManifest) GetMediaType() string { + return DockerMediaTypeManifest +} + +type DockerManifestList specv1.Index + +func (DockerManifestList) GetMediaType() string { + return DockerMediaTypeManifestList +} + +type Payload struct { + Media `json:"-"` + + Raw []byte `json:"-"` +} + +func From(media Media) (*Payload, error) { + switch x := media.(type) { + case *Payload: + return x, nil + case Payload: + return &x, nil + } + + m := (&Payload{}).Mapping() + if m, ok := m[media.GetMediaType()]; ok { + return &Payload{ + Media: m.(Media), + }, nil + } + + return nil, errors.Errorf("invalid media %s", media.GetMediaType()) +} + +func (Payload) Discriminator() string { + return "mediaType" +} + +func (Payload) Mapping() map[string]any { + return map[string]any{ + specv1.MediaTypeImageManifest: Media(&Manifest{}), + specv1.MediaTypeImageIndex: Media(&Index{}), + + DockerMediaTypeManifest: Media(&DockerManifest{}), + DockerMediaTypeManifestList: Media(&DockerManifestList{}), + } +} + +func (m *Payload) SetUnderlying(u any) { + m.Media = u.(Media) +} + +func (m *Payload) UnmarshalJSON(data []byte) error { + mm := Payload{ + Raw: data, + } + if err := util.UnmarshalTaggedUnionFromJSON(data, &mm); err != nil { + return err + } + *m = mm + return nil +} + +func (m Payload) MarshalJSON() ([]byte, error) { + if len(m.Raw) != 0 { + return m.Raw[:], nil + } + if m.Media == nil { + return []byte("{}"), nil + } + + return json.Marshal(m.Media) +} diff --git a/pkg/content/named.go b/pkg/content/named.go new file mode 100644 index 0000000..dc17075 --- /dev/null +++ b/pkg/content/named.go @@ -0,0 +1,19 @@ +package content + +import "github.com/opencontainers/go-digest" + +type Name string + +func (n Name) String() string { + return string(n) +} + +func (n Name) Name() string { + return string(n) +} + +type TagOrDigest string + +func (tag TagOrDigest) Digest() (digest.Digest, error) { + return digest.Parse(string(tag)) +} diff --git a/pkg/content/namespace.go b/pkg/content/namespace.go new file mode 100644 index 0000000..7910b2d --- /dev/null +++ b/pkg/content/namespace.go @@ -0,0 +1,14 @@ +package content + +import ( + "context" + + "github.com/distribution/reference" + contextx "github.com/octohelm/x/context" +) + +type Namespace interface { + Repository(ctx context.Context, named reference.Named) Repository +} + +var NamespaceContext = contextx.New[Namespace]() diff --git a/pkg/content/repository.go b/pkg/content/repository.go new file mode 100644 index 0000000..1ddc087 --- /dev/null +++ b/pkg/content/repository.go @@ -0,0 +1,16 @@ +package content + +import ( + "context" + "github.com/distribution/reference" + contextx "github.com/octohelm/x/context" +) + +var RepositoryContext = contextx.New[Repository]() + +type Repository interface { + Named() reference.Named + Manifests(ctx context.Context) (ManifestService, error) + Tags(ctx context.Context) (TagService, error) + Blobs(ctx context.Context) (BlobStore, error) +} diff --git a/pkg/content/tag_service.go b/pkg/content/tag_service.go new file mode 100644 index 0000000..f85af17 --- /dev/null +++ b/pkg/content/tag_service.go @@ -0,0 +1,10 @@ +package content + +import "context" + +type TagService interface { + Get(ctx context.Context, tag string) (Descriptor, error) + Tag(ctx context.Context, tag string, desc Descriptor) error + Untag(ctx context.Context, tag string) error + All(ctx context.Context) ([]string, error) +} diff --git a/pkg/content/zz_generated.runtimedoc.go b/pkg/content/zz_generated.runtimedoc.go new file mode 100644 index 0000000..5748dc5 --- /dev/null +++ b/pkg/content/zz_generated.runtimedoc.go @@ -0,0 +1,304 @@ +/* +Package content GENERATED BY gengo:runtimedoc +DON'T EDIT THIS FILE +*/ +package content + +// nolint:deadcode,unused +func runtimeDoc(v any, names ...string) ([]string, bool) { + if c, ok := v.(interface { + RuntimeDoc(names ...string) ([]string, bool) + }); ok { + return c.RuntimeDoc(names...) + } + return nil, false +} + +func (v DockerManifest) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Versioned": + return []string{}, true + case "MediaType": + return []string{ + "MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json`", + }, true + case "ArtifactType": + return []string{ + "ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact.", + }, true + case "Config": + return []string{ + "Config references a configuration object for a container, by digest.", + "The referenced configuration object is a JSON blob that the runtime uses to set up the container.", + }, true + case "Layers": + return []string{ + "Layers is an indexed list of layers referenced by the manifest.", + }, true + case "Subject": + return []string{ + "Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest.", + }, true + case "Annotations": + return []string{ + "Annotations contains arbitrary metadata for the image manifest.", + }, true + + } + if doc, ok := runtimeDoc(v.Versioned, names...); ok { + return doc, ok + } + + return nil, false + } + return []string{}, true +} + +func (v DockerManifestList) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Versioned": + return []string{}, true + case "MediaType": + return []string{ + "MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json`", + }, true + case "ArtifactType": + return []string{ + "ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact.", + }, true + case "Manifests": + return []string{ + "Manifests references platform specific manifests.", + }, true + case "Subject": + return []string{ + "Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest.", + }, true + case "Annotations": + return []string{ + "Annotations contains arbitrary metadata for the image index.", + }, true + + } + if doc, ok := runtimeDoc(v.Versioned, names...); ok { + return doc, ok + } + + return nil, false + } + return []string{}, true +} + +func (v ErrManifestBlobUnknown) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Digest": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v ErrManifestNameInvalid) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Name": + return []string{}, true + case "Reason": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v ErrManifestUnknown) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Name": + return []string{}, true + case "Tag": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v ErrManifestUnknownRevision) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Name": + return []string{}, true + case "Revision": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v ErrManifestUnverified) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + + } + + return nil, false + } + return []string{}, true +} + +func (v ErrRepositoryNameInvalid) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Name": + return []string{}, true + case "Reason": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v ErrRepositoryUnknown) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Name": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v ErrTagUnknown) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Tag": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v Index) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Versioned": + return []string{}, true + case "MediaType": + return []string{ + "MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json`", + }, true + case "ArtifactType": + return []string{ + "ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact.", + }, true + case "Manifests": + return []string{ + "Manifests references platform specific manifests.", + }, true + case "Subject": + return []string{ + "Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest.", + }, true + case "Annotations": + return []string{ + "Annotations contains arbitrary metadata for the image index.", + }, true + + } + if doc, ok := runtimeDoc(v.Versioned, names...); ok { + return doc, ok + } + + return nil, false + } + return []string{}, true +} + +func (v Manifest) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Versioned": + return []string{}, true + case "MediaType": + return []string{ + "MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json`", + }, true + case "ArtifactType": + return []string{ + "ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact.", + }, true + case "Config": + return []string{ + "Config references a configuration object for a container, by digest.", + "The referenced configuration object is a JSON blob that the runtime uses to set up the container.", + }, true + case "Layers": + return []string{ + "Layers is an indexed list of layers referenced by the manifest.", + }, true + case "Subject": + return []string{ + "Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest.", + }, true + case "Annotations": + return []string{ + "Annotations contains arbitrary metadata for the image manifest.", + }, true + + } + if doc, ok := runtimeDoc(v.Versioned, names...); ok { + return doc, ok + } + + return nil, false + } + return []string{}, true +} + +func (Name) RuntimeDoc(names ...string) ([]string, bool) { + return []string{}, true +} +func (v Payload) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Media": + return []string{}, true + case "Raw": + return []string{}, true + + } + if doc, ok := runtimeDoc(v.Media, names...); ok { + return doc, ok + } + + return nil, false + } + return []string{}, true +} + +func (TagOrDigest) RuntimeDoc(names ...string) ([]string, bool) { + return []string{}, true +} diff --git a/pkg/registryhttp/apis/api.go b/pkg/registryhttp/apis/api.go new file mode 100644 index 0000000..4e68798 --- /dev/null +++ b/pkg/registryhttp/apis/api.go @@ -0,0 +1,18 @@ +package apis + +import ( + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/courier/pkg/courierhttp/handler/httprouter" + "github.com/octohelm/crkit/pkg/registryhttp/apis/registry" +) + +var R = courierhttp.GroupRouter("/").With( + + courierhttp.GroupRouter("/api").With( + courier.NewRouter(&httprouter.OpenAPI{}), + courier.NewRouter(&httprouter.OpenAPIView{}), + ), + + registry.R, +) diff --git a/pkg/registryhttp/apis/registry/api.go b/pkg/registryhttp/apis/registry/api.go new file mode 100644 index 0000000..81453a3 --- /dev/null +++ b/pkg/registryhttp/apis/registry/api.go @@ -0,0 +1,12 @@ +// +gengo:operator:register=R +// +gengo:operator:tag=containerregistry +package registry + +import ( + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" +) + +var R = courier.NewRouter( + courierhttp.Group("/v2"), +) diff --git a/pkg/registryhttp/apis/registry/base_url.go b/pkg/registryhttp/apis/registry/base_url.go new file mode 100644 index 0000000..411fa46 --- /dev/null +++ b/pkg/registryhttp/apis/registry/base_url.go @@ -0,0 +1,15 @@ +package registry + +import ( + "context" + + "github.com/octohelm/courier/pkg/courierhttp" +) + +type BaseURL struct { + courierhttp.MethodGet +} + +func (r *BaseURL) Output(ctx context.Context) (any, error) { + return map[string]string{}, nil +} diff --git a/pkg/registryhttp/apis/registry/blob__get.go b/pkg/registryhttp/apis/registry/blob__get.go new file mode 100644 index 0000000..04cd942 --- /dev/null +++ b/pkg/registryhttp/apis/registry/blob__get.go @@ -0,0 +1,42 @@ +package registry + +import ( + "context" + + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/crkit/pkg/content" + registryoperator "github.com/octohelm/crkit/pkg/registryhttp/apis/registry/operator" + "github.com/opencontainers/go-digest" +) + +func (GetBlob) MiddleOperators() courier.MiddleOperators { + return courier.MiddleOperators{ + ®istryoperator.NameScoped{}, + } +} + +type GetBlob struct { + courierhttp.MethodGet `path:"/blobs/{digest}"` + + Digest digest.Digest `name:"digest" in:"path"` +} + +func (req *GetBlob) Output(ctx context.Context) (any, error) { + repo := content.RepositoryContext.From(ctx) + + blobs, err := repo.Blobs(ctx) + if err != nil { + return nil, err + } + + b, err := blobs.Open(ctx, req.Digest) + if err != nil { + return nil, err + } + + return courierhttp.Wrap( + b, + courierhttp.WithMetadata("Docker-Content-Digest", req.Digest.String()), + ), nil +} diff --git a/pkg/registryhttp/apis/registry/blob__head.go b/pkg/registryhttp/apis/registry/blob__head.go new file mode 100644 index 0000000..3f8de24 --- /dev/null +++ b/pkg/registryhttp/apis/registry/blob__head.go @@ -0,0 +1,45 @@ +package registry + +import ( + "context" + "fmt" + + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/crkit/pkg/content" + registryoperator "github.com/octohelm/crkit/pkg/registryhttp/apis/registry/operator" + "github.com/opencontainers/go-digest" +) + +func (HeadBlob) MiddleOperators() courier.MiddleOperators { + return courier.MiddleOperators{ + ®istryoperator.NameScoped{}, + } +} + +type HeadBlob struct { + courierhttp.MethodHead `path:"/blobs/{digest}"` + + Digest digest.Digest `name:"digest" in:"path"` +} + +func (req *HeadBlob) Output(ctx context.Context) (any, error) { + repo := content.RepositoryContext.From(ctx) + + blobs, err := repo.Blobs(ctx) + if err != nil { + return nil, err + } + + d, err := blobs.Info(ctx, req.Digest) + if err != nil { + return nil, err + } + + return courierhttp.Wrap[any](nil, + courierhttp.WithStatusCode(200), + courierhttp.WithMetadata("Docker-Content-Digest", d.Digest.String()), + courierhttp.WithMetadata("Content-Type", d.MediaType), + courierhttp.WithMetadata("Content-Length", fmt.Sprintf("%d", d.Size)), + ), nil +} diff --git a/pkg/registryhttp/apis/registry/blob__upload.go b/pkg/registryhttp/apis/registry/blob__upload.go new file mode 100644 index 0000000..ea0319d --- /dev/null +++ b/pkg/registryhttp/apis/registry/blob__upload.go @@ -0,0 +1,56 @@ +package registry + +import ( + "context" + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/crkit/pkg/content" + registryoperator "github.com/octohelm/crkit/pkg/registryhttp/apis/registry/operator" + "github.com/opencontainers/go-digest" + "io" +) + +func (UploadBlob) MiddleOperators() courier.MiddleOperators { + return courier.MiddleOperators{ + ®istryoperator.NameScoped{}, + } +} + +type UploadBlob struct { + courierhttp.MethodPost `path:"/blobs/uploads"` + + ContentType string `name:"Content-Type,omitempty" in:"header"` + Digest digest.Digest `name:"digest,omitempty" in:"query"` + Blob io.ReadCloser `in:"body"` +} + +func (req *UploadBlob) Output(ctx context.Context) (any, error) { + repo := content.RepositoryContext.From(ctx) + + blobs, err := repo.Blobs(ctx) + if err != nil { + return nil, err + } + + w, err := blobs.Writer(ctx) + if err != nil { + return nil, err + } + defer w.Close() + + if _, err := io.Copy(w, req.Blob); err != nil { + return nil, err + } + + d, err := w.Commit(ctx, content.Descriptor{ + Digest: req.Digest, + }) + if err != nil { + return nil, err + } + + return courierhttp.Wrap[any](nil, + courierhttp.WithStatusCode(200), + courierhttp.WithMetadata("Docker-Content-Digest", d.Digest.String()), + ), nil +} diff --git a/pkg/registryhttp/apis/registry/manifest__get.go b/pkg/registryhttp/apis/registry/manifest__get.go new file mode 100644 index 0000000..597688e --- /dev/null +++ b/pkg/registryhttp/apis/registry/manifest__get.go @@ -0,0 +1,57 @@ +package registry + +import ( + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/crkit/pkg/content" + registryoperator "github.com/octohelm/crkit/pkg/registryhttp/apis/registry/operator" +) + +import ( + "context" +) + +func (GetManifest) MiddleOperators() courier.MiddleOperators { + return courier.MiddleOperators{ + ®istryoperator.NameScoped{}, + } +} + +type GetManifest struct { + courierhttp.MethodGet `path:"/manifests/{reference}"` + + Reference content.TagOrDigest `name:"reference" in:"path"` +} + +func (req *GetManifest) Output(ctx context.Context) (any, error) { + repo := content.RepositoryContext.From(ctx) + + dgst, err := req.Reference.Digest() + if err != nil { + tags, err := repo.Tags(ctx) + if err != nil { + return nil, err + } + + d, err := tags.Get(ctx, string(req.Reference)) + if err != nil { + return nil, err + } + dgst = d.Digest + } + + manifests, err := repo.Manifests(ctx) + if err != nil { + return nil, err + } + + m, err := manifests.Get(ctx, dgst) + if err != nil { + return nil, err + } + + return courierhttp.Wrap(manifests, + courierhttp.WithMetadata("Docker-Content-Digest", dgst.String()), + courierhttp.WithMetadata("Content-Type", m.GetMediaType()), + ), nil +} diff --git a/pkg/registryhttp/apis/registry/manifest__head.go b/pkg/registryhttp/apis/registry/manifest__head.go new file mode 100644 index 0000000..bf22acc --- /dev/null +++ b/pkg/registryhttp/apis/registry/manifest__head.go @@ -0,0 +1,56 @@ +package registry + +import ( + "context" + + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/crkit/pkg/content" + registryoperator "github.com/octohelm/crkit/pkg/registryhttp/apis/registry/operator" +) + +func (HeadManifest) MiddleOperators() courier.MiddleOperators { + return courier.MiddleOperators{ + ®istryoperator.NameScoped{}, + } +} + +type HeadManifest struct { + courierhttp.MethodHead `path:"/manifests/{reference}"` + + Reference content.TagOrDigest `name:"reference" in:"path"` +} + +func (req *HeadManifest) Output(ctx context.Context) (any, error) { + repo := content.RepositoryContext.From(ctx) + + dgst, err := req.Reference.Digest() + if err != nil { + tags, err := repo.Tags(ctx) + if err != nil { + return nil, err + } + + d, err := tags.Get(ctx, string(req.Reference)) + if err != nil { + return nil, err + } + dgst = d.Digest + } + + manifests, err := repo.Manifests(ctx) + if err != nil { + return nil, err + } + + m, err := manifests.Get(ctx, dgst) + if err != nil { + return nil, err + } + + return courierhttp.Wrap(manifests, + courierhttp.WithStatusCode(200), + courierhttp.WithMetadata("Docker-Content-Digest", dgst.String()), + courierhttp.WithMetadata("Content-Type", m.GetMediaType()), + ), nil +} diff --git a/pkg/registryhttp/apis/registry/manifest__put.go b/pkg/registryhttp/apis/registry/manifest__put.go new file mode 100644 index 0000000..f158c77 --- /dev/null +++ b/pkg/registryhttp/apis/registry/manifest__put.go @@ -0,0 +1,55 @@ +package registry + +import ( + "context" + + "github.com/octohelm/courier/pkg/courier" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/crkit/pkg/content" + registryoperator "github.com/octohelm/crkit/pkg/registryhttp/apis/registry/operator" +) + +func (PutManifest) MiddleOperators() courier.MiddleOperators { + return courier.MiddleOperators{ + ®istryoperator.NameScoped{}, + } +} + +type PutManifest struct { + courierhttp.MethodPut `path:"/manifests/{reference}"` + + Reference content.TagOrDigest `name:"reference" in:"path"` + Media content.Media `in:"body"` +} + +func (req *PutManifest) Output(ctx context.Context) (any, error) { + repo := content.RepositoryContext.From(ctx) + + manifests, err := repo.Manifests(ctx) + if err != nil { + return nil, err + } + + d, err := manifests.Put(ctx, req.Media) + if err != nil { + return nil, err + } + + if _, err := req.Reference.Digest(); err == nil { + tags, err := repo.Tags(ctx) + if err != nil { + return nil, err + } + + if err := tags.Tag(ctx, string(req.Reference), content.Descriptor{ + Digest: d, + }); err != nil { + return nil, err + } + } + + return courierhttp.Wrap[any](nil, + courierhttp.WithStatusCode(200), + courierhttp.WithMetadata("Docker-Content-Digest", d.String()), + ), nil +} diff --git a/pkg/registryhttp/apis/registry/operator/namescoped.go b/pkg/registryhttp/apis/registry/operator/namescoped.go new file mode 100644 index 0000000..fe98c7d --- /dev/null +++ b/pkg/registryhttp/apis/registry/operator/namescoped.go @@ -0,0 +1,19 @@ +package operator + +import ( + "context" + "github.com/octohelm/courier/pkg/courierhttp" + "github.com/octohelm/crkit/pkg/content" +) + +type NameScoped struct { + courierhttp.Method `path:"/{name...}"` + + Name content.Name `name:"name" in:"path"` +} + +func (req *NameScoped) Output(ctx context.Context) (any, error) { + n := content.NamespaceContext.From(ctx) + repo := n.Repository(ctx, req.Name) + return content.RepositoryContext.Inject(ctx, repo), nil +} diff --git a/pkg/registryhttp/apis/registry/operator/zz_generated.runtimedoc.go b/pkg/registryhttp/apis/registry/operator/zz_generated.runtimedoc.go new file mode 100644 index 0000000..e8930f5 --- /dev/null +++ b/pkg/registryhttp/apis/registry/operator/zz_generated.runtimedoc.go @@ -0,0 +1,28 @@ +/* +Package operator GENERATED BY gengo:runtimedoc +DON'T EDIT THIS FILE +*/ +package operator + +// nolint:deadcode,unused +func runtimeDoc(v any, names ...string) ([]string, bool) { + if c, ok := v.(interface { + RuntimeDoc(names ...string) ([]string, bool) + }); ok { + return c.RuntimeDoc(names...) + } + return nil, false +} + +func (v NameScoped) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Name": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} diff --git a/pkg/registryhttp/apis/registry/zz_generated.operator.go b/pkg/registryhttp/apis/registry/zz_generated.operator.go new file mode 100644 index 0000000..8ab68ec --- /dev/null +++ b/pkg/registryhttp/apis/registry/zz_generated.operator.go @@ -0,0 +1,90 @@ +/* +Package registry GENERATED BY gengo:operator +DON'T EDIT THIS FILE +*/ +package registry + +import ( + io "io" + + courier "github.com/octohelm/courier/pkg/courier" + content "github.com/octohelm/crkit/pkg/content" +) + +func init() { + R.Register(courier.NewRouter(&BaseURL{})) +} + +func (*BaseURL) ResponseContent() any { + return new(map[string]string) +} + +func (*BaseURL) ResponseData() *map[string]string { + return new(map[string]string) +} +func init() { + R.Register(courier.NewRouter(&GetBlob{})) +} + +func (*GetBlob) ResponseContent() any { + return new(io.ReadCloser) +} + +func (*GetBlob) ResponseData() *io.ReadCloser { + return new(io.ReadCloser) +} +func init() { + R.Register(courier.NewRouter(&GetManifest{})) +} + +func (*GetManifest) ResponseContent() any { + return new(content.ManifestService) +} + +func (*GetManifest) ResponseData() *content.ManifestService { + return new(content.ManifestService) +} +func init() { + R.Register(courier.NewRouter(&HeadBlob{})) +} + +func (*HeadBlob) ResponseContent() any { + return new(any) +} + +func (*HeadBlob) ResponseData() *any { + return new(any) +} +func init() { + R.Register(courier.NewRouter(&HeadManifest{})) +} + +func (*HeadManifest) ResponseContent() any { + return new(content.ManifestService) +} + +func (*HeadManifest) ResponseData() *content.ManifestService { + return new(content.ManifestService) +} +func init() { + R.Register(courier.NewRouter(&PutManifest{})) +} + +func (*PutManifest) ResponseContent() any { + return new(any) +} + +func (*PutManifest) ResponseData() *any { + return new(any) +} +func init() { + R.Register(courier.NewRouter(&UploadBlob{})) +} + +func (*UploadBlob) ResponseContent() any { + return new(any) +} + +func (*UploadBlob) ResponseData() *any { + return new(any) +} diff --git a/pkg/registryhttp/apis/registry/zz_generated.runtimedoc.go b/pkg/registryhttp/apis/registry/zz_generated.runtimedoc.go new file mode 100644 index 0000000..17de3fb --- /dev/null +++ b/pkg/registryhttp/apis/registry/zz_generated.runtimedoc.go @@ -0,0 +1,110 @@ +/* +Package registry GENERATED BY gengo:runtimedoc +DON'T EDIT THIS FILE +*/ +package registry + +// nolint:deadcode,unused +func runtimeDoc(v any, names ...string) ([]string, bool) { + if c, ok := v.(interface { + RuntimeDoc(names ...string) ([]string, bool) + }); ok { + return c.RuntimeDoc(names...) + } + return nil, false +} + +func (v BaseURL) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + + } + + return nil, false + } + return []string{}, true +} + +func (v GetBlob) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Digest": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v GetManifest) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Reference": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v HeadBlob) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Digest": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v HeadManifest) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Reference": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v PutManifest) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Reference": + return []string{}, true + case "Media": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} + +func (v UploadBlob) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "ContentType": + return []string{}, true + case "Digest": + return []string{}, true + case "Blob": + return []string{}, true + + } + + return nil, false + } + return []string{}, true +} diff --git a/pkg/registryhttp/server.go b/pkg/registryhttp/server.go new file mode 100644 index 0000000..a9dad06 --- /dev/null +++ b/pkg/registryhttp/server.go @@ -0,0 +1,29 @@ +package registryhttp + +import ( + "context" + + infraconfiguration "github.com/innoai-tech/infra/pkg/configuration" + infrahttp "github.com/innoai-tech/infra/pkg/http" + "github.com/octohelm/crkit/pkg/registryhttp/apis" +) + +type Server struct { + infrahttp.Server +} + +func (s *Server) SetDefaults() { + if s.Addr == "" { + s.Addr = ":5000" + } +} + +func (s *Server) Init(ctx context.Context) error { + s.ApplyRouter(apis.R) + + return infraconfiguration.TypedInit(ctx, &s.Server) +} + +func (s *Server) InjectContext(ctx context.Context) context.Context { + return infraconfiguration.InjectContext(ctx) +} diff --git a/pkg/registryhttp/zz_generated.runtimedoc.go b/pkg/registryhttp/zz_generated.runtimedoc.go new file mode 100644 index 0000000..1ba9a3e --- /dev/null +++ b/pkg/registryhttp/zz_generated.runtimedoc.go @@ -0,0 +1,31 @@ +/* +Package registryhttp GENERATED BY gengo:runtimedoc +DON'T EDIT THIS FILE +*/ +package registryhttp + +// nolint:deadcode,unused +func runtimeDoc(v any, names ...string) ([]string, bool) { + if c, ok := v.(interface { + RuntimeDoc(names ...string) ([]string, bool) + }); ok { + return c.RuntimeDoc(names...) + } + return nil, false +} + +func (v Server) RuntimeDoc(names ...string) ([]string, bool) { + if len(names) > 0 { + switch names[0] { + case "Server": + return []string{}, true + + } + if doc, ok := runtimeDoc(v.Server, names...); ok { + return doc, ok + } + + return nil, false + } + return []string{}, true +}