diff --git a/Makefile b/Makefile index a0b0803ba..263bd253a 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,9 @@ VERSION_INJECTION += -X $(PACKAGE)/pkg/version.GitCommit=$(GITCOMMIT) LDFLAGS = "-w $(VERSION_INJECTION)" MIN_MACOS_VERSION ?= 11.0 +FINCH_DAEMON_LOCATION_ROOT ?= $(FINCH_OS_IMAGE_LOCATION_ROOT)/finch-daemon +FINCH_DAEMON_LOCATION ?= $(FINCH_DAEMON_LOCATION_ROOT)/finch-daemon + GOOS ?= $(shell $(GO) env GOOS) ifeq ($(GOOS),windows) BINARYNAME := $(addsuffix .exe, $(BINARYNAME)) @@ -75,7 +78,7 @@ endif FINCH_CORE_DIR := $(CURDIR)/deps/finch-core -remote-all: arch-test finch install.finch-core-dependencies finch.yaml networks.yaml config.yaml +remote-all: arch-test finch install.finch-core-dependencies finch.yaml networks.yaml config.yaml $(OUTDIR)/finch-daemon/finch@.service ifeq ($(BUILD_OS), Windows_NT) include Makefile.windows @@ -174,6 +177,9 @@ finch-all: .PHONY: release release: check-licenses all download-licenses +$(OUTDIR)/finch-daemon/finch@.service: + cp finch@.service $(OUTDIR)/finch-daemon/finch@.service + .PHONY: coverage coverage: go test $(shell go list ./... | grep -v e2e | grep -v benchmark | grep -v mocks) -coverprofile=test-coverage.out diff --git a/Makefile.darwin b/Makefile.darwin index e587ffeb8..13776058b 100644 --- a/Makefile.darwin +++ b/Makefile.darwin @@ -18,9 +18,21 @@ FINCH_OS_IMAGE_LOCATION_ROOT ?= $(DEST) FINCH_IMAGE_LOCATION ?= $(FINCH_OS_IMAGE_LOCATION_ROOT)/os/$(FINCH_OS_BASENAME) FINCH_IMAGE_DIGEST ?= "sha512:$(FINCH_OS_DIGEST)" +# check if finch-daemon socket is in a default path +SHOULD_ADD_DAEMON_MOUNT = $(shell if [[ $(FINCH_DAEMON_LOCATION_ROOT) = ^\/Users\/.* ]]; then echo "0"; else echo "1"; fi) + +.PHONY: finch.yaml +finch.yaml: $(OS_OUTDIR)/finch.yaml + +# only add the finch-daemon mount when its not in a default path +# this scenario is common in dev, where the typical path is /Users/... +ifeq ($(SHOULD_ADD_DAEMON_MOUNT),0) +finch.yaml: add-daemon-mount +endif + $(OS_OUTDIR)/finch.yaml: $(OS_OUTDIR) finch.yaml.d/common.yaml finch.yaml.d/mac.yaml # merge the appropriate YAMLs into a temporary finch.yaml file on the current working directory - cd finch.yaml.d && yq eval-all '. as $$item ireduce ({}; . *+ $$item)' mac.yaml common.yaml > ../finch.yaml.temp + cd finch.yaml.d && yq eval-all '. as $$item ireduce ({}; . *+ $$item)' common.yaml mac.yaml > ./../finch.yaml.temp # using -i.bak is very intentional, it allows the following commands to succeed for both GNU / BSD sed # this sed command uses the alternative separator of "|" because the image location uses "/" @@ -31,8 +43,19 @@ $(OS_OUTDIR)/finch.yaml: $(OS_OUTDIR) finch.yaml.d/common.yaml finch.yaml.d/mac. sed -i.bak -e "s//$(CONTAINER_RUNTIME_ARCHIVE_AARCH64_DIGEST)/g" finch.yaml.temp sed -i.bak -e "s||$(CONTAINER_RUNTIME_ARCHIVE_X86_64_LOCATION)|g" finch.yaml.temp sed -i.bak -e "s//$(CONTAINER_RUNTIME_ARCHIVE_X86_64_DIGEST)/g" finch.yaml.temp + sed -i.bak -e "s||$(FINCH_DAEMON_LOCATION_ROOT)|g" finch.yaml.temp + sed -i.bak -e "s||$(FINCH_DAEMON_LOCATION)|g" finch.yaml.temp # Replacement was successful, so cleanup .bak @rm finch.yaml.temp.bak mv finch.yaml.temp $@ + +.PHONY: add-daemon-mount +add-daemon-mount: + cd finch.yaml.d && yq eval-all '. as $$item ireduce ({}; . *+ $$item)' $(OS_OUTDIR)/finch.yaml finch-daemon-mount.yaml > ./../finch.yaml.temp + sed -i.bak -e "s||$(FINCH_DAEMON_LOCATION_ROOT)|g" finch.yaml.temp + # Replacement was successful, so cleanup .bak + @rm finch.yaml.temp.bak + + mv finch.yaml.temp $(OS_OUTDIR)/finch.yaml diff --git a/e2e/vm/daemon_darwin_test.go b/e2e/vm/daemon_darwin_test.go new file mode 100644 index 000000000..dd56dae8f --- /dev/null +++ b/e2e/vm/daemon_darwin_test.go @@ -0,0 +1,73 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +//go:build darwin + +package vm + +import ( + "context" + "path/filepath" + "sync" + "time" + + "github.com/docker/docker/api/types/image" + "github.com/docker/docker/client" + "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + "github.com/runfinch/common-tests/option" +) + +var testDaemon = func(_ *option.Option, installed bool) { + imageRef := "public.ecr.aws/docker/library/alpine:latest" + ginkgo.Describe("Daemon smoke test", func() { + ginkgo.It("docker client should be able to pull and list images", func(gCtx ginkgo.SpecContext) { + // create a context which is cancelled with the ginkgo test timeout + testCtx, cancelCtx := context.WithCancel(context.Background()) + defer cancelCtx() + go func() { + defer cancelCtx() + <-gCtx.Done() + }() + + daemonSocketPath := filepath.Join(limaDataDirPath(installed), "finch", "sock", "finch.sock") + apiClient, err := client.NewClientWithOpts( + client.WithHost("unix://"+daemonSocketPath), + client.WithVersion("v1.43"), + ) + gomega.Expect(err).ShouldNot(gomega.HaveOccurred()) + defer func() { + gomega.Expect(apiClient.Close()).ShouldNot(gomega.HaveOccurred()) + }() + + _, err = apiClient.ImagePull(testCtx, imageRef, image.PullOptions{}) + gomega.Expect(err).ShouldNot(gomega.HaveOccurred()) + + // ImagePull is asynchronous -- poll to check that the image has been pulled every second + imagePulled := false + wg := sync.WaitGroup{} + wg.Add(1) + go func(wg *sync.WaitGroup) { + for { + time.Sleep(1 * time.Second) + images, err := apiClient.ImageList(testCtx, image.ListOptions{}) + if err != nil { + gomega.Expect(err).ShouldNot(gomega.HaveOccurred()) + } + for _, img := range images { + for _, tag := range img.RepoTags { + if tag == imageRef { + imagePulled = true + wg.Done() + return + } + } + } + } + }(&wg) + wg.Wait() + + gomega.Expect(imagePulled).Should(gomega.BeTrue()) + }) + }) +} diff --git a/e2e/vm/vm_darwin_test.go b/e2e/vm/vm_darwin_test.go index 9354e727d..db9d20ef2 100644 --- a/e2e/vm/vm_darwin_test.go +++ b/e2e/vm/vm_darwin_test.go @@ -71,6 +71,7 @@ func TestVM(t *testing.T) { testCredHelper(o, *e2e.Installed, *e2e.Registry) testSoci(o, *e2e.Installed) testVMNetwork(o, *e2e.Installed) + testDaemon(o, *e2e.Installed) }) gomega.RegisterFailHandler(ginkgo.Fail) diff --git a/finch.yaml.d/common.yaml b/finch.yaml.d/common.yaml index 60b748953..7878b2076 100644 --- a/finch.yaml.d/common.yaml +++ b/finch.yaml.d/common.yaml @@ -85,8 +85,9 @@ provision: printf '[Unit]\nDescription=Delete hanging data on boot\nDefaultDependencies=no\nBefore=basic.target\n\n[Service]\nType=oneshot\nExecStart=/bin/bash -c "sudo rm -rf /var/lib/cni/networks/bridge/**; sudo rm -rf /var/lib/cni/results/bridge-finch-*"\n\n[Install]\nWantedBy=basic.target\n' | sudo tee /usr/local/lib/systemd/system/finch-cleanup-on-boot.service sudo systemctl enable --now finch-cleanup-on-boot.service - sudo systemctl restart containerd.service + sudo systemctl daemon-reload + sudo systemctl restart containerd.service env: # Containerd namespace is used by the lima cidata script # 40-install-containerd.sh. Specifically this variable is defining the diff --git a/finch.yaml.d/finch-daemon-mount.yaml b/finch.yaml.d/finch-daemon-mount.yaml new file mode 100644 index 000000000..5a6725bf9 --- /dev/null +++ b/finch.yaml.d/finch-daemon-mount.yaml @@ -0,0 +1,3 @@ +mounts: + - location: "" + writable: true diff --git a/finch.yaml.d/mac.yaml b/finch.yaml.d/mac.yaml index 56f80ad35..b173016bd 100644 --- a/finch.yaml.d/mac.yaml +++ b/finch.yaml.d/mac.yaml @@ -7,6 +7,14 @@ provision: - mode: boot script: | modprobe virtiofs + # port this to common.yaml after windows socket forwarding is added + - mode: user + script: | + sudo cp /usr/local/bin/finch-daemon + sudo cp /finch@.service /usr/local/lib/systemd/system/finch@.service + + sudo systemctl daemon-reload + sudo systemctl enable --now finch@${UID} mounts: - location: "~" mountPoint: null @@ -22,9 +30,9 @@ mounts: cache: "fscache" - location: "/tmp/lima" writable: true - - location: "/var/folders" + - location: "/private" writable: true - - location: "/private/var/folders" + - location: "/var/folders" writable: true ssh: @@ -44,3 +52,7 @@ hostResolver: hosts: host.finch.internal: host.lima.internal host.docker.internal: host.lima.internal + +portForwards: +- guestSocket: "/run/finch.sock" + hostSocket: "{{.Dir}}/sock/finch.sock" diff --git a/finch@.service b/finch@.service new file mode 100644 index 000000000..f656b807c --- /dev/null +++ b/finch@.service @@ -0,0 +1,16 @@ +[Unit] +Description=Finch daemon %I +Documentation=https://runfinch.com https://github.com/runfinch/finch-daemon +After=network.target local-fs.target containerd.service buildkit.service + +[Service] +ExecStart=/usr/local/bin/finch-daemon --socket-owner %i +ExecStartPost=-rm -rf /var/run/docker.sock +ExecStartPost=ln -s /run/finch.sock /var/run/docker.sock +Type=notify +Delegate=yes +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/go.mod b/go.mod index 0f34ae351..2bbdb5316 100644 --- a/go.mod +++ b/go.mod @@ -100,6 +100,7 @@ require ( github.com/moby/sys/signal v0.7.1 // indirect github.com/moby/sys/user v0.3.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect diff --git a/go.sum b/go.sum index dcead2350..5a8467dea 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8af github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20231105174938-2b5cbb29f3e2 h1:dIScnXFlF784X79oi7MzVT6GWqr/W1uUt0pB5CsDs9M= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20231105174938-2b5cbb29f3e2/go.mod h1:gCLVsLfv1egrcZu+GoJATN5ts75F2s62ih/457eWzOw= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -26,6 +28,8 @@ github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0 github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/braydonk/yaml v0.7.0 h1:ySkqO7r0MGoCNhiRJqE0Xe9yhINMyvOAB3nFjgyJn2k= github.com/braydonk/yaml v0.7.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -175,6 +179,8 @@ 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/google/yamlfmt v0.15.0 h1:8VqeHp87EEyfAeCTp3QpV/8bnhDh04jKN6EeifiTM70= github.com/google/yamlfmt v0.15.0/go.mod h1:MPmHSVetV8ofpKmeiEZAh2p4jbDapC+FNqilNN7JQVk= +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= @@ -238,6 +244,10 @@ github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= @@ -384,6 +394,10 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuH go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= @@ -392,6 +406,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= 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= @@ -478,6 +494,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -500,6 +518,9 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI= google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=