From 1f90d7e5b9324ffbd2782831116b9a7817d0e781 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 01:21:40 +0000 Subject: [PATCH 01/12] chore(deps-dev): bump vite from 4.5.1 to 4.5.3 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.1 to 4.5.3. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v4.5.3/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v4.5.3/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- test/e2e/webui/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ebb725f..bd11dae3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5406,9 +5406,9 @@ } }, "node_modules/vite": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", - "integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -6018,7 +6018,7 @@ "viem": "^1.19.9" }, "devDependencies": { - "vite": "^4.4.5" + "vite": "^4.5.3" } } } diff --git a/test/e2e/webui/package.json b/test/e2e/webui/package.json index 16672d28..8abc9f0c 100644 --- a/test/e2e/webui/package.json +++ b/test/e2e/webui/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^4.4.5" + "vite": "^4.5.3" }, "dependencies": { "viem": "^1.19.9" From d1df026002e08898a42afcb3502560098b577e2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:09:00 +0000 Subject: [PATCH 02/12] chore(deps): bump ws Bumps and [ws](https://github.com/websockets/ws). These dependencies needed to be updated together. Updates `ws` from 6.2.2 to 8.17.1 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/6.2.2...8.17.1) Updates `ws` from 7.5.9 to 8.17.1 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/6.2.2...8.17.1) Updates `ws` from 8.16.0 to 8.17.1 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/6.2.2...8.17.1) Updates `ws` from 8.17.0 to 8.17.1 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/6.2.2...8.17.1) --- updated-dependencies: - dependency-name: ws dependency-type: indirect - dependency-name: ws dependency-type: indirect - dependency-name: ws dependency-type: indirect - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 67 +++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 49 deletions(-) diff --git a/package-lock.json b/package-lock.json index 017e8016..b6cf2629 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3770,26 +3770,6 @@ "ws": "^8.17.0" } }, - "node_modules/@libp2p/websockets/node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@libp2p/webtransport": { "version": "4.0.32", "resolved": "https://registry.npmjs.org/@libp2p/webtransport/-/webtransport-4.0.32.tgz", @@ -4784,9 +4764,9 @@ } }, "node_modules/@react-native-community/cli-server-api/node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", "peer": true, "dependencies": { "async-limiter": "~1.0.0" @@ -5514,9 +5494,9 @@ } }, "node_modules/@react-native/dev-middleware/node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", "peer": true, "dependencies": { "async-limiter": "~1.0.0" @@ -5906,17 +5886,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@scure/bip39": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", @@ -11778,9 +11747,9 @@ } }, "node_modules/metro/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "peer": true, "engines": { "node": ">=8.3.0" @@ -13106,9 +13075,9 @@ } }, "node_modules/react-devtools-core/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "peer": true, "engines": { "node": ">=8.3.0" @@ -13217,9 +13186,9 @@ } }, "node_modules/react-native/node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", "peer": true, "dependencies": { "async-limiter": "~1.0.0" @@ -15553,9 +15522,9 @@ } }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, From 017231da3f5600afd78e383434eaea09f62e0431 Mon Sep 17 00:00:00 2001 From: revoltez Date: Mon, 15 Jul 2024 15:58:21 +0100 Subject: [PATCH 03/12] feat: create Raft utils & KV store library Added an example on how they could be used as a simple integration test --- go.mod | 111 +++-- go.sum | 433 ++++++++++++++---- pkg/raft/raft.go | 115 +++++ pkg/raft/store.go | 117 +++++ test/integration/{containerd => ipcr}/main.go | 0 .../{containerd => ipcr}/run-test.sh | 0 test/integration/raft/main.go | 132 ++++++ 7 files changed, 787 insertions(+), 121 deletions(-) create mode 100644 pkg/raft/raft.go create mode 100644 pkg/raft/store.go rename test/integration/{containerd => ipcr}/main.go (100%) rename test/integration/{containerd => ipcr}/run-test.sh (100%) create mode 100644 test/integration/raft/main.go diff --git a/go.mod b/go.mod index f41e5ca0..03a72478 100644 --- a/go.mod +++ b/go.mod @@ -12,21 +12,25 @@ require ( github.com/containers/ocicrypt v1.1.9 github.com/ethereum/go-ethereum v1.13.15 github.com/go-jose/go-jose/v3 v3.0.3 - github.com/gorilla/websocket v1.5.1 + github.com/gorilla/websocket v1.5.3 + github.com/hashicorp/raft v1.6.1 + github.com/hashicorp/raft-boltdb/v2 v2.3.0 github.com/ipfs/boxo v0.16.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/kubo v0.25.0 github.com/kedacore/http-add-on v0.7.0 - github.com/libp2p/go-libp2p v0.32.2 + github.com/libp2p/go-libp2p v0.35.2 + github.com/libp2p/go-libp2p-consensus v0.0.1 + github.com/libp2p/go-libp2p-raft v0.5.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.12.0 + github.com/multiformats/go-multiaddr v0.12.4 github.com/olekukonko/tablewriter v0.0.5 github.com/opencontainers/image-spec v1.1.0-rc6 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 - golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 - google.golang.org/protobuf v1.33.0 + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 + google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.29.0 k8s.io/apimachinery v0.29.0 @@ -39,17 +43,20 @@ require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/DataDog/zstd v1.4.5 // indirect + github.com/DataDog/zstd v1.5.2 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.12.0-rc.0 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/awslabs/soci-snapshotter v0.4.1 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect github.com/bufbuild/protovalidate-go v0.3.2 // indirect @@ -64,6 +71,7 @@ require ( github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/containerd/accelerated-container-image v1.0.2 // indirect + github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/cgroups/v3 v3.0.3 // indirect github.com/containerd/console v1.0.3 // indirect github.com/containerd/continuity v0.4.3 // indirect @@ -87,8 +95,9 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/djherbis/times v1.5.0 // indirect github.com/docker/cli v25.0.1+incompatible // indirect @@ -97,15 +106,19 @@ require ( github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/elastic/gosigar v0.14.2 // indirect github.com/emicklei/go-restful/v3 v3.11.2 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/evanphx/json-patch/v5 v5.8.1 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/fahedouch/go-logrotate v0.2.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/ferranbt/fastssz v0.1.2 // indirect github.com/fjl/memsize v0.0.2 // indirect github.com/fluent/fluent-logger-golang v1.9.0 // indirect + github.com/flynn/noise v1.1.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect @@ -116,6 +129,7 @@ require ( github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/swag v0.22.7 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -128,11 +142,15 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/gopacket v1.1.19 // indirect + github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect github.com/google/uuid v1.5.0 // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -161,29 +179,39 @@ require ( github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect + github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect + github.com/libp2p/go-reuseport v0.4.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/miekg/dns v1.1.57 // indirect + github.com/miekg/dns v1.1.58 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect @@ -203,27 +231,50 @@ require ( github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect - github.com/philhofer/fwd v1.1.1 // indirect + github.com/philhofer/fwd v1.1.2 // indirect + github.com/pion/datachannel v1.5.6 // indirect + github.com/pion/dtls/v2 v2.2.11 // indirect + github.com/pion/ice/v2 v2.3.25 // indirect + github.com/pion/interceptor v0.1.29 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/mdns v0.0.12 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.14 // indirect + github.com/pion/rtp v1.8.6 // indirect + github.com/pion/sctp v1.8.16 // indirect + github.com/pion/sdp/v3 v3.0.9 // indirect + github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/turn/v2 v2.1.6 // indirect + github.com/pion/webrtc/v3 v3.2.40 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/quic-go v0.44.0 // indirect + github.com/quic-go/webtransport-go v0.8.0 // indirect + github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/rootless-containers/bypass4netns v0.4.0 // indirect @@ -240,16 +291,18 @@ require ( github.com/status-im/keycard-go v0.2.0 // indirect github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tidwall/gjson v1.17.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect - github.com/tinylib/msgp v1.1.6 // indirect + github.com/tinylib/msgp v1.1.8 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect github.com/urfave/cli/v2 v2.25.7 // indirect github.com/vbatts/tar-split v0.11.5 // indirect github.com/vishvananda/netlink v1.2.1-beta.2 // indirect @@ -258,6 +311,7 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yuchanns/srslog v1.1.0 // indirect + go.etcd.io/bbolt v1.3.7 // indirect go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect @@ -265,19 +319,22 @@ require ( go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.22.1 // indirect + go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.21.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect @@ -292,7 +349,7 @@ require ( k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 // indirect k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect - lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/blake3 v1.2.2 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/go.sum b/go.sum index de82f480..c01b03a2 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,9 @@ bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc/go.mod h1:FbcW6z/2VytnFDhZfumh buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230914171853-63dfe56cc2c4.1 h1:2gmp+PRca1fqQHf/WMKOgu9inVb0R0N07TucgY3QZCQ= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230914171853-63dfe56cc2c4.1/go.mod h1:xafc+XIsTxTy76GJQ1TKgvJWsSugFBqMaN27WhUblew= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= @@ -41,7 +43,12 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= connectrpc.com/connect v1.14.0 h1:PDS+J7uoz5Oui2VEOMcfz6Qft7opQM9hPiKvtGC01pA= connectrpc.com/connect v1.14.0/go.mod h1:uoAq5bmhhn43TwhaKdGKN/bZcGtzPW1v+ngDTn5u+8s= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA= @@ -57,8 +64,9 @@ github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= @@ -75,21 +83,31 @@ github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9 github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/awslabs/soci-snapshotter v0.4.1 h1:f1TdTG5QZ1B6umgSPQfM1pSXDlMZu+raCKWP4QkRYL8= github.com/awslabs/soci-snapshotter v0.4.1/go.mod h1:faOXa3a6SsMRln4misZi82nAa4ez8Nu9i5N39kQyukY= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +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= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= @@ -98,6 +116,9 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM= @@ -106,6 +127,7 @@ github.com/bufbuild/protovalidate-go v0.3.2 h1:7sG1R83PkCzOZb3P187gAchWFLHY6LQ8a github.com/bufbuild/protovalidate-go v0.3.2/go.mod h1:ywZqKUjMhQA8fmhsc+0DUlMfan8/umJ+5mKvjdxAD3M= github.com/bufbuild/protoyaml-go v0.1.4 h1:wPSKIb/DkHwUK71Dqw5cUkLpohWD7JY+TeLBbrlN8nM= github.com/bufbuild/protoyaml-go v0.1.4/go.mod h1:6G7eGacFmps/ilH7uyfjv18HQ74Feri8I5dZi7XMs1o= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -115,13 +137,17 @@ github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y= github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= 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= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -149,6 +175,7 @@ github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJ github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/containerd/accelerated-container-image v1.0.2 h1:4GmZg/8TrxAbTTpighuipeFPrjqH1ZKZgoa4bggMZVs= github.com/containerd/accelerated-container-image v1.0.2/go.mod h1:0/cMmA65Zervb+pO+sZvxvhqiO/pWoKdTf2zgbh59Zo= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= @@ -197,10 +224,13 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= @@ -226,8 +256,8 @@ github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6 github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/deepmap/oapi-codegen v1.6.0 h1:w/d1ntwh91XI0b/8ja7+u5SvA4IFfM0UNNLmiDR1gg0= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -249,12 +279,14 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= 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/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/emicklei/go-restful/v3 v3.11.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU= @@ -279,6 +311,9 @@ github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:Jp github.com/fahedouch/go-logrotate v0.2.0 h1:UR9Fv8MDVfWwnkirmFHck+tRSWzqOwRjVRLMpQgSxaI= github.com/fahedouch/go-logrotate v0.2.0/go.mod h1:1RL/yr7LntS4zadAC6FT6yB/C1CQt3V6eHAZzymfwzE= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -289,8 +324,9 @@ github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7 github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/fluent/fluent-logger-golang v1.9.0 h1:zUdY44CHX2oIUc7VTNZc+4m+ORuO/mldQDA7czhWXEg= github.com/fluent/fluent-logger-golang v1.9.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -311,6 +347,7 @@ github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -321,6 +358,10 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= @@ -341,6 +382,7 @@ github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHa github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -348,12 +390,14 @@ github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaL github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -367,6 +411,7 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -417,6 +462,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -437,14 +483,17 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -453,10 +502,12 @@ github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRid github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -464,8 +515,22 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= +github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= 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/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -475,6 +540,12 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/raft v1.6.1 h1:v/jm5fcYHvVkL0akByAp+IDdDSzCNCGhdO6VdB56HIM= +github.com/hashicorp/raft v1.6.1/go.mod h1:N1sKh6Vn47mrWvEArQgILTyng8GoDRNYlgKyK7PMjs0= +github.com/hashicorp/raft-boltdb v0.0.0-20230125174641-2a8082862702 h1:RLKEcCuKcZ+qp2VlaaZsYZfLOmIiuJNpEi48Rl8u9cQ= +github.com/hashicorp/raft-boltdb v0.0.0-20230125174641-2a8082862702/go.mod h1:nTakvJ4XYq45UXtn0DbwR4aU9ZdjlnIenpbs6Cd+FM0= +github.com/hashicorp/raft-boltdb/v2 v2.3.0 h1:fPpQR1iGEVYjZ2OELvUHX600VAK5qmdnDEv3eXOwZUA= +github.com/hashicorp/raft-boltdb/v2 v2.3.0/go.mod h1:YHukhB04ChJsLHLJEUD6vjFyLX2L3dsX3wPBZcX4tmc= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= @@ -586,9 +657,11 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= 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= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -598,6 +671,7 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= @@ -610,19 +684,23 @@ 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.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/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/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +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/pty v1.1.3/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= @@ -641,10 +719,14 @@ github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+ github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= -github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p v0.35.2 h1:287oHbuplkrLdAF+syB0n/qDgd50AUBtEODqS0e0HDs= +github.com/libp2p/go-libp2p v0.35.2/go.mod h1:RKCDNt30IkFipGL0tl8wQW/3zVWEGFUZo8g2gAKxwjU= +github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= +github.com/libp2p/go-libp2p-consensus v0.0.1 h1:jcVbHRZLwTXU9iT/mPi+Lx4/OrIzq3bU1TbZNhYFCV8= +github.com/libp2p/go-libp2p-consensus v0.0.1/go.mod h1:+9Wrfhc5QOqWB0gXI0m6ARlkHfdJpcFXmRU0WoHz4Mo= +github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU= +github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= @@ -653,6 +735,8 @@ github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= +github.com/libp2p/go-libp2p-raft v0.5.0 h1:WvOYD1feqnGHVoUVVaEUmXJntvm97ClQjaLZ0eZdJrQ= +github.com/libp2p/go-libp2p-raft v0.5.0/go.mod h1:vsYlHmXR6F4U05gIu+DLMT/SzMGWdkPkfkO2q4J+9Ho= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= @@ -673,9 +757,11 @@ github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCy github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -686,6 +772,8 @@ github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIG github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 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.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -702,14 +790,18 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= +github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= @@ -748,6 +840,7 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -762,9 +855,10 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= -github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= +github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= +github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -785,12 +879,16 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= 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/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -813,15 +911,18 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= github.com/opencontainers/image-spec v1.1.0-rc6/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -833,43 +934,56 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= +github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= -github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= -github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= +github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= -github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= -github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= -github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= +github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= +github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= +github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= -github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= +github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= -github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= -github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= -github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= -github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= -github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= -github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= -github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= -github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= -github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= -github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= -github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= +github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= +github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= +github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= +github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= +github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= -github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= -github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= -github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= +github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= +github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= +github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= +github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= +github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= +github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -878,25 +992,37 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +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.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +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.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/client_model v0.2.0/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.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +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.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw= github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= -github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= -github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= -github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= +github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= +github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= +github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -921,10 +1047,35 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -934,6 +1085,8 @@ github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -961,44 +1114,54 @@ github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= -github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= +github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= @@ -1010,6 +1173,8 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs= github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= @@ -1049,8 +1214,11 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak= go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1087,11 +1255,11 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= +go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= +go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1101,27 +1269,39 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1132,10 +1312,11 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= -golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1159,21 +1340,27 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1206,12 +1393,21 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1222,6 +1418,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1235,15 +1432,21 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1262,6 +1465,7 @@ golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1274,6 +1478,7 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1295,29 +1500,43 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/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.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1328,10 +1547,15 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1339,7 +1563,9 @@ golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1387,7 +1613,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1398,9 +1623,10 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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= @@ -1412,6 +1638,9 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1432,6 +1661,8 @@ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1442,6 +1673,10 @@ google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAs google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1484,6 +1719,9 @@ google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1516,8 +1754,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1538,8 +1777,10 @@ gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -1551,6 +1792,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1572,8 +1815,8 @@ k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 h1:avRdiaB03v88Mfvum2S3BB k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022/go.mod h1:sIV51WBTkZrlGOJMCDZDA1IaPBUDTulPpD4y7oe038k= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= +lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= @@ -1587,3 +1830,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+s sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/pkg/raft/raft.go b/pkg/raft/raft.go new file mode 100644 index 00000000..f491230b --- /dev/null +++ b/pkg/raft/raft.go @@ -0,0 +1,115 @@ +package raft + +import ( + "fmt" + "io" + "path/filepath" + "time" + + "github.com/hashicorp/raft" + raftboltdb "github.com/hashicorp/raft-boltdb/v2" + "github.com/libp2p/go-libp2p" + raftp2p "github.com/libp2p/go-libp2p-raft" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peerstore" +) + +const ( + SNAPSHOT_RETAIN = 3 + RAFT_TIMEOUT = 10 * time.Second +) + +type TestState struct { + Value int +} + +type RaftNode struct { + Raft *raft.Raft + Consensus *raftp2p.Consensus + Actor *raftp2p.Actor + Transport *raft.NetworkTransport + Config raft.Config + Snapshots raft.SnapshotStore + StableStore raft.StableStore + LogStore raft.LogStore +} + +func NewRaftNode(host host.Host, peers []*host.Host, raftDir *string) (*RaftNode, error) { + for _, peerPtr := range peers { + peer := *peerPtr + if peer.Addrs()[0].String() != host.Addrs()[0].String() { + host.Peerstore().AddAddrs(peer.ID(), peer.Addrs(), peerstore.PermanentAddrTTL) + } + } + + transport, err := raftp2p.NewLibp2pTransport(host, time.Minute) + if err != nil { + return nil, fmt.Errorf("Failed creating transport:%s", err) + } + + config := raft.DefaultConfig() + config.LogOutput = io.Discard + config.Logger = nil + config.LocalID = raft.ServerID(host.ID().String()) + + raftNode := RaftNode{ + Transport: transport, + } + + if raftDir == nil { + raftNode.LogStore = raft.NewInmemStore() + raftNode.StableStore = raft.NewInmemStore() + raftNode.Snapshots = raft.NewInmemSnapshotStore() + } else { + boltDB, err := raftboltdb.New(raftboltdb.Options{ + Path: filepath.Join(*raftDir, "raft.db"), + }) + if err != nil { + return nil, fmt.Errorf("new bolt store: %s", err) + } + raftNode.LogStore = boltDB + raftNode.StableStore = boltDB + raftNode.Snapshots, err = raft.NewFileSnapshotStore(filepath.Join(*raftDir, "raft_snapshots"), SNAPSHOT_RETAIN, nil) + if err != nil { + return nil, fmt.Errorf("Failed creating file snapshot store") + } + } + servers := make([]raft.Server, 0) + for _, peerPtr := range peers { + peer := *peerPtr + servers = append(servers, raft.Server{ + Suffrage: raft.Voter, + ID: raft.ServerID(peer.ID().String()), + Address: raft.ServerAddress(peer.ID().String()), + }) + } + serversCfg := raft.Configuration{Servers: servers} + + // initializes a server's storage with the given cluster configuration, + err = raft.BootstrapCluster(config, raftNode.LogStore, raftNode.StableStore, raftNode.Snapshots, raftNode.Transport, serversCfg.Clone()) + if err != nil { + return nil, fmt.Errorf("Failed bootstraping cluster:%v", err) + } + raftNode.Config = *config + return &raftNode, nil +} + +func (node *RaftNode) StartNode(c *raftp2p.Consensus) error { + node.Consensus = c + instance, err := raft.NewRaft(&node.Config, node.Consensus.FSM(), node.LogStore, node.StableStore, node.Snapshots, node.Transport) + if err != nil { + return fmt.Errorf("Failed creating Raft instance:%v", err) + } + node.Raft = instance + node.Actor = raftp2p.NewActor(node.Raft) + node.Consensus.SetActor(node.Actor) + return nil +} + +func NewPeer(multiaddr string) (host.Host, error) { + h, err := libp2p.New(libp2p.ListenAddrStrings(multiaddr)) + if err != nil { + return nil, err + } + return h, nil +} diff --git a/pkg/raft/store.go b/pkg/raft/store.go new file mode 100644 index 00000000..d347eefb --- /dev/null +++ b/pkg/raft/store.go @@ -0,0 +1,117 @@ +package raft + +import ( + "fmt" + "sync" + + "github.com/hashicorp/raft" + consensus "github.com/libp2p/go-libp2p-consensus" + raftp2p "github.com/libp2p/go-libp2p-raft" +) + +// Data is exported because it needs to be serialized +type KVStore struct { + Data map[string]string + mu sync.Mutex + node *RaftNode +} + +// all fields must be public otherwise raft will dismiss them in (de)serilization +type KVOperation struct { + Op string + Key string + Value string +} + +func NewKVStore(node *RaftNode) (*KVStore, error) { + store := KVStore{Data: make(map[string]string), node: node} + // c := raftp2p.NewConsensus(&KVStore{}) + c := raftp2p.NewOpLog(&store, &KVOperation{}) + err := node.StartNode(c) + if err != nil { + return nil, err + } + return &store, nil +} + +func (s *KVOperation) ApplyTo(state consensus.State) (consensus.State, error) { + // get the underlying store + store := state.(*KVStore) + switch s.Op { + case "set": + err := store.applySet(s.Key, s.Value) + if err != nil { + return store, err + } + return store, nil + case "delete": + err := store.applyDelete(s.Key) + if err != nil { + return store, err + } + return store, nil + default: + return s, fmt.Errorf("unrecognized command op: %s", s.Op) + } +} + +// Get returns the value for the given key. +func (s *KVStore) Get(key string) (string, error) { + s.mu.Lock() + defer s.mu.Unlock() + return s.Data[key], nil +} + +func (s *KVStore) Set(key, value string) error { + if s.node.Raft.State() != raft.Leader { + return &NotLeaderError{} + } + + op := KVOperation{ + Op: "set", + Key: key, + Value: value, + } + _, err := s.node.Consensus.CommitOp(&op) + if err != nil { + return err + } + return nil +} + +// Delete deletes the given key. +func (s *KVStore) Delete(key string) error { + if s.node.Raft.State() != raft.Leader { + return &NotLeaderError{} + } + op := KVOperation{ + Op: "delete", + Key: key, + } + _, err := s.node.Consensus.CommitOp(&op) + if err != nil { + return err + } + return nil +} + +func (store *KVStore) applySet(key, value string) error { + store.mu.Lock() + defer store.mu.Unlock() + store.Data[key] = value + return nil +} + +func (store *KVStore) applyDelete(key string) error { + store.mu.Lock() + defer store.mu.Unlock() + delete(store.Data, key) + return nil +} + +type NotLeaderError struct{} + +// Implement the Error method for NotLeaderError +func (e *NotLeaderError) Error() string { + return "Not leader" +} diff --git a/test/integration/containerd/main.go b/test/integration/ipcr/main.go similarity index 100% rename from test/integration/containerd/main.go rename to test/integration/ipcr/main.go diff --git a/test/integration/containerd/run-test.sh b/test/integration/ipcr/run-test.sh similarity index 100% rename from test/integration/containerd/run-test.sh rename to test/integration/ipcr/run-test.sh diff --git a/test/integration/raft/main.go b/test/integration/raft/main.go new file mode 100644 index 00000000..830fe018 --- /dev/null +++ b/test/integration/raft/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "fmt" + "time" + + "github.com/comrade-coop/apocryph/pkg/raft" + "github.com/libp2p/go-libp2p/core/host" +) + +func main() { + + peer1, _ := raft.NewPeer("/ip4/127.0.0.1/tcp/9997") + fmt.Printf("Node ID:%s \n", peer1.ID().String()) + peer2, _ := raft.NewPeer("/ip4/127.0.0.1/tcp/9998") + fmt.Printf("Node ID:%s \n", peer2.ID().String()) + peer3, _ := raft.NewPeer("/ip4/127.0.0.1/tcp/9999") + fmt.Printf("Node ID:%s \n", peer3.ID().String()) + + defer peer1.Close() + defer peer2.Close() + defer peer3.Close() + + peers := []*host.Host{&peer1, &peer2, &peer3} + node1, err := raft.NewRaftNode(peer1, peers, nil) + if err != nil { + fmt.Printf("Error:%s", err) + return + } + node2, err := raft.NewRaftNode(peer2, peers, nil) + if err != nil { + fmt.Printf("Error:%s", err) + return + } + node3, err := raft.NewRaftNode(peer3, peers, nil) + if err != nil { + fmt.Printf("Error:%s", err) + return + } + // create the kv stores + store1, _ := raft.NewKVStore(node1) + store2, _ := raft.NewKVStore(node2) + store3, _ := raft.NewKVStore(node3) + + fmt.Println("Waiting for leader election") + // Provide some time for leader election + time.Sleep(5 * time.Second) + + domain := "www.webapp.com" + fmt.Printf("Trying to set the key:%v with node1\n", domain) + err = store1.Set(domain, "/ip4/127.0.0.1/tcp/9997") + if err != nil { + if _, ok := err.(*raft.NotLeaderError); ok { + fmt.Println("Node1 not a leader: Trying to Set with node2") + err = store2.Set(domain, "/ip4/127.0.0.1/tcp/9998") + if _, ok := err.(*raft.NotLeaderError); ok { + fmt.Println("Node2 not a leader: Trying to Set with node3") + err = store3.Set(domain, "/ip4/127.0.0.1/tcp/9999") + if err != nil { + panic(err) + } + } else { + panic(err) + } + } else { + panic(err) + } + } + + fmt.Println("Waiting for updates...") + time.Sleep(5 * time.Second) + + value, _ := store1.Get(domain) + value2, _ := store2.Get(domain) + value3, _ := store3.Get(domain) + + fmt.Printf("Store1 domain value:%v\n", value) + fmt.Printf("Store2 domain value:%v\n", value2) + fmt.Printf("Store3 domain value:%v\n", value3) + + fmt.Printf("Deleting key:%v from the store...\n", domain) + err = store1.Delete(domain) + if err != nil { + if _, ok := err.(*raft.NotLeaderError); ok { + fmt.Println("Node1 not a leader: Trying to Delete with node2") + err = store2.Delete(domain) + if _, ok := err.(*raft.NotLeaderError); ok { + fmt.Println("Node2 not a leader: Trying to Delete with node3") + err = store3.Delete(domain) + if err != nil { + panic(err) + } + } else { + panic(err) + } + } else { + panic(err) + } + } + + fmt.Println("Waiting for updates...") + time.Sleep(5 * time.Second) + + // Final states + finalState1, err := node1.Consensus.GetCurrentState() + if err != nil { + fmt.Println(err) + return + } + finalState2, err := node2.Consensus.GetCurrentState() + if err != nil { + fmt.Println(err) + return + } + finalState3, err := node3.Consensus.GetCurrentState() + if err != nil { + fmt.Println(err) + return + } + finalRaftState1 := finalState1.(*raft.KVStore) + finalRaftState2 := finalState2.(*raft.KVStore) + finalRaftState3 := finalState3.(*raft.KVStore) + + fmt.Printf("Raft1 final state: %v\n", finalRaftState1) + fmt.Printf("Raft2 final state: %v\n", finalRaftState2) + fmt.Printf("Raft3 final state: %v\n", finalRaftState3) + + node1.Raft.Shutdown().Error() + node2.Raft.Shutdown().Error() + node3.Raft.Shutdown().Error() + +} From 6c4255fea16540a781710cf77cf3ba13f2e221b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:08:05 +0000 Subject: [PATCH 04/12] chore(deps): bump braces from 3.0.2 to 3.0.3 Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 017e8016..cf5f9219 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5906,17 +5906,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@scure/bip39": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", @@ -7444,11 +7433,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -9265,9 +9254,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, From 47a529ddc7db8257283ffeff6ad9eacda692296e Mon Sep 17 00:00:00 2001 From: revoltez Date: Wed, 17 Jul 2024 20:55:19 +0100 Subject: [PATCH 05/12] wip: create autoscaler cli as simple kv store & prepare 3 dev clusters the kvstore will eventually become the autoscaler so might as well create it as a cli app --- Dockerfile | 15 +++ cmd/autoscaler/main.go | 23 ++++ cmd/autoscaler/root.go | 24 ++++ cmd/autoscaler/start.go | 111 +++++++++++++++++++ cmd/tpodserver/registry.go | 2 + pkg/raft/raft.go | 10 +- test/e2e/autoscaler/deploy.sh | 79 +++++++++++++ test/e2e/autoscaler/manifest-autoscaler.yaml | 16 +++ test/e2e/autoscaler/run-test.sh | 111 +++++++++++++++++++ test/e2e/minikube/helmfile.yaml | 2 +- test/integration/raft/main.go | 12 +- 11 files changed, 396 insertions(+), 9 deletions(-) create mode 100644 cmd/autoscaler/main.go create mode 100644 cmd/autoscaler/root.go create mode 100644 cmd/autoscaler/start.go create mode 100755 test/e2e/autoscaler/deploy.sh create mode 100644 test/e2e/autoscaler/manifest-autoscaler.yaml create mode 100755 test/e2e/autoscaler/run-test.sh diff --git a/Dockerfile b/Dockerfile index c335dc69..f4e2a6be 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,3 +46,18 @@ FROM run-common as server COPY --from=build-server /usr/local/bin/tpodserver /usr/local/bin/tpodserver ENTRYPOINT ["tpodserver"] + +## autoscaler: ## + +FROM build-common as build-autoscaler + +COPY cmd/autoscaler ./cmd/autoscaler +RUN --mount=type=cache,target=/root/.cache/go-build go build -v -o /usr/local/bin/autoscaler ./cmd/autoscaler + +FROM run-common as autoscaler + +COPY --from=build-autoscaler /usr/local/bin/autoscaler /usr/local/bin/autoscaler + +ENTRYPOINT ["autoscaler"] + + diff --git a/cmd/autoscaler/main.go b/cmd/autoscaler/main.go new file mode 100644 index 00000000..fb85dc4c --- /dev/null +++ b/cmd/autoscaler/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "context" + "os" + "os/signal" +) + +func main() { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + interruptChan := make(chan os.Signal, 1) + signal.Notify(interruptChan, os.Interrupt) + + go func() { + <-interruptChan + cancel() + }() + + if err := rootCmd.ExecuteContext(ctx); err != nil { + os.Exit(1) + } +} diff --git a/cmd/autoscaler/root.go b/cmd/autoscaler/root.go new file mode 100644 index 00000000..f507e0d8 --- /dev/null +++ b/cmd/autoscaler/root.go @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 + +package main + +import ( + "github.com/spf13/cobra" +) + +const ( + keystorePath string = "/tmp/keystore" +) + +var rootCmd = &cobra.Command{ + Use: "Autonomous Autoscaler", + Short: "Autoscaler is autonomous application offering service discovery and fault-tolerance of applications accross Apocryph network", + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return nil + }, + SilenceUsage: true, +} + +func init() { + rootCmd.AddCommand(startCmd) +} diff --git a/cmd/autoscaler/start.go b/cmd/autoscaler/start.go new file mode 100644 index 00000000..d4961cbf --- /dev/null +++ b/cmd/autoscaler/start.go @@ -0,0 +1,111 @@ +package main + +import ( + "context" + "fmt" + "log" + "time" + + tpraft "github.com/comrade-coop/apocryph/pkg/raft" + "github.com/hashicorp/raft" + "github.com/libp2p/go-libp2p/core/host" + "github.com/spf13/cobra" +) + +var peersMultiAddr []string +var port uint16 +var raftPath string +var appDomain string +var gateway string + +var startCmd = &cobra.Command{ + Use: "start", + Short: "Start the autonomous autoscaler", + RunE: func(cmd *cobra.Command, args []string) error { + log.Println("Forming a Raft Cluster with the following peers:", peersMultiAddr) + + self, _ := tpraft.NewPeer(fmt.Sprintf("/ip4/0.0.0.0/tcp/%v", port)) + var peers []*host.Host + for _, addr := range peersMultiAddr { + peer, _ := tpraft.NewPeer(addr) + peers = append(peers, &peer) + log.Printf("Peer %s ID:%s \n", addr, peer.ID().String()) + } + + node, err := tpraft.NewRaftNode(self, peers, raftPath) + if err != nil { + return fmt.Errorf("Failed creating Raft node: %s", err) + } + + // create the KVStore + store, err := tpraft.NewKVStore(node) + + log.Println("Waiting for leader election") + time.Sleep(5 * time.Second) + + setKey := func() { + if node.Raft.State() == raft.Leader { + log.Println("Setting the domain value to the current apocryph node gateway") + err := store.Set(appDomain, fmt.Sprintf("%v", gateway)) + // leadership could be changed right before setting the value + if _, ok := err.(*tpraft.NotLeaderError); ok { + newLeaderAddr, newLeaderID := node.Raft.LeaderWithID() + log.Printf("Leadership changed to %v:%v", newLeaderAddr, newLeaderID) + } else { + log.Printf("Failed setting key:%v: %v\n", appDomain, err) + } + } + } + + // print the new state whenever it changes + printNewState := func() { + for range node.Consensus.Subscribe() { + newState, err := node.Consensus.GetCurrentState() + if err != nil { + log.Printf("Failed getting current state %v", err) + } + log.Printf("State Changed, New State: %v", newState) + } + } + + // using Raft.leaderCh() wont help because it works does not work with + // first leader, therefore from the docs, this is the way to detect the new leader + obsCh := make(chan raft.Observation, 1) + observer := raft.NewObserver(obsCh, false, nil) + node.Raft.RegisterObserver(observer) + defer node.Raft.DeregisterObserver(observer) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + ticker := time.NewTicker(time.Second / 2) + defer ticker.Stop() + for { + select { + case obs := <-obsCh: + switch obs.Data.(type) { + case raft.RaftState: + if leaderAddr, _ := node.Raft.LeaderWithID(); leaderAddr != "" { + setKey() + printNewState() + } + } + case <-ticker.C: + if leaderAddr, _ := node.Raft.LeaderWithID(); leaderAddr != "" { + setKey() + printNewState() + } + case <-ctx.Done(): + fmt.Println("timed out waiting for Leader") + return nil + } + } + }, +} + +func init() { + startCmd.Flags().StringSliceVarP(&peersMultiAddr, "peers", "p", []string{}, "List of peers multiaddresses that the autoscaler will use to redeploy your application in case of a failure") + startCmd.Flags().Uint16Var(&port, "port", 9999, "port number for this node") + startCmd.Flags().StringVar(&raftPath, "path", "", "path where raft will save it's state (Default is In Memory)") + startCmd.Flags().StringVar(&appDomain, "doamin", "www.apocryph.com", "the application domain name") + startCmd.Flags().StringVar(&gateway, "gateway", "127.0.0.1", "Apocryph node Gateway") +} diff --git a/cmd/tpodserver/registry.go b/cmd/tpodserver/registry.go index 0421eb2d..39c57fb6 100644 --- a/cmd/tpodserver/registry.go +++ b/cmd/tpodserver/registry.go @@ -199,6 +199,8 @@ var registerCmd = &cobra.Command{ }, } +// automatically injects current ipfs peer id in the multiaddrs field from the +// config file provided, the peerID is needed for p2p connection over ipfs func getHostInfo(ctx context.Context, ipfs *rpc.HttpApi) (*pb.HostInfo, error) { if hostInfoContents == "" { return nil, fmt.Errorf("Empty host info") diff --git a/pkg/raft/raft.go b/pkg/raft/raft.go index f491230b..7ffa6a60 100644 --- a/pkg/raft/raft.go +++ b/pkg/raft/raft.go @@ -34,7 +34,7 @@ type RaftNode struct { LogStore raft.LogStore } -func NewRaftNode(host host.Host, peers []*host.Host, raftDir *string) (*RaftNode, error) { +func NewRaftNode(host host.Host, peers []*host.Host, raftDir string) (*RaftNode, error) { for _, peerPtr := range peers { peer := *peerPtr if peer.Addrs()[0].String() != host.Addrs()[0].String() { @@ -56,20 +56,20 @@ func NewRaftNode(host host.Host, peers []*host.Host, raftDir *string) (*RaftNode Transport: transport, } - if raftDir == nil { + if raftDir == "" { raftNode.LogStore = raft.NewInmemStore() raftNode.StableStore = raft.NewInmemStore() raftNode.Snapshots = raft.NewInmemSnapshotStore() } else { boltDB, err := raftboltdb.New(raftboltdb.Options{ - Path: filepath.Join(*raftDir, "raft.db"), + Path: filepath.Join(raftDir, "raft.db"), }) if err != nil { return nil, fmt.Errorf("new bolt store: %s", err) } raftNode.LogStore = boltDB raftNode.StableStore = boltDB - raftNode.Snapshots, err = raft.NewFileSnapshotStore(filepath.Join(*raftDir, "raft_snapshots"), SNAPSHOT_RETAIN, nil) + raftNode.Snapshots, err = raft.NewFileSnapshotStore(filepath.Join(raftDir, "raft_snapshots"), SNAPSHOT_RETAIN, nil) if err != nil { return nil, fmt.Errorf("Failed creating file snapshot store") } @@ -88,7 +88,7 @@ func NewRaftNode(host host.Host, peers []*host.Host, raftDir *string) (*RaftNode // initializes a server's storage with the given cluster configuration, err = raft.BootstrapCluster(config, raftNode.LogStore, raftNode.StableStore, raftNode.Snapshots, raftNode.Transport, serversCfg.Clone()) if err != nil { - return nil, fmt.Errorf("Failed bootstraping cluster:%v", err) + return nil, fmt.Errorf("Failed bootstraping cluster: %v", err) } raftNode.Config = *config return &raftNode, nil diff --git a/test/e2e/autoscaler/deploy.sh b/test/e2e/autoscaler/deploy.sh new file mode 100755 index 00000000..4c32342b --- /dev/null +++ b/test/e2e/autoscaler/deploy.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +set -e + +trap 'pkill -f "kubectl port-forward" && kill $(jobs -p) &>/dev/null' EXIT + +if [ "$1" = "teardown" ]; then + minikube delete + + if [ "$2" = "full" ]; then + docker rm --force registry + docker rm --force anvil + rm -r /home/ezio/.apocryph/deployment/ + exit 0 + fi + exit 0 +fi + + +which curl >/dev/null; which jq >/dev/null; which xargs >/dev/null; which sed >/dev/null +which go >/dev/null +which ipfs >/dev/null +which forge &>/dev/null || export PATH=$PATH:~/.bin/foundry +which forge >/dev/null; which cast >/dev/null +which minikube >/dev/null; which helmfile >/dev/null; which helm >/dev/null; which kubectl >/dev/null +which docker >/dev/null + +# based on https://stackoverflow.com/a/31269848 / https://bobcopeland.com/blog/2012/10/goto-in-bash/ +if [ -n "$1" ]; then + STEP=${1:-1} + eval "set -v; $(sed -n "/## $STEP: /{:a;n;p;ba};" $0)" + exit +fi + +echo -e "\e[1;32m---" +echo "Note: To skip steps, use '$0 '" +echo " e.g. to skip ahead to configuring IPFS, run '$0 1.2'" +echo -e "---\e[0m" + + +## 1: Set up the Kubernetes environment ## + +## 1.1: Apply Helm configurations ## + +helmfile sync -f ../minikube/ + +## 1.2: Configure provider/in-cluster IPFS and publisher IPFS ## + +{ while ! kubectl get -n ipfs endpoints ipfs-rpc -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; } + +O_IPFS_PATH=$IPFS_PATH +export IPFS_PATH=$(mktemp ipfs.XXXX --tmpdir -d) + +[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } +echo /ip4/127.0.0.1/tcp/5004 > $IPFS_PATH/api + +SWARM_ADDRESSES=$(minikube service -n ipfs ipfs-swarm --url | head -n 1 | sed -E 's|http://(.+):(.+)|["/ip4/\1/tcp/\2", "/ip4/\1/udp/\2/quic", "/ip4/\1/udp/\2/quic-v1", "/ip4/\1/udp/\2/quic-v1/webtransport"]|') + +PROVIDER_IPFS=$(curl -X POST "http://127.0.0.1:5004/api/v0/id" | jq '.ID' -r); echo $PROVIDER_IPFS + +CONFIG_BEFORE=$(ipfs config Addresses.AppendAnnounce) +ipfs config Addresses.AppendAnnounce --json "$SWARM_ADDRESSES" +CONFIG_AFTER=$(ipfs config Addresses.AppendAnnounce) + +[ "$CONFIG_BEFORE" = "$CONFIG_AFTER" ] || kubectl delete -n ipfs $(kubectl get po -o name -n ipfs) # Restart ipfs daemon + +export IPFS_PATH=$O_IPFS_PATH + +{ while ! kubectl get -n ipfs endpoints ipfs-rpc -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; } + +ipfs id &>/dev/null || ipfs init + +ipfs config --json Experimental.Libp2pStreamMounting true + +[ -n "$IPFS_DAEMON" ] || { IPFS_DAEMON=yes; ipfs daemon & { while ! [ -f ${IPFS_PATH:-~/.ipfs}/api ]; do sleep 0.1; done; } 2>/dev/null; } + +echo "$SWARM_ADDRESSES" | jq -r '.[] + "/p2p/'"$PROVIDER_IPFS"'"' | xargs -n 1 ipfs swarm connect || true + +sleep 1 diff --git a/test/e2e/autoscaler/manifest-autoscaler.yaml b/test/e2e/autoscaler/manifest-autoscaler.yaml new file mode 100644 index 00000000..e27c8872 --- /dev/null +++ b/test/e2e/autoscaler/manifest-autoscaler.yaml @@ -0,0 +1,16 @@ +containers: + - name: autoscaler + image: + url: autoscaler + ports: + - containerPort: '9999' + hostHttpHost: autoscaler.local + name: internal + resourceRequests: + - amountMillis: '10' + resource: cpu + - amount: '100000000' + resource: memory +replicas: + min: 1 + max: 1 diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh new file mode 100755 index 00000000..e9312f0a --- /dev/null +++ b/test/e2e/autoscaler/run-test.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +cd "$(dirname "$0")" + +set -v + +# based on https://stackoverflow.com/a/31269848 / https://bobcopeland.com/blog/2012/10/goto-in-bash/ +if [ -n "$1" ]; then + STEP=${1:-1} + eval "set -v; $(sed -n "/## $STEP: /{:a;n;p;ba};" $0)" + exit +fi + +sudo chmod o+rw /run/containerd/containerd.sock + +## 0: Set up the external environment + +## 0.1: Build/tag server and p2p-helper and autoscaler images + +docker build -t comradecoop/apocryph/server:latest ../../.. --target server + +docker build -t comradecoop/apocryph/p2p-helper:latest ../../.. --target p2p-helper + +docker build -t comradecoop/apocryph/autoscaler:latest ../../.. --target autoscaler + +## 0.2: Create local registry and push server and p2p-helper images + +docker run -d -p 5000:5000 --restart=always --name registry registry:2 || echo "Docker registry already running" + +docker tag comradecoop/apocryph/server:latest localhost:5000/comradecoop/apocryph/server:latest +docker push localhost:5000/comradecoop/apocryph/server:latest + +docker tag comradecoop/apocryph/p2p-helper:latest localhost:5000/comradecoop/apocryph/p2p-helper:latest +docker push localhost:5000/comradecoop/apocryph/p2p-helper:latest + +## 0.3: Set up a local ethereum node and deploy contracts to it + +# (NOTE: Unfortunately, we cannot use a port other than 8545, or otherwise the eth-rpc service will break) +docker run -d -p 8545:8545 --restart=always --name=anvil \ + ghcr.io/foundry-rs/foundry:nightly-619f3c56302b5a665164002cb98263cd9812e4d5 \ + -- 'anvil --host 0.0.0.0 --state /anvil-state.json' 2>/dev/null || { + docker exec anvil ash -c 'kill 1 && rm -f /anvil-state.json' # Reset anvil state +} +sleep 5 + +# deploy the contracts +DEPLOYER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(0\)/ {print $2; exit}') # anvil.accounts[0] +( cd ../../../contracts; forge script script/Deploy.s.sol --private-key "$DEPLOYER_KEY" --rpc-url http://localhost:8545 --broadcast) + +## 1.0 Starting the First Cluster +echo "Starting the first cluster" +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd -p c1 +minikube profile c1 +./deploy.sh + +minikube profile list + +## 1.1: Register the provider in the marketplace +[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } +go run ../../../cmd/tpodserver registry register \ + --config ../common/config.yaml \ + --ipfs /ip4/127.0.0.1/tcp/5004 \ + --ethereum-rpc http://127.0.0.1:8545 \ + --ethereum-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d \ + --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ + --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ + + +## 2.0: Starting the second Cluster +echo "Starting the second cluster" +minikube delete -p c2 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd -p c2 +minikube profile c2 +./deploy.sh + +[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } +go run ../../../cmd/tpodserver registry register \ + --config ../common/config.yaml \ + --ipfs /ip4/127.0.0.1/tcp/5004 \ + --ethereum-rpc http://127.0.0.1:8545 \ + --ethereum-key 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a \ + --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ + --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ + +minikube profile list + + +## 3.0: Starting the third Cluster +echo "Starting the third cluster" +minikube delete -p c3 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd -p c3 +minikube profile c3 +./deploy.sh + +minikube profile list +[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5005:5001 & sleep 0.5; } +go run ../../../cmd/tpodserver registry register \ + --config ../common/config.yaml \ + --ipfs /ip4/127.0.0.1/tcp/5005 \ + --ethereum-rpc http://127.0.0.1:8545 \ + --ethereum-key 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6 \ + --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ + --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ + +kubectl wait --namespace keda --for=condition=available deployment/ingress-nginx-controller +kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-kube-state-metrics +kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-prometheus-pushgateway +kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-server +kubectl wait --namespace eth --for=condition=available deployment/anvil +kubectl wait --namespace ipfs --for=condition=available deployment/ipfs +kubectl wait --namespace trustedpods --for=condition=available deployment/tpodserver diff --git a/test/e2e/minikube/helmfile.yaml b/test/e2e/minikube/helmfile.yaml index 94d03b31..1c0ca16b 100644 --- a/test/e2e/minikube/helmfile.yaml +++ b/test/e2e/minikube/helmfile.yaml @@ -25,7 +25,7 @@ releases: - 'keda' - '--for=condition=available' - 'deployment/ingress-nginx-controller' - - '--timeout=1600s' + - '--timeout=500000s' - name: keda-http-addon namespace: keda chart: kedacore/keda-add-ons-http diff --git a/test/integration/raft/main.go b/test/integration/raft/main.go index 830fe018..eb2c177e 100644 --- a/test/integration/raft/main.go +++ b/test/integration/raft/main.go @@ -22,17 +22,17 @@ func main() { defer peer3.Close() peers := []*host.Host{&peer1, &peer2, &peer3} - node1, err := raft.NewRaftNode(peer1, peers, nil) + node1, err := raft.NewRaftNode(peer1, peers, "") if err != nil { fmt.Printf("Error:%s", err) return } - node2, err := raft.NewRaftNode(peer2, peers, nil) + node2, err := raft.NewRaftNode(peer2, peers, "") if err != nil { fmt.Printf("Error:%s", err) return } - node3, err := raft.NewRaftNode(peer3, peers, nil) + node3, err := raft.NewRaftNode(peer3, peers, "") if err != nil { fmt.Printf("Error:%s", err) return @@ -46,6 +46,12 @@ func main() { // Provide some time for leader election time.Sleep(5 * time.Second) + go func() { + for range node1.Raft.LeaderCh() { + fmt.Println("Leadership changed") + } + }() + domain := "www.webapp.com" fmt.Printf("Trying to set the key:%v with node1\n", domain) err = store1.Set(domain, "/ip4/127.0.0.1/tcp/9997") From fdeb7691f293d4ed0f01db815fcbc38e6305b7b4 Mon Sep 17 00:00:00 2001 From: revoltez Date: Thu, 18 Jul 2024 16:28:47 +0100 Subject: [PATCH 06/12] fix: use kvm2 for the clusters, docker breaks kube-proxy docker driver breaks kube-proxy for new clusters, used to stop the clusters for kube-proxy to avoid CrashLoopBackOff error. using kvm2 fixed it. --- test/e2e/autoscaler/deploy.sh | 3 ++- test/e2e/autoscaler/run-test.sh | 29 +++++++++++-------------- test/e2e/autoscaler/wait-deployments.sh | 8 +++++++ test/e2e/constellation/qemu/run-test.sh | 3 +-- 4 files changed, 24 insertions(+), 19 deletions(-) create mode 100755 test/e2e/autoscaler/wait-deployments.sh diff --git a/test/e2e/autoscaler/deploy.sh b/test/e2e/autoscaler/deploy.sh index 4c32342b..3eb207ea 100755 --- a/test/e2e/autoscaler/deploy.sh +++ b/test/e2e/autoscaler/deploy.sh @@ -42,7 +42,8 @@ echo -e "---\e[0m" ## 1.1: Apply Helm configurations ## -helmfile sync -f ../minikube/ + +helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } ## 1.2: Configure provider/in-cluster IPFS and publisher IPFS ## diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh index e9312f0a..39575155 100755 --- a/test/e2e/autoscaler/run-test.sh +++ b/test/e2e/autoscaler/run-test.sh @@ -49,11 +49,12 @@ DEPLOYER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^ ## 1.0 Starting the First Cluster echo "Starting the first cluster" -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd -p c1 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=kvm2 -p c1 minikube profile c1 ./deploy.sh -minikube profile list +# wait until all the deployments are ready +./wait-deployments.sh ## 1.1: Register the provider in the marketplace [ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } @@ -68,11 +69,13 @@ go run ../../../cmd/tpodserver registry register \ ## 2.0: Starting the second Cluster echo "Starting the second cluster" -minikube delete -p c2 -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd -p c2 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=kvm2 -p c2 minikube profile c2 ./deploy.sh +# wait until all the deployments are ready +./wait-deployments.sh + [ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } go run ../../../cmd/tpodserver registry register \ --config ../common/config.yaml \ @@ -82,17 +85,16 @@ go run ../../../cmd/tpodserver registry register \ --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ -minikube profile list - ## 3.0: Starting the third Cluster echo "Starting the third cluster" -minikube delete -p c3 -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd -p c3 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=kvm2 -p c3 minikube profile c3 ./deploy.sh -minikube profile list +# wait until all the deployments are ready +./wait-deployments.sh + [ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5005:5001 & sleep 0.5; } go run ../../../cmd/tpodserver registry register \ --config ../common/config.yaml \ @@ -102,10 +104,5 @@ go run ../../../cmd/tpodserver registry register \ --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ -kubectl wait --namespace keda --for=condition=available deployment/ingress-nginx-controller -kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-kube-state-metrics -kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-prometheus-pushgateway -kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-server -kubectl wait --namespace eth --for=condition=available deployment/anvil -kubectl wait --namespace ipfs --for=condition=available deployment/ipfs -kubectl wait --namespace trustedpods --for=condition=available deployment/tpodserver + +minikube profile list diff --git a/test/e2e/autoscaler/wait-deployments.sh b/test/e2e/autoscaler/wait-deployments.sh new file mode 100755 index 00000000..22cf0951 --- /dev/null +++ b/test/e2e/autoscaler/wait-deployments.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +kubectl wait --namespace keda --for=condition=available deployment/ingress-nginx-controller +kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-kube-state-metrics +kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-prometheus-pushgateway +kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-server +kubectl wait --namespace ipfs --for=condition=available StatefulSet/ipfs +kubectl wait --namespace trustedpods --for=condition=available deployment/tpodserver diff --git a/test/e2e/constellation/qemu/run-test.sh b/test/e2e/constellation/qemu/run-test.sh index 2a01dbe4..c4946dcd 100755 --- a/test/e2e/constellation/qemu/run-test.sh +++ b/test/e2e/constellation/qemu/run-test.sh @@ -37,8 +37,7 @@ kubectl wait --namespace keda --for=condition=available deployment/ingress-nginx kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-kube-state-metrics kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-prometheus-pushgateway kubectl wait --namespace prometheus --for=condition=available deployment/prometheus-server -kubectl wait --namespace eth --for=condition=available deployment/anvil -kubectl wait --namespace ipfs --for=condition=available deployment/ipfs +kubectl wait --namespace ipfs --for=condition=available StatefulSet/ipfs kubectl wait --namespace trustedpods --for=condition=available deployment/tpodserver ## 2: Deploy sample App From cf4493254336a360fed57353f608aba564e06d3f Mon Sep 17 00:00:00 2001 From: revoltez Date: Fri, 19 Jul 2024 20:51:46 +0100 Subject: [PATCH 07/12] fix!: kvm2 create private subnets, switch to virtualbox driver We want to allow the clusters to be reached by the client and with each other, since by design mnikube runs each cluster in a private subnets when using kvm driver, simply adding routes using route command does not work, also tried port-forwarding in the host and sending requests within the vm to the host and it didn't work, and to fix it this you need to manually edit the network settings from outside and destroy it and restart the vm as explained here https://github.com/kubernetes/minikube/issues/11499, which makes the tests harder to run. A solution would be to use docker and create a loop until all kube-proxy pods are running as needed, but it can only do 2 clusters for some reason, the third will automatically use kvm2. moreover it behaves differently for each run. But that won't be needed as virtualbox driver runs all clusters within the same network. Also registered 3 different providers, one for each cluster using their own ipfs node. and simplified the scripts. --- cmd/autoscaler/start.go | 5 +- cmd/trustedpods/flags.go | 1 + test/e2e/autoscaler/deploy.sh | 80 ------------------ test/e2e/autoscaler/redeploy-contracts.sh | 15 ++++ test/e2e/autoscaler/run-test.sh | 98 ++++++++++++++--------- test/e2e/common/config2.yaml | 35 ++++++++ test/e2e/common/config3.yaml | 35 ++++++++ 7 files changed, 148 insertions(+), 121 deletions(-) delete mode 100755 test/e2e/autoscaler/deploy.sh create mode 100755 test/e2e/autoscaler/redeploy-contracts.sh create mode 100644 test/e2e/common/config2.yaml create mode 100644 test/e2e/common/config3.yaml diff --git a/cmd/autoscaler/start.go b/cmd/autoscaler/start.go index d4961cbf..d3a6931e 100644 --- a/cmd/autoscaler/start.go +++ b/cmd/autoscaler/start.go @@ -68,8 +68,9 @@ var startCmd = &cobra.Command{ } } - // using Raft.leaderCh() wont help because it works does not work with - // first leader, therefore from the docs, this is the way to detect the new leader + // using Raft.leaderCh() wont help because it does not count + // first leader election as a leadership change, therefore from the docs, + // this is the way to detect the new leader obsCh := make(chan raft.Observation, 1) observer := raft.NewObserver(obsCh, false, nil) node.Raft.RegisterObserver(observer) diff --git a/cmd/trustedpods/flags.go b/cmd/trustedpods/flags.go index fd4dcf84..6a0a3e5d 100644 --- a/cmd/trustedpods/flags.go +++ b/cmd/trustedpods/flags.go @@ -73,6 +73,7 @@ var _ = func() error { syncFlags.AddFlag(uploadFlags.Lookup("ipfs")) + registryFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed") registryFlags.StringVar(®istryContractAddress, "registry-contract", "", "registry contract address") registryFlags.StringVar(&tokenContractAddress, "token-contract", "", "token contract address") registryFlags.AddFlag(fundFlags.Lookup("payment-contract")) diff --git a/test/e2e/autoscaler/deploy.sh b/test/e2e/autoscaler/deploy.sh deleted file mode 100755 index 3eb207ea..00000000 --- a/test/e2e/autoscaler/deploy.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -set -e - -trap 'pkill -f "kubectl port-forward" && kill $(jobs -p) &>/dev/null' EXIT - -if [ "$1" = "teardown" ]; then - minikube delete - - if [ "$2" = "full" ]; then - docker rm --force registry - docker rm --force anvil - rm -r /home/ezio/.apocryph/deployment/ - exit 0 - fi - exit 0 -fi - - -which curl >/dev/null; which jq >/dev/null; which xargs >/dev/null; which sed >/dev/null -which go >/dev/null -which ipfs >/dev/null -which forge &>/dev/null || export PATH=$PATH:~/.bin/foundry -which forge >/dev/null; which cast >/dev/null -which minikube >/dev/null; which helmfile >/dev/null; which helm >/dev/null; which kubectl >/dev/null -which docker >/dev/null - -# based on https://stackoverflow.com/a/31269848 / https://bobcopeland.com/blog/2012/10/goto-in-bash/ -if [ -n "$1" ]; then - STEP=${1:-1} - eval "set -v; $(sed -n "/## $STEP: /{:a;n;p;ba};" $0)" - exit -fi - -echo -e "\e[1;32m---" -echo "Note: To skip steps, use '$0 '" -echo " e.g. to skip ahead to configuring IPFS, run '$0 1.2'" -echo -e "---\e[0m" - - -## 1: Set up the Kubernetes environment ## - -## 1.1: Apply Helm configurations ## - - -helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } - -## 1.2: Configure provider/in-cluster IPFS and publisher IPFS ## - -{ while ! kubectl get -n ipfs endpoints ipfs-rpc -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; } - -O_IPFS_PATH=$IPFS_PATH -export IPFS_PATH=$(mktemp ipfs.XXXX --tmpdir -d) - -[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } -echo /ip4/127.0.0.1/tcp/5004 > $IPFS_PATH/api - -SWARM_ADDRESSES=$(minikube service -n ipfs ipfs-swarm --url | head -n 1 | sed -E 's|http://(.+):(.+)|["/ip4/\1/tcp/\2", "/ip4/\1/udp/\2/quic", "/ip4/\1/udp/\2/quic-v1", "/ip4/\1/udp/\2/quic-v1/webtransport"]|') - -PROVIDER_IPFS=$(curl -X POST "http://127.0.0.1:5004/api/v0/id" | jq '.ID' -r); echo $PROVIDER_IPFS - -CONFIG_BEFORE=$(ipfs config Addresses.AppendAnnounce) -ipfs config Addresses.AppendAnnounce --json "$SWARM_ADDRESSES" -CONFIG_AFTER=$(ipfs config Addresses.AppendAnnounce) - -[ "$CONFIG_BEFORE" = "$CONFIG_AFTER" ] || kubectl delete -n ipfs $(kubectl get po -o name -n ipfs) # Restart ipfs daemon - -export IPFS_PATH=$O_IPFS_PATH - -{ while ! kubectl get -n ipfs endpoints ipfs-rpc -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; } - -ipfs id &>/dev/null || ipfs init - -ipfs config --json Experimental.Libp2pStreamMounting true - -[ -n "$IPFS_DAEMON" ] || { IPFS_DAEMON=yes; ipfs daemon & { while ! [ -f ${IPFS_PATH:-~/.ipfs}/api ]; do sleep 0.1; done; } 2>/dev/null; } - -echo "$SWARM_ADDRESSES" | jq -r '.[] + "/p2p/'"$PROVIDER_IPFS"'"' | xargs -n 1 ipfs swarm connect || true - -sleep 1 diff --git a/test/e2e/autoscaler/redeploy-contracts.sh b/test/e2e/autoscaler/redeploy-contracts.sh new file mode 100755 index 00000000..8ad9c612 --- /dev/null +++ b/test/e2e/autoscaler/redeploy-contracts.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +docker rm --force anvil || true + +# (NOTE: Unfortunately, we cannot use a port other than 8545, or otherwise the eth-rpc service will break) +docker run -d -p 8545:8545 --restart=always --name=anvil \ + ghcr.io/foundry-rs/foundry:nightly-619f3c56302b5a665164002cb98263cd9812e4d5 \ + -- 'anvil --host 0.0.0.0 --state /anvil-state.json' 2>/dev/null || { + docker exec anvil ash -c 'kill 1 && rm -f /anvil-state.json' # Reset anvil state +} +sleep 5 + +# deploy the contracts +DEPLOYER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(0\)/ {print $2; exit}') # anvil.accounts[0] +( cd ../../../contracts; forge script script/Deploy.s.sol --private-key "$DEPLOYER_KEY" --rpc-url http://localhost:8545 --broadcast) diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh index 39575155..6921b043 100755 --- a/test/e2e/autoscaler/run-test.sh +++ b/test/e2e/autoscaler/run-test.sh @@ -2,6 +2,16 @@ cd "$(dirname "$0")" +trap 'kill $(jobs -p) &>/dev/null' EXIT + +which curl >/dev/null; which jq >/dev/null; which xargs >/dev/null; which sed >/dev/null +which go >/dev/null +which ipfs >/dev/null +which forge &>/dev/null || export PATH=$PATH:~/.bin/foundry +which forge >/dev/null; which cast >/dev/null +which minikube >/dev/null; which helmfile >/dev/null; which helm >/dev/null; which kubectl >/dev/null +which docker >/dev/null + set -v # based on https://stackoverflow.com/a/31269848 / https://bobcopeland.com/blog/2012/10/goto-in-bash/ @@ -35,29 +45,42 @@ docker push localhost:5000/comradecoop/apocryph/p2p-helper:latest ## 0.3: Set up a local ethereum node and deploy contracts to it -# (NOTE: Unfortunately, we cannot use a port other than 8545, or otherwise the eth-rpc service will break) -docker run -d -p 8545:8545 --restart=always --name=anvil \ - ghcr.io/foundry-rs/foundry:nightly-619f3c56302b5a665164002cb98263cd9812e4d5 \ - -- 'anvil --host 0.0.0.0 --state /anvil-state.json' 2>/dev/null || { - docker exec anvil ash -c 'kill 1 && rm -f /anvil-state.json' # Reset anvil state -} -sleep 5 - -# deploy the contracts -DEPLOYER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(0\)/ {print $2; exit}') # anvil.accounts[0] -( cd ../../../contracts; forge script script/Deploy.s.sol --private-key "$DEPLOYER_KEY" --rpc-url http://localhost:8545 --broadcast) +./redeploy-contracts.sh ## 1.0 Starting the First Cluster -echo "Starting the first cluster" -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=kvm2 -p c1 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c1 minikube profile c1 -./deploy.sh +helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } # wait until all the deployments are ready ./wait-deployments.sh -## 1.1: Register the provider in the marketplace -[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } + +## 2.0: Starting the second Cluster +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c2 +minikube profile c2 +helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } + +# wait until all the deployments are ready +./wait-deployments.sh + + +## 3.0: Starting the third Cluster +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c3 +minikube profile c3 +helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } + +# wait until all the deployments are ready +./wait-deployments.sh + + +minikube profile list + +## 4.0: Register the providers in the marketplace + +minikube profile c1 +pkill -f "kubectl port-forward" +kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; go run ../../../cmd/tpodserver registry register \ --config ../common/config.yaml \ --ipfs /ip4/127.0.0.1/tcp/5004 \ @@ -67,42 +90,39 @@ go run ../../../cmd/tpodserver registry register \ --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ -## 2.0: Starting the second Cluster -echo "Starting the second cluster" -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=kvm2 -p c2 minikube profile c2 -./deploy.sh - -# wait until all the deployments are ready -./wait-deployments.sh - -[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } +pkill -f "kubectl port-forward" +kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; go run ../../../cmd/tpodserver registry register \ - --config ../common/config.yaml \ + --config ../common/config2.yaml \ --ipfs /ip4/127.0.0.1/tcp/5004 \ --ethereum-rpc http://127.0.0.1:8545 \ - --ethereum-key 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a \ + --ethereum-key 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97 \ --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ -## 3.0: Starting the third Cluster -echo "Starting the third cluster" -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=kvm2 -p c3 minikube profile c3 -./deploy.sh +pkill -f "kubectl port-forward" +kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; -# wait until all the deployments are ready -./wait-deployments.sh - -[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5005:5001 & sleep 0.5; } go run ../../../cmd/tpodserver registry register \ - --config ../common/config.yaml \ - --ipfs /ip4/127.0.0.1/tcp/5005 \ + --config ../common/config3.yaml \ + --ipfs /ip4/127.0.0.1/tcp/5004 \ --ethereum-rpc http://127.0.0.1:8545 \ - --ethereum-key 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6 \ + --ethereum-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 \ --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ +# Connect the three ipfs nodes -minikube profile list +## 4.1: Get the tables and the providers + + +pkill -f "kubectl port-forward" + +ipfs daemon >/dev/null & +go run ../../../cmd/trustedpods registry get --config ../../integration/registry/config.yaml config.yaml \ + --ethereum-key 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a \ + --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ + --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ diff --git a/test/e2e/common/config2.yaml b/test/e2e/common/config2.yaml new file mode 100644 index 00000000..e756e3b5 --- /dev/null +++ b/test/e2e/common/config2.yaml @@ -0,0 +1,35 @@ +pricing: + table: + format: yaml + # filename: pricing.yaml + contents: | + tables: + - paymentContractAddress: "5/FyXnc0ziiPg2fhuxQ+kLs/BRI=" + resources: + - resource: "cpu" + priceForReservation: 200000000000 + - resource: "ram" + priceForReservation: 500 + - resource: "storage" + priceForUsage: 500 + - resource: "bandwidth_ingress" + priceForUsage: 800 + - resource: "bandwidth_egress" + priceForUsage: 800 +cpu_model: 'Intel Xeon Platinum 8452Y Processor' +tee_type: 'Secure Enclaves' +withdraw: + address: '0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f' + time: 15 +info: + format: yaml + contents: | + regions: + - name: "usa" + zone: "north" + num: 5 + - name: "aus" + zone: "south" + num: 2 + multiaddrs: + - "https://kubo.business/" diff --git a/test/e2e/common/config3.yaml b/test/e2e/common/config3.yaml new file mode 100644 index 00000000..b981e740 --- /dev/null +++ b/test/e2e/common/config3.yaml @@ -0,0 +1,35 @@ +pricing: + table: + format: yaml + # filename: pricing.yaml + contents: | + tables: + - paymentContractAddress: "5/FyXnc0ziiPg2fhuxQ+kLs/BRI=" + resources: + - resource: "cpu" + priceForReservation: 200000000000 + - resource: "ram" + priceForReservation: 500 + - resource: "storage" + priceForUsage: 500 + - resource: "bandwidth_ingress" + priceForUsage: 800 + - resource: "bandwidth_egress" + priceForUsage: 800 +cpu_model: 'Intel Xeon Platinum 8452Y Processor' +tee_type: 'CVM' +withdraw: + address: '0xa0Ee7A142d267C1f36714E4a8F75612F20a79720' + time: 15 +info: + format: yaml + contents: | + regions: + - name: "bul" + zone: "north" + num: 3 + - name: "alg" + zone: "south" + num: 8 + multiaddrs: + - "https://kubo.business/" From 9ed15bfeb0e9db924462c4b7dcb5546b78d9d276 Mon Sep 17 00:00:00 2001 From: revoltez Date: Sun, 21 Jul 2024 22:34:41 +0100 Subject: [PATCH 08/12] wip: add connect rpc server & cli client for the autoscaler --- cmd/autoscaler/main.go | 39 +-- cmd/autoscaler/root.go | 24 -- cmd/autoscaler/server.go | 145 ++++++++++ cmd/autoscaler/start.go | 112 -------- cmd/trustedpods/autoscaler.go | 48 ++++ pkg/proto/autoscaler.pb.go | 253 ++++++++++++++++++ pkg/proto/generate.go | 1 + pkg/proto/protoconnect/autoscaler.connect.go | 118 ++++++++ .../protoconnect/provision-pod.connect.go | 35 ++- proto/autoscaler.proto | 23 ++ test/e2e/autoscaler/run-test.sh | 1 + turbo.json | 2 +- 12 files changed, 640 insertions(+), 161 deletions(-) delete mode 100644 cmd/autoscaler/root.go create mode 100644 cmd/autoscaler/server.go delete mode 100644 cmd/autoscaler/start.go create mode 100644 cmd/trustedpods/autoscaler.go create mode 100644 pkg/proto/autoscaler.pb.go create mode 100644 pkg/proto/protoconnect/autoscaler.connect.go create mode 100644 proto/autoscaler.proto diff --git a/cmd/autoscaler/main.go b/cmd/autoscaler/main.go index fb85dc4c..910a0a64 100644 --- a/cmd/autoscaler/main.go +++ b/cmd/autoscaler/main.go @@ -1,23 +1,32 @@ package main import ( - "context" - "os" - "os/signal" + "fmt" + "log" + "net/http" + + pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" + tpraft "github.com/comrade-coop/apocryph/pkg/raft" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" ) func main() { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - interruptChan := make(chan os.Signal, 1) - signal.Notify(interruptChan, os.Interrupt) - - go func() { - <-interruptChan - cancel() - }() - - if err := rootCmd.ExecuteContext(ctx); err != nil { - os.Exit(1) + mux := http.NewServeMux() + self, err := tpraft.NewPeer(fmt.Sprintf("/ip4/0.0.0.0/tcp/%v", RAFT_P2P_PORT)) + if err != nil { + fmt.Println("Failed creating p2p node") + return } + server := &AutoScalerServer{self: self} + server.mainLoop = setAppGatewayExample + path, handler := pbcon.NewAutoscalerServiceHandler(server) + mux.Handle(path, handler) + log.Println("Autoscaler RPC Server Started") + http.ListenAndServe( + "localhost:8080", + // Use h2c so we can serve HTTP/2 without TLS. + h2c.NewHandler(mux, &http2.Server{}), + ) + } diff --git a/cmd/autoscaler/root.go b/cmd/autoscaler/root.go deleted file mode 100644 index f507e0d8..00000000 --- a/cmd/autoscaler/root.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -package main - -import ( - "github.com/spf13/cobra" -) - -const ( - keystorePath string = "/tmp/keystore" -) - -var rootCmd = &cobra.Command{ - Use: "Autonomous Autoscaler", - Short: "Autoscaler is autonomous application offering service discovery and fault-tolerance of applications accross Apocryph network", - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - return nil - }, - SilenceUsage: true, -} - -func init() { - rootCmd.AddCommand(startCmd) -} diff --git a/cmd/autoscaler/server.go b/cmd/autoscaler/server.go new file mode 100644 index 00000000..bda784fa --- /dev/null +++ b/cmd/autoscaler/server.go @@ -0,0 +1,145 @@ +package main + +import ( + "context" + "fmt" + "log" + "time" + + "connectrpc.com/connect" + pb "github.com/comrade-coop/apocryph/pkg/proto" + pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" + tpraft "github.com/comrade-coop/apocryph/pkg/raft" + "github.com/hashicorp/raft" + "github.com/libp2p/go-libp2p/core/host" +) + +const RAFT_P2P_PORT = 9999 +const RAFT_PATH = "" + +type AutoScalerServer struct { + pbcon.UnimplementedAutoscalerServiceHandler + node *tpraft.RaftNode + store *tpraft.KVStore + peers []string + self host.Host + nodeGateway string + mainLoop func(*AutoScalerServer) +} + +func (s *AutoScalerServer) ConnectCluster(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.ConnectClusterResponse], error) { + log.Println("Forming a Raft Cluster with the following providers:", req.Msg.Servers) + + var peers []*host.Host + for _, addr := range req.Msg.Servers { + addr = fmt.Sprintf("/ip4/%v/tcp/%v", addr, RAFT_P2P_PORT) + log.Printf("Adding Peer:%v\n", addr) + peer, err := tpraft.NewPeer(addr) + if err != nil { + return connect.NewResponse(&pb.ConnectClusterResponse{ + Success: false, + Error: fmt.Sprintf("Failed creating peer %v: %v", addr, err), + }), nil + } + peers = append(peers, &peer) + log.Printf("Peer %s ID:%s \n", addr, peer.ID().String()) + } + + node, err := tpraft.NewRaftNode(s.self, peers, RAFT_PATH) + if err != nil { + log.Println("Error:Could not Creat Raft Node") + return connect.NewResponse(&pb.ConnectClusterResponse{ + Success: false, + Error: fmt.Sprintf("Failed Creating Raft Node %v\n", err), + }), nil + + } + + // create the KVStore + store, err := tpraft.NewKVStore(node) + + s.node = node + s.store = store + s.peers = req.Msg.Servers + s.nodeGateway = req.Msg.NodeGateway + + err = s.waitLeaderElection(req.Msg.Timeout) + if err != nil { + response := &pb.ConnectClusterResponse{Success: false, Error: err.Error()} + return connect.NewResponse(response), nil + } + + response := &pb.ConnectClusterResponse{Success: true} + return connect.NewResponse(response), nil +} + +func (s *AutoScalerServer) waitLeaderElection(timeout uint32) error { + + log.Printf("Waiting for leader election with %v seoncds timout ...", timeout) + time.Sleep(5 * time.Second) + + go s.watchNewStates() + + // using Raft.leaderCh() wont help because it does not count + // first leader election as a leadership change, therefore from the docs, + // this is the way to detect the new leader + obsCh := make(chan raft.Observation, 1) + observer := raft.NewObserver(obsCh, false, nil) + s.node.Raft.RegisterObserver(observer) + defer s.node.Raft.DeregisterObserver(observer) + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + timeoutCh := time.After(time.Duration(timeout) * time.Second) + for { + select { + case obs := <-obsCh: + switch obs.Data.(type) { + case raft.RaftState: + if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { + go s.mainLoop(s) + return nil + } + } + case <-ticker.C: + if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { + go s.mainLoop(s) + return nil + } + case <-timeoutCh: + log.Println("timed out waiting for leader") + return fmt.Errorf("Timed out waiting for leadership election") + } + } +} + +func (s *AutoScalerServer) watchNewStates() { + for range s.node.Consensus.Subscribe() { + newState, err := s.node.Consensus.GetCurrentState() + if err != nil { + log.Printf("Failed getting current state %v\n", err) + } + log.Printf("State Changed, New State: %v\n", newState) + } +} + +// example of main loop setting the value of a test domain with the current node +// gateway every 5 seconds +func setAppGatewayExample(s *AutoScalerServer) { + log.Println("Starting Main Loop:") + for { + if s.node.Raft.State() == raft.Leader { + log.Println("Setting the domain value to the current apocryph node gateway") + err := s.store.Set("www.test.com", s.nodeGateway) + // leadership could be changed right before setting the value + if _, ok := err.(*tpraft.NotLeaderError); ok { + newLeaderAddr, newLeaderID := s.node.Raft.LeaderWithID() + log.Printf("Leadership changed to %v:%v", newLeaderAddr, newLeaderID) + } else { + log.Printf("Failed setting key:%v: %v\n", "www.test.com", err) + } + } + time.Sleep(5 * time.Second) + } +} diff --git a/cmd/autoscaler/start.go b/cmd/autoscaler/start.go deleted file mode 100644 index d3a6931e..00000000 --- a/cmd/autoscaler/start.go +++ /dev/null @@ -1,112 +0,0 @@ -package main - -import ( - "context" - "fmt" - "log" - "time" - - tpraft "github.com/comrade-coop/apocryph/pkg/raft" - "github.com/hashicorp/raft" - "github.com/libp2p/go-libp2p/core/host" - "github.com/spf13/cobra" -) - -var peersMultiAddr []string -var port uint16 -var raftPath string -var appDomain string -var gateway string - -var startCmd = &cobra.Command{ - Use: "start", - Short: "Start the autonomous autoscaler", - RunE: func(cmd *cobra.Command, args []string) error { - log.Println("Forming a Raft Cluster with the following peers:", peersMultiAddr) - - self, _ := tpraft.NewPeer(fmt.Sprintf("/ip4/0.0.0.0/tcp/%v", port)) - var peers []*host.Host - for _, addr := range peersMultiAddr { - peer, _ := tpraft.NewPeer(addr) - peers = append(peers, &peer) - log.Printf("Peer %s ID:%s \n", addr, peer.ID().String()) - } - - node, err := tpraft.NewRaftNode(self, peers, raftPath) - if err != nil { - return fmt.Errorf("Failed creating Raft node: %s", err) - } - - // create the KVStore - store, err := tpraft.NewKVStore(node) - - log.Println("Waiting for leader election") - time.Sleep(5 * time.Second) - - setKey := func() { - if node.Raft.State() == raft.Leader { - log.Println("Setting the domain value to the current apocryph node gateway") - err := store.Set(appDomain, fmt.Sprintf("%v", gateway)) - // leadership could be changed right before setting the value - if _, ok := err.(*tpraft.NotLeaderError); ok { - newLeaderAddr, newLeaderID := node.Raft.LeaderWithID() - log.Printf("Leadership changed to %v:%v", newLeaderAddr, newLeaderID) - } else { - log.Printf("Failed setting key:%v: %v\n", appDomain, err) - } - } - } - - // print the new state whenever it changes - printNewState := func() { - for range node.Consensus.Subscribe() { - newState, err := node.Consensus.GetCurrentState() - if err != nil { - log.Printf("Failed getting current state %v", err) - } - log.Printf("State Changed, New State: %v", newState) - } - } - - // using Raft.leaderCh() wont help because it does not count - // first leader election as a leadership change, therefore from the docs, - // this is the way to detect the new leader - obsCh := make(chan raft.Observation, 1) - observer := raft.NewObserver(obsCh, false, nil) - node.Raft.RegisterObserver(observer) - defer node.Raft.DeregisterObserver(observer) - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - ticker := time.NewTicker(time.Second / 2) - defer ticker.Stop() - for { - select { - case obs := <-obsCh: - switch obs.Data.(type) { - case raft.RaftState: - if leaderAddr, _ := node.Raft.LeaderWithID(); leaderAddr != "" { - setKey() - printNewState() - } - } - case <-ticker.C: - if leaderAddr, _ := node.Raft.LeaderWithID(); leaderAddr != "" { - setKey() - printNewState() - } - case <-ctx.Done(): - fmt.Println("timed out waiting for Leader") - return nil - } - } - }, -} - -func init() { - startCmd.Flags().StringSliceVarP(&peersMultiAddr, "peers", "p", []string{}, "List of peers multiaddresses that the autoscaler will use to redeploy your application in case of a failure") - startCmd.Flags().Uint16Var(&port, "port", 9999, "port number for this node") - startCmd.Flags().StringVar(&raftPath, "path", "", "path where raft will save it's state (Default is In Memory)") - startCmd.Flags().StringVar(&appDomain, "doamin", "www.apocryph.com", "the application domain name") - startCmd.Flags().StringVar(&gateway, "gateway", "127.0.0.1", "Apocryph node Gateway") -} diff --git a/cmd/trustedpods/autoscaler.go b/cmd/trustedpods/autoscaler.go new file mode 100644 index 00000000..16927982 --- /dev/null +++ b/cmd/trustedpods/autoscaler.go @@ -0,0 +1,48 @@ +package main + +import ( + "context" + "fmt" + "log" + "net/http" + + "connectrpc.com/connect" + "github.com/spf13/cobra" + + pb "github.com/comrade-coop/apocryph/pkg/proto" + pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" +) + +var nodesAddrs []string +var raftPath string +var appManifest string +var baseUrl string + +var autoscalerCmd = &cobra.Command{ + Use: "autoscale", + Short: "Configure the deployed autonomous autoscaler", + RunE: func(cmd *cobra.Command, args []string) error { + client := pbcon.NewAutoscalerServiceClient( + http.DefaultClient, + baseUrl) + log.Printf("%v\n", nodesAddrs) + request := connect.NewRequest(&pb.ConnectClusterRequest{NodeGateway: baseUrl, Servers: nodesAddrs, Timeout: 10}) + response, err := client.ConnectCluster(context.Background(), request) + if err != nil { + return fmt.Errorf("Error connecting to cluster:%v", err) + } + log.Printf("Received response: %v", response) + return nil + + }, +} + +func init() { + // this could be removed if we store the list of providers directly in the pod configuration + autoscalerCmd.Flags().StringSliceVarP(&nodesAddrs, "providers", "p", []string{}, "List of All providers cluster ip addresses that the autoscaler will use to redeploy your application in case of a failure") + autoscalerCmd.Flags().StringVar(&raftPath, "path", "", "Optional: path where raft will save it's state (Default is In Memory)") + autoscalerCmd.Flags().StringVar(&appManifest, "manifest", "", "path to application manifest to autoscale") + autoscalerCmd.Flags().StringVar(&baseUrl, "url", "", "apocryph node gateway running autoscaler instance") + + rootCmd.AddCommand(autoscalerCmd) +} diff --git a/pkg/proto/autoscaler.pb.go b/pkg/proto/autoscaler.pb.go new file mode 100644 index 00000000..8905450a --- /dev/null +++ b/pkg/proto/autoscaler.pb.go @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-3.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.12.4 +// source: autoscaler.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ConnectClusterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // could get it from within the cluster maybe? + NodeGateway string `protobuf:"bytes,1,opt,name=nodeGateway,proto3" json:"nodeGateway,omitempty"` + Servers []string `protobuf:"bytes,2,rep,name=servers,proto3" json:"servers,omitempty"` + Timeout uint32 `protobuf:"varint,3,opt,name=timeout,proto3" json:"timeout,omitempty"` +} + +func (x *ConnectClusterRequest) Reset() { + *x = ConnectClusterRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_autoscaler_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnectClusterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectClusterRequest) ProtoMessage() {} + +func (x *ConnectClusterRequest) ProtoReflect() protoreflect.Message { + mi := &file_autoscaler_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectClusterRequest.ProtoReflect.Descriptor instead. +func (*ConnectClusterRequest) Descriptor() ([]byte, []int) { + return file_autoscaler_proto_rawDescGZIP(), []int{0} +} + +func (x *ConnectClusterRequest) GetNodeGateway() string { + if x != nil { + return x.NodeGateway + } + return "" +} + +func (x *ConnectClusterRequest) GetServers() []string { + if x != nil { + return x.Servers + } + return nil +} + +func (x *ConnectClusterRequest) GetTimeout() uint32 { + if x != nil { + return x.Timeout + } + return 0 +} + +type ConnectClusterResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *ConnectClusterResponse) Reset() { + *x = ConnectClusterResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_autoscaler_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnectClusterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectClusterResponse) ProtoMessage() {} + +func (x *ConnectClusterResponse) ProtoReflect() protoreflect.Message { + mi := &file_autoscaler_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectClusterResponse.ProtoReflect.Descriptor instead. +func (*ConnectClusterResponse) Descriptor() ([]byte, []int) { + return file_autoscaler_proto_rawDescGZIP(), []int{1} +} + +func (x *ConnectClusterResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *ConnectClusterResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +var File_autoscaler_proto protoreflect.FileDescriptor + +var file_autoscaler_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x1c, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, + 0x22, 0x6d, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, + 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x6e, 0x6f, 0x64, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, + 0x48, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0x90, 0x01, 0x0a, 0x11, 0x41, 0x75, + 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x7b, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, + 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, + 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2c, 0x5a, 0x2a, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, + 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, + 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_autoscaler_proto_rawDescOnce sync.Once + file_autoscaler_proto_rawDescData = file_autoscaler_proto_rawDesc +) + +func file_autoscaler_proto_rawDescGZIP() []byte { + file_autoscaler_proto_rawDescOnce.Do(func() { + file_autoscaler_proto_rawDescData = protoimpl.X.CompressGZIP(file_autoscaler_proto_rawDescData) + }) + return file_autoscaler_proto_rawDescData +} + +var file_autoscaler_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_autoscaler_proto_goTypes = []interface{}{ + (*ConnectClusterRequest)(nil), // 0: apocryph.proto.v0.autoscaler.ConnectClusterRequest + (*ConnectClusterResponse)(nil), // 1: apocryph.proto.v0.autoscaler.ConnectClusterResponse +} +var file_autoscaler_proto_depIdxs = []int32{ + 0, // 0: apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster:input_type -> apocryph.proto.v0.autoscaler.ConnectClusterRequest + 1, // 1: apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster:output_type -> apocryph.proto.v0.autoscaler.ConnectClusterResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_autoscaler_proto_init() } +func file_autoscaler_proto_init() { + if File_autoscaler_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_autoscaler_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnectClusterRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_autoscaler_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnectClusterResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_autoscaler_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_autoscaler_proto_goTypes, + DependencyIndexes: file_autoscaler_proto_depIdxs, + MessageInfos: file_autoscaler_proto_msgTypes, + }.Build() + File_autoscaler_proto = out.File + file_autoscaler_proto_rawDesc = nil + file_autoscaler_proto_goTypes = nil + file_autoscaler_proto_depIdxs = nil +} diff --git a/pkg/proto/generate.go b/pkg/proto/generate.go index ffc350ba..f5a5514c 100644 --- a/pkg/proto/generate.go +++ b/pkg/proto/generate.go @@ -9,6 +9,7 @@ //go:generate protoc -I=../../proto --go_out=paths=source_relative:. ../../proto/pricing.proto //go:generate protoc -I=../../proto --go_out=paths=source_relative:. ../../proto/deployment.proto //go:generate protoc -I=../../proto --go_out=paths=source_relative:. --connect-go_out=paths=source_relative:. ../../proto/provision-pod.proto +//go:generate protoc -I=../../proto --go_out=paths=source_relative:. --connect-go_out=paths=source_relative:. ../../proto/autoscaler.proto //go:generate protoc -I=../../proto --go_out=paths=source_relative:. ../../proto/provisioning-capacity.proto //go:generate protoc -I=../../proto --go_out=paths=source_relative:. ../../proto/registry.proto package proto diff --git a/pkg/proto/protoconnect/autoscaler.connect.go b/pkg/proto/protoconnect/autoscaler.connect.go new file mode 100644 index 00000000..50cc9450 --- /dev/null +++ b/pkg/proto/protoconnect/autoscaler.connect.go @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-3.0 + +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: autoscaler.proto + +package protoconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + proto "github.com/comrade-coop/apocryph/pkg/proto" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // AutoscalerServiceName is the fully-qualified name of the AutoscalerService service. + AutoscalerServiceName = "apocryph.proto.v0.autoscaler.AutoscalerService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // AutoscalerServiceConnectClusterProcedure is the fully-qualified name of the AutoscalerService's + // ConnectCluster RPC. + AutoscalerServiceConnectClusterProcedure = "/apocryph.proto.v0.autoscaler.AutoscalerService/ConnectCluster" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + autoscalerServiceServiceDescriptor = proto.File_autoscaler_proto.Services().ByName("AutoscalerService") + autoscalerServiceConnectClusterMethodDescriptor = autoscalerServiceServiceDescriptor.Methods().ByName("ConnectCluster") +) + +// AutoscalerServiceClient is a client for the apocryph.proto.v0.autoscaler.AutoscalerService +// service. +type AutoscalerServiceClient interface { + ConnectCluster(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.ConnectClusterResponse], error) +} + +// NewAutoscalerServiceClient constructs a client for the +// apocryph.proto.v0.autoscaler.AutoscalerService service. By default, it uses the Connect protocol +// with the binary Protobuf Codec, asks for gzipped responses, and sends uncompressed requests. To +// use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or connect.WithGRPCWeb() +// options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewAutoscalerServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AutoscalerServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &autoscalerServiceClient{ + connectCluster: connect.NewClient[proto.ConnectClusterRequest, proto.ConnectClusterResponse]( + httpClient, + baseURL+AutoscalerServiceConnectClusterProcedure, + connect.WithSchema(autoscalerServiceConnectClusterMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// autoscalerServiceClient implements AutoscalerServiceClient. +type autoscalerServiceClient struct { + connectCluster *connect.Client[proto.ConnectClusterRequest, proto.ConnectClusterResponse] +} + +// ConnectCluster calls apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster. +func (c *autoscalerServiceClient) ConnectCluster(ctx context.Context, req *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.ConnectClusterResponse], error) { + return c.connectCluster.CallUnary(ctx, req) +} + +// AutoscalerServiceHandler is an implementation of the +// apocryph.proto.v0.autoscaler.AutoscalerService service. +type AutoscalerServiceHandler interface { + ConnectCluster(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.ConnectClusterResponse], error) +} + +// NewAutoscalerServiceHandler builds an HTTP handler from the service implementation. It returns +// the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewAutoscalerServiceHandler(svc AutoscalerServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + autoscalerServiceConnectClusterHandler := connect.NewUnaryHandler( + AutoscalerServiceConnectClusterProcedure, + svc.ConnectCluster, + connect.WithSchema(autoscalerServiceConnectClusterMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/apocryph.proto.v0.autoscaler.AutoscalerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case AutoscalerServiceConnectClusterProcedure: + autoscalerServiceConnectClusterHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedAutoscalerServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedAutoscalerServiceHandler struct{} + +func (UnimplementedAutoscalerServiceHandler) ConnectCluster(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.ConnectClusterResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster is not implemented")) +} diff --git a/pkg/proto/protoconnect/provision-pod.connect.go b/pkg/proto/protoconnect/provision-pod.connect.go index 3001ce5e..d40c3ab5 100644 --- a/pkg/proto/protoconnect/provision-pod.connect.go +++ b/pkg/proto/protoconnect/provision-pod.connect.go @@ -20,7 +20,7 @@ import ( // generated with a version of connect newer than the one compiled into your binary. You can fix the // problem by either regenerating this code with an older version of connect or updating the connect // version compiled into your binary. -const _ = connect.IsAtLeastVersion0_1_0 +const _ = connect.IsAtLeastVersion1_13_0 const ( // ProvisionPodServiceName is the fully-qualified name of the ProvisionPodService service. @@ -49,6 +49,15 @@ const ( ProvisionPodServiceGetPodLogsProcedure = "/apocryph.proto.v0.provisionPod.ProvisionPodService/GetPodLogs" ) +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + provisionPodServiceServiceDescriptor = proto.File_provision_pod_proto.Services().ByName("ProvisionPodService") + provisionPodServiceProvisionPodMethodDescriptor = provisionPodServiceServiceDescriptor.Methods().ByName("ProvisionPod") + provisionPodServiceUpdatePodMethodDescriptor = provisionPodServiceServiceDescriptor.Methods().ByName("UpdatePod") + provisionPodServiceDeletePodMethodDescriptor = provisionPodServiceServiceDescriptor.Methods().ByName("DeletePod") + provisionPodServiceGetPodLogsMethodDescriptor = provisionPodServiceServiceDescriptor.Methods().ByName("GetPodLogs") +) + // ProvisionPodServiceClient is a client for the apocryph.proto.v0.provisionPod.ProvisionPodService // service. type ProvisionPodServiceClient interface { @@ -72,22 +81,26 @@ func NewProvisionPodServiceClient(httpClient connect.HTTPClient, baseURL string, provisionPod: connect.NewClient[proto.ProvisionPodRequest, proto.ProvisionPodResponse]( httpClient, baseURL+ProvisionPodServiceProvisionPodProcedure, - opts..., + connect.WithSchema(provisionPodServiceProvisionPodMethodDescriptor), + connect.WithClientOptions(opts...), ), updatePod: connect.NewClient[proto.UpdatePodRequest, proto.ProvisionPodResponse]( httpClient, baseURL+ProvisionPodServiceUpdatePodProcedure, - opts..., + connect.WithSchema(provisionPodServiceUpdatePodMethodDescriptor), + connect.WithClientOptions(opts...), ), deletePod: connect.NewClient[proto.DeletePodRequest, proto.DeletePodResponse]( httpClient, baseURL+ProvisionPodServiceDeletePodProcedure, - opts..., + connect.WithSchema(provisionPodServiceDeletePodMethodDescriptor), + connect.WithClientOptions(opts...), ), getPodLogs: connect.NewClient[proto.PodLogRequest, proto.PodLogResponse]( httpClient, baseURL+ProvisionPodServiceGetPodLogsProcedure, - opts..., + connect.WithSchema(provisionPodServiceGetPodLogsMethodDescriptor), + connect.WithClientOptions(opts...), ), } } @@ -138,22 +151,26 @@ func NewProvisionPodServiceHandler(svc ProvisionPodServiceHandler, opts ...conne provisionPodServiceProvisionPodHandler := connect.NewUnaryHandler( ProvisionPodServiceProvisionPodProcedure, svc.ProvisionPod, - opts..., + connect.WithSchema(provisionPodServiceProvisionPodMethodDescriptor), + connect.WithHandlerOptions(opts...), ) provisionPodServiceUpdatePodHandler := connect.NewUnaryHandler( ProvisionPodServiceUpdatePodProcedure, svc.UpdatePod, - opts..., + connect.WithSchema(provisionPodServiceUpdatePodMethodDescriptor), + connect.WithHandlerOptions(opts...), ) provisionPodServiceDeletePodHandler := connect.NewUnaryHandler( ProvisionPodServiceDeletePodProcedure, svc.DeletePod, - opts..., + connect.WithSchema(provisionPodServiceDeletePodMethodDescriptor), + connect.WithHandlerOptions(opts...), ) provisionPodServiceGetPodLogsHandler := connect.NewServerStreamHandler( ProvisionPodServiceGetPodLogsProcedure, svc.GetPodLogs, - opts..., + connect.WithSchema(provisionPodServiceGetPodLogsMethodDescriptor), + connect.WithHandlerOptions(opts...), ) return "/apocryph.proto.v0.provisionPod.ProvisionPodService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { diff --git a/proto/autoscaler.proto b/proto/autoscaler.proto new file mode 100644 index 00000000..7b6e31c5 --- /dev/null +++ b/proto/autoscaler.proto @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-3.0 + +syntax = "proto3"; +package apocryph.proto.v0.autoscaler; + +option go_package = "github.com/comrade-coop/apocryph/pkg/proto"; + + +service AutoscalerService { + rpc ConnectCluster(ConnectClusterRequest) returns (ConnectClusterResponse); +} + +message ConnectClusterRequest{ + // could get it from within the cluster maybe? + string nodeGateway = 1; + repeated string servers = 2; + uint32 timeout = 3; +} + +message ConnectClusterResponse{ + bool success = 1; + string error = 2; +} diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh index 6921b043..0a9d1a26 100755 --- a/test/e2e/autoscaler/run-test.sh +++ b/test/e2e/autoscaler/run-test.sh @@ -11,6 +11,7 @@ which forge &>/dev/null || export PATH=$PATH:~/.bin/foundry which forge >/dev/null; which cast >/dev/null which minikube >/dev/null; which helmfile >/dev/null; which helm >/dev/null; which kubectl >/dev/null which docker >/dev/null +which virtualbox >/dev/null set -v diff --git a/turbo.json b/turbo.json index 82d92092..3c2aa641 100644 --- a/turbo.json +++ b/turbo.json @@ -9,7 +9,7 @@ "dependsOn": ["//#go-build", "ts-gen-proto", "ts-gen-abi"] }, "//#go-build": { - "inputs": ["./proto/**"], + "inputs": ["./proto/**", "./pkg/proto/**"], "dependsOn": ["//#build-contracts"] }, "//#build-contracts": { From 9512412b3c7a81613b03dd825a21aa0efbcc746c Mon Sep 17 00:00:00 2001 From: revoltez Date: Mon, 22 Jul 2024 18:14:29 +0100 Subject: [PATCH 09/12] fix!: force containerd to pull already saved tagged images Images were pulled from remote registries and not from the already saved images from ipfs during pod creation. so i tried to tag the images with the CID and replace the image url with the tag. this also fixes the case where the client uploads from private registries, because they will be inaccessible such as the case with the autoscaler in the test that is stored in the local docker registry. The problem was that containerd will always prefix the tagged images with docker.io/ to resolve them remotely again, therefore bypassing the saved images from ipfs. and unless its a known registry, such as gcr or docker.io, it will always get prefixed, even localhost. So the solution was simple,just disable pulling images completely, therefore it will resort to the saved images with prefixing, it just takes it as it is. --- cmd/trustedpods/flags.go | 1 + pkg/ipcr/containerd.go | 6 +- pkg/kubernetes/pods.go | 11 ++-- pkg/provider/download.go | 7 ++- test/e2e/autoscaler/redeploy-images.sh | 30 ++++++++++ test/e2e/autoscaler/run-test.sh | 58 +++++++++++-------- test/e2e/autoscaler/swarm-connect.sh | 38 ++++++++++++ test/e2e/common/config3.yaml | 2 +- .../manifest-autoscaler.yaml | 7 ++- test/integration/ipcr/main.go | 4 +- 10 files changed, 124 insertions(+), 40 deletions(-) create mode 100755 test/e2e/autoscaler/redeploy-images.sh create mode 100755 test/e2e/autoscaler/swarm-connect.sh rename test/e2e/{autoscaler => common}/manifest-autoscaler.yaml (61%) diff --git a/cmd/trustedpods/flags.go b/cmd/trustedpods/flags.go index 6a0a3e5d..51c75479 100644 --- a/cmd/trustedpods/flags.go +++ b/cmd/trustedpods/flags.go @@ -58,6 +58,7 @@ var _ = func() error { deploymentFlags.StringVar(&providerPeer, "provider", "", "provider peer id") deploymentFlags.StringVar(&providerEthAddress, "provider-eth", "", "provider public address") deploymentFlags.Int64Var(&expirationOffset, "token-expiration", 10, "authentication token expires after token-expiration seconds (expired after 10 seconds by default)") + deploymentFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed") uploadFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed") uploadFlags.BoolVar(&uploadImages, "upload-images", true, "upload images") diff --git a/pkg/ipcr/containerd.go b/pkg/ipcr/containerd.go index 2846c0b4..f6fdce0c 100644 --- a/pkg/ipcr/containerd.go +++ b/pkg/ipcr/containerd.go @@ -158,14 +158,12 @@ func PullImage(ctx context.Context, client *containerd.Client, ipfsAddr, image, if err != nil { return err } + err = img.Tag(ctx, client, types.ImageTagOptions{Source: image, Target: target}) if err != nil { return err } - err = img.Remove(ctx, client, []string{image}, types.ImageRemoveOptions{Stdout: cmd.OutOrStdout()}) - if err != nil { - return err - } + return nil } diff --git a/pkg/kubernetes/pods.go b/pkg/kubernetes/pods.go index a7120295..19c564e9 100644 --- a/pkg/kubernetes/pods.go +++ b/pkg/kubernetes/pods.go @@ -99,11 +99,12 @@ func ApplyPodRequest( for cIdx, container := range podManifest.Containers { containerSpec := corev1.Container{ - Name: container.Name, - Image: images[container.Name], - Command: container.Entrypoint, - Args: container.Command, - WorkingDir: container.WorkingDir, + Name: container.Name, + Image: images[container.Name], + ImagePullPolicy: corev1.PullNever, + Command: container.Entrypoint, + Args: container.Command, + WorkingDir: container.WorkingDir, } for field, value := range container.Env { containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: field, Value: value}) diff --git a/pkg/provider/download.go b/pkg/provider/download.go index 7d859d79..c25dacd3 100644 --- a/pkg/provider/download.go +++ b/pkg/provider/download.go @@ -40,12 +40,15 @@ func DownloadImages(ctx context.Context, client *containerd.Client, ipfsAddress, return nil, err } if !exists { - err = ipcr.PullImage(ctx, client, ipfsAddress, string(c.Image.Cid), c.Image.Url) + target := string(c.Image.Cid) + err = ipcr.PullImage(ctx, client, ipfsAddress, string(c.Image.Cid), target) if err != nil { return nil, err } + // Update the url + c.Image.Url = target log.Printf("Pulled Image %v Successfully, Decrypting ...\n", c.Image.Url) - err = ipcr.DecryptImage(ctx, client, "", c.Image.Url, c.Image.Key.Data) + err = ipcr.DecryptImage(ctx, client, "", target, c.Image.Key.Data) if err != nil { return nil, err } diff --git a/test/e2e/autoscaler/redeploy-images.sh b/test/e2e/autoscaler/redeploy-images.sh new file mode 100755 index 00000000..19ec24ad --- /dev/null +++ b/test/e2e/autoscaler/redeploy-images.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +docker build -t comradecoop/apocryph/server:latest ../../.. --target server + +docker build -t comradecoop/apocryph/p2p-helper:latest ../../.. --target p2p-helper + +docker build -t comradecoop/apocryph/autoscaler:latest ../../.. --target autoscaler + +docker run -d -p 5000:5000 --restart=always --name registry registry:2 || echo "Docker registry already running" + +docker tag comradecoop/apocryph/server:latest localhost:5000/comradecoop/apocryph/server:latest +docker push localhost:5000/comradecoop/apocryph/server:latest + +docker tag comradecoop/apocryph/p2p-helper:latest localhost:5000/comradecoop/apocryph/p2p-helper:latest +docker push localhost:5000/comradecoop/apocryph/p2p-helper:latest + +docker tag comradecoop/apocryph/autoscaler:latest localhost:5000/comradecoop/apocryph/autoscaler:latest +docker push localhost:5000/comradecoop/apocryph/autoscaler:latest + +minikube profile c1 +kubectl delete namespace trustedpods +helmfile apply -f ../minikube -l name=trustedpods --skip-deps + +minikube profile c2 +kubectl delete namespace trustedpods +helmfile apply -f ../minikube -l name=trustedpods --skip-deps + +minikube profile c3 +kubectl delete namespace trustedpods +helmfile apply -f ../minikube -l name=trustedpods --skip-deps diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh index 0a9d1a26..78e95a0c 100755 --- a/test/e2e/autoscaler/run-test.sh +++ b/test/e2e/autoscaler/run-test.sh @@ -27,31 +27,16 @@ sudo chmod o+rw /run/containerd/containerd.sock ## 0: Set up the external environment ## 0.1: Build/tag server and p2p-helper and autoscaler images +./redeploy-images.sh -docker build -t comradecoop/apocryph/server:latest ../../.. --target server - -docker build -t comradecoop/apocryph/p2p-helper:latest ../../.. --target p2p-helper - -docker build -t comradecoop/apocryph/autoscaler:latest ../../.. --target autoscaler - -## 0.2: Create local registry and push server and p2p-helper images - -docker run -d -p 5000:5000 --restart=always --name registry registry:2 || echo "Docker registry already running" - -docker tag comradecoop/apocryph/server:latest localhost:5000/comradecoop/apocryph/server:latest -docker push localhost:5000/comradecoop/apocryph/server:latest - -docker tag comradecoop/apocryph/p2p-helper:latest localhost:5000/comradecoop/apocryph/p2p-helper:latest -docker push localhost:5000/comradecoop/apocryph/p2p-helper:latest - -## 0.3: Set up a local ethereum node and deploy contracts to it +## 0.2: Set up a local ethereum node and deploy contracts to it ./redeploy-contracts.sh ## 1.0 Starting the First Cluster minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c1 minikube profile c1 -helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } +helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply -f ../minikube; } # wait until all the deployments are ready ./wait-deployments.sh @@ -60,7 +45,7 @@ helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress- ## 2.0: Starting the second Cluster minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c2 minikube profile c2 -helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } +helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply -f ../minikube; } # wait until all the deployments are ready ./wait-deployments.sh @@ -69,7 +54,7 @@ helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress- ## 3.0: Starting the third Cluster minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c3 minikube profile c3 -helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply; } +helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply -f ../minikube; } # wait until all the deployments are ready ./wait-deployments.sh @@ -115,15 +100,40 @@ go run ../../../cmd/tpodserver registry register \ --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ -# Connect the three ipfs nodes - ## 4.1: Get the tables and the providers - pkill -f "kubectl port-forward" +kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; -ipfs daemon >/dev/null & go run ../../../cmd/trustedpods registry get --config ../../integration/registry/config.yaml config.yaml \ --ethereum-key 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a \ --registry-contract 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0 \ --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ + --ipfs /ip4/127.0.0.1/tcp/5004 \ + +## 5.0: Deploy the autoscaler to the providers using their p2p multiaddr +minikube profile c1 + + +source swarm-connect.sh + +PROVIDER_ETH=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 #TODO= anvil.accounts[1] +PUBLISHER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(2\)/ {print $2; exit}') +PAYMENT_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.payment.value') +REGISTRY_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.registry.value') +FUNDS=10000000000000000000000 + +set +v +set -x + +go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ + --ethereum-key "$PUBLISHER_KEY" \ + --payment-contract "$PAYMENT_CONTRACT" \ + --registry-contract "$REGISTRY_CONTRACT" \ + --funds "$FUNDS" \ + --upload-images=true \ + --mint-funds \ + --provider /p2p/"$PROVIDER_IPFS" \ + --provider-eth "$PROVIDER_ETH" + + diff --git a/test/e2e/autoscaler/swarm-connect.sh b/test/e2e/autoscaler/swarm-connect.sh new file mode 100755 index 00000000..75e0165f --- /dev/null +++ b/test/e2e/autoscaler/swarm-connect.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +## Configure provider/in-cluster IPFS and publisher IPFS ## +pkill -f "kubectl port-forward" +pkill ipfs + +{ while ! kubectl get -n ipfs endpoints ipfs-rpc -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; } + +O_IPFS_PATH=$IPFS_PATH +export IPFS_PATH=$(mktemp ipfs.XXXX --tmpdir -d) + +[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } +echo /ip4/127.0.0.1/tcp/5004 > $IPFS_PATH/api + +SWARM_ADDRESSES=$(minikube service -n ipfs ipfs-swarm --url | head -n 1 | sed -E 's|http://(.+):(.+)|["/ip4/\1/tcp/\2", "/ip4/\1/udp/\2/quic", "/ip4/\1/udp/\2/quic-v1", "/ip4/\1/udp/\2/quic-v1/webtransport"]|') + +PROVIDER_IPFS=$(curl -X POST "http://127.0.0.1:5004/api/v0/id" | jq '.ID' -r); echo $PROVIDER_IPFS + +CONFIG_BEFORE=$(ipfs config Addresses.AppendAnnounce) +ipfs config Addresses.AppendAnnounce --json "$SWARM_ADDRESSES" +CONFIG_AFTER=$(ipfs config Addresses.AppendAnnounce) + +[ "$CONFIG_BEFORE" = "$CONFIG_AFTER" ] || kubectl delete -n ipfs $(kubectl get po -o name -n ipfs) # Restart ipfs daemon + +export IPFS_PATH=$O_IPFS_PATH + +{ while ! kubectl get -n ipfs endpoints ipfs-rpc -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; } + +ipfs id &>/dev/null || ipfs init + +ipfs config --json Experimental.Libp2pStreamMounting true + +[ -n "$IPFS_DAEMON" ] || { IPFS_DAEMON=yes; ipfs daemon & { while ! [ -f ${IPFS_PATH:-~/.ipfs}/api ]; do sleep 0.1; done; } 2>/dev/null; } + +echo "$SWARM_ADDRESSES" | jq -r '.[] + "/p2p/'"$PROVIDER_IPFS"'"' | xargs -n 1 ipfs swarm connect || true + +sleep 5 + diff --git a/test/e2e/common/config3.yaml b/test/e2e/common/config3.yaml index b981e740..45a1f7a0 100644 --- a/test/e2e/common/config3.yaml +++ b/test/e2e/common/config3.yaml @@ -16,7 +16,7 @@ pricing: priceForUsage: 800 - resource: "bandwidth_egress" priceForUsage: 800 -cpu_model: 'Intel Xeon Platinum 8452Y Processor' +cpu_model: 'AMD EPIC 7742' tee_type: 'CVM' withdraw: address: '0xa0Ee7A142d267C1f36714E4a8F75612F20a79720' diff --git a/test/e2e/autoscaler/manifest-autoscaler.yaml b/test/e2e/common/manifest-autoscaler.yaml similarity index 61% rename from test/e2e/autoscaler/manifest-autoscaler.yaml rename to test/e2e/common/manifest-autoscaler.yaml index e27c8872..1bd6aeb7 100644 --- a/test/e2e/autoscaler/manifest-autoscaler.yaml +++ b/test/e2e/common/manifest-autoscaler.yaml @@ -1,11 +1,14 @@ containers: - name: autoscaler image: - url: autoscaler + url: localhost:5000/comradecoop/apocryph/autoscaler ports: - - containerPort: '9999' + - containerPort: '8080' hostHttpHost: autoscaler.local name: internal + - containerPort: '32500' + hostTcpPort: 32500 + name: raft resourceRequests: - amountMillis: '10' resource: cpu diff --git a/test/integration/ipcr/main.go b/test/integration/ipcr/main.go index 217048fd..e7fa8e9d 100644 --- a/test/integration/ipcr/main.go +++ b/test/integration/ipcr/main.go @@ -52,14 +52,14 @@ func main() { // pulling the ecnrypted image from ipfs log.Println("Pulling Encrypted Image") - err = ipcr.PullImage(context.Background(), client, IPFS_ADDRESS, cid, IMAGE_NAME) + err = ipcr.PullImage(context.Background(), client, IPFS_ADDRESS, cid, cid) if err != nil { log.Panic(err) } printImages(client) // decrypting pulled Image - err = ipcr.DecryptImage(context.Background(), client, PASSWORD, IMAGE_NAME, prvKey) + err = ipcr.DecryptImage(context.Background(), client, PASSWORD, cid, prvKey) if err != nil { log.Panic(err) } From f31a4d00bde963cfd86b12528cb34308f5b26936 Mon Sep 17 00:00:00 2001 From: revoltez Date: Tue, 23 Jul 2024 13:48:14 +0100 Subject: [PATCH 10/12] feat: create apocryph helm chart Needed to pass the provider keys dynamically, and templating wont work with helmfile without a proper helm chart, because it won't subsitute the values therefore produce incorrect yaml. --- test/e2e/autoscaler/redeploy-images.sh | 6 +++-- test/e2e/minikube/trustedpods/.helmignore | 23 ++++++++++++++++++ test/e2e/minikube/trustedpods/Chart.yaml | 24 +++++++++++++++++++ .../minikube/trustedpods/templates/NOTES.txt | 6 +++++ .../{ => templates}/serviceaccount.yml | 0 .../{ => templates}/tpodserver.yml | 6 ++--- test/e2e/minikube/trustedpods/values.yaml | 3 +++ 7 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/e2e/minikube/trustedpods/.helmignore create mode 100644 test/e2e/minikube/trustedpods/Chart.yaml create mode 100644 test/e2e/minikube/trustedpods/templates/NOTES.txt rename test/e2e/minikube/trustedpods/{ => templates}/serviceaccount.yml (100%) rename test/e2e/minikube/trustedpods/{ => templates}/tpodserver.yml (90%) create mode 100644 test/e2e/minikube/trustedpods/values.yaml diff --git a/test/e2e/autoscaler/redeploy-images.sh b/test/e2e/autoscaler/redeploy-images.sh index 19ec24ad..5512ac1e 100755 --- a/test/e2e/autoscaler/redeploy-images.sh +++ b/test/e2e/autoscaler/redeploy-images.sh @@ -23,8 +23,10 @@ helmfile apply -f ../minikube -l name=trustedpods --skip-deps minikube profile c2 kubectl delete namespace trustedpods -helmfile apply -f ../minikube -l name=trustedpods --skip-deps +helmfile apply -f ../minikube -l name=trustedpods --skip-deps --set withdraw.address="0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f" --set ethKey="0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97" + minikube profile c3 kubectl delete namespace trustedpods -helmfile apply -f ../minikube -l name=trustedpods --skip-deps +helmfile apply -f ../minikube -l name=trustedpods --skip-deps --set withdraw.address=0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 --set ethKey="0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6" + diff --git a/test/e2e/minikube/trustedpods/.helmignore b/test/e2e/minikube/trustedpods/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/test/e2e/minikube/trustedpods/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/test/e2e/minikube/trustedpods/Chart.yaml b/test/e2e/minikube/trustedpods/Chart.yaml new file mode 100644 index 00000000..9a1ff447 --- /dev/null +++ b/test/e2e/minikube/trustedpods/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: trustedpods +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/test/e2e/minikube/trustedpods/templates/NOTES.txt b/test/e2e/minikube/trustedpods/templates/NOTES.txt new file mode 100644 index 00000000..0da7585c --- /dev/null +++ b/test/e2e/minikube/trustedpods/templates/NOTES.txt @@ -0,0 +1,6 @@ + _ _ + / \ _ __ ___ ___ _ __ _ _ _ __ | |__ + / _ \ | '_ \ / _ \ / __| '__| | | | '_ \| '_ \ + / ___ \| |_) | (_) | (__| | | |_| | |_) | | | | +/_/ \_\ .__/ \___/ \___|_| \__, | .__/|_| |_| + |_| |___/|_| diff --git a/test/e2e/minikube/trustedpods/serviceaccount.yml b/test/e2e/minikube/trustedpods/templates/serviceaccount.yml similarity index 100% rename from test/e2e/minikube/trustedpods/serviceaccount.yml rename to test/e2e/minikube/trustedpods/templates/serviceaccount.yml diff --git a/test/e2e/minikube/trustedpods/tpodserver.yml b/test/e2e/minikube/trustedpods/templates/tpodserver.yml similarity index 90% rename from test/e2e/minikube/trustedpods/tpodserver.yml rename to test/e2e/minikube/trustedpods/templates/tpodserver.yml index 06966754..3d8cc00e 100644 --- a/test/e2e/minikube/trustedpods/tpodserver.yml +++ b/test/e2e/minikube/trustedpods/templates/tpodserver.yml @@ -36,7 +36,7 @@ data: - resource: "ram" priceForReservation: 500 withdraw: - address: "0x90F79bf6EB2c4f870365E785982E1f101E93b906" + address: {{ .Values.withdraw.address }} time: 15 cpu_model: "Intel Xeon Platinum 8452Y Processor" tee_type: "Secure Enclaves" @@ -79,7 +79,7 @@ spec: "--ipfs", "/dns4/ipfs-rpc.ipfs.svc.cluster.local/tcp/5001", "--oci-registry", "host.minikube.internal:5000", "--ethereum-rpc", "http://eth-rpc.eth.svc.cluster.local:8545", - "--ethereum-key", "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", # TODO= anvil.accounts[1] prvkey + "--ethereum-key", {{ .Values.ethKey }}, # TODO= anvil.accounts[1] prvkey ] ports: - containerPort: 8080 @@ -100,7 +100,7 @@ spec: "--config", "config.yaml", "--prometheus", "http://prometheus-server.prometheus.svc.cluster.local:80/", "--ethereum-rpc", "http://eth-rpc.eth.svc.cluster.local:8545", - "--ethereum-key", "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", # TODO= anvil.accounts[1] + "--ethereum-key", {{ .Values.ethKey }}, # TODO= anvil.accounts[1] ] ports: - containerPort: 8080 diff --git a/test/e2e/minikube/trustedpods/values.yaml b/test/e2e/minikube/trustedpods/values.yaml new file mode 100644 index 00000000..dd612595 --- /dev/null +++ b/test/e2e/minikube/trustedpods/values.yaml @@ -0,0 +1,3 @@ +ethKey: "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" +withdraw: + address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" From ef6b429c08f6047bab2d5961d41197dbfc3cb7b3 Mon Sep 17 00:00:00 2001 From: revoltez Date: Tue, 23 Jul 2024 19:37:06 +0100 Subject: [PATCH 11/12] feat: make autoscaler trigger the rest of the instances The client selects any instance and provide it with all the apocryph node gateways and it will trigger the rest and for the cluster instead of sending multiple connect requests to every provider. --- cmd/autoscaler/main.go | 3 +- cmd/autoscaler/server.go | 120 +++++++++++++---- cmd/trustedpods/autoscaler.go | 7 +- package.json | 8 +- pkg/proto/autoscaler.pb.go | 135 ++++++++++++++----- pkg/proto/protoconnect/autoscaler.connect.go | 30 +++++ pkg/raft/raft.go | 12 +- proto/autoscaler.proto | 10 +- test/e2e/autoscaler/run-test.sh | 76 ++++++++++- test/e2e/autoscaler/swarm-connect.sh | 12 +- test/integration/raft/main.go | 18 ++- turbo.json | 2 +- 12 files changed, 350 insertions(+), 83 deletions(-) diff --git a/cmd/autoscaler/main.go b/cmd/autoscaler/main.go index 910a0a64..4244caa0 100644 --- a/cmd/autoscaler/main.go +++ b/cmd/autoscaler/main.go @@ -18,13 +18,14 @@ func main() { fmt.Println("Failed creating p2p node") return } + fmt.Printf("PEER ID: %v\n", self.ID()) server := &AutoScalerServer{self: self} server.mainLoop = setAppGatewayExample path, handler := pbcon.NewAutoscalerServiceHandler(server) mux.Handle(path, handler) log.Println("Autoscaler RPC Server Started") http.ListenAndServe( - "localhost:8080", + ":8080", // Use h2c so we can serve HTTP/2 without TLS. h2c.NewHandler(mux, &http2.Server{}), ) diff --git a/cmd/autoscaler/server.go b/cmd/autoscaler/server.go index bda784fa..e41195c7 100644 --- a/cmd/autoscaler/server.go +++ b/cmd/autoscaler/server.go @@ -4,6 +4,9 @@ import ( "context" "fmt" "log" + "net/http" + "net/url" + "strings" "time" "connectrpc.com/connect" @@ -12,9 +15,11 @@ import ( tpraft "github.com/comrade-coop/apocryph/pkg/raft" "github.com/hashicorp/raft" "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" ) -const RAFT_P2P_PORT = 9999 +const RAFT_P2P_PORT = 32500 const RAFT_PATH = "" type AutoScalerServer struct { @@ -22,42 +27,57 @@ type AutoScalerServer struct { node *tpraft.RaftNode store *tpraft.KVStore peers []string + started bool self host.Host nodeGateway string mainLoop func(*AutoScalerServer) } -func (s *AutoScalerServer) ConnectCluster(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.ConnectClusterResponse], error) { - log.Println("Forming a Raft Cluster with the following providers:", req.Msg.Servers) +func (s *AutoScalerServer) TriggerNode(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.TriggerNodeResponse], error) { + if s.started == false { + log.Println("Node Triggered") + go s.BoostrapCluster(req) + s.started = true + } + return connect.NewResponse(&pb.TriggerNodeResponse{PeerID: s.self.ID().String()}), nil +} - var peers []*host.Host - for _, addr := range req.Msg.Servers { - addr = fmt.Sprintf("/ip4/%v/tcp/%v", addr, RAFT_P2P_PORT) - log.Printf("Adding Peer:%v\n", addr) - peer, err := tpraft.NewPeer(addr) +func (s *AutoScalerServer) BoostrapCluster(req *connect.Request[pb.ConnectClusterRequest]) error { + + peerIDs, err := s.FetchPeerIDsFromServers(req) + if err != nil { + return fmt.Errorf("Failed to fetch PeerIDs: %v", err) + } + + var peers []*peer.AddrInfo + for serverAddr, addr := range peerIDs { + addr := GetMultiAddr(serverAddr, addr) + if addr == "" { + return fmt.Errorf("Failed to parse server address: %v", serverAddr) + } + + maddr, err := multiaddr.NewMultiaddr(addr) if err != nil { - return connect.NewResponse(&pb.ConnectClusterResponse{ - Success: false, - Error: fmt.Sprintf("Failed creating peer %v: %v", addr, err), - }), nil + return fmt.Errorf("Failed to parse multiaddr: %v: %v", addr, err) } - peers = append(peers, &peer) - log.Printf("Peer %s ID:%s \n", addr, peer.ID().String()) + + peerInfo, err := peer.AddrInfoFromP2pAddr(maddr) + if err != nil { + return fmt.Errorf("Failed to extract peer info from %v, Error: %v", addr, err) + } + + peers = append(peers, peerInfo) + log.Printf("Added Peer %v ID:%s \n", peerInfo.Addrs, peerInfo.ID.String()) } node, err := tpraft.NewRaftNode(s.self, peers, RAFT_PATH) if err != nil { log.Println("Error:Could not Creat Raft Node") - return connect.NewResponse(&pb.ConnectClusterResponse{ - Success: false, - Error: fmt.Sprintf("Failed Creating Raft Node %v\n", err), - }), nil - + return fmt.Errorf("Failed Creating Raft Node %v\n", err) } // create the KVStore store, err := tpraft.NewKVStore(node) - s.node = node s.store = store s.peers = req.Msg.Servers @@ -65,14 +85,44 @@ func (s *AutoScalerServer) ConnectCluster(c context.Context, req *connect.Reques err = s.waitLeaderElection(req.Msg.Timeout) if err != nil { - response := &pb.ConnectClusterResponse{Success: false, Error: err.Error()} - return connect.NewResponse(response), nil + return err } + return nil +} + +func (s *AutoScalerServer) ConnectCluster(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.ConnectClusterResponse], error) { + log.Println("Forming a Raft Cluster with the following providers:", req.Msg.Servers) + s.started = true + err := s.BoostrapCluster(req) + if err != nil { + return connect.NewResponse(&pb.ConnectClusterResponse{ + Success: false, + Error: fmt.Sprintf("Failed Bootstraping Cluster: %v\n", err), + }), nil + } response := &pb.ConnectClusterResponse{Success: true} return connect.NewResponse(response), nil } +func (s *AutoScalerServer) FetchPeerIDsFromServers(req *connect.Request[pb.ConnectClusterRequest]) (map[string]string, error) { + peerIDs := make(map[string]string) + + for _, addr := range req.Msg.Servers { + client := pbcon.NewAutoscalerServiceClient( + http.DefaultClient, + addr) + + resp, err := client.TriggerNode(context.Background(), req) + if err != nil { + return nil, fmt.Errorf("failed to get PeerID from server %v: %w", addr, err) + } + peerIDs[addr] = resp.Msg.PeerID + } + + return peerIDs, nil +} + func (s *AutoScalerServer) waitLeaderElection(timeout uint32) error { log.Printf("Waiting for leader election with %v seoncds timout ...", timeout) @@ -98,12 +148,14 @@ func (s *AutoScalerServer) waitLeaderElection(timeout uint32) error { switch obs.Data.(type) { case raft.RaftState: if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { + fmt.Printf("Leader Elected: %v\n", leaderAddr) go s.mainLoop(s) return nil } } case <-ticker.C: if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { + fmt.Printf("Leader Elected: %v\n", leaderAddr) go s.mainLoop(s) return nil } @@ -131,15 +183,33 @@ func setAppGatewayExample(s *AutoScalerServer) { for { if s.node.Raft.State() == raft.Leader { log.Println("Setting the domain value to the current apocryph node gateway") - err := s.store.Set("www.test.com", s.nodeGateway) + err := s.store.Set("www.test.com", "http://localhost:8080") // leadership could be changed right before setting the value if _, ok := err.(*tpraft.NotLeaderError); ok { newLeaderAddr, newLeaderID := s.node.Raft.LeaderWithID() log.Printf("Leadership changed to %v:%v", newLeaderAddr, newLeaderID) - } else { + } else if err != nil { log.Printf("Failed setting key:%v: %v\n", "www.test.com", err) } } - time.Sleep(5 * time.Second) + time.Sleep(10 * time.Second) + } +} + +func GetMultiAddr(addr, peerID string) string { + // Parse the URL + parsedURL, err := url.Parse(addr) + if err != nil { + fmt.Println("Error parsing URL:", err) + return "" + } + hostPort := parsedURL.Host + parts := strings.Split(hostPort, ":") + if len(parts) != 2 { + log.Println("Invalid host:port format") + return "" } + ip := parts[0] + // Change the port to the RAFT_P2P_PORT + return fmt.Sprintf("/ip4/%s/tcp/%v/p2p/%s", ip, RAFT_P2P_PORT, peerID) } diff --git a/cmd/trustedpods/autoscaler.go b/cmd/trustedpods/autoscaler.go index 16927982..5cc1d3ad 100644 --- a/cmd/trustedpods/autoscaler.go +++ b/cmd/trustedpods/autoscaler.go @@ -25,8 +25,11 @@ var autoscalerCmd = &cobra.Command{ client := pbcon.NewAutoscalerServiceClient( http.DefaultClient, baseUrl) - log.Printf("%v\n", nodesAddrs) - request := connect.NewRequest(&pb.ConnectClusterRequest{NodeGateway: baseUrl, Servers: nodesAddrs, Timeout: 10}) + log.Printf("Connecting Clusters:%v\n", nodesAddrs) + request := connect.NewRequest(&pb.ConnectClusterRequest{NodeGateway: baseUrl, Servers: nodesAddrs, Timeout: 30}) + // Add the Host that is needed for the ingress to route the autoscaler pod + request.Header().Set("Host", "autoscaler.local") + log.Printf("Sending Request to: %v\n", baseUrl) response, err := client.ConnectCluster(context.Background(), request) if err != nil { return fmt.Errorf("Error connecting to cluster:%v", err) diff --git a/package.json b/package.json index 7860d8b3..a00c8cca 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "directories": { "test": "test" }, + "packageManager": "npm@10.7.0", "scripts": { "lint": "eslint pkg/**/*.\\{ts,js\\} test/**/*.\\{ts,js\\} --ignore-pattern **/*.config.ts", "fmt": "eslint --fix pkg/**/*.\\{ts,js\\} test/**/*.\\{ts,js\\} --ignore-pattern **/*.config.ts", @@ -49,10 +50,5 @@ "helia": "^4.2.1", "private-ip": "^3.0.2" }, - "workspaces": [ - "test/e2e/webui", - "pkg/ipfs-ts", - "pkg/proto-ts", - "pkg/abi-ts" - ] + "workspaces": ["test/e2e/webui", "pkg/ipfs-ts", "pkg/proto-ts", "pkg/abi-ts"] } diff --git a/pkg/proto/autoscaler.pb.go b/pkg/proto/autoscaler.pb.go index 8905450a..a48379b0 100644 --- a/pkg/proto/autoscaler.pb.go +++ b/pkg/proto/autoscaler.pb.go @@ -9,6 +9,7 @@ package proto import ( + _ "github.com/golang/protobuf/ptypes/empty" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -141,37 +142,96 @@ func (x *ConnectClusterResponse) GetError() string { return "" } +type TriggerNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PeerID string `protobuf:"bytes,1,opt,name=peerID,proto3" json:"peerID,omitempty"` +} + +func (x *TriggerNodeResponse) Reset() { + *x = TriggerNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_autoscaler_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TriggerNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerNodeResponse) ProtoMessage() {} + +func (x *TriggerNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_autoscaler_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerNodeResponse.ProtoReflect.Descriptor instead. +func (*TriggerNodeResponse) Descriptor() ([]byte, []int) { + return file_autoscaler_proto_rawDescGZIP(), []int{2} +} + +func (x *TriggerNodeResponse) GetPeerID() string { + if x != nil { + return x.PeerID + } + return "" +} + var File_autoscaler_proto protoreflect.FileDescriptor var file_autoscaler_proto_rawDesc = []byte{ 0x0a, 0x10, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, - 0x22, 0x6d, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, - 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x6e, 0x6f, 0x64, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, - 0x48, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0x90, 0x01, 0x0a, 0x11, 0x41, 0x75, - 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x7b, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, - 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, - 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, - 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2c, 0x5a, 0x2a, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, - 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, - 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6d, 0x0a, + 0x15, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x47, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x6f, 0x64, + 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x48, 0x0a, 0x16, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2d, 0x0a, 0x13, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, + 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, + 0x65, 0x65, 0x72, 0x49, 0x44, 0x32, 0x87, 0x02, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x6f, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, 0x0a, 0x0e, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x33, 0x2e, + 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, + 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, + 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x61, 0x75, 0x74, 0x6f, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x61, + 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, + 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, + 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, + 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -186,16 +246,19 @@ func file_autoscaler_proto_rawDescGZIP() []byte { return file_autoscaler_proto_rawDescData } -var file_autoscaler_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_autoscaler_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_autoscaler_proto_goTypes = []interface{}{ (*ConnectClusterRequest)(nil), // 0: apocryph.proto.v0.autoscaler.ConnectClusterRequest (*ConnectClusterResponse)(nil), // 1: apocryph.proto.v0.autoscaler.ConnectClusterResponse + (*TriggerNodeResponse)(nil), // 2: apocryph.proto.v0.autoscaler.TriggerNodeResponse } var file_autoscaler_proto_depIdxs = []int32{ 0, // 0: apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster:input_type -> apocryph.proto.v0.autoscaler.ConnectClusterRequest - 1, // 1: apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster:output_type -> apocryph.proto.v0.autoscaler.ConnectClusterResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type + 0, // 1: apocryph.proto.v0.autoscaler.AutoscalerService.TriggerNode:input_type -> apocryph.proto.v0.autoscaler.ConnectClusterRequest + 1, // 2: apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster:output_type -> apocryph.proto.v0.autoscaler.ConnectClusterResponse + 2, // 3: apocryph.proto.v0.autoscaler.AutoscalerService.TriggerNode:output_type -> apocryph.proto.v0.autoscaler.TriggerNodeResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -231,6 +294,18 @@ func file_autoscaler_proto_init() { return nil } } + file_autoscaler_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TriggerNodeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -238,7 +313,7 @@ func file_autoscaler_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_autoscaler_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/proto/protoconnect/autoscaler.connect.go b/pkg/proto/protoconnect/autoscaler.connect.go index 50cc9450..14e0f39b 100644 --- a/pkg/proto/protoconnect/autoscaler.connect.go +++ b/pkg/proto/protoconnect/autoscaler.connect.go @@ -38,18 +38,23 @@ const ( // AutoscalerServiceConnectClusterProcedure is the fully-qualified name of the AutoscalerService's // ConnectCluster RPC. AutoscalerServiceConnectClusterProcedure = "/apocryph.proto.v0.autoscaler.AutoscalerService/ConnectCluster" + // AutoscalerServiceTriggerNodeProcedure is the fully-qualified name of the AutoscalerService's + // TriggerNode RPC. + AutoscalerServiceTriggerNodeProcedure = "/apocryph.proto.v0.autoscaler.AutoscalerService/TriggerNode" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( autoscalerServiceServiceDescriptor = proto.File_autoscaler_proto.Services().ByName("AutoscalerService") autoscalerServiceConnectClusterMethodDescriptor = autoscalerServiceServiceDescriptor.Methods().ByName("ConnectCluster") + autoscalerServiceTriggerNodeMethodDescriptor = autoscalerServiceServiceDescriptor.Methods().ByName("TriggerNode") ) // AutoscalerServiceClient is a client for the apocryph.proto.v0.autoscaler.AutoscalerService // service. type AutoscalerServiceClient interface { ConnectCluster(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.ConnectClusterResponse], error) + TriggerNode(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.TriggerNodeResponse], error) } // NewAutoscalerServiceClient constructs a client for the @@ -69,12 +74,19 @@ func NewAutoscalerServiceClient(httpClient connect.HTTPClient, baseURL string, o connect.WithSchema(autoscalerServiceConnectClusterMethodDescriptor), connect.WithClientOptions(opts...), ), + triggerNode: connect.NewClient[proto.ConnectClusterRequest, proto.TriggerNodeResponse]( + httpClient, + baseURL+AutoscalerServiceTriggerNodeProcedure, + connect.WithSchema(autoscalerServiceTriggerNodeMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // autoscalerServiceClient implements AutoscalerServiceClient. type autoscalerServiceClient struct { connectCluster *connect.Client[proto.ConnectClusterRequest, proto.ConnectClusterResponse] + triggerNode *connect.Client[proto.ConnectClusterRequest, proto.TriggerNodeResponse] } // ConnectCluster calls apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster. @@ -82,10 +94,16 @@ func (c *autoscalerServiceClient) ConnectCluster(ctx context.Context, req *conne return c.connectCluster.CallUnary(ctx, req) } +// TriggerNode calls apocryph.proto.v0.autoscaler.AutoscalerService.TriggerNode. +func (c *autoscalerServiceClient) TriggerNode(ctx context.Context, req *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.TriggerNodeResponse], error) { + return c.triggerNode.CallUnary(ctx, req) +} + // AutoscalerServiceHandler is an implementation of the // apocryph.proto.v0.autoscaler.AutoscalerService service. type AutoscalerServiceHandler interface { ConnectCluster(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.ConnectClusterResponse], error) + TriggerNode(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.TriggerNodeResponse], error) } // NewAutoscalerServiceHandler builds an HTTP handler from the service implementation. It returns @@ -100,10 +118,18 @@ func NewAutoscalerServiceHandler(svc AutoscalerServiceHandler, opts ...connect.H connect.WithSchema(autoscalerServiceConnectClusterMethodDescriptor), connect.WithHandlerOptions(opts...), ) + autoscalerServiceTriggerNodeHandler := connect.NewUnaryHandler( + AutoscalerServiceTriggerNodeProcedure, + svc.TriggerNode, + connect.WithSchema(autoscalerServiceTriggerNodeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/apocryph.proto.v0.autoscaler.AutoscalerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case AutoscalerServiceConnectClusterProcedure: autoscalerServiceConnectClusterHandler.ServeHTTP(w, r) + case AutoscalerServiceTriggerNodeProcedure: + autoscalerServiceTriggerNodeHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -116,3 +142,7 @@ type UnimplementedAutoscalerServiceHandler struct{} func (UnimplementedAutoscalerServiceHandler) ConnectCluster(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.ConnectClusterResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("apocryph.proto.v0.autoscaler.AutoscalerService.ConnectCluster is not implemented")) } + +func (UnimplementedAutoscalerServiceHandler) TriggerNode(context.Context, *connect.Request[proto.ConnectClusterRequest]) (*connect.Response[proto.TriggerNodeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("apocryph.proto.v0.autoscaler.AutoscalerService.TriggerNode is not implemented")) +} diff --git a/pkg/raft/raft.go b/pkg/raft/raft.go index 7ffa6a60..eff6e0d6 100644 --- a/pkg/raft/raft.go +++ b/pkg/raft/raft.go @@ -11,6 +11,7 @@ import ( "github.com/libp2p/go-libp2p" raftp2p "github.com/libp2p/go-libp2p-raft" "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peerstore" ) @@ -34,11 +35,12 @@ type RaftNode struct { LogStore raft.LogStore } -func NewRaftNode(host host.Host, peers []*host.Host, raftDir string) (*RaftNode, error) { +func NewRaftNode(host host.Host, peers []*peer.AddrInfo, raftDir string) (*RaftNode, error) { for _, peerPtr := range peers { peer := *peerPtr - if peer.Addrs()[0].String() != host.Addrs()[0].String() { - host.Peerstore().AddAddrs(peer.ID(), peer.Addrs(), peerstore.PermanentAddrTTL) + // skip adding self + if peer.Addrs[0].String() != host.Addrs()[0].String() { + host.Peerstore().AddAddrs(peer.ID, peer.Addrs, peerstore.PermanentAddrTTL) } } @@ -79,8 +81,8 @@ func NewRaftNode(host host.Host, peers []*host.Host, raftDir string) (*RaftNode, peer := *peerPtr servers = append(servers, raft.Server{ Suffrage: raft.Voter, - ID: raft.ServerID(peer.ID().String()), - Address: raft.ServerAddress(peer.ID().String()), + ID: raft.ServerID(peer.ID.String()), + Address: raft.ServerAddress(peer.ID.String()), }) } serversCfg := raft.Configuration{Servers: servers} diff --git a/proto/autoscaler.proto b/proto/autoscaler.proto index 7b6e31c5..362a21ec 100644 --- a/proto/autoscaler.proto +++ b/proto/autoscaler.proto @@ -5,19 +5,25 @@ package apocryph.proto.v0.autoscaler; option go_package = "github.com/comrade-coop/apocryph/pkg/proto"; +import "google/protobuf/empty.proto"; service AutoscalerService { rpc ConnectCluster(ConnectClusterRequest) returns (ConnectClusterResponse); + rpc TriggerNode(ConnectClusterRequest) returns (TriggerNodeResponse); } -message ConnectClusterRequest{ +message ConnectClusterRequest { // could get it from within the cluster maybe? string nodeGateway = 1; repeated string servers = 2; uint32 timeout = 3; } -message ConnectClusterResponse{ +message ConnectClusterResponse { bool success = 1; string error = 2; } + +message TriggerNodeResponse { + string peerID =1; +} diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh index 78e95a0c..5067acb2 100755 --- a/test/e2e/autoscaler/run-test.sh +++ b/test/e2e/autoscaler/run-test.sh @@ -1,6 +1,9 @@ #!/bin/bash cd "$(dirname "$0")" +set -v + +sudo chmod o+rw /run/containerd/containerd.sock trap 'kill $(jobs -p) &>/dev/null' EXIT @@ -13,7 +16,6 @@ which minikube >/dev/null; which helmfile >/dev/null; which helm >/dev/null; whi which docker >/dev/null which virtualbox >/dev/null -set -v # based on https://stackoverflow.com/a/31269848 / https://bobcopeland.com/blog/2012/10/goto-in-bash/ if [ -n "$1" ]; then @@ -22,7 +24,6 @@ if [ -n "$1" ]; then exit fi -sudo chmod o+rw /run/containerd/containerd.sock ## 0: Set up the external environment @@ -62,6 +63,8 @@ helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress- minikube profile list +sleep 5 + ## 4.0: Register the providers in the marketplace minikube profile c1 @@ -112,19 +115,46 @@ go run ../../../cmd/trustedpods registry get --config ../../integration/registry --ipfs /ip4/127.0.0.1/tcp/5004 \ ## 5.0: Deploy the autoscaler to the providers using their p2p multiaddr -minikube profile c1 +set -v +rm -f ~/.apocryph/deployment/* +PAYMENT_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.payment.value') +REGISTRY_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.registry.value') +PUBLISHER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(2\)/ {print $2; exit}') +FUNDS=10000000000000000000000 + +minikube profile c1 source swarm-connect.sh PROVIDER_ETH=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 #TODO= anvil.accounts[1] +echo $PROVIDER_IPFS + +go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ + --ethereum-key "$PUBLISHER_KEY" \ + --payment-contract "$PAYMENT_CONTRACT" \ + --registry-contract "$REGISTRY_CONTRACT" \ + --funds "$FUNDS" \ + --upload-images=true \ + --mint-funds \ + --provider /p2p/"$PROVIDER_IPFS" \ + --provider-eth "$PROVIDER_ETH" + +sleep 5 + +## 5.2: deploy to the second cluster +minikube profile c2 +source swarm-connect.sh +# for now just remove the deployment file to avoid uploading instead of deploying +rm -f ~/.apocryph/deployment/* + PUBLISHER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(2\)/ {print $2; exit}') PAYMENT_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.payment.value') REGISTRY_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.registry.value') FUNDS=10000000000000000000000 -set +v -set -x +PROVIDER_ETH=0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f #TODO= anvil.accounts[7] +echo $PROVIDER_IPFS go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ --ethereum-key "$PUBLISHER_KEY" \ @@ -136,4 +166,40 @@ go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ --provider /p2p/"$PROVIDER_IPFS" \ --provider-eth "$PROVIDER_ETH" +sleep 5 + +## 5.3: deploy to the third cluster +minikube profile c3 +source swarm-connect.sh +rm -f ~/.apocryph/deployment/* + +PUBLISHER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(2\)/ {print $2; exit}') +PAYMENT_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.payment.value') +REGISTRY_CONTRACT=$(cat ../../../contracts/broadcast/Deploy.s.sol/31337/run-latest.json | jq -r '.returns.registry.value') +FUNDS=10000000000000000000000 + +PROVIDER_ETH=0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 #TODO= anvil.accounts[8] +FUNDS=10000000000000000000000 + +echo $PROVIDER_IPFS + +go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ + --ethereum-key "$PUBLISHER_KEY" \ + --payment-contract "$PAYMENT_CONTRACT" \ + --registry-contract "$REGISTRY_CONTRACT" \ + --funds "$FUNDS" \ + --upload-images=true \ + --mint-funds \ + --provider /p2p/"$PROVIDER_IPFS" \ + --provider-eth "$PROVIDER_ETH" + +## 6.0: Connect the cluster + +minikube profile c1 +C1_INGRESS_URL=$(minikube service -n keda ingress-nginx-controller --url=true | head -n 1); echo $C1_INGRESS_URL +minikube profile c2 +C2_INGRESS_URL=$(minikube service -n keda ingress-nginx-controller --url=true | head -n 1); echo $C2_INGRESS_URL +minikube profile c3 +C3_INGRESS_URL=$(minikube service -n keda ingress-nginx-controller --url=true | head -n 1); echo $C3_INGRESS_URL +go run ../../../cmd/trustedpods/ autoscale --url "$C1_INGRESS_URL" --providers "$C1_INGRESS_URL","$C2_INGRESS_URL","$C3_INGRESS_URL" diff --git a/test/e2e/autoscaler/swarm-connect.sh b/test/e2e/autoscaler/swarm-connect.sh index 75e0165f..1abc8c5c 100755 --- a/test/e2e/autoscaler/swarm-connect.sh +++ b/test/e2e/autoscaler/swarm-connect.sh @@ -1,15 +1,20 @@ #!/bin/bash ## Configure provider/in-cluster IPFS and publisher IPFS ## -pkill -f "kubectl port-forward" pkill ipfs +pkill -f "kubectl port-forward" + +PORT_5004="" +PROVIDER_IPFS="" +IPFS_DAEMON="" { while ! kubectl get -n ipfs endpoints ipfs-rpc -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; } O_IPFS_PATH=$IPFS_PATH export IPFS_PATH=$(mktemp ipfs.XXXX --tmpdir -d) -[ "$PORT_5004" == "" ] && { PORT_5004="yes" ; kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & sleep 0.5; } +kubectl port-forward --namespace ipfs svc/ipfs-rpc 5004:5001 & + echo /ip4/127.0.0.1/tcp/5004 > $IPFS_PATH/api SWARM_ADDRESSES=$(minikube service -n ipfs ipfs-swarm --url | head -n 1 | sed -E 's|http://(.+):(.+)|["/ip4/\1/tcp/\2", "/ip4/\1/udp/\2/quic", "/ip4/\1/udp/\2/quic-v1", "/ip4/\1/udp/\2/quic-v1/webtransport"]|') @@ -30,9 +35,8 @@ ipfs id &>/dev/null || ipfs init ipfs config --json Experimental.Libp2pStreamMounting true -[ -n "$IPFS_DAEMON" ] || { IPFS_DAEMON=yes; ipfs daemon & { while ! [ -f ${IPFS_PATH:-~/.ipfs}/api ]; do sleep 0.1; done; } 2>/dev/null; } +ipfs daemon & { while ! [ -f ${IPFS_PATH:-~/.ipfs}/api ]; do sleep 0.1; done; } echo "$SWARM_ADDRESSES" | jq -r '.[] + "/p2p/'"$PROVIDER_IPFS"'"' | xargs -n 1 ipfs swarm connect || true sleep 5 - diff --git a/test/integration/raft/main.go b/test/integration/raft/main.go index eb2c177e..d6bbe42b 100644 --- a/test/integration/raft/main.go +++ b/test/integration/raft/main.go @@ -5,7 +5,7 @@ import ( "time" "github.com/comrade-coop/apocryph/pkg/raft" - "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" ) func main() { @@ -21,7 +21,21 @@ func main() { defer peer2.Close() defer peer3.Close() - peers := []*host.Host{&peer1, &peer2, &peer3} + peerInfo1, err := peer.AddrInfoFromString(fmt.Sprintf("/ip4/127.0.0.1/tcp/9997/p2p/%v", peer1.ID())) + if err != nil { + panic("failed to create AddrInfo from address") + } + peerInfo2, err := peer.AddrInfoFromString(fmt.Sprintf("/ip4/127.0.0.1/tcp/9998/p2p/%v", peer2.ID())) + if err != nil { + panic("failed to create AddrInfo from address") + } + peerInfo3, err := peer.AddrInfoFromString(fmt.Sprintf("/ip4/127.0.0.1/tcp/9999/p2p/%v", peer3.ID())) + if err != nil { + panic("failed to create AddrInfo from address") + } + + peers := []*peer.AddrInfo{peerInfo1, peerInfo2, peerInfo3} + node1, err := raft.NewRaftNode(peer1, peers, "") if err != nil { fmt.Printf("Error:%s", err) diff --git a/turbo.json b/turbo.json index 3c2aa641..5b804325 100644 --- a/turbo.json +++ b/turbo.json @@ -1,6 +1,6 @@ { "$schema": "https://turbo.build/schema.json", - "pipeline": { + "tasks": { "build": { "dependsOn": ["//#build-images"] }, From 46459b4d41e18397c55eceb0bad781b5c972dc40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:37:00 +0000 Subject: [PATCH 12/12] chore(deps): bump fast-xml-parser from 4.4.0 to 4.4.1 Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 4.4.0 to 4.4.1. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.4.0...v4.4.1) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ecac6846..081a06f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9183,9 +9183,9 @@ "dev": true }, "node_modules/fast-xml-parser": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", - "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "funding": [ { "type": "github",