Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rqlite for openSUSE:Factory checked in at 2025-10-09 15:05:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rqlite (Old) and /work/SRC/openSUSE:Factory/.rqlite.new.11973 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rqlite" Thu Oct 9 15:05:08 2025 rev:28 rq:1309849 version:9.1.2 Changes: -------- --- /work/SRC/openSUSE:Factory/rqlite/rqlite.changes 2025-09-20 22:04:32.499831777 +0200 +++ /work/SRC/openSUSE:Factory/.rqlite.new.11973/rqlite.changes 2025-10-09 15:08:01.642482259 +0200 @@ -1,0 +2,7 @@ +Wed Oct 08 19:26:06 UTC 2025 - Andreas Stieger <[email protected]> + +- Update to version 9.1.2: + * Support Linearizable reads on the Unified Endpoint + * 'go mod' updates + +------------------------------------------------------------------- Old: ---- rqlite-9.1.0.tar.xz New: ---- rqlite-9.1.2.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rqlite.spec ++++++ --- /var/tmp/diff_new_pack.1mgL8w/_old 2025-10-09 15:08:02.282509237 +0200 +++ /var/tmp/diff_new_pack.1mgL8w/_new 2025-10-09 15:08:02.282509237 +0200 @@ -16,14 +16,14 @@ # Name: rqlite -Version: 9.1.0 +Version: 9.1.2 Release: 0 Summary: Distributed relational database built on SQLite License: MIT URL: https://rqlite.io/ Source: %{name}-%{version}.tar.xz Source1: vendor.tar.xz -BuildRequires: go >= 1.22.0 +BuildRequires: go >= 1.25.0 BuildRequires: golang-packaging BuildRequires: pkgconfig BuildRequires: pkgconfig(sqlite3) ++++++ _service ++++++ --- /var/tmp/diff_new_pack.1mgL8w/_old 2025-10-09 15:08:02.338511598 +0200 +++ /var/tmp/diff_new_pack.1mgL8w/_new 2025-10-09 15:08:02.346511935 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/rqlite/rqlite.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v9.1.0</param> + <param name="revision">v9.1.2</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.1mgL8w/_old 2025-10-09 15:08:02.378513284 +0200 +++ /var/tmp/diff_new_pack.1mgL8w/_new 2025-10-09 15:08:02.390513790 +0200 @@ -1,7 +1,7 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/rqlite/rqlite.git</param> - <param name="changesrevision">9c74a149e1eb2aaf15837b34805afad253c448f0</param> + <param name="changesrevision">6ab73777f471f2c3e59329b1b013621fd73c1c3b</param> </service> </servicedata> (No newline at EOF) ++++++ rqlite-9.1.0.tar.xz -> rqlite-9.1.2.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/.circleci/config.yml new/rqlite-9.1.2/.circleci/config.yml --- old/rqlite-9.1.0/.circleci/config.yml 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/.circleci/config.yml 2025-10-03 16:33:42.000000000 +0200 @@ -214,27 +214,14 @@ end_to_end_multi: docker: - image: << pipeline.parameters.primary_image >> + environment: + RQLITED_PATH: /home/circleci/go/bin/rqlited steps: - checkout - restore_and_save_cache - run: go install ./... - - run: - command: python3 system_test/e2e/multi_node.py - environment: - RQLITED_PATH: /home/circleci/go/bin/rqlited - resource_class: large - - end_to_end_multi_adv: - docker: - - image: << pipeline.parameters.primary_image >> - steps: - - checkout - - restore_and_save_cache - - run: go install ./... - - run: - command: python3 system_test/e2e/multi_node_adv.py - environment: - RQLITED_PATH: /home/circleci/go/bin/rqlited + - run: python3 system_test/e2e/multi_node.py + - run: python3 system_test/e2e/multi_node_adv.py resource_class: large end_to_end_autoclustering: @@ -252,52 +239,32 @@ RQLITED_PATH: /home/circleci/go/bin/rqlited resource_class: large - end_to_end_auto_state_s3: + end_to_end_auto_state: docker: - image: << pipeline.parameters.primary_image >> - image: minio/minio name: minio command: server /data + environment: + RQLITED_PATH: /home/circleci/go/bin/rqlited + MINIO_ENDPOINT: http://minio:9000 + MINIO_ROOT_USER: minioadmin + MINIO_ROOT_PASSWORD: minioadmin + MINIO_BUCKET: minio-bucket + # All other required env vars for GCS and S3 are set via CircleCI project settings steps: - checkout - restore_and_save_cache + # Build rqlite now, which will give time for minio to come up - run: go install ./... - run: mc alias set myminio http://minio:9000 minioadmin minioadmin - run: mc mb myminio/minio-bucket - run: - command: python3 system_test/e2e/auto_state_s3.py - environment: - RQLITED_PATH: /home/circleci/go/bin/rqlited - MINIO_ENDPOINT: http://minio:9000 - MINIO_ROOT_USER: minioadmin - MINIO_ROOT_PASSWORD: minioadmin - MINIO_BUCKET: minio-bucket - resource_class: large - - end_to_end_auto_state_file: - docker: - - image: << pipeline.parameters.primary_image >> - steps: - - checkout - - restore_and_save_cache - - run: go install ./... - - run: command: python3 system_test/e2e/auto_state_file.py - environment: - RQLITED_PATH: /home/circleci/go/bin/rqlited - resource_class: large - - end_to_end_auto_state_gcs: - docker: - - image: << pipeline.parameters.primary_image >> - steps: - - checkout - - restore_and_save_cache - - run: go install ./... - run: command: python3 system_test/e2e/auto_state_gcs.py - environment: - RQLITED_PATH: /home/circleci/go/bin/rqlited + - run: + command: python3 system_test/e2e/auto_state_s3.py resource_class: large end_to_end_cdc: @@ -356,12 +323,9 @@ - test_odd_race - end_to_end_single - end_to_end_multi - - end_to_end_multi_adv - end_to_end_joining - end_to_end_autoclustering - - end_to_end_auto_state_s3 - - end_to_end_auto_state_gcs - - end_to_end_auto_state_file + - end_to_end_auto_state - end_to_end_upgrade - end_to_end_cdc - end_to_end_extensions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/CHANGELOG.md new/rqlite-9.1.2/CHANGELOG.md --- old/rqlite-9.1.0/CHANGELOG.md 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/CHANGELOG.md 2025-10-03 16:33:42.000000000 +0200 @@ -1,3 +1,11 @@ +## v9.1.2 (October 3rd 2025) +There are no changes in this release relative to v9.1.1. However this release is the first that mirrors container images to the [GitHub Container Registry](https://docs.github.com/en/packages). + +## v9.1.1 (October 1st 2025) +### Implementation changes and bug fixes +- [PR #2349](https://github.com/rqlite/rqlite/pull/2349): Support Linearizable reads on the Unified Endpoint, fixes issue [#2347](https://github.com/rqlite/rqlite/issues/2347). +- [PR #2350](https://github.com/rqlite/rqlite/pull/2350): 'go mod' updates. + ## v9.1.0 (September 19th 2025) ### New features - [PR #2340](https://github.com/rqlite/rqlite/pull/2340): Support file-based storage for automatic backups, fixes issue [#2332](https://github.com/rqlite/rqlite/issues/2332). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/README.md new/rqlite-9.1.2/README.md --- old/rqlite-9.1.0/README.md 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/README.md 2025-10-03 16:33:42.000000000 +0200 @@ -13,9 +13,9 @@ [](https://www.rqlite.io/join-slack) [](https://groups.google.com/group/rqlite) -[**rqlite**](https://rqlite.io) is a [rock](https://www.sqlite.org/testing.html)-[solid](https://philipotoole.com/how-is-rqlite-tested/), highly-available, distributed relational database built on [SQLite](https://www.sqlite.org/). It's lightweight, developer-friendly, and exceptionally easy to operate. +[**rqlite**](https://rqlite.io) is a [rock](https://www.sqlite.org/testing.html)-[solid](https://philipotoole.com/how-is-rqlite-tested/), fault-tolerant, distributed relational database built on [SQLite](https://www.sqlite.org/). It's lightweight, developer-friendly, and exceptionally easy to operate. -Use rqlite to reliably store your most important data, ensuring it's always available to your applications -- think [etcd](https://etcd.io/), but with relational modeling available. Whether you're deploying **resilient services in the cloud** or **reliable applications at the edge**, rqlite is a solution that offers effortless installation, deployment, and operation. +Use rqlite to reliably store your most important data, ensuring it's always available to your applications -- think [etcd](https://etcd.io/), but with relational modeling available. Whether you're deploying **resilient services in the cloud** or **reliable applications at the edge**, rqlite is a solution that offers **effortless installation, deployment, and operation**. <a href="https://rqlite.io"><strong>Website</strong></a> ยท <a href="https://www.rqlite.io/join-slack"><strong>Slack</strong></a> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/command/proto/command.pb.go new/rqlite-9.1.2/command/proto/command.pb.go --- old/rqlite-9.1.0/command/proto/command.pb.go 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/command/proto/command.pb.go 2025-10-03 16:33:42.000000000 +0200 @@ -887,14 +887,15 @@ } type ExecuteQueryRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Request *Request `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"` - Timings bool `protobuf:"varint,2,opt,name=timings,proto3" json:"timings,omitempty"` - Level QueryRequest_Level `protobuf:"varint,3,opt,name=level,proto3,enum=command.QueryRequest_Level" json:"level,omitempty"` - Freshness int64 `protobuf:"varint,4,opt,name=freshness,proto3" json:"freshness,omitempty"` - FreshnessStrict bool `protobuf:"varint,5,opt,name=freshness_strict,json=freshnessStrict,proto3" json:"freshness_strict,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Request *Request `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"` + Timings bool `protobuf:"varint,2,opt,name=timings,proto3" json:"timings,omitempty"` + Level QueryRequest_Level `protobuf:"varint,3,opt,name=level,proto3,enum=command.QueryRequest_Level" json:"level,omitempty"` + Freshness int64 `protobuf:"varint,4,opt,name=freshness,proto3" json:"freshness,omitempty"` + FreshnessStrict bool `protobuf:"varint,5,opt,name=freshness_strict,json=freshnessStrict,proto3" json:"freshness_strict,omitempty"` + LinearizableTimeout int64 `protobuf:"varint,6,opt,name=linearizable_timeout,json=linearizableTimeout,proto3" json:"linearizable_timeout,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ExecuteQueryRequest) Reset() { @@ -962,6 +963,13 @@ return false } +func (x *ExecuteQueryRequest) GetLinearizableTimeout() int64 { + if x != nil { + return x.LinearizableTimeout + } + return 0 +} + type ExecuteQueryResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Result: @@ -2124,13 +2132,14 @@ "\x0elast_insert_id\x18\x01 \x01(\x03R\flastInsertId\x12#\n" + "\rrows_affected\x18\x02 \x01(\x03R\frowsAffected\x12\x14\n" + "\x05error\x18\x03 \x01(\tR\x05error\x12\x12\n" + - "\x04time\x18\x04 \x01(\x01R\x04time\"\xd7\x01\n" + + "\x04time\x18\x04 \x01(\x01R\x04time\"\x8a\x02\n" + "\x13ExecuteQueryRequest\x12*\n" + "\arequest\x18\x01 \x01(\v2\x10.command.RequestR\arequest\x12\x18\n" + "\atimings\x18\x02 \x01(\bR\atimings\x121\n" + "\x05level\x18\x03 \x01(\x0e2\x1b.command.QueryRequest.LevelR\x05level\x12\x1c\n" + "\tfreshness\x18\x04 \x01(\x03R\tfreshness\x12)\n" + - "\x10freshness_strict\x18\x05 \x01(\bR\x0ffreshnessStrict\"\x84\x01\n" + + "\x10freshness_strict\x18\x05 \x01(\bR\x0ffreshnessStrict\x121\n" + + "\x14linearizable_timeout\x18\x06 \x01(\x03R\x13linearizableTimeout\"\x84\x01\n" + "\x14ExecuteQueryResponse\x12\"\n" + "\x01q\x18\x01 \x01(\v2\x12.command.QueryRowsH\x00R\x01q\x12&\n" + "\x01e\x18\x02 \x01(\v2\x16.command.ExecuteResultH\x00R\x01e\x12\x16\n" + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/command/proto/command.proto new/rqlite-9.1.2/command/proto/command.proto --- old/rqlite-9.1.0/command/proto/command.proto 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/command/proto/command.proto 2025-10-03 16:33:42.000000000 +0200 @@ -74,6 +74,7 @@ QueryRequest.Level level = 3; int64 freshness = 4; bool freshness_strict = 5; + int64 linearizable_timeout = 6; } message ExecuteQueryResponse { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/db/db_preupdate_test.go new/rqlite-9.1.2/db/db_preupdate_test.go --- old/rqlite-9.1.0/db/db_preupdate_test.go 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/db/db_preupdate_test.go 2025-10-03 16:33:42.000000000 +0200 @@ -145,6 +145,37 @@ }, }, { + name: "INSERT new row, all NULLs", + sql: `INSERT INTO foo(id, name, employer, ssn, age, weight, dob, active, data) VALUES( + 6, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL)`, + ev: &proto.CDCEvent{ + Table: "foo", + Op: proto.CDCEvent_INSERT, + NewRowId: 6, + NewRow: &proto.CDCRow{ + Values: []*proto.CDCValue{ + {Value: &proto.CDCValue_I{I: 6}}, + {Value: nil}, + {Value: nil}, + {Value: nil}, + {Value: nil}, + {Value: nil}, + {Value: nil}, + {Value: nil}, + {Value: nil}, + }, + }, + }, + }, + { name: "UPDATE single column", sql: `UPDATE foo SET name="declan" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/go.mod new/rqlite-9.1.2/go.mod --- old/rqlite-9.1.0/go.mod 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/go.mod 2025-10-03 16:33:42.000000000 +0200 @@ -1,13 +1,13 @@ module github.com/rqlite/rqlite/v9 -go 1.24.0 +go 1.25.0 require ( - github.com/aws/aws-sdk-go-v2 v1.39.0 - github.com/aws/aws-sdk-go-v2/config v1.31.8 - github.com/aws/aws-sdk-go-v2/credentials v1.18.12 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.6 - github.com/aws/aws-sdk-go-v2/service/s3 v1.88.1 + github.com/aws/aws-sdk-go-v2 v1.39.2 + github.com/aws/aws-sdk-go-v2/config v1.31.12 + github.com/aws/aws-sdk-go-v2/credentials v1.18.16 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.10 + github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/raft v1.7.3 github.com/mattn/go-sqlite3 v1.14.32 @@ -25,32 +25,34 @@ require ( github.com/armon/go-metrics v0.5.4 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.7 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.7 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.7 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.7 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.29.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 // indirect github.com/aws/smithy-go v1.23.0 // indirect + github.com/clipperhouse/uax29/v2 v2.2.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/fatih/color v1.18.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect - github.com/hashicorp/consul/api v1.32.1 // indirect + github.com/hashicorp/consul/api v1.32.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-metrics v0.5.4 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect - github.com/hashicorp/go-msgpack/v2 v2.1.3 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -58,23 +60,21 @@ github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mkideal/expr v0.1.0 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - go.etcd.io/etcd/api/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/v3 v3.6.4 // indirect + go.etcd.io/etcd/api/v3 v3.6.5 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.5 // indirect + go.etcd.io/etcd/client/v3 v3.6.5 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.42.0 // indirect - golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/term v0.35.0 // indirect golang.org/x/text v0.29.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect google.golang.org/grpc v1.75.1 // indirect ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/go.sum new/rqlite-9.1.2/go.sum --- old/rqlite-9.1.0/go.sum 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/go.sum 2025-10-03 16:33:42.000000000 +0200 @@ -5,42 +5,42 @@ 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-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aws/aws-sdk-go-v2 v1.39.0 h1:xm5WV/2L4emMRmMjHFykqiA4M/ra0DJVSWUkDyBjbg4= -github.com/aws/aws-sdk-go-v2 v1.39.0/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= +github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 h1:i8p8P4diljCr60PpJp6qZXNlgX4m2yQFpYk+9ZT+J4E= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1/go.mod h1:ddqbooRZYNoJ2dsTwOty16rM+/Aqmk/GOXrK8cg7V00= -github.com/aws/aws-sdk-go-v2/config v1.31.8 h1:kQjtOLlTU4m4A64TsRcqwNChhGCwaPBt+zCQt/oWsHU= -github.com/aws/aws-sdk-go-v2/config v1.31.8/go.mod h1:QPpc7IgljrKwH0+E6/KolCgr4WPLerURiU592AYzfSY= -github.com/aws/aws-sdk-go-v2/credentials v1.18.12 h1:zmc9e1q90wMn8wQbjryy8IwA6Q4XlaL9Bx2zIqdNNbk= -github.com/aws/aws-sdk-go-v2/credentials v1.18.12/go.mod h1:3VzdRDR5u3sSJRI4kYcOSIBbeYsgtVk7dG5R/U6qLWY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.7 h1:Is2tPmieqGS2edBnmOJIbdvOA6Op+rRpaYR60iBAwXM= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.7/go.mod h1:F1i5V5421EGci570yABvpIXgRIBPb5JM+lSkHF6Dq5w= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.6 h1:bByPm7VcaAgeT2+z5m0Lj5HDzm+g9AwbA3WFx2hPby0= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.6/go.mod h1:PhTe8fR8aFW0wDc6IV9BHeIzXhpv3q6AaVHnqiv5Pyc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.7 h1:UCxq0X9O3xrlENdKf1r9eRJoKz/b0AfGkpp3a7FPlhg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.7/go.mod h1:rHRoJUNUASj5Z/0eqI4w32vKvC7atoWR0jC+IkmVH8k= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.7 h1:Y6DTZUn7ZUC4th9FMBbo8LVE+1fyq3ofw+tRwkUd3PY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.7/go.mod h1:x3XE6vMnU9QvHN/Wrx2s44kwzV2o2g5x/siw4ZUJ9g8= +github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8= +github.com/aws/aws-sdk-go-v2/config v1.31.12/go.mod h1:/MM0dyD7KSDPR+39p9ZNVKaHDLb9qnfDurvVS2KAhN8= +github.com/aws/aws-sdk-go-v2/credentials v1.18.16 h1:4JHirI4zp958zC026Sm+V4pSDwW4pwLefKrc0bF2lwI= +github.com/aws/aws-sdk-go-v2/credentials v1.18.16/go.mod h1:qQMtGx9OSw7ty1yLclzLxXCRbrkjWAM7JnObZjmCB7I= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wgeqPL5DRFu5bQL9BGPQ8Y= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.10 h1:i9EmUTyCWtUp1KsBwKGTtZUxaRym4LmiFiBcb//i8Kw= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.10/go.mod h1:IPS1CSYQ8lfLYGytpMEPW4erZmVFUdxLpC0RCI/RCn8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.7 h1:BszAktdUo2xlzmYHjWMq70DqJ7cROM8iBd3f6hrpuMQ= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.7/go.mod h1:XJ1yHki/P7ZPuG4fd3f0Pg/dSGA2cTQBCLw82MH2H48= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9 h1:w9LnHqTq8MEdlnyhV4Bwfizd65lfNCNgdlNC6mM5paE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9/go.mod h1:LGEP6EK4nj+bwWNdrvX/FnDTFowdBNwcSPuZu/ouFys= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.7 h1:zmZ8qvtE9chfhBPuKB2aQFxW5F/rpwXUgmcVCgQzqRw= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.7/go.mod h1:vVYfbpd2l+pKqlSIDIOgouxNsGu5il9uDp0ooWb0jys= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7 h1:mLgc5QIgOy26qyh5bvW+nDoAppxgn3J2WV3m9ewq7+8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7/go.mod h1:wXb/eQnqt8mDQIQTTmcw58B5mYGxzLGZGK8PWNFZ0BA= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.7 h1:u3VbDKUCWarWiU+aIUK4gjTr/wQFXV17y3hgNno9fcA= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.7/go.mod h1:/OuMQwhSyRapYxq6ZNpPer8juGNrB4P5Oz8bZ2cgjQE= -github.com/aws/aws-sdk-go-v2/service/s3 v1.88.1 h1:+RpGuaQ72qnU83qBKVwxkznewEdAGhIWo/PQCmkhhog= -github.com/aws/aws-sdk-go-v2/service/s3 v1.88.1/go.mod h1:xajPTguLoeQMAOE44AAP2RQoUhF8ey1g5IFHARv71po= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.3 h1:7PKX3VYsZ8LUWceVRuv0+PU+E7OtQb1lgmi5vmUE9CM= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.3/go.mod h1:Ql6jE9kyyWI5JHn+61UT/Y5Z0oyVJGmgmJbZD5g4unY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.4 h1:e0XBRn3AptQotkyBFrHAxFB8mDhAIOfsG+7KyJ0dg98= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.4/go.mod h1:XclEty74bsGBCr1s0VSaA11hQ4ZidK4viWK7rRfO88I= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.4 h1:PR00NXRYgY4FWHqOGx3fC3lhVKjsp1GdloDv2ynMSd8= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.4/go.mod h1:Z+Gd23v97pX9zK97+tX4ppAgqCt3Z2dIXB02CtBncK8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9 h1:by3nYZLR9l8bUH7kgaMU4dJgYFjyRdFEfORlDpPILB4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9/go.mod h1:IWjQYlqw4EX9jw2g3qnEPPWvCE6bS8fKzhMed1OK7c8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9 h1:wuZ5uW2uhJR63zwNlqWH2W4aL4ZjeJP3o92/W+odDY4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9/go.mod h1:/G58M2fGszCrOzvJUkDdY8O9kycodunH4VdT5oBAqls= +github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3 h1:P18I4ipbk+b/3dZNq5YYh+Hq6XC0vp5RWkLp1tJldDA= +github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3/go.mod h1:Rm3gw2Jov6e6kDuamDvyIlZJDMYk97VeCZ82wz/mVZ0= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 h1:A1oRkiSQOWstGh61y4Wc/yQ04sqrQZr1Si/oAXj20/s= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.6/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8= github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -50,6 +50,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= +github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= @@ -74,6 +76,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -103,10 +107,10 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= -github.com/hashicorp/consul/api v1.32.1 h1:0+osr/3t/aZNAdJX558crU3PEjVrG4x6715aZHRgceE= -github.com/hashicorp/consul/api v1.32.1/go.mod h1:mXUWLnxftwTmDv4W3lzxYCPD199iNLLUyLfLGFJbtl4= -github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg= -github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s= +github.com/hashicorp/consul/api v1.32.4 h1:xNe27KcBNYHbqWX/6c6WTAlPoZlZv8onDEySmjcspO0= +github.com/hashicorp/consul/api v1.32.4/go.mod h1:jy0q71iTvUGfbCwo+ExBF0gEesE5cY2TSeAz2EoNG8E= +github.com/hashicorp/consul/sdk v0.16.3 h1:kI/oax+yeaoremkh36G/f4Q13ivdFF4AE+Co/LlZa0Q= +github.com/hashicorp/consul/sdk v0.16.3/go.mod h1:TSPshuYdi1OQwpLund2vkTHpp4WnLyhf7Q/YihGMtp0= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -126,8 +130,8 @@ github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= -github.com/hashicorp/go-msgpack/v2 v2.1.3 h1:cB1w4Zrk0O3jQBTcFMKqYQWRFfsSQ/TYKNyUUVyCP2c= -github.com/hashicorp/go-msgpack/v2 v2.1.3/go.mod h1:SjlwKKFnwBXvxD/I1bEcfJIBbEJ+MCUn39TxymNR5ZU= +github.com/hashicorp/go-msgpack/v2 v2.1.5 h1:Ue879bPnutj/hXfmUk6s/jtIK90XxgiUIcXRl656T44= +github.com/hashicorp/go-msgpack/v2 v2.1.5/go.mod h1:bjCsRXpZ7NsJdk45PoCQnzRGDaK8TKm5ZnDI/9y3J4M= 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= @@ -182,15 +186,13 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mkideal/cli v0.2.7 h1:mB/XrMzuddmTJ8f7KY1c+KzfYoM149tYGAnzmqRdvOU= github.com/mkideal/cli v0.2.7/go.mod h1:efaTeFI4jdPqzAe0bv3myLB2NW5yzMBLvWB70a6feco= github.com/mkideal/expr v0.1.0 h1:fzborV9TeSUmLm0aEQWTWcexDURFFo4v5gHSc818Kl8= @@ -231,9 +233,6 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rqlite/go-sqlite3 v1.42.0 h1:xfOaauBRqJyww/6g2z910/p3gyw/vjb2GgQYKfrZSrU= github.com/rqlite/go-sqlite3 v1.42.0/go.mod h1:R9H7CatgYBt3c+fSV/5yo2vLh4ZjCB0aMHdkv69fP4A= github.com/rqlite/raft-boltdb/v2 v2.0.0-20230523104317-c08e70f4de48 h1:NZ62M+kT0JqhyFUMc8I4SMmfmD4NGJxhb2ePJQXjryc= @@ -265,12 +264,12 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/api/v3 v3.6.5 h1:pMMc42276sgR1j1raO/Qv3QI9Af/AuyQUW6CBAWuntA= +go.etcd.io/etcd/api/v3 v3.6.5/go.mod h1:ob0/oWA/UQQlT1BmaEkWQzI0sJ1M0Et0mMpaABxguOQ= +go.etcd.io/etcd/client/pkg/v3 v3.6.5 h1:Duz9fAzIZFhYWgRjp/FgNq2gO1jId9Yae/rLn3RrBP8= +go.etcd.io/etcd/client/pkg/v3 v3.6.5/go.mod h1:8Wx3eGRPiy0qOFMZT/hfvdos+DjEaPxdIDiCDUv/FQk= +go.etcd.io/etcd/client/v3 v3.6.5 h1:yRwZNFBx/35VKHTcLDeO7XVLbCBFbPi+XV4OC3QJf2U= +go.etcd.io/etcd/client/v3 v3.6.5/go.mod h1:ZqwG/7TAFZ0BJ0jXRPoJjKQJtbFo/9NIY8uoFFKcCyo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= @@ -296,12 +295,12 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= -golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0= -golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -363,8 +362,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= @@ -372,10 +371,10 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 h1:d8Nakh1G+ur7+P3GcMjpRDEkoLUcLW2iU92XVqR+XMQ= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 h1:/OQuEa4YWtDt7uQWHd3q3sUMb+QOLQUg1xa8CEsRv5w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= +google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 h1:8XJ4pajGwOlasW+L13MnEGA8W4115jJySQtVfS2/IBU= +google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 h1:i8QOKZfYg6AbGVZzUAY3LrNWCKF8O6zFisU9Wl9RER4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/store/store.go new/rqlite-9.1.2/store/store.go --- old/rqlite-9.1.0/store/store.go 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/store/store.go 2025-10-03 16:33:42.000000000 +0200 @@ -63,6 +63,10 @@ // requested freshness. ErrStaleRead = errors.New("stale read") + // ErrStrongReadNeeded is returned if a strong read is required to + // guarantee linearizability. + ErrStrongReadNeeded = errors.New("strong read required") + // ErrOpenTimeout is returned when the Store does not apply its initial // logs within the specified time. ErrOpenTimeout = errors.New("timeout waiting for initial logs application") @@ -103,6 +107,9 @@ // ErrNodeNotFound is returned when a node with a given ID is not found in the cluster. ErrNodeNotFound = errors.New("node not found in cluster") + + // ErrClusterNotFound is returned when a cluster should exist but does not. + ErrClusterNotFound = errors.New("cluster not found") ) const ( @@ -834,8 +841,8 @@ return nil } -// WaitForAppliedFSM waits until the currently applied logs (at the time this -// function is called) are actually reflected by the FSM, or the timeout expires. +// WaitForAppliedFSM waits until the log Raft considers Applied (sent +// to the FSM) has actually been applied to the underlying state machine. func (s *Store) WaitForAppliedFSM(timeout time.Duration) (uint64, error) { if timeout == 0 { return 0, nil @@ -855,6 +862,16 @@ } } +// WaitForAllFSM waits for the last index in the Raft log to have been +// applied to the FSM. +func (s *Store) WaitForAllFSM(timeout time.Duration) error { + if timeout == 0 { + return nil + } + _, err := s.WaitForFSMIndex(s.raft.LastIndex(), timeout) + return err +} + // WaitForAllApplied waits for all Raft log entries to be applied to the // underlying database. func (s *Store) WaitForAllApplied(timeout time.Duration) error { @@ -1043,20 +1060,23 @@ if f.Error() != nil { return nil, f.Error() } + servers := f.Configuration().Servers + if len(servers) == 0 { + return nil, ErrClusterNotFound + } _, id := s.raft.LeaderWithID() if id == "" { return nil, ErrLeaderNotFound } - rs := f.Configuration().Servers - followers := make([]*Server, 0, len(rs)-1) - for i := range rs { - if rs[i].ID != raft.ServerID(id) && rs[i].Suffrage == raft.Voter { + followers := make([]*Server, 0, len(servers)-1) + for i := range servers { + if servers[i].ID != raft.ServerID(id) && servers[i].Suffrage == raft.Voter { followers = append(followers, &Server{ - ID: string(rs[i].ID), - Addr: string(rs[i].Address), - Suffrage: rs[i].Suffrage.String(), + ID: string(servers[i].ID), + Addr: string(servers[i].Address), + Suffrage: servers[i].Suffrage.String(), }) } } @@ -1332,48 +1352,16 @@ } } - // If linearizable consistency is requested, we will need to check the - // term when heartbeat processing completes to ensure the Leader didn't - // change during the processing of a Linearizable read. We also need to - // be sure that this node -- if Leader -- has actually committed a log - // in *this* term. Currently the Raft library doesn't help us do this, - // so we have to do it ourselves, by checking if at least one Strong - // Read has gone through the Raft log in this term. If it hasn't then - // we convert the first Linearizable read into a strong read. Subsequent - // Linearizable reads will then be able to operate normally in this term. - // - // See https://groups.google.com/g/raft-dev/c/4QlyV0aptEQ/m/1JxcmSgRAwAJ - // for an extensive discussion of this logic. readTerm := s.raft.CurrentTerm() - if qr.Level == proto.QueryRequest_QUERY_REQUEST_LEVEL_LINEARIZABLE && - readTerm != s.strongReadTerm.Load() { - qr.Level = proto.QueryRequest_QUERY_REQUEST_LEVEL_STRONG - s.numLRUpgraded.Add(1) - } - if qr.Level == proto.QueryRequest_QUERY_REQUEST_LEVEL_LINEARIZABLE { - if s.raft.State() != raft.Leader { - return nil, 0, ErrNotLeader - } - if !s.Ready() { - return nil, 0, ErrNotReady - } - - // Implement the technique from the Raft dissertation, section - // 6.4 "Processing read-only queries more efficiently". - readIndex := s.raft.CommitIndex() - if err := s.VerifyLeader(); err != nil { - return nil, 0, err - } - if s.raft.CurrentTerm() != readTerm { - return nil, 0, ErrStaleRead - } - lt := time.Duration(qr.LinearizableTimeout) - if lt == 0 { - lt = linearizableTimeout - } - if _, err := s.WaitForFSMIndex(readIndex, time.Duration(lt)); err != nil { - return nil, 0, err + err := s.waitForLinearizableRead(readTerm, qr.LinearizableTimeout) + if err != nil { + if err == ErrStrongReadNeeded { + qr.Level = proto.QueryRequest_QUERY_REQUEST_LEVEL_STRONG + s.numLRUpgraded.Add(1) + } else { + return nil, 0, err + } } } @@ -1408,6 +1396,10 @@ } return nil, 0, af.Error() } + // It's possible that the term has changed since we read it. But that's OK, + // worse case it will just mean another Strong read. It would be worse to + // store the current term, which could be later than when the strong read + // was performed. s.strongReadTerm.Store(readTerm) r := af.Response().(*fsmQueryResponse) return r.rows, af.Index(), r.error @@ -1458,9 +1450,23 @@ if !s.open.Is() { return nil, 0, ErrNotOpen } - nRW, _ := s.RORWCount(eqr) + nRW, nRO := s.RORWCount(eqr) isLeader := s.raft.State() == raft.Leader + // See the Query() code for a full explanation of this. + readTerm := s.raft.CurrentTerm() + if eqr.Level == proto.QueryRequest_QUERY_REQUEST_LEVEL_LINEARIZABLE { + err := s.waitForLinearizableRead(readTerm, eqr.LinearizableTimeout) + if err != nil { + if err == ErrStrongReadNeeded { + eqr.Level = proto.QueryRequest_QUERY_REQUEST_LEVEL_STRONG + s.numLRUpgraded.Add(1) + } else { + return nil, 0, err + } + } + } + if nRW == 0 && eqr.Level != proto.QueryRequest_QUERY_REQUEST_LEVEL_STRONG { // It's a little faster just to do a Query of the DB if we know there is no need // for consensus. @@ -1473,6 +1479,7 @@ } return resp } + if eqr.Level == proto.QueryRequest_QUERY_REQUEST_LEVEL_NONE && s.isStaleRead(eqr.Freshness, eqr.FreshnessStrict) { return nil, 0, ErrStaleRead } else if eqr.Level == proto.QueryRequest_QUERY_REQUEST_LEVEL_WEAK { @@ -1516,6 +1523,13 @@ return nil, 0, af.Error() } r := af.Response().(*fsmExecuteQueryResponse) + + // If we sent any reads through consensus they were strong reads by definition. + // Update our strong read term. + if nRO > 0 { + s.strongReadTerm.Store(readTerm) + } + return r.results, af.Index(), r.error } @@ -2142,6 +2156,51 @@ return config } +// waitForLinearizableRead performs the preprocessing needed for a +// linearizable read, or timeouts. Once this function returns without +// error subsequent reads on the Leader will be linearizable. +func (s *Store) waitForLinearizableRead(currReadTerm uint64, linearizableTimeoutParam int64) error { + // If linearizable consistency is requested, we will need to check the + // term when heartbeat processing completes to ensure the Leader didn't + // change during the processing of a Linearizable read. We also need to + // be sure that this node -- if Leader -- has actually committed a log + // in *this* term. Currently the Raft library doesn't help us do this, + // so we have to do it ourselves, by checking if at least one Strong + // Read has gone through the Raft log in this term. If it hasn't then + // we return an error indicating that a Strong Read is needed. + // + // See https://groups.google.com/g/raft-dev/c/4QlyV0aptEQ/m/1JxcmSgRAwAJ + // for an extensive discussion of this logic. + if currReadTerm != s.strongReadTerm.Load() { + return ErrStrongReadNeeded + } + + if s.raft.State() != raft.Leader { + return ErrNotLeader + } + if !s.Ready() { + return ErrNotReady + } + + // Implement the technique from the Raft dissertation, section + // 6.4 "Processing read-only queries more efficiently". + readIndex := s.raft.CommitIndex() + if err := s.VerifyLeader(); err != nil { + return err + } + if s.raft.CurrentTerm() != currReadTerm { + return ErrStaleRead + } + lt := time.Duration(linearizableTimeoutParam) + if lt == 0 { + lt = linearizableTimeout + } + if _, err := s.WaitForFSMIndex(readIndex, lt); err != nil { + return err + } + return nil +} + func (s *Store) isStaleRead(freshness int64, strict bool) bool { if s.raft.State() == raft.Leader { return false @@ -2182,7 +2241,7 @@ if s.firstLogAppliedT.IsZero() { s.firstLogAppliedT = time.Now() - s.logger.Printf("first log applied since node start, log at index %d", l.Index) + s.logger.Printf("first log applied since node %s started, log at index %d", s.raftID, l.Index) } cmd, mutated, r := func() (*proto.Command, bool, any) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/store/store_multi_test.go new/rqlite-9.1.2/store/store_multi_test.go --- old/rqlite-9.1.0/store/store_multi_test.go 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/store/store_multi_test.go 2025-10-03 16:33:42.000000000 +0200 @@ -41,6 +41,18 @@ t.Fatalf("Error waiting for leader: %s", err) } + // Send a noop through to ensure that the Configuration changes due to + // joining node have gone through the Raft log. + if af, err := s0.Noop("don't care"); err != nil || af.Error() != nil { + t.Fatalf("failed to noop on single node: %s", err.Error()) + } + if err := s0.WaitForAllFSM(500 * time.Millisecond); err != nil { + t.Fatalf("failed to wait for all FSM on leader: %s", err.Error()) + } + if err := s1.WaitForAllFSM(500 * time.Millisecond); err != nil { + t.Fatalf("failed to wait for all FSM on follower: %s", err.Error()) + } + // Ensure the leader is the same on both nodes. node0, err := s0.Leader() if err != nil { @@ -1847,13 +1859,14 @@ t.Fatalf("failed to execute on leader: %s", err.Error()) } + time.Sleep(time.Second) + // Perform a bunch of linearizable queries concurrently, to stress test // the system. Must be done on Leader. - count := 100 var wg sync.WaitGroup wg.Add(count) - for i := 0; i < count; i++ { + for range count { go func() { defer wg.Done() qr := queryRequestFromString("SELECT * FROM foo", false, false) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rqlite-9.1.0/store/store_test.go new/rqlite-9.1.2/store/store_test.go --- old/rqlite-9.1.0/store/store_test.go 2025-09-19 13:59:02.000000000 +0200 +++ new/rqlite-9.1.2/store/store_test.go 2025-10-03 16:33:42.000000000 +0200 @@ -1015,6 +1015,71 @@ } } +// Test_SingleNodeRequest_Linearizable tests that a Store correctly responds to a +// simple Request with Linearizable consistency level. +func Test_SingleNodeRequest_Linearizable(t *testing.T) { + s, ln := mustNewStore(t) + defer ln.Close() + + if err := s.Open(); err != nil { + t.Fatalf("failed to open single-node store: %s", err.Error()) + } + if err := s.Bootstrap(NewServer(s.ID(), s.Addr(), true)); err != nil { + t.Fatalf("failed to bootstrap single-node store: %s", err.Error()) + } + defer s.Close(true) + _, err := s.WaitForLeader(10 * time.Second) + if err != nil { + t.Fatalf("Error waiting for leader: %s", err) + } + + er := executeRequestFromStrings([]string{ + `CREATE TABLE foo (id INTEGER NOT NULL PRIMARY KEY, name TEXT)`, + `INSERT INTO foo(id, name) VALUES(1, "fiona")`, + }, false, false) + _, _, err = s.Execute(er) + if err != nil { + t.Fatalf("failed to execute on single node: %s", err.Error()) + } + + // Perform the first linearizable request, which should be upgraded to a strong query. + eqr := executeQueryRequestFromString("SELECT * FROM foo", proto.QueryRequest_QUERY_REQUEST_LEVEL_LINEARIZABLE, false, false) + r, _, err := s.Request(eqr) + if err != nil { + t.Fatalf("failed to perform linearizable request on single node: %s", err.Error()) + } + if r[0].GetQ() == nil { + t.Fatalf("expected query result, got %v", r[0]) + } + if exp, got := `["id","name"]`, asJSON(r[0].GetQ().Columns); exp != got { + t.Fatalf("unexpected results for request\nexp: %s\ngot: %s", exp, got) + } + if exp, got := `[[1,"fiona"]]`, asJSON(r[0].GetQ().Values); exp != got { + t.Fatalf("unexpected results for request\nexp: %s\ngot: %s", exp, got) + } + if s.numLRUpgraded.Load() != 1 { + t.Fatalf("expected 1 linearizable upgrade, got %d", s.numLRUpgraded.Load()) + } + + // Perform the second linearizable request, which should not be upgraded to a strong query. + r, _, err = s.Request(eqr) + if err != nil { + t.Fatalf("failed to perform linearizable request on single node: %s", err.Error()) + } + if r[0].GetQ() == nil { + t.Fatalf("expected query result, got %v", r[0]) + } + if exp, got := `["id","name"]`, asJSON(r[0].GetQ().Columns); exp != got { + t.Fatalf("unexpected results for request\nexp: %s\ngot: %s", exp, got) + } + if exp, got := `[[1,"fiona"]]`, asJSON(r[0].GetQ().Values); exp != got { + t.Fatalf("unexpected results for request\nexp: %s\ngot: %s", exp, got) + } + if s.numLRUpgraded.Load() != 1 { + t.Fatalf("expected 1 linearizable upgrade, got %d", s.numLRUpgraded.Load()) + } +} + // Test_SingleNodeExecuteQueryTx tests that a Store correctly responds to a simple // Execute and Query request, when the request is wrapped in a transaction. func Test_SingleNodeExecuteQueryTx(t *testing.T) { ++++++ vendor.tar.xz ++++++ ++++ 25461 lines of diff (skipped)
